summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-01-11 19:46:12 (GMT)
committerBrad King <brad.king@kitware.com>2021-01-11 20:00:51 (GMT)
commit9f48a468cd68d69e16302174ff202e9e51035023 (patch)
tree2fe4a4c3ba4b9eb2d6996014536faebd2036e458 /Source
parente20560a2dc9668bb9fd55bea79ef7508ab72c746 (diff)
parent06dfa5a7b6c0174bfcb4691a9aaf00809bd7271d (diff)
downloadCMake-9f48a468cd68d69e16302174ff202e9e51035023.zip
CMake-9f48a468cd68d69e16302174ff202e9e51035023.tar.gz
CMake-9f48a468cd68d69e16302174ff202e9e51035023.tar.bz2
Merge branch 'master' into cmake-gui-qrc-fix
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt23
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx35
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h4
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx8
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.h2
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.cxx6
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx63
-rw-r--r--Source/CPack/cmCPackComponentGroup.cxx2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx186
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackGenerator.cxx67
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx32
-rw-r--r--Source/CPack/cmCPackNuGetGenerator.cxx23
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx65
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx2
-rw-r--r--Source/CTest/cmCTestBZR.cxx6
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx45
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx8
-rw-r--r--Source/CTest/cmCTestLaunchReporter.cxx2
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx24
-rw-r--r--Source/CTest/cmCTestP4.cxx72
-rw-r--r--Source/CTest/cmCTestRunTest.cxx17
-rw-r--r--Source/CTest/cmCTestSVN.cxx8
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx8
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx3
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.cxx4
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx4
-rw-r--r--Source/CTest/cmParseDelphiCoverage.cxx2
-rw-r--r--Source/CTest/cmProcess.cxx2
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.cxx2
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.in.l2
-rw-r--r--Source/QtDialog/CMakeLists.txt132
-rw-r--r--Source/QtDialog/CMakeSetup.cxx6
-rw-r--r--Source/QtDialog/EnvironmentDialog.cxx4
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx4
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx38
-rw-r--r--Source/bindexplib.cxx4
-rw-r--r--Source/cmAddCustomCommandCommand.cxx40
-rw-r--r--Source/cmAddCustomTargetCommand.cxx14
-rw-r--r--Source/cmAlgorithms.h3
-rw-r--r--Source/cmArchiveWrite.h2
-rw-r--r--Source/cmCMakePathCommand.cxx113
-rw-r--r--Source/cmCMakePolicyCommand.cxx3
-rw-r--r--Source/cmCPluginAPI.cxx11
-rw-r--r--Source/cmCTest.cxx52
-rw-r--r--Source/cmCheckCustomOutputs.cxx36
-rw-r--r--Source/cmCheckCustomOutputs.h15
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx2
-rw-r--r--Source/cmCommandLineArgument.h159
-rw-r--r--Source/cmCommands.cxx19
-rw-r--r--Source/cmCommonTargetGenerator.cxx2
-rw-r--r--Source/cmComputeLinkInformation.cxx18
-rw-r--r--Source/cmComputeLinkInformation.h1
-rw-r--r--Source/cmComputeTargetDepends.cxx2
-rw-r--r--Source/cmConditionEvaluator.cxx16
-rw-r--r--Source/cmConfigureFileCommand.cxx109
-rw-r--r--Source/cmConnection.cxx173
-rw-r--r--Source/cmConnection.h137
-rw-r--r--Source/cmCreateTestSourceList.cxx4
-rw-r--r--Source/cmCryptoHash.cxx2
-rw-r--r--Source/cmCustomCommandGenerator.cxx265
-rw-r--r--Source/cmCustomCommandGenerator.h25
-rw-r--r--Source/cmCustomCommandTypes.h7
-rw-r--r--Source/cmDependsC.cxx31
-rw-r--r--Source/cmDependsCompiler.cxx261
-rw-r--r--Source/cmDependsCompiler.h60
-rw-r--r--Source/cmDependsFortran.cxx29
-rw-r--r--Source/cmDocumentation.cxx2
-rw-r--r--Source/cmELF.cxx8
-rw-r--r--Source/cmExportFileGenerator.cxx6
-rw-r--r--Source/cmExprParserHelper.cxx16
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h6
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx35
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx36
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx7
-rw-r--r--Source/cmFileAPICMakeFiles.cxx4
-rw-r--r--Source/cmFileAPICache.cxx2
-rw-r--r--Source/cmFileAPICodemodel.cxx2
-rw-r--r--Source/cmFileCommand.cxx249
-rw-r--r--Source/cmFileMonitor.cxx383
-rw-r--r--Source/cmFileMonitor.h35
-rw-r--r--Source/cmFilePathChecksum.cxx13
-rw-r--r--Source/cmFileTimes.cxx6
-rw-r--r--Source/cmFileTimes.h2
-rw-r--r--Source/cmFindCommon.cxx4
-rw-r--r--Source/cmFindLibraryCommand.cxx2
-rw-r--r--Source/cmFindPackageCommand.cxx12
-rw-r--r--Source/cmFindPathCommand.cxx2
-rw-r--r--Source/cmFindProgramCommand.cxx8
-rw-r--r--Source/cmFunctionCommand.cxx7
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx33
-rw-r--r--Source/cmGccDepfileLexerHelper.h3
-rw-r--r--Source/cmGccDepfileReader.cxx38
-rw-r--r--Source/cmGccDepfileReader.h10
-rw-r--r--Source/cmGeneratedFileStream.cxx8
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx6
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx23
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h2
-rw-r--r--Source/cmGeneratorExpressionLexer.cxx4
-rw-r--r--Source/cmGeneratorExpressionNode.cxx14
-rw-r--r--Source/cmGeneratorExpressionParser.cxx2
-rw-r--r--Source/cmGeneratorTarget.cxx142
-rw-r--r--Source/cmGeneratorTarget.h11
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx43
-rw-r--r--Source/cmGetPropertyCommand.cxx22
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx7
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx15
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx9
-rw-r--r--Source/cmGlobalGenerator.cxx17
-rw-r--r--Source/cmGlobalGenerator.h29
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx20
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx431
-rw-r--r--Source/cmGlobalNinjaGenerator.h86
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx15
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h27
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx7
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx274
-rw-r--r--Source/cmGlobalXCodeGenerator.h8
-rw-r--r--Source/cmGraphVizWriter.cxx32
-rw-r--r--Source/cmIncludeCommand.cxx22
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx2
-rw-r--r--Source/cmInstallExportGenerator.cxx6
-rw-r--r--Source/cmInstallFilesGenerator.cxx2
-rw-r--r--Source/cmInstallScriptGenerator.cxx2
-rw-r--r--Source/cmJsonObjectDictionary.h45
-rw-r--r--Source/cmJsonObjects.cxx692
-rw-r--r--Source/cmJsonObjects.h24
-rw-r--r--Source/cmLinkedTree.h4
-rw-r--r--Source/cmListCommand.cxx25
-rw-r--r--Source/cmListFileCache.cxx122
-rw-r--r--Source/cmListFileCache.h10
-rw-r--r--Source/cmLoadCommandCommand.cxx11
-rw-r--r--Source/cmLocalGenerator.cxx499
-rw-r--r--Source/cmLocalGenerator.h115
-rw-r--r--Source/cmLocalNinjaGenerator.cxx321
-rw-r--r--Source/cmLocalNinjaGenerator.h14
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx570
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h33
-rw-r--r--Source/cmMSVC60LinkLineComputer.cxx2
-rw-r--r--Source/cmMacroCommand.cxx7
-rw-r--r--Source/cmMakefile.cxx375
-rw-r--r--Source/cmMakefile.h120
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx13
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx256
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx39
-rw-r--r--Source/cmNewLineStyle.cxx14
-rw-r--r--Source/cmNinjaLinkLineComputer.cxx2
-rw-r--r--Source/cmNinjaLinkLineDeviceComputer.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx68
-rw-r--r--Source/cmNinjaTargetGenerator.cxx567
-rw-r--r--Source/cmNinjaTargetGenerator.h19
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx60
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.h4
-rw-r--r--Source/cmPipeConnection.cxx71
-rw-r--r--Source/cmPipeConnection.h29
-rw-r--r--Source/cmPolicies.h22
-rw-r--r--Source/cmProcessOutput.cxx4
-rw-r--r--Source/cmProjectCommand.cxx13
-rw-r--r--Source/cmPropertyMap.cxx22
-rw-r--r--Source/cmQTWrapCPPCommand.cxx3
-rw-r--r--Source/cmQtAutoGen.h12
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx54
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h2
-rw-r--r--Source/cmQtAutoGenInitializer.cxx219
-rw-r--r--Source/cmQtAutoGenInitializer.h7
-rw-r--r--Source/cmQtAutoGenerator.cxx119
-rw-r--r--Source/cmQtAutoGenerator.h14
-rw-r--r--Source/cmQtAutoMocUic.cxx1257
-rw-r--r--Source/cmQtAutoRcc.cxx360
-rw-r--r--Source/cmRulePlaceholderExpander.cxx16
-rw-r--r--Source/cmRulePlaceholderExpander.h79
-rw-r--r--Source/cmScanDepFormat.cxx265
-rw-r--r--Source/cmScanDepFormat.h30
-rw-r--r--Source/cmServer.cxx570
-rw-r--r--Source/cmServer.h162
-rw-r--r--Source/cmServerConnection.cxx165
-rw-r--r--Source/cmServerConnection.h67
-rw-r--r--Source/cmServerDictionary.h67
-rw-r--r--Source/cmServerProtocol.cxx760
-rw-r--r--Source/cmServerProtocol.h162
-rw-r--r--Source/cmSetPropertyCommand.cxx105
-rw-r--r--Source/cmSetPropertyCommand.h15
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx11
-rw-r--r--Source/cmSourceFile.cxx157
-rw-r--r--Source/cmSourceFile.h47
-rw-r--r--Source/cmSourceFileLocation.cxx3
-rw-r--r--Source/cmStandardLevelResolver.cxx43
-rw-r--r--Source/cmState.cxx33
-rw-r--r--Source/cmState.h8
-rw-r--r--Source/cmStateDirectory.cxx10
-rw-r--r--Source/cmString.cxx43
-rw-r--r--Source/cmString.hxx134
-rw-r--r--Source/cmStringAlgorithms.cxx16
-rw-r--r--Source/cmStringAlgorithms.h8
-rw-r--r--Source/cmStringCommand.cxx12
-rw-r--r--Source/cmSystemTools.cxx24
-rw-r--r--Source/cmSystemTools.h6
-rw-r--r--Source/cmTarget.cxx701
-rw-r--r--Source/cmTarget.h5
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx5
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx2
-rw-r--r--Source/cmTargetPropCommandBase.cxx41
-rw-r--r--Source/cmTargetPropCommandBase.h5
-rw-r--r--Source/cmTargetSourcesCommand.cxx8
-rw-r--r--Source/cmTestGenerator.cxx2
-rw-r--r--Source/cmTimestamp.cxx6
-rw-r--r--Source/cmTransformDepfile.cxx101
-rw-r--r--Source/cmTransformDepfile.h14
-rw-r--r--Source/cmUVHandlePtr.cxx43
-rw-r--r--Source/cmUVHandlePtr.h2
-rw-r--r--Source/cmUuid.cxx6
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx92
-rw-r--r--Source/cmWorkerPool.cxx341
-rw-r--r--Source/cmWorkerPool.h23
-rw-r--r--Source/cmWorkingDirectory.h4
-rw-r--r--Source/cmXCodeObject.h7
-rw-r--r--Source/cmXMLWriter.h20
-rw-r--r--Source/cm_codecvt.cxx8
-rw-r--r--Source/cmake.cxx827
-rw-r--r--Source/cmake.h20
-rw-r--r--Source/cmakemain.cxx418
-rw-r--r--Source/cmcmd.cxx302
-rw-r--r--Source/ctest.cxx1
-rw-r--r--Source/kwsys/SystemInformation.cxx68
228 files changed, 8670 insertions, 8437 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ca56d3a..c5b67c0 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -181,8 +181,6 @@ set(SRCS
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
cmCacheManager.cxx
cmCacheManager.h
- cmCheckCustomOutputs.h
- cmCheckCustomOutputs.cxx
cmCLocaleEnvironmentScope.h
cmCLocaleEnvironmentScope.cxx
cmCMakePath.h
@@ -227,6 +225,8 @@ set(SRCS
cmDependsJava.h
cmDependsJavaParserHelper.cxx
cmDependsJavaParserHelper.h
+ cmDependsCompiler.cxx
+ cmDependsCompiler.h
cmDocumentation.cxx
cmDocumentationFormatter.cxx
cmDocumentationSection.cxx
@@ -444,6 +444,8 @@ set(SRCS
cmTest.h
cmTestGenerator.cxx
cmTestGenerator.h
+ cmTransformDepfile.cxx
+ cmTransformDepfile.h
cmUuid.cxx
cmUVHandlePtr.cxx
cmUVHandlePtr.h
@@ -508,6 +510,8 @@ set(SRCS
cmCMakeLanguageCommand.h
cmCMakeMinimumRequired.cxx
cmCMakeMinimumRequired.h
+ cmCMakePathCommand.h
+ cmCMakePathCommand.cxx
cmCMakePolicyCommand.cxx
cmCMakePolicyCommand.h
cmConditionEvaluator.cxx
@@ -833,6 +837,7 @@ endif()
# Ninja support
set(SRCS ${SRCS}
+ cmScanDepFormat.cxx
cmGlobalNinjaGenerator.cxx
cmGlobalNinjaGenerator.h
cmNinjaTypes.h
@@ -1157,20 +1162,6 @@ add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h ${MANIFEST_FILE})
list(APPEND _tools cmake)
target_link_libraries(cmake CMakeLib)
-add_library(CMakeServerLib
- cmConnection.h cmConnection.cxx
- cmFileMonitor.cxx cmFileMonitor.h
- cmJsonObjectDictionary.h
- cmJsonObjects.h
- cmJsonObjects.cxx
- cmPipeConnection.cxx cmPipeConnection.h
- cmServer.cxx cmServer.h
- cmServerConnection.cxx cmServerConnection.h
- cmServerProtocol.cxx cmServerProtocol.h
- )
-target_link_libraries(CMakeServerLib CMakeLib)
-target_link_libraries(cmake CMakeServerLib)
-
# Build CTest executable
add_executable(ctest ctest.cxx ${MANIFEST_FILE})
list(APPEND _tools ctest)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 799b2fc..a92003f 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 19)
-set(CMake_VERSION_PATCH 2)
+set(CMake_VERSION_PATCH 20210111)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index 4bad598..359fc56 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -66,7 +66,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
this->GetOption("CPACK_IFW_PACKAGE_PUBLISHER")) {
this->Publisher = optIFW_PACKAGE_PUBLISHER;
} else if (const char* optPACKAGE_VENDOR =
- GetOption("CPACK_PACKAGE_VENDOR")) {
+ this->GetOption("CPACK_PACKAGE_VENDOR")) {
this->Publisher = optPACKAGE_VENDOR;
}
@@ -174,6 +174,26 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
this->WizardDefaultHeight = option;
}
+ // WizardShowPageList
+ if (const char* option =
+ this->GetOption("CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST")) {
+ if (!this->IsVersionLess("4.0")) {
+ if (this->IsSetToOff("CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST")) {
+ this->WizardShowPageList = "false";
+ } else if (this->IsOn("CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST")) {
+ this->WizardShowPageList = "true";
+ } else {
+ this->WizardShowPageList.clear();
+ }
+ } else {
+ cmCPackIFWLogger(
+ WARNING,
+ "Option CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST is set to value \""
+ << option << "\". But has no any effect for QtIFW less than 4.0 "
+ << "and will be skipped." << std::endl);
+ }
+ }
+
// TitleColor
if (const char* option = this->GetOption("CPACK_IFW_PACKAGE_TITLE_COLOR")) {
this->TitleColor = option;
@@ -184,7 +204,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) {
this->StartMenuDir = optIFW_START_MENU_DIR;
} else {
- this->StartMenuDir = Name;
+ this->StartMenuDir = this->Name;
}
// Default target directory for installation
@@ -283,7 +303,7 @@ protected:
void StartElement(const std::string& name, const char** /*atts*/) override
{
this->file = name == "file";
- if (file) {
+ if (this->file) {
this->hasFiles = true;
}
}
@@ -317,7 +337,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile()
xout.StartDocument();
- WriteGeneratedByToStrim(xout);
+ this->WriteGeneratedByToStrim(xout);
xout.StartElement("Installer");
@@ -408,6 +428,11 @@ void cmCPackIFWInstaller::GenerateInstallerFile()
xout.Element("WizardDefaultHeight", this->WizardDefaultHeight);
}
+ // WizardShowPageList
+ if (!this->IsVersionLess("4.0") && !this->WizardShowPageList.empty()) {
+ xout.Element("WizardShowPageList", this->WizardShowPageList);
+ }
+
// TitleColor
if (!this->TitleColor.empty()) {
xout.Element("TitleColor", this->TitleColor);
@@ -510,7 +535,7 @@ void cmCPackIFWInstaller::GeneratePackageFiles()
package.ConfigureFromGroup(option);
std::string forcedOption = "CPACK_IFW_COMPONENT_GROUP_" +
cmsys::SystemTools::UpperCase(option) + "_FORCED_INSTALLATION";
- if (!GetOption(forcedOption)) {
+ if (!this->GetOption(forcedOption)) {
package.ForcedInstallation = "true";
}
} else {
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
index 6f398e3..a031fc2 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.h
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -80,6 +80,10 @@ public:
/// Wizard height
std::string WizardDefaultHeight;
+ /// Set to false if the widget listing installer pages on the left side
+ /// of the wizard should not be shown
+ std::string WizardShowPageList;
+
/// Title color
std::string TitleColor;
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 56a74c5..c4bd7f1 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -337,7 +337,7 @@ int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName)
group.Name = groupName;
- if (Generator) {
+ if (this->Generator) {
this->Name = this->Generator->GetGroupPackageName(&group);
} else {
this->Name = group.Name;
@@ -530,7 +530,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
xout.StartDocument();
- WriteGeneratedByToStrim(xout);
+ this->WriteGeneratedByToStrim(xout);
xout.StartElement("Package");
@@ -577,7 +577,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
}
// User Interfaces (copy to meta dir)
- std::vector<std::string> userInterfaces = UserInterfaces;
+ std::vector<std::string> userInterfaces = this->UserInterfaces;
for (std::string& userInterface : userInterfaces) {
std::string name = cmSystemTools::GetFilenameName(userInterface);
std::string path = this->Directory + "/meta/" + name;
@@ -593,7 +593,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
}
// Translations (copy to meta dir)
- std::vector<std::string> translations = Translations;
+ std::vector<std::string> translations = this->Translations;
for (std::string& translation : translations) {
std::string name = cmSystemTools::GetFilenameName(translation);
std::string path = this->Directory + "/meta/" + name;
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h
index dbd5540..0cc6f2f 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.h
+++ b/Source/CPack/IFW/cmCPackIFWPackage.h
@@ -53,7 +53,7 @@ public:
bool operator<(const DependenceStruct& other) const
{
- return Name < other.Name;
+ return this->Name < other.Name;
}
};
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index f5e8744..1287907 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -46,9 +46,9 @@ bool cmCPackIFWRepository::ConfigureFromOptions()
// Update
if (this->IsOn(prefix + "ADD")) {
this->Update = cmCPackIFWRepository::Add;
- } else if (IsOn(prefix + "REMOVE")) {
+ } else if (this->IsOn(prefix + "REMOVE")) {
this->Update = cmCPackIFWRepository::Remove;
- } else if (IsOn(prefix + "REPLACE")) {
+ } else if (this->IsOn(prefix + "REPLACE")) {
this->Update = cmCPackIFWRepository::Replace;
} else {
this->Update = cmCPackIFWRepository::None;
@@ -247,7 +247,7 @@ void cmCPackIFWRepository::WriteRepositoryUpdate(cmXMLWriter& xout)
if (this->Update == cmCPackIFWRepository::Add ||
this->Update == cmCPackIFWRepository::Remove) {
xout.Attribute("url", this->Url);
- } else if (Update == cmCPackIFWRepository::Replace) {
+ } else if (this->Update == cmCPackIFWRepository::Replace) {
xout.Attribute("oldUrl", this->OldUrl);
xout.Attribute("newUrl", this->NewUrl);
}
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 967cc60..5348f86 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -80,10 +80,10 @@ std::string cmCPackArchiveGenerator::GetArchiveComponentFileName(
packageFileName +=
this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME");
} else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
- packageFileName += GetComponentPackageFileName(
+ packageFileName += this->GetComponentPackageFileName(
this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName);
} else {
- packageFileName += GetComponentPackageFileName(
+ packageFileName += this->GetComponentPackageFileName(
this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName);
}
@@ -181,7 +181,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
{
- packageFileNames.clear();
+ this->packageFileNames.clear();
// The default behavior is to have one package by component group
// unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
if (!ignoreGroup) {
@@ -189,7 +189,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging component group: " << compG.first << std::endl);
// Begin the archive for this group
- std::string packageFileName = std::string(toplevel) + "/" +
+ std::string packageFileName = std::string(this->toplevel) + "/" +
this->GetArchiveComponentFileName(compG.first, true);
// open a block in order to automatically close archive
@@ -199,11 +199,11 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
// now iterate over the component of this group
for (cmCPackComponent* comp : (compG.second).Components) {
// Add the files of this component to the archive
- addOneComponentToArchive(archive, comp);
+ this->addOneComponentToArchive(archive, comp);
}
}
// add the generated package to package file names list
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
}
// Handle Orphan components (components not belonging to any groups)
for (auto& comp : this->Components) {
@@ -217,7 +217,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
<< std::endl);
std::string localToplevel(
this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
- std::string packageFileName = std::string(toplevel);
+ std::string packageFileName = std::string(this->toplevel);
localToplevel += "/" + comp.first;
packageFileName +=
@@ -226,10 +226,10 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
{
DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
// Add the files of this component to the archive
- addOneComponentToArchive(archive, &(comp.second));
+ this->addOneComponentToArchive(archive, &(comp.second));
}
// add the generated package to package file names list
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
}
}
}
@@ -238,7 +238,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
else {
for (auto& comp : this->Components) {
std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
- std::string packageFileName = std::string(toplevel);
+ std::string packageFileName = std::string(this->toplevel);
localToplevel += "/" + comp.first;
packageFileName +=
@@ -247,10 +247,10 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
{
DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive);
// Add the files of this component to the archive
- addOneComponentToArchive(archive, &(comp.second));
+ this->addOneComponentToArchive(archive, &(comp.second));
}
// add the generated package to package file names list
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
}
}
return 1;
@@ -259,17 +259,17 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
int cmCPackArchiveGenerator::PackageComponentsAllInOne()
{
// reset the package file names
- packageFileNames.clear();
- packageFileNames.emplace_back(toplevel);
- packageFileNames[0] += "/";
+ this->packageFileNames.clear();
+ this->packageFileNames.emplace_back(this->toplevel);
+ this->packageFileNames[0] += "/";
if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) {
- packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME");
+ this->packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME");
} else {
- packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ this->packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME");
}
- packageFileNames[0] += this->GetOutputExtension();
+ this->packageFileNames[0] += this->GetOutputExtension();
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging all groups in one package..."
@@ -280,7 +280,7 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne()
// The ALL COMPONENTS in ONE package case
for (auto& comp : this->Components) {
// Add the files of this component to the archive
- addOneComponentToArchive(archive, &(comp.second));
+ this->addOneComponentToArchive(archive, &(comp.second));
}
// archive goes out of scope so it will finalized and closed.
@@ -289,41 +289,42 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne()
int cmCPackArchiveGenerator::PackageFiles()
{
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Toplevel: " << this->toplevel << std::endl);
- if (WantsComponentInstallation()) {
+ if (this->WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (componentPackageMethod == ONE_PACKAGE) {
- return PackageComponentsAllInOne();
+ if (this->componentPackageMethod == ONE_PACKAGE) {
+ return this->PackageComponentsAllInOne();
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- return PackageComponents(componentPackageMethod ==
- ONE_PACKAGE_PER_COMPONENT);
+ return this->PackageComponents(this->componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
// CASE 3 : NON COMPONENT package.
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive);
- cmWorkingDirectory workdir(toplevel);
+ cmWorkingDirectory workdir(this->toplevel);
if (workdir.Failed()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Failed to change working directory to "
- << toplevel << " : "
+ << this->toplevel << " : "
<< std::strerror(workdir.GetLastResult()) << std::endl);
return 0;
}
- for (std::string const& file : files) {
+ for (std::string const& file : this->files) {
// Get the relative path to the file
- std::string rp = cmSystemTools::RelativePath(toplevel, file);
+ std::string rp = cmSystemTools::RelativePath(this->toplevel, file);
archive.Add(rp, 0, nullptr, false);
if (!archive) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem while adding file <"
- << file << "> to archive <" << packageFileNames[0]
+ << file << "> to archive <" << this->packageFileNames[0]
<< ">, ERROR = " << archive.GetError() << std::endl);
return 0;
}
@@ -342,7 +343,7 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
// The Component installation support should only
// be activated if explicitly requested by the user
// (for backward compatibility reason)
- return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
+ return this->IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
}
bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive)
diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx
index d40e5fc..4305c7e 100644
--- a/Source/CPack/cmCPackComponentGroup.cxx
+++ b/Source/CPack/cmCPackComponentGroup.cxx
@@ -25,6 +25,6 @@ unsigned long cmCPackComponent::GetInstalledSize(
unsigned long cmCPackComponent::GetInstalledSizeInKbytes(
const std::string& installDir) const
{
- unsigned long result = (GetInstalledSize(installDir) + 512) / 1024;
+ unsigned long result = (this->GetInstalledSize(installDir) + 512) / 1024;
return result ? result : 1;
}
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 560e5c1..43dbdb5 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -96,20 +96,20 @@ DebGenerator::DebGenerator(
}
if (!strcmp(debianCompressionType, "lzma")) {
- CompressionSuffix = ".lzma";
- TarCompressionType = cmArchiveWrite::CompressLZMA;
+ this->CompressionSuffix = ".lzma";
+ this->TarCompressionType = cmArchiveWrite::CompressLZMA;
} else if (!strcmp(debianCompressionType, "xz")) {
- CompressionSuffix = ".xz";
- TarCompressionType = cmArchiveWrite::CompressXZ;
+ this->CompressionSuffix = ".xz";
+ this->TarCompressionType = cmArchiveWrite::CompressXZ;
} else if (!strcmp(debianCompressionType, "bzip2")) {
- CompressionSuffix = ".bz2";
- TarCompressionType = cmArchiveWrite::CompressBZip2;
+ this->CompressionSuffix = ".bz2";
+ this->TarCompressionType = cmArchiveWrite::CompressBZip2;
} else if (!strcmp(debianCompressionType, "gzip")) {
- CompressionSuffix = ".gz";
- TarCompressionType = cmArchiveWrite::CompressGZip;
+ this->CompressionSuffix = ".gz";
+ this->TarCompressionType = cmArchiveWrite::CompressGZip;
} else if (!strcmp(debianCompressionType, "none")) {
- CompressionSuffix.clear();
- TarCompressionType = cmArchiveWrite::CompressNone;
+ this->CompressionSuffix.clear();
+ this->TarCompressionType = cmArchiveWrite::CompressNone;
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error unrecognized compression type: "
@@ -119,22 +119,22 @@ DebGenerator::DebGenerator(
bool DebGenerator::generate() const
{
- generateDebianBinaryFile();
- generateControlFile();
- if (!generateDataTar()) {
+ this->generateDebianBinaryFile();
+ this->generateControlFile();
+ if (!this->generateDataTar()) {
return false;
}
- std::string md5Filename = generateMD5File();
- if (!generateControlTar(md5Filename)) {
+ std::string md5Filename = this->generateMD5File();
+ if (!this->generateControlTar(md5Filename)) {
return false;
}
- return generateDeb();
+ return this->generateDeb();
}
void DebGenerator::generateDebianBinaryFile() const
{
// debian-binary file
- const std::string dbfilename = WorkDir + "/debian-binary";
+ const std::string dbfilename = this->WorkDir + "/debian-binary";
cmGeneratedFileStream out;
out.Open(dbfilename, false, true);
out << "2.0\n"; // required for valid debian package
@@ -142,18 +142,18 @@ void DebGenerator::generateDebianBinaryFile() const
void DebGenerator::generateControlFile() const
{
- std::string ctlfilename = WorkDir + "/control";
+ std::string ctlfilename = this->WorkDir + "/control";
cmGeneratedFileStream out;
out.Open(ctlfilename, false, true);
- for (auto const& kv : ControlValues) {
+ for (auto const& kv : this->ControlValues) {
out << kv.first << ": " << kv.second << "\n";
}
unsigned long totalSize = 0;
{
- std::string dirName = cmStrCat(TemporaryDir, '/');
- for (std::string const& file : PackageFiles) {
+ std::string dirName = cmStrCat(this->TemporaryDir, '/');
+ for (std::string const& file : this->PackageFiles) {
totalSize += cmSystemTools::FileLength(file);
}
}
@@ -162,7 +162,8 @@ void DebGenerator::generateControlFile() const
bool DebGenerator::generateDataTar() const
{
- std::string filename_data_tar = WorkDir + "/data.tar" + CompressionSuffix;
+ std::string filename_data_tar =
+ this->WorkDir + "/data.tar" + this->CompressionSuffix;
cmGeneratedFileStream fileStream_data_tar;
fileStream_data_tar.Open(filename_data_tar, false, true);
if (!fileStream_data_tar) {
@@ -171,8 +172,8 @@ bool DebGenerator::generateDataTar() const
<< filename_data_tar << "\" for writing" << std::endl);
return false;
}
- cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType,
- DebianArchiveType);
+ cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType,
+ this->DebianArchiveType);
data_tar.Open();
// uid/gid should be the one of the root user, and this root user has
@@ -184,16 +185,16 @@ bool DebGenerator::generateDataTar() const
// collect all top level install dirs for that
// e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
// give /usr and /opt
- size_t topLevelLength = WorkDir.length();
+ size_t topLevelLength = this->WorkDir.length();
cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "WDIR: \"" << WorkDir << "\", length = " << topLevelLength
- << std::endl);
+ "WDIR: \"" << this->WorkDir
+ << "\", length = " << topLevelLength << std::endl);
std::set<std::string> orderedFiles;
// we have to reconstruct the parent folders as well
- for (std::string currentPath : PackageFiles) {
- while (currentPath != WorkDir) {
+ for (std::string currentPath : this->PackageFiles) {
+ while (currentPath != this->WorkDir) {
// the last one IS WorkDir, but we do not want this one:
// XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
// should not add XXX/application
@@ -235,7 +236,7 @@ bool DebGenerator::generateDataTar() const
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem adding file to tar:"
<< std::endl
- << "#top level directory: " << WorkDir << std::endl
+ << "#top level directory: " << this->WorkDir << std::endl
<< "#file: " << file << std::endl
<< "#error:" << data_tar.GetError() << std::endl);
return false;
@@ -246,13 +247,13 @@ bool DebGenerator::generateDataTar() const
std::string DebGenerator::generateMD5File() const
{
- std::string md5filename = WorkDir + "/md5sums";
+ std::string md5filename = this->WorkDir + "/md5sums";
cmGeneratedFileStream out;
out.Open(md5filename, false, true);
- std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/');
- for (std::string const& file : PackageFiles) {
+ std::string topLevelWithTrailingSlash = cmStrCat(this->TemporaryDir, '/');
+ for (std::string const& file : this->PackageFiles) {
// hash only regular files
if (cmSystemTools::FileIsDirectory(file) ||
cmSystemTools::FileIsSymlink(file)) {
@@ -281,7 +282,7 @@ std::string DebGenerator::generateMD5File() const
bool DebGenerator::generateControlTar(std::string const& md5Filename) const
{
- std::string filename_control_tar = WorkDir + "/control.tar.gz";
+ std::string filename_control_tar = this->WorkDir + "/control.tar.gz";
cmGeneratedFileStream fileStream_control_tar;
fileStream_control_tar.Open(filename_control_tar, false, true);
@@ -292,7 +293,8 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
return false;
}
cmArchiveWrite control_tar(fileStream_control_tar,
- cmArchiveWrite::CompressGZip, DebianArchiveType);
+ cmArchiveWrite::CompressGZip,
+ this->DebianArchiveType);
control_tar.Open();
// sets permissions and uid/gid for the files
@@ -314,24 +316,25 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
control_tar.SetPermissions(permission644);
// adds control and md5sums
- if (!control_tar.Add(md5Filename, WorkDir.length(), ".") ||
- !control_tar.Add(WorkDir + "/control", WorkDir.length(), ".")) {
+ if (!control_tar.Add(md5Filename, this->WorkDir.length(), ".") ||
+ !control_tar.Add(this->WorkDir + "/control", this->WorkDir.length(),
+ ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error adding file to tar:"
<< std::endl
- << "#top level directory: " << WorkDir << std::endl
+ << "#top level directory: " << this->WorkDir << std::endl
<< "#file: \"control\" or \"md5sums\"" << std::endl
<< "#error:" << control_tar.GetError() << std::endl);
return false;
}
// adds generated shlibs file
- if (GenShLibs) {
- if (!control_tar.Add(ShLibsFilename, WorkDir.length(), ".")) {
+ if (this->GenShLibs) {
+ if (!control_tar.Add(this->ShLibsFilename, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error adding file to tar:"
<< std::endl
- << "#top level directory: " << WorkDir << std::endl
+ << "#top level directory: " << this->WorkDir << std::endl
<< "#file: \"shlibs\"" << std::endl
<< "#error:" << control_tar.GetError() << std::endl);
return false;
@@ -339,13 +342,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
}
// adds LDCONFIG related files
- if (GenPostInst) {
+ if (this->GenPostInst) {
control_tar.SetPermissions(permission755);
- if (!control_tar.Add(PostInst, WorkDir.length(), ".")) {
+ if (!control_tar.Add(this->PostInst, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error adding file to tar:"
<< std::endl
- << "#top level directory: " << WorkDir << std::endl
+ << "#top level directory: " << this->WorkDir << std::endl
<< "#file: \"postinst\"" << std::endl
<< "#error:" << control_tar.GetError() << std::endl);
return false;
@@ -353,13 +356,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
control_tar.SetPermissions(permission644);
}
- if (GenPostRm) {
+ if (this->GenPostRm) {
control_tar.SetPermissions(permission755);
- if (!control_tar.Add(PostRm, WorkDir.length(), ".")) {
+ if (!control_tar.Add(this->PostRm, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error adding file to tar:"
<< std::endl
- << "#top level directory: " << WorkDir << std::endl
+ << "#top level directory: " << this->WorkDir << std::endl
<< "#file: \"postinst\"" << std::endl
<< "#error:" << control_tar.GetError() << std::endl);
return false;
@@ -370,7 +373,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// for the other files, we use
// -either the original permission on the files
// -either a permission strictly defined by the Debian policies
- if (ControlExtra) {
+ if (this->ControlExtra) {
// permissions are now controlled by the original file permissions
static const char* strictFiles[] = { "config", "postinst", "postrm",
@@ -381,19 +384,20 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// default
control_tar.ClearPermissions();
- std::vector<std::string> controlExtraList = cmExpandedList(ControlExtra);
+ std::vector<std::string> controlExtraList =
+ cmExpandedList(this->ControlExtra);
for (std::string const& i : controlExtraList) {
std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
- std::string localcopy = WorkDir + "/" + filenamename;
+ std::string localcopy = this->WorkDir + "/" + filenamename;
- if (PermissionStrictPolicy) {
+ if (this->PermissionStrictPolicy) {
control_tar.SetPermissions(
setStrictFiles.count(filenamename) ? permission755 : permission644);
}
// if we can copy the file, it means it does exist, let's add it:
if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) {
- control_tar.Add(localcopy, WorkDir.length(), ".");
+ control_tar.Add(localcopy, this->WorkDir.length(), ".");
}
}
}
@@ -408,8 +412,8 @@ bool DebGenerator::generateDeb() const
// difference is that debian uses the BSD ar style archive whereas most
// Linux distro have a GNU ar.
// See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
- std::string const outputPath = TopLevelDir + "/" + OutputName;
- std::string const tlDir = WorkDir + "/";
+ std::string const outputPath = this->TopLevelDir + "/" + this->OutputName;
+ std::string const tlDir = this->WorkDir + "/";
cmGeneratedFileStream debStream;
debStream.Open(outputPath, false, true);
cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
@@ -422,12 +426,13 @@ bool DebGenerator::generateDeb() const
if (!deb.Add(tlDir + "debian-binary", tlDir.length()) ||
!deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
- !deb.Add(tlDir + "data.tar" + CompressionSuffix, tlDir.length())) {
+ !deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error creating debian package:"
<< std::endl
- << "#top level directory: " << TopLevelDir << std::endl
- << "#file: " << OutputName << std::endl
+ << "#top level directory: " << this->TopLevelDir
+ << std::endl
+ << "#file: " << this->OutputName << std::endl
<< "#error:" << deb.GetError() << std::endl);
return false;
}
@@ -455,7 +460,8 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
int retval = 1;
// Begin the archive for this pack
std::string localToplevel(initialTopLevel);
- std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(this->toplevel));
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + "-" +
packageName + this->GetOutputExtension());
@@ -495,19 +501,20 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
<< std::endl);
return 0;
}
- packageFiles = gl.GetFiles();
+ this->packageFiles = gl.GetFiles();
}
- int res = createDeb();
+ int res = this->createDeb();
if (res != 1) {
retval = 0;
}
// add the generated package to package file names list
packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
- if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE")) {
+ if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") &&
+ this->GetOption("GEN_DBGSYMDIR")) {
cmsys::Glob gl;
std::string findExpr(this->GetOption("GEN_DBGSYMDIR"));
findExpr += "/*";
@@ -520,9 +527,9 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
<< std::endl);
return 0;
}
- packageFiles = gl.GetFiles();
+ this->packageFiles = gl.GetFiles();
- res = createDbgsymDDeb();
+ res = this->createDbgsymDDeb();
if (res != 1) {
retval = 0;
}
@@ -530,7 +537,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
packageFileName =
cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"));
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
}
return retval;
@@ -541,7 +548,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
int retval = 1;
/* Reset package file name list it will be populated during the
* component packaging run*/
- packageFileNames.clear();
+ this->packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
// The default behavior is to have one package by component group
@@ -551,7 +558,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging component group: " << compG.first << std::endl);
// Begin the archive for this group
- retval &= PackageOnePack(initialTopLevel, compG.first);
+ retval &= this->PackageOnePack(initialTopLevel, compG.first);
}
// Handle Orphan components (components not belonging to any groups)
for (auto const& comp : this->Components) {
@@ -564,7 +571,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
<< "> does not belong to any group, package it separately."
<< std::endl);
// Begin the archive for this orphan component
- retval &= PackageOnePack(initialTopLevel, comp.first);
+ retval &= this->PackageOnePack(initialTopLevel, comp.first);
}
}
}
@@ -572,7 +579,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
// We build 1 package per component
else {
for (auto const& comp : this->Components) {
- retval &= PackageOnePack(initialTopLevel, comp.first);
+ retval &= this->PackageOnePack(initialTopLevel, comp.first);
}
}
return retval;
@@ -585,7 +592,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
int retval = 1;
/* Reset package file name list it will be populated during the
* component packaging run*/
- packageFileNames.clear();
+ this->packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
@@ -595,7 +602,8 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
// The ALL GROUPS in ONE package case
std::string localToplevel(initialTopLevel);
- std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(this->toplevel));
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) +
this->GetOutputExtension());
@@ -640,38 +648,38 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
<< std::endl);
return 0;
}
- packageFiles = gl.GetFiles();
+ this->packageFiles = gl.GetFiles();
- int res = createDeb();
+ int res = this->createDeb();
if (res != 1) {
retval = 0;
}
// add the generated package to package file names list
packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
- packageFileNames.push_back(std::move(packageFileName));
+ this->packageFileNames.push_back(std::move(packageFileName));
return retval;
}
int cmCPackDebGenerator::PackageFiles()
{
/* Are we in the component packaging case */
- if (WantsComponentInstallation()) {
+ if (this->WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (componentPackageMethod == ONE_PACKAGE) {
- return PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
+ if (this->componentPackageMethod == ONE_PACKAGE) {
+ return this->PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- return PackageComponents(componentPackageMethod ==
- ONE_PACKAGE_PER_COMPONENT);
+ return this->PackageComponents(this->componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
// CASE 3 : NON COMPONENT package.
- return PackageComponentsAllInOne("");
+ return this->PackageComponentsAllInOne("");
}
int cmCPackDebGenerator::createDeb()
@@ -786,7 +794,7 @@ int cmCPackDebGenerator::createDeb()
}
DebGenerator gen(
- Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR,
+ this->Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR,
this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
this->GetOption("CPACK_TEMPORARY_DIRECTORY"),
this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"),
@@ -795,7 +803,7 @@ int cmCPackDebGenerator::createDeb()
this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM"), postrm,
this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"),
this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
- packageFiles);
+ this->packageFiles);
if (!gen.generate()) {
return 0;
@@ -841,7 +849,7 @@ int cmCPackDebGenerator::createDbgsymDDeb()
}
DebGenerator gen(
- Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"),
+ this->Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"),
this->GetOption("GEN_DBGSYMDIR"),
this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
@@ -850,7 +858,7 @@ int cmCPackDebGenerator::createDbgsymDDeb()
this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, false, "",
false, "", false, "", nullptr,
this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
- packageFiles);
+ this->packageFiles);
if (!gen.generate()) {
return 0;
@@ -860,25 +868,25 @@ int cmCPackDebGenerator::createDbgsymDDeb()
bool cmCPackDebGenerator::SupportsComponentInstallation() const
{
- return IsOn("CPACK_DEB_COMPONENT_INSTALL");
+ return this->IsOn("CPACK_DEB_COMPONENT_INSTALL");
}
std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
const std::string& componentName)
{
- if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
+ if (this->componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
return componentName;
}
- if (componentPackageMethod == ONE_PACKAGE) {
+ if (this->componentPackageMethod == ONE_PACKAGE) {
return std::string("ALL_COMPONENTS_IN_ONE");
}
// We have to find the name of the COMPONENT GROUP
// the current COMPONENT belongs to.
std::string groupVar =
"CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
- if (nullptr != GetOption(groupVar)) {
- return std::string(GetOption(groupVar));
+ if (nullptr != this->GetOption(groupVar)) {
+ return std::string(this->GetOption(groupVar));
}
return componentName;
}
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 0bc8456..e3521a0 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -95,7 +95,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstallCommands(
bool setDestDir, const std::string& tempInstallDirectory)
{
if (this->StagingEnabled()) {
- return cmCPackGenerator::InstallProjectViaInstallCommands(
+ return this->cmCPackGenerator::InstallProjectViaInstallCommands(
setDestDir, tempInstallDirectory);
}
@@ -106,7 +106,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstallScript(
bool setDestDir, const std::string& tempInstallDirectory)
{
if (this->StagingEnabled()) {
- return cmCPackGenerator::InstallProjectViaInstallScript(
+ return this->cmCPackGenerator::InstallProjectViaInstallScript(
setDestDir, tempInstallDirectory);
}
@@ -118,7 +118,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories(
const mode_t* default_dir_mode)
{
if (this->StagingEnabled()) {
- return cmCPackGenerator::InstallProjectViaInstalledDirectories(
+ return this->cmCPackGenerator::InstallProjectViaInstalledDirectories(
setDestDir, tempInstallDirectory, default_dir_mode);
}
@@ -130,7 +130,7 @@ int cmCPackExternalGenerator::RunPreinstallTarget(
cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
{
if (this->StagingEnabled()) {
- return cmCPackGenerator::RunPreinstallTarget(
+ return this->cmCPackGenerator::RunPreinstallTarget(
installProjectName, installDirectory, globalGenerator, buildConfig);
}
@@ -145,7 +145,7 @@ int cmCPackExternalGenerator::InstallCMakeProject(
std::string& absoluteDestFiles)
{
if (this->StagingEnabled()) {
- return cmCPackGenerator::InstallCMakeProject(
+ return this->cmCPackGenerator::InstallCMakeProject(
setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode,
component, componentInstall, installSubDirectory, buildConfig,
absoluteDestFiles);
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index a9fe91c..3db4162 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -60,18 +60,18 @@ int cmCPackGenerator::PrepareNames()
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Create temp directory." << std::endl);
// checks CPACK_SET_DESTDIR support
- if (IsOn("CPACK_SET_DESTDIR")) {
- if (SETDESTDIR_UNSUPPORTED == SupportsSetDestdir()) {
+ if (this->IsOn("CPACK_SET_DESTDIR")) {
+ if (SETDESTDIR_UNSUPPORTED == this->SupportsSetDestdir()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_SET_DESTDIR is set to ON but the '"
- << Name << "' generator does NOT support it."
+ << this->Name << "' generator does NOT support it."
<< std::endl);
return 0;
}
- if (SETDESTDIR_SHOULD_NOT_BE_USED == SupportsSetDestdir()) {
+ if (SETDESTDIR_SHOULD_NOT_BE_USED == this->SupportsSetDestdir()) {
cmCPackLogger(cmCPackLog::LOG_WARNING,
"CPACK_SET_DESTDIR is set to ON but it is "
- << "usually a bad idea to do that with '" << Name
+ << "usually a bad idea to do that with '" << this->Name
<< "' generator. Use at your own risk." << std::endl);
}
}
@@ -380,8 +380,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
<< std::endl);
return 0;
}
- files = gl.GetFiles();
- for (std::string const& gf : files) {
+ this->files = gl.GetFiles();
+ for (std::string const& gf : this->files) {
bool skip = false;
std::string inFile = gf;
if (cmSystemTools::FileIsDirectory(gf)) {
@@ -763,7 +763,7 @@ int cmCPackGenerator::InstallCMakeProject(
// one install directory for each component **GROUP**
// instead of the default
// one install directory for each component.
- tempInstallDirectory += GetComponentInstallDirNameSuffix(component);
+ tempInstallDirectory += this->GetComponentInstallDirNameSuffix(component);
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
tempInstallDirectory += "/";
tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME");
@@ -897,7 +897,7 @@ int cmCPackGenerator::InstallCMakeProject(
// ABSOLUTE INSTALL DESTINATION or CPack has been asked for
// then ask cmake_install.cmake script to error out
// as soon as it occurs (before installing file)
- if (!SupportsAbsoluteDestination() ||
+ if (!this->SupportsAbsoluteDestination() ||
this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) {
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
}
@@ -933,7 +933,7 @@ int cmCPackGenerator::InstallCMakeProject(
localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit);
localFileName =
localFileName.substr(localFileName.find_first_not_of('/'));
- Components[component].Files.push_back(localFileName);
+ this->Components[component].Files.push_back(localFileName);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Adding file <" << localFileName << "> to component <"
<< component << ">" << std::endl);
@@ -952,7 +952,7 @@ int cmCPackGenerator::InstallCMakeProject(
if (componentInstall) {
std::string absoluteDestFileComponent =
std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" +
- GetComponentInstallDirNameSuffix(component);
+ this->GetComponentInstallDirNameSuffix(component);
if (nullptr != this->GetOption(absoluteDestFileComponent)) {
std::string absoluteDestFilesListComponent =
cmStrCat(this->GetOption(absoluteDestFileComponent), ';', *d);
@@ -1073,17 +1073,17 @@ int cmCPackGenerator::DoPackage()
}
// The files to be installed
- files = gl.GetFiles();
+ this->files = gl.GetFiles();
- packageFileNames.clear();
+ this->packageFileNames.clear();
/* Put at least one file name into the list of
* wanted packageFileNames. The specific generator
* may update this during PackageFiles.
* (either putting several names or updating the provided one)
*/
- packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName
- : "");
- toplevel = tempDirectory;
+ this->packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName
+ : "");
+ this->toplevel = tempDirectory;
{ // scope that enables package generators to run internal scripts with
// latest CMake policies enabled
cmMakefile::ScopePushPop pp{ this->MakefileMap };
@@ -1127,10 +1127,10 @@ int cmCPackGenerator::DoPackage()
* (because the specific generator did 'normalize' it)
*/
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
- "Copying final package(s) [" << packageFileNames.size()
+ "Copying final package(s) [" << this->packageFileNames.size()
<< "]:" << std::endl);
/* now copy package one by one */
- for (std::string const& pkgFileName : packageFileNames) {
+ for (std::string const& pkgFileName : this->packageFileNames) {
std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
std::string filename(cmSystemTools::GetFilenameName(pkgFileName));
tempPackageFileName = pkgFileName.c_str();
@@ -1211,7 +1211,7 @@ bool cmCPackGenerator::IsSet(const std::string& name) const
bool cmCPackGenerator::IsOn(const std::string& name) const
{
- return cmIsOn(GetOption(name));
+ return cmIsOn(this->GetOption(name));
}
bool cmCPackGenerator::IsSetToOff(const std::string& op) const
@@ -1329,7 +1329,7 @@ bool cmCPackGenerator::ConfigureFile(const std::string& inName,
bool copyOnly /* = false */)
{
return this->MakefileMap->ConfigureFile(inName, outName, copyOnly, true,
- false, true) == 1;
+ false) == 1;
}
int cmCPackGenerator::CleanTemporaryDirectory()
@@ -1405,7 +1405,7 @@ int cmCPackGenerator::PrepareGroupingKind()
// fallback to default if not group based
if (method == ONE_PACKAGE_PER_GROUP && this->ComponentGroups.empty() &&
!this->Components.empty()) {
- if (componentPackageMethod == ONE_PACKAGE) {
+ if (this->componentPackageMethod == ONE_PACKAGE) {
method = ONE_PACKAGE;
} else {
method = ONE_PACKAGE_PER_COMPONENT;
@@ -1421,7 +1421,7 @@ int cmCPackGenerator::PrepareGroupingKind()
// if user specified packaging method, override the default packaging
// method
if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) {
- componentPackageMethod = method;
+ this->componentPackageMethod = method;
}
const char* method_names[] = { "ALL_COMPONENTS_IN_ONE", "IGNORE_GROUPS",
@@ -1430,7 +1430,8 @@ int cmCPackGenerator::PrepareGroupingKind()
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"[" << this->Name << "]"
<< " requested component grouping = "
- << method_names[componentPackageMethod] << std::endl);
+ << method_names[this->componentPackageMethod]
+ << std::endl);
return 1;
}
@@ -1451,13 +1452,14 @@ std::string cmCPackGenerator::GetComponentPackageFileName(
*/
std::string suffix = "-" + groupOrComponentName;
/* check if we should use DISPLAY name */
- std::string dispNameVar = "CPACK_" + Name + "_USE_DISPLAY_NAME_IN_FILENAME";
- if (IsOn(dispNameVar)) {
+ std::string dispNameVar =
+ "CPACK_" + this->Name + "_USE_DISPLAY_NAME_IN_FILENAME";
+ if (this->IsOn(dispNameVar)) {
/* the component Group case */
if (isGroupName) {
std::string groupDispVar = "CPACK_COMPONENT_GROUP_" +
cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
- const char* groupDispName = GetOption(groupDispVar);
+ const char* groupDispName = this->GetOption(groupDispVar);
if (groupDispName) {
suffix = "-" + std::string(groupDispName);
}
@@ -1466,7 +1468,7 @@ std::string cmCPackGenerator::GetComponentPackageFileName(
else {
std::string dispVar = "CPACK_COMPONENT_" +
cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
- const char* dispName = GetOption(dispVar);
+ const char* dispName = this->GetOption(dispVar);
if (dispName) {
suffix = "-" + std::string(dispName);
}
@@ -1493,8 +1495,8 @@ bool cmCPackGenerator::SupportsComponentInstallation() const
bool cmCPackGenerator::WantsComponentInstallation() const
{
- return (!IsOn("CPACK_MONOLITHIC_INSTALL") &&
- SupportsComponentInstallation()
+ return (!this->IsOn("CPACK_MONOLITHIC_INSTALL") &&
+ this->SupportsComponentInstallation()
// check that we have at least one group or component
&& (!this->ComponentGroups.empty() || !this->Components.empty()));
}
@@ -1557,7 +1559,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
const char* groupName = this->GetOption(macroPrefix + "_GROUP");
if (cmNonempty(groupName)) {
- component->Group = GetComponentGroup(projectName, groupName);
+ component->Group = this->GetComponentGroup(projectName, groupName);
component->Group->Components.push_back(component);
} else {
component->Group = nullptr;
@@ -1584,7 +1586,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
if (cmNonempty(depends)) {
std::vector<std::string> dependsVector = cmExpandedList(depends);
for (std::string const& depend : dependsVector) {
- cmCPackComponent* child = GetComponent(projectName, depend);
+ cmCPackComponent* child = this->GetComponent(projectName, depend);
component->Dependencies.push_back(child);
child->ReverseDependencies.push_back(component);
}
@@ -1620,7 +1622,8 @@ cmCPackComponentGroup* cmCPackGenerator::GetComponentGroup(
const char* parentGroupName =
this->GetOption(macroPrefix + "_PARENT_GROUP");
if (cmNonempty(parentGroupName)) {
- group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
+ group->ParentGroup =
+ this->GetComponentGroup(projectName, parentGroupName);
group->ParentGroup->Subgroups.push_back(group);
} else {
group->ParentGroup = nullptr;
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2109b4e..435f0ec 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -31,7 +31,7 @@
cmCPackNSISGenerator::cmCPackNSISGenerator(bool nsis64)
{
- Nsis64 = nsis64;
+ this->Nsis64 = nsis64;
}
cmCPackNSISGenerator::~cmCPackNSISGenerator() = default;
@@ -61,18 +61,18 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
nsisFileName += "/project.nsi";
std::ostringstream str;
- for (std::string const& file : files) {
+ for (std::string const& file : this->files) {
std::string outputDir = "$INSTDIR";
- std::string fileN = cmSystemTools::RelativePath(toplevel, file);
+ std::string fileN = cmSystemTools::RelativePath(this->toplevel, file);
if (!this->Components.empty()) {
const std::string::size_type pos = fileN.find('/');
// Use the custom component install directory if we have one
if (pos != std::string::npos) {
auto componentName = cm::string_view(fileN).substr(0, pos);
- outputDir = CustomComponentInstallDirectory(componentName);
+ outputDir = this->CustomComponentInstallDirectory(componentName);
} else {
- outputDir = CustomComponentInstallDirectory(fileN);
+ outputDir = this->CustomComponentInstallDirectory(fileN);
}
// Strip off the component part of the path.
@@ -86,15 +86,15 @@ int cmCPackNSISGenerator::PackageFiles()
"Uninstall Files: " << str.str() << std::endl);
this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str());
std::vector<std::string> dirs;
- this->GetListOfSubdirectories(toplevel.c_str(), dirs);
+ this->GetListOfSubdirectories(this->toplevel.c_str(), dirs);
std::ostringstream dstr;
for (std::string const& dir : dirs) {
std::string componentName;
- std::string fileN = cmSystemTools::RelativePath(toplevel, dir);
+ std::string fileN = cmSystemTools::RelativePath(this->toplevel, dir);
if (fileN.empty()) {
continue;
}
- if (!Components.empty()) {
+ if (!this->Components.empty()) {
// If this is a component installation, strip off the component
// part of the path.
std::string::size_type slash = fileN.find('/');
@@ -110,7 +110,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::replace(fileN.begin(), fileN.end(), '/', '\\');
const std::string componentOutputDir =
- CustomComponentInstallDirectory(componentName);
+ this->CustomComponentInstallDirectory(componentName);
dstr << " RMDir \"" << componentOutputDir << "\\" << fileN << "\""
<< std::endl;
@@ -677,7 +677,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
}
const std::string componentOutputDir =
- CustomComponentInstallDirectory(component->Name);
+ this->CustomComponentInstallDirectory(component->Name);
componentCode += cmStrCat(" SetOutPath \"", componentOutputDir, "\"\n");
// Create the actual installation commands
@@ -833,14 +833,16 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
// depends on.
std::set<cmCPackComponent*> visited;
macrosOut << "!macro Select_" << component->Name << "_depends\n";
- macrosOut << CreateSelectionDependenciesDescription(component, visited);
+ macrosOut << this->CreateSelectionDependenciesDescription(component,
+ visited);
macrosOut << "!macroend\n";
// Macro used to deselect each of the components that depend on this
// component.
visited.clear();
macrosOut << "!macro Deselect_required_by_" << component->Name << "\n";
- macrosOut << CreateDeselectionDependenciesDescription(component, visited);
+ macrosOut << this->CreateDeselectionDependenciesDescription(component,
+ visited);
macrosOut << "!macroend\n";
return componentCode;
}
@@ -862,7 +864,8 @@ std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription(
out << " SectionSetFlags ${" << depend->Name << "} $0\n";
out << " IntOp $" << depend->Name << "_selected 0 + ${SF_SELECTED}\n";
// Recurse
- out << CreateSelectionDependenciesDescription(depend, visited).c_str();
+ out
+ << this->CreateSelectionDependenciesDescription(depend, visited).c_str();
}
return out.str();
@@ -887,7 +890,8 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription(
out << " IntOp $" << depend->Name << "_selected 0 + 0\n";
// Recurse
- out << CreateDeselectionDependenciesDescription(depend, visited).c_str();
+ out << this->CreateDeselectionDependenciesDescription(depend, visited)
+ .c_str();
}
return out.str();
diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx
index 60faecd..98dc890 100644
--- a/Source/CPack/cmCPackNuGetGenerator.cxx
+++ b/Source/CPack/cmCPackNuGetGenerator.cxx
@@ -17,32 +17,33 @@
bool cmCPackNuGetGenerator::SupportsComponentInstallation() const
{
- return IsOn("CPACK_NUGET_COMPONENT_INSTALL");
+ return this->IsOn("CPACK_NUGET_COMPONENT_INSTALL");
}
int cmCPackNuGetGenerator::PackageFiles()
{
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Toplevel: " << this->toplevel << std::endl);
/* Reset package file name list it will be populated after the
* `CPackNuGet.cmake` run */
- packageFileNames.clear();
+ this->packageFileNames.clear();
/* Are we in the component packaging case */
- if (WantsComponentInstallation()) {
- if (componentPackageMethod == ONE_PACKAGE) {
+ if (this->WantsComponentInstallation()) {
+ if (this->componentPackageMethod == ONE_PACKAGE) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// Meaning that all per-component pre-installed files
// goes into the single package.
this->SetOption("CPACK_NUGET_ALL_IN_ONE", "TRUE");
- SetupGroupComponentVariables(true);
+ this->SetupGroupComponentVariables(true);
} else {
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- SetupGroupComponentVariables(componentPackageMethod ==
- ONE_PACKAGE_PER_COMPONENT);
+ this->SetupGroupComponentVariables(this->componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
} else {
// CASE 3 : NON COMPONENT package.
@@ -51,7 +52,7 @@ int cmCPackNuGetGenerator::PackageFiles()
auto retval = this->ReadListFile("Internal/CPack/CPackNuGet.cmake");
if (retval) {
- AddGeneratedPackageNames();
+ this->AddGeneratedPackageNames();
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while execution CPackNuGet.cmake" << std::endl);
@@ -133,9 +134,9 @@ void cmCPackNuGetGenerator::AddGeneratedPackageNames()
std::string::size_type pos1 = 0;
std::string::size_type pos2 = fileNames.find(sep, pos1 + 1);
while (pos2 != std::string::npos) {
- packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+ this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
pos2 = fileNames.find(sep, pos1 + 1);
}
- packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+ this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
}
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 0c1cecf..c3f6d59 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -51,11 +51,11 @@ void cmCPackRPMGenerator::AddGeneratedPackageNames()
std::string::size_type pos1 = 0;
std::string::size_type pos2 = fileNames.find(sep, pos1 + 1);
while (pos2 != std::string::npos) {
- packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+ this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
pos2 = fileNames.find(sep, pos1 + 1);
}
- packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
+ this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1));
}
int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel,
@@ -64,10 +64,11 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel,
int retval = 1;
// Begin the archive for this pack
std::string localToplevel(initialToplevel);
- std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(this->toplevel));
std::string outputFileName(
- GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
- packageName, true) +
+ this->GetComponentPackageFileName(
+ this->GetOption("CPACK_PACKAGE_FILE_NAME"), packageName, true) +
this->GetOutputExtension());
localToplevel += "/" + packageName;
@@ -99,7 +100,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
int retval = 1;
/* Reset package file name list it will be populated during the
* component packaging run*/
- packageFileNames.clear();
+ this->packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT");
@@ -202,7 +203,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging component group: " << compGIt->first
<< std::endl);
- retval &= PackageOnePack(initialTopLevel, compGIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compGIt->first);
}
// Handle Orphan components (components not belonging to any groups)
auto mainCompIt = this->Components.end();
@@ -227,7 +228,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
<< compIt->second.Name
<< "> does not belong to any group, package it separately."
<< std::endl);
- retval &= PackageOnePack(initialTopLevel, compIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compIt->first);
}
}
@@ -235,9 +236,9 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
this->SetOption("GENERATE_SPEC_PARTS", "OFF");
if (mainCompGIt != this->ComponentGroups.end()) {
- retval &= PackageOnePack(initialTopLevel, mainCompGIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, mainCompGIt->first);
} else if (mainCompIt != this->Components.end()) {
- retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, mainCompIt->first);
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_RPM_MAIN_COMPONENT set"
@@ -264,14 +265,14 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
continue;
}
- retval &= PackageOnePack(initialTopLevel, compIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compIt->first);
}
if (retval) {
this->SetOption("GENERATE_SPEC_PARTS", "OFF");
if (mainCompIt != this->Components.end()) {
- retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, mainCompIt->first);
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_RPM_MAIN_COMPONENT set"
@@ -291,7 +292,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging component group: " << compGIt->first
<< std::endl);
- retval &= PackageOnePack(initialTopLevel, compGIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compGIt->first);
}
// Handle Orphan components (components not belonging to any groups)
std::map<std::string, cmCPackComponent>::iterator compIt;
@@ -305,7 +306,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
<< compIt->second.Name
<< "> does not belong to any group, package it separately."
<< std::endl);
- retval &= PackageOnePack(initialTopLevel, compIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compIt->first);
}
}
}
@@ -315,7 +316,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
std::map<std::string, cmCPackComponent>::iterator compIt;
for (compIt = this->Components.begin(); compIt != this->Components.end();
++compIt) {
- retval &= PackageOnePack(initialTopLevel, compIt->first);
+ retval &= this->PackageOnePack(initialTopLevel, compIt->first);
}
}
} else {
@@ -328,7 +329,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
}
if (retval) {
- AddGeneratedPackageNames();
+ this->AddGeneratedPackageNames();
}
return retval;
@@ -340,7 +341,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
int retval = 1;
/* Reset package file name list it will be populated during the
* component packaging run*/
- packageFileNames.clear();
+ this->packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) {
@@ -354,7 +355,8 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
// The ALL GROUPS in ONE package case
std::string localToplevel(initialTopLevel);
- std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel));
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(this->toplevel));
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) +
this->GetOutputExtension());
@@ -378,7 +380,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
}
if (this->ReadListFile("Internal/CPack/CPackRPM.cmake")) {
- AddGeneratedPackageNames();
+ this->AddGeneratedPackageNames();
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while execution CPackRPM.cmake" << std::endl);
@@ -390,48 +392,49 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
int cmCPackRPMGenerator::PackageFiles()
{
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Toplevel: " << this->toplevel << std::endl);
/* Are we in the component packaging case */
- if (WantsComponentInstallation()) {
+ if (this->WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (componentPackageMethod == ONE_PACKAGE) {
- return PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
+ if (this->componentPackageMethod == ONE_PACKAGE) {
+ return this->PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE");
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- return PackageComponents(componentPackageMethod ==
- ONE_PACKAGE_PER_COMPONENT);
+ return this->PackageComponents(this->componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
// CASE 3 : NON COMPONENT package.
- return PackageComponentsAllInOne("");
+ return this->PackageComponentsAllInOne("");
}
bool cmCPackRPMGenerator::SupportsComponentInstallation() const
{
- return IsOn("CPACK_RPM_COMPONENT_INSTALL");
+ return this->IsOn("CPACK_RPM_COMPONENT_INSTALL");
}
std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
const std::string& componentName)
{
- if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
+ if (this->componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
return componentName;
}
- if (componentPackageMethod == ONE_PACKAGE) {
+ if (this->componentPackageMethod == ONE_PACKAGE) {
return std::string("ALL_COMPONENTS_IN_ONE");
}
// We have to find the name of the COMPONENT GROUP
// the current COMPONENT belongs to.
std::string groupVar =
"CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP";
- if (nullptr != GetOption(groupVar)) {
- return std::string(GetOption(groupVar));
+ if (nullptr != this->GetOption(groupVar)) {
+ return std::string(this->GetOption(groupVar));
}
return componentName;
}
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index a4a5e6f..3e36e8c 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -50,7 +50,7 @@ int cmCPackSTGZGenerator::PackageFiles()
* have generated several packages (component packaging)
* so we must iterate over generated packages.
*/
- for (std::string const& pfn : packageFileNames) {
+ for (std::string const& pfn : this->packageFileNames) {
retval &= cmSystemTools::SetPermissions(pfn.c_str(),
#if defined(_MSC_VER) || defined(__MINGW32__)
S_IREAD | S_IWRITE | S_IEXEC
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index c533cd7..a353435 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -104,8 +104,8 @@ private:
{
if (this->RegexCheckOut.find(this->Line)) {
this->BZR->URL = this->RegexCheckOut.match(1);
- CheckOutFound = true;
- } else if (!CheckOutFound && this->RegexParent.find(this->Line)) {
+ this->CheckOutFound = true;
+ } else if (!this->CheckOutFound && this->RegexParent.find(this->Line)) {
this->BZR->URL = this->RegexParent.match(1);
}
return true;
@@ -191,7 +191,7 @@ public:
int InitializeParser() override
{
- int res = cmXMLParser::InitializeParser();
+ int res = this->cmXMLParser::InitializeParser();
if (res) {
XML_SetUnknownEncodingHandler(static_cast<XML_Parser>(this->Parser),
cmBZRXMLParserUnknownEncodingHandler,
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 1cc267e..88e2871 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -54,22 +54,21 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
//
cmProp ctestBuildConfiguration =
this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
- const std::string* cmakeBuildConfiguration = !this->Configuration.empty()
- ? &this->Configuration
- : (cmNonempty(ctestBuildConfiguration) ? ctestBuildConfiguration
- : &this->CTest->GetConfigType());
-
- const std::string* cmakeBuildAdditionalFlags = !this->Flags.empty()
- ? &this->Flags
- : this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
- const std::string* cmakeBuildTarget = !this->Target.empty()
- ? &this->Target
- : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
+ std::string cmakeBuildConfiguration = cmNonempty(this->Configuration)
+ ? this->Configuration
+ : cmNonempty(ctestBuildConfiguration) ? *ctestBuildConfiguration
+ : this->CTest->GetConfigType();
+
+ const std::string& cmakeBuildAdditionalFlags = cmNonempty(this->Flags)
+ ? this->Flags
+ : this->Makefile->GetSafeDefinition("CTEST_BUILD_FLAGS");
+ const std::string& cmakeBuildTarget = cmNonempty(this->Target)
+ ? this->Target
+ : this->Makefile->GetSafeDefinition("CTEST_BUILD_TARGET");
if (cmNonempty(cmakeGeneratorName)) {
- if (!cmakeBuildConfiguration) {
- static const std::string sRelease = "Release";
- cmakeBuildConfiguration = &sRelease;
+ if (cmakeBuildConfiguration.empty()) {
+ cmakeBuildConfiguration = "Release";
}
if (this->GlobalGenerator) {
if (this->GlobalGenerator->GetName() != *cmakeGeneratorName) {
@@ -88,24 +87,18 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
return nullptr;
}
}
- if (cmakeBuildConfiguration->empty()) {
- const std::string* config = nullptr;
+ if (cmakeBuildConfiguration.empty()) {
#ifdef CMAKE_INTDIR
- static const std::string sIntDir = CMAKE_INTDIR;
- config = &sIntDir;
+ cmakeBuildConfiguration = CMAKE_INTDIR;
+#else
+ cmakeBuildConfiguration = "Debug";
#endif
- if (!config) {
- static const std::string sDebug = "Debug";
- config = &sDebug;
- }
- cmakeBuildConfiguration = config;
}
std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
std::string buildCommand =
this->GlobalGenerator->GenerateCMakeBuildCommand(
- cmakeBuildTarget ? *cmakeBuildTarget : "", *cmakeBuildConfiguration,
- cmakeBuildAdditionalFlags ? *cmakeBuildAdditionalFlags : "",
+ cmakeBuildTarget, cmakeBuildConfiguration, cmakeBuildAdditionalFlags,
this->Makefile->IgnoreErrorsCMP0061());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetMakeCommand:" << buildCommand << "\n",
@@ -144,7 +137,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- bool ret = cmCTestHandlerCommand::InitialPass(args, status);
+ bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
if (!this->NumberErrors.empty()) {
this->Makefile->AddDefinition(
this->NumberErrors, std::to_string(this->Handler->GetTotalErrors()));
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 093b2d1..5fb52bf 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -778,16 +778,16 @@ struct cmCTestCoverageHandlerLocale
{
std::string l;
if (cmSystemTools::GetEnv("LC_ALL", l)) {
- lc_all = l;
+ this->lc_all = l;
}
- if (lc_all != "C") {
+ if (this->lc_all != "C") {
cmSystemTools::PutEnv("LC_ALL=C");
}
}
~cmCTestCoverageHandlerLocale()
{
- if (!lc_all.empty()) {
- cmSystemTools::PutEnv("LC_ALL=" + lc_all);
+ if (!this->lc_all.empty()) {
+ cmSystemTools::PutEnv("LC_ALL=" + this->lc_all);
} else {
cmSystemTools::UnsetEnv("LC_ALL");
}
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 6ec7d0e..f89fc9b 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -284,7 +284,7 @@ void cmCTestLaunchReporter::DumpFileToXML(cmXMLElement& e3, const char* tag,
cmXMLElement e4(e3, tag);
while (cmSystemTools::GetLineFromStream(fin, line)) {
- if (MatchesFilterPrefix(line)) {
+ if (this->MatchesFilterPrefix(line)) {
continue;
}
if (this->Match(line, this->RegexWarningSuppress)) {
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index a08cb34..9793c5b 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -56,8 +56,8 @@ public:
// Sorts tests in descending order of cost
bool operator()(int index1, int index2) const
{
- return Handler->Properties[index1]->Cost >
- Handler->Properties[index2]->Cost;
+ return this->Handler->Properties[index1]->Cost >
+ this->Handler->Properties[index2]->Cost;
}
private:
@@ -169,7 +169,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->TestRunningMap[test] = true; // mark the test as running
// now remove the test itself
this->EraseTest(test);
- this->RunningCount += GetProcessorsUsed(test);
+ this->RunningCount += this->GetProcessorsUsed(test);
auto testRun = cm::make_unique<cmCTestRunTest>(*this);
@@ -552,12 +552,12 @@ void cmCTestMultiProcessHandler::StartNextTests()
continue;
}
- size_t processors = GetProcessorsUsed(test);
+ size_t processors = this->GetProcessorsUsed(test);
bool testLoadOk = true;
if (this->TestLoad > 0) {
if (processors <= spareLoad) {
cmCTestLog(this->CTest, DEBUG,
- "OK to run " << GetName(test) << ", it requires "
+ "OK to run " << this->GetName(test) << ", it requires "
<< processors << " procs & system load is: "
<< systemLoad << std::endl);
allTestsFailedTestLoadCheck = false;
@@ -568,7 +568,7 @@ void cmCTestMultiProcessHandler::StartNextTests()
if (processors <= minProcessorsRequired) {
minProcessorsRequired = processors;
- testWithMinProcessors = GetName(test);
+ testWithMinProcessors = this->GetName(test);
}
if (testLoadOk && processors <= numToStart && this->StartTest(test)) {
@@ -660,7 +660,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(
this->WriteCheckpoint(test);
this->DeallocateResources(test);
this->UnlockResources(test);
- this->RunningCount -= GetProcessorsUsed(test);
+ this->RunningCount -= this->GetProcessorsUsed(test);
for (auto p : properties->Affinity) {
this->ProcessorsAvailable.insert(p);
@@ -793,9 +793,9 @@ int cmCTestMultiProcessHandler::SearchByName(std::string const& name)
void cmCTestMultiProcessHandler::CreateTestCostList()
{
if (this->ParallelLevel > 1) {
- CreateParallelTestCostList();
+ this->CreateParallelTestCostList();
} else {
- CreateSerialTestCostList();
+ this->CreateSerialTestCostList();
}
}
@@ -862,7 +862,7 @@ void cmCTestMultiProcessHandler::GetAllTestDependencies(int test,
{
TestSet const& dependencySet = this->Tests[test];
for (int i : dependencySet) {
- GetAllTestDependencies(i, dependencies);
+ this->GetAllTestDependencies(i, dependencies);
dependencies.push_back(i);
}
}
@@ -886,7 +886,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
}
TestList dependencies;
- GetAllTestDependencies(test, dependencies);
+ this->GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
if (!cm::contains(alreadySortedTests, testDependency)) {
@@ -1274,7 +1274,7 @@ void cmCTestMultiProcessHandler::PrintOutputAsJson()
void cmCTestMultiProcessHandler::PrintTestList()
{
if (this->CTest->GetOutputAsJson()) {
- PrintOutputAsJson();
+ this->PrintOutputAsJson();
return;
}
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 1375be4..50c9c16 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -56,7 +56,7 @@ public:
ChangesParser(cmCTestP4* p4, const char* prefix)
: P4(p4)
{
- this->SetLog(&P4->Log, prefix);
+ this->SetLog(&this->P4->Log, prefix);
this->RegexIdentify.compile("^Change ([0-9]+) on");
}
@@ -67,7 +67,7 @@ private:
bool ProcessLine() override
{
if (this->RegexIdentify.find(this->Line)) {
- P4->ChangeLists.push_back(this->RegexIdentify.match(1));
+ this->P4->ChangeLists.push_back(this->RegexIdentify.match(1));
}
return true;
}
@@ -79,7 +79,7 @@ public:
UserParser(cmCTestP4* p4, const char* prefix)
: P4(p4)
{
- this->SetLog(&P4->Log, prefix);
+ this->SetLog(&this->P4->Log, prefix);
this->RegexUser.compile("^(.+) <(.*)> \\((.*)\\) accessed (.*)$");
}
@@ -96,7 +96,7 @@ private:
NewUser.EMail = this->RegexUser.match(2);
NewUser.Name = this->RegexUser.match(3);
NewUser.AccessTime = this->RegexUser.match(4);
- P4->Users[this->RegexUser.match(1)] = NewUser;
+ this->P4->Users[this->RegexUser.match(1)] = NewUser;
return false;
}
@@ -120,7 +120,7 @@ public:
: P4(p4)
, AlreadyNotified(false)
{
- this->SetLog(&P4->Log, prefix);
+ this->SetLog(&this->P4->Log, prefix);
this->RegexDiff.compile("^==== (.*)#[0-9]+ - (.*)");
}
@@ -134,12 +134,12 @@ private:
{
if (!this->Line.empty() && this->Line[0] == '=' &&
this->RegexDiff.find(this->Line)) {
- CurrentPath = this->RegexDiff.match(1);
- AlreadyNotified = false;
+ this->CurrentPath = this->RegexDiff.match(1);
+ this->AlreadyNotified = false;
} else {
- if (!AlreadyNotified) {
- P4->DoModification(PathModified, CurrentPath);
- AlreadyNotified = true;
+ if (!this->AlreadyNotified) {
+ this->P4->DoModification(PathModified, this->CurrentPath);
+ this->AlreadyNotified = true;
}
}
return true;
@@ -148,11 +148,11 @@ private:
cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
{
- auto it = Users.find(username);
+ auto it = this->Users.find(username);
- if (it == Users.end()) {
+ if (it == this->Users.end()) {
std::vector<char const*> p4_users;
- SetP4Options(p4_users);
+ this->SetP4Options(p4_users);
p4_users.push_back("users");
p4_users.push_back("-m");
p4_users.push_back("1");
@@ -161,11 +161,11 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
UserParser out(this, "users-out> ");
OutputLogger err(this->Log, "users-err> ");
- RunChild(&p4_users[0], &out, &err);
+ this->RunChild(&p4_users[0], &out, &err);
// The user should now be added to the map. Search again.
- it = Users.find(username);
- if (it == Users.end()) {
+ it = this->Users.find(username);
+ if (it == this->Users.end()) {
return cmCTestP4::User();
}
}
@@ -195,7 +195,7 @@ public:
, P4(p4)
, Section(SectionHeader)
{
- this->SetLog(&P4->Log, prefix);
+ this->SetLog(&this->P4->Log, prefix);
this->RegexHeader.compile("^Change ([0-9]+) by (.+)@(.+) on (.*)$");
this->RegexDiff.compile(R"(^\.\.\. (.*)#[0-9]+ ([^ ]+)$)");
}
@@ -259,7 +259,7 @@ private:
this->Rev.Rev = this->RegexHeader.match(1);
this->Rev.Date = this->RegexHeader.match(4);
- cmCTestP4::User user = P4->GetUserData(this->RegexHeader.match(2));
+ cmCTestP4::User user = this->P4->GetUserData(this->RegexHeader.match(2));
this->Rev.Author = user.Name;
this->Rev.EMail = user.EMail;
@@ -300,38 +300,38 @@ private:
change.Action = 'M';
}
- Changes.push_back(change);
+ this->Changes.push_back(change);
}
}
};
void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
{
- if (P4Options.empty()) {
+ if (this->P4Options.empty()) {
const char* p4 = this->CommandLineTool.c_str();
- P4Options.emplace_back(p4);
+ this->P4Options.emplace_back(p4);
// The CTEST_P4_CLIENT variable sets the P4 client used when issuing
// Perforce commands, if it's different from the default one.
std::string client = this->CTest->GetCTestConfiguration("P4Client");
if (!client.empty()) {
- P4Options.emplace_back("-c");
- P4Options.push_back(client);
+ this->P4Options.emplace_back("-c");
+ this->P4Options.push_back(client);
}
// Set the message language to be English, in case the P4 admin
// has localized them
- P4Options.emplace_back("-L");
- P4Options.emplace_back("en");
+ this->P4Options.emplace_back("-L");
+ this->P4Options.emplace_back("en");
// The CTEST_P4_OPTIONS variable adds additional Perforce command line
// options before the main command
std::string opts = this->CTest->GetCTestConfiguration("P4Options");
- cm::append(P4Options, cmSystemTools::ParseArguments(opts));
+ cm::append(this->P4Options, cmSystemTools::ParseArguments(opts));
}
CommandOptions.clear();
- for (std::string const& o : P4Options) {
+ for (std::string const& o : this->P4Options) {
CommandOptions.push_back(o.c_str());
}
}
@@ -339,7 +339,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
std::string cmCTestP4::GetWorkingRevision()
{
std::vector<char const*> p4_identify;
- SetP4Options(p4_identify);
+ this->SetP4Options(p4_identify);
p4_identify.push_back("changes");
p4_identify.push_back("-m");
@@ -354,7 +354,7 @@ std::string cmCTestP4::GetWorkingRevision()
IdentifyParser out(this, "p4_changes-out> ", rev);
OutputLogger err(this->Log, "p4_changes-err> ");
- bool result = RunChild(&p4_identify[0], &out, &err);
+ bool result = this->RunChild(&p4_identify[0], &out, &err);
// If there was a problem contacting the server return "<unknown>"
if (!result) {
@@ -391,7 +391,7 @@ bool cmCTestP4::NoteNewRevision()
bool cmCTestP4::LoadRevisions()
{
std::vector<char const*> p4_changes;
- SetP4Options(p4_changes);
+ this->SetP4Options(p4_changes);
// Use 'p4 changes ...@old,new' to get a list of changelists
std::string range = this->SourceDirectory + "/...";
@@ -417,17 +417,17 @@ bool cmCTestP4::LoadRevisions()
ChangesParser out(this, "p4_changes-out> ");
OutputLogger err(this->Log, "p4_changes-err> ");
- ChangeLists.clear();
+ this->ChangeLists.clear();
this->RunChild(&p4_changes[0], &out, &err);
- if (ChangeLists.empty()) {
+ if (this->ChangeLists.empty()) {
return true;
}
// p4 describe -s ...@1111111,2222222
std::vector<char const*> p4_describe;
- for (std::string const& i : cmReverseRange(ChangeLists)) {
- SetP4Options(p4_describe);
+ for (std::string const& i : cmReverseRange(this->ChangeLists)) {
+ this->SetP4Options(p4_describe);
p4_describe.push_back("describe");
p4_describe.push_back("-s");
p4_describe.push_back(i.c_str());
@@ -443,7 +443,7 @@ bool cmCTestP4::LoadRevisions()
bool cmCTestP4::LoadModifications()
{
std::vector<char const*> p4_diff;
- SetP4Options(p4_diff);
+ this->SetP4Options(p4_diff);
p4_diff.push_back("diff");
@@ -491,7 +491,7 @@ bool cmCTestP4::UpdateImpl()
}
std::vector<char const*> p4_sync;
- SetP4Options(p4_sync);
+ this->SetP4Options(p4_sync);
p4_sync.push_back("sync");
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 4d65c9b..5a6c775 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -139,7 +139,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
}
this->TestResult.CompletionStatus = s.str();
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
+ outputStream << "***Skipped ";
skipped = true;
} else if (success != this->TestProperties->WillFail) {
this->TestResult.Status = cmCTestTestHandler::COMPLETED;
@@ -195,10 +195,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
sprintf(buf, "%6.2f sec", this->TestProcess->GetTotalTime().count());
outputStream << buf << "\n";
+ bool passedOrSkipped = passed || skipped;
if (this->CTest->GetTestProgressOutput()) {
- if (!passed) {
+ if (!passedOrSkipped) {
// If the test did not pass, reprint test name and error
- std::string output = GetTestPrefix(completed, total);
+ std::string output = this->GetTestPrefix(completed, total);
std::string testName = this->TestProperties->Name;
const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
testName.resize(maxTestNameWidth + 4, '.');
@@ -211,12 +212,12 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, "\n"); // flush
}
if (completed == total) {
- std::string testName =
- GetTestPrefix(completed, total) + this->TestProperties->Name + "\n";
+ std::string testName = this->GetTestPrefix(completed, total) +
+ this->TestProperties->Name + "\n";
cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName);
}
}
- if (!this->CTest->GetTestProgressOutput() || !passed) {
+ if (!this->CTest->GetTestProgressOutput() || !passedOrSkipped) {
cmCTestLog(this->CTest, HANDLER_OUTPUT, outputStream.str());
}
@@ -485,8 +486,8 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
<< this->TestProperties->Index << ": "
<< this->TestProperties->Name << std::endl);
} else {
- std::string testName =
- GetTestPrefix(completed, total) + this->TestProperties->Name + "\n";
+ std::string testName = this->GetTestPrefix(completed, total) +
+ this->TestProperties->Name + "\n";
cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName);
}
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 44dfab2..4692dbd 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -286,9 +286,9 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
args.push_back(nullptr);
if (strcmp(parameters[0], "update") == 0) {
- return RunUpdateCommand(&args[0], out, err);
+ return this->RunUpdateCommand(&args[0], out, err);
}
- return RunChild(&args[0], out, err);
+ return this->RunChild(&args[0], out, err);
}
class cmCTestSVN::LogParser
@@ -328,7 +328,7 @@ private:
this->CData.clear();
if (name == "logentry") {
this->Rev = Revision();
- this->Rev.SVNInfo = &SVNRepo;
+ this->Rev.SVNInfo = &this->SVNRepo;
if (const char* rev =
cmCTestSVN::LogParser::FindAttribute(atts, "revision")) {
this->Rev.Rev = rev;
@@ -354,7 +354,7 @@ private:
this->SVN->DoRevisionSVN(this->Rev, this->Changes);
} else if (!this->CData.empty() && name == "path") {
std::string orig_path(&this->CData[0], this->CData.size());
- std::string new_path = SVNRepo.BuildLocalPath(orig_path);
+ std::string new_path = this->SVNRepo.BuildLocalPath(orig_path);
this->CurChange.Path.assign(new_path);
this->Changes.push_back(this->CurChange);
} else if (!this->CData.empty() && name == "author") {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4d1a589..a8c9df6 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -122,7 +122,7 @@ bool cmCTestSubdirCommand(std::vector<std::string> const& args,
readit = status.GetMakefile().ReadDependentFile(fname);
}
if (!readit) {
- status.SetError(cmStrCat("Could not find include file: ", fname));
+ status.SetError(cmStrCat("Could not load include file: ", fname));
return false;
}
}
@@ -340,7 +340,7 @@ void cmCTestTestHandler::Initialize()
this->ExcludeFixtureSetupRegExp.clear();
this->ExcludeFixtureCleanupRegExp.clear();
- TestsToRunString.clear();
+ this->TestsToRunString.clear();
this->UseUnion = false;
this->TestList.clear();
}
@@ -877,7 +877,7 @@ bool cmCTestTestHandler::ComputeTestList()
finalList.push_back(tp);
}
- UpdateForFixtures(finalList);
+ this->UpdateForFixtures(finalList);
// Save the total number of tests before exclusions
this->TotalNumberOfTests = this->TestList.size();
@@ -906,7 +906,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
finalList.push_back(tp);
}
- UpdateForFixtures(finalList);
+ this->UpdateForFixtures(finalList);
// Save the total number of tests before exclusions
this->TotalNumberOfTests = this->TestList.size();
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 6fef90a..0ba2c41 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -5,7 +5,6 @@
#include "cmCTest.h"
#include "cmCTestUpdateHandler.h"
#include "cmMakefile.h"
-#include "cmProperty.h"
#include "cmSystemTools.h"
cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
@@ -18,7 +17,7 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
this->CTest->SetCTestConfiguration(
"SourceDirectory",
cmSystemTools::CollapseFullPath(
- cmToCStrSafe(this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))),
+ this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
this->Quiet);
}
std::string source_dir =
diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx
index 409025f..3a6651f 100644
--- a/Source/CTest/cmParseBlanketJSCoverage.cxx
+++ b/Source/CTest/cmParseBlanketJSCoverage.cxx
@@ -66,7 +66,7 @@ public:
}
foundFile = true;
inSource = false;
- filename = getValue(line, 0);
+ filename = this->getValue(line, 0);
} else if ((line.find("coverage") != std::string::npos) && foundFile &&
inSource) {
/*
@@ -78,7 +78,7 @@ public:
* FoundFile and foundSource ensure that
* only the value of the line coverage is captured
*/
- std::string result = getValue(line, 1);
+ std::string result = this->getValue(line, 1);
result = result.substr(2);
if (result == "\"\"") {
// Empty quotation marks indicate that the
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 711a856..9311769 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -66,7 +66,7 @@ protected:
// Check if this is an absolute path that falls within our
// source or binary directories.
- for (std::string const& filePath : FilePaths) {
+ for (std::string const& filePath : this->FilePaths) {
if (cmHasPrefix(filename, filePath)) {
this->CurFileName = filename;
break;
@@ -76,7 +76,7 @@ protected:
if (this->CurFileName.empty()) {
// Check if this is a path that is relative to our source or
// binary directories.
- for (std::string const& filePath : FilePaths) {
+ for (std::string const& filePath : this->FilePaths) {
finalpath = cmStrCat(filePath, "/", filename);
if (cmSystemTools::FileExists(finalpath)) {
this->CurFileName = finalpath;
diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx
index 016e90c..640873e 100644
--- a/Source/CTest/cmParseDelphiCoverage.cxx
+++ b/Source/CTest/cmParseDelphiCoverage.cxx
@@ -133,7 +133,7 @@ public:
cmsys::Glob gl;
gl.RecurseOn();
gl.RecurseThroughSymlinksOff();
- std::string glob = Coverage.SourceDir + "*/" + filename;
+ std::string glob = this->Coverage.SourceDir + "*/" + filename;
gl.FindFiles(glob);
std::vector<std::string> const& files = gl.GetFiles();
if (files.empty()) {
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 9ee1c17..c7cbd34 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -177,7 +177,7 @@ bool cmProcess::Buffer::GetLine(std::string& line)
// Start a new range for the next line.
++this->Last;
- this->First = Last;
+ this->First = this->Last;
// Return the line extracted.
return true;
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
index a98969d..3630f4e 100644
--- a/Source/LexerParser/cmGccDepfileLexer.cxx
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -994,7 +994,7 @@ case 5:
YY_RULE_SETUP
{
// A line continuation ends the current file name.
- yyextra->newDependency();
+ yyextra->newRuleOrDependency();
}
YY_BREAK
case 6:
diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l
index 08f8577..c83cb75 100644
--- a/Source/LexerParser/cmGccDepfileLexer.in.l
+++ b/Source/LexerParser/cmGccDepfileLexer.in.l
@@ -42,7 +42,7 @@ NEWLINE \r?\n
}
{WSPACE}*\\{NEWLINE} {
// A line continuation ends the current file name.
- yyextra->newDependency();
+ yyextra->newRuleOrDependency();
}
{NEWLINE} {
// A newline ends the current file name and the current rule.
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 0f0c39a..0c263bb 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,20 +3,52 @@
project(QtDialog)
CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets REQUIRED)
+set (QT_COMPONENTS
+ Core
+ Widgets
+ Gui
+)
+
+set(CMake_QT_MAJOR_VERSION "A" CACHE
+ STRING "Expected Qt major version. Valid values are A (auto-select), 5, 6.")
+set(SUPPORTED_QT_VERSIONS "A" 5 6)
+set_property(CACHE CMake_QT_MAJOR_VERSION PROPERTY STRINGS ${SUPPORTED_QT_VERSIONS})
+if(NOT CMake_QT_MAJOR_VERSION STREQUAL "A")
+ if(NOT CMake_QT_MAJOR_VERSION IN_LIST SUPPORTED_QT_VERSIONS)
+ message(FATAL_ERROR "Supported Qt versions are \"${SUPPORTED_QT_VERSIONS}\"."
+ " But CMake_QT_MAJOR_VERSION is set to ${CMake_QT_MAJOR_VERSION}.")
+ endif()
+ set(INSTALLED_QT_VERSION ${CMake_QT_MAJOR_VERSION})
+else()
+ find_package(Qt6Widgets QUIET)
+ set(INSTALLED_QT_VERSION 6)
+ if(NOT Qt6Widgets_FOUND)
+ find_package(Qt5Widgets QUIET)
+ if(NOT Qt5Widgets_FOUND)
+ message(FATAL_ERROR "Could not find a valid Qt installation.")
+ endif()
+ set(INSTALLED_QT_VERSION 5)
+ endif()
+endif()
+
+find_package(Qt${INSTALLED_QT_VERSION}
+ COMPONENTS ${QT_COMPONENTS}
+ REQUIRED QUIET
+)
set(CMake_QT_EXTRA_LIBRARIES)
# Try to find the package WinExtras for the task bar progress
if(WIN32)
- find_package(Qt5WinExtras QUIET)
- if (Qt5WinExtras_FOUND)
+ find_package(Qt${INSTALLED_QT_VERSION}WinExtras QUIET)
+ if (Qt${INSTALLED_QT_VERSION}WinExtras_FOUND)
add_definitions(-DQT_WINEXTRAS)
- list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
+ list(APPEND CMake_QT_EXTRA_LIBRARIES Qt${INSTALLED_QT_VERSION}::WinExtras)
+ list(APPEND QT_COMPONENTS WinExtras)
endif()
endif()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt${INSTALLED_QT_VERSION}Widgets_EXECUTABLE_COMPILE_FLAGS}")
if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
@@ -31,11 +63,25 @@ if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
endif()
# We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
-# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
-# Qt5 support is missing there.
if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
- macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
- get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ function(_qt_get_plugin_name_with_version target out_var)
+ string(REGEX REPLACE "^Qt::(.+)" "Qt${INSTALLED_QT_VERSION}::\\1"
+ qt_plugin_with_version "${target}")
+ if(TARGET "${qt_plugin_with_version}")
+ set("${out_var}" "${qt_plugin_with_version}" PARENT_SCOPE)
+ else()
+ set("${out_var}" "" PARENT_SCOPE)
+ endif()
+ endfunction()
+ macro(install_qt_plugin _qt_plugin_name _qt_plugins_var)
+ if(TARGET "${_qt_plugin_name}")
+ get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ else()
+ _qt_get_plugin_name_with_version("Qt::${_qt_plugin_name}" _qt_plugin_with_version_name)
+ if(TARGET "${_qt_plugin_with_version_name}")
+ get_target_property(_qt_plugin_path "${_qt_plugin_with_version_name}" LOCATION)
+ endif()
+ endif()
if(EXISTS "${_qt_plugin_path}")
get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
@@ -51,14 +97,34 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
${COMPONENT})
set(${_qt_plugins_var}
"${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
- else()
- message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif()
endmacro()
+ macro(install_qt_plugins _comps _plugins_var)
+ foreach(_qt_comp ${${_comps}})
+ if (INSTALLED_QT_VERSION VERSION_LESS 6)
+ set(_qt_module_plugins ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_PLUGINS})
+ else()
+ get_target_property(_qt_module_plugins Qt${INSTALLED_QT_VERSION}::${_qt_comp} QT_PLUGINS)
+ endif()
+ foreach(_qt_plugin ${_qt_module_plugins})
+ if (INSTALLED_QT_VERSION VERSION_GREATER_EQUAL 6)
+ # Qt6 provides the plugins as individual packages that need to be found.
+ find_package(Qt${INSTALLED_QT_VERSION}${_qt_plugin} QUIET
+ PATHS ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_DIR})
+ endif()
+ install_qt_plugin("${_qt_plugin}" "${_plugins_var}")
+ endforeach()
+ endforeach()
+ endmacro()
if(APPLE)
- install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
- if(TARGET Qt5::QMacStylePlugin)
- install_qt5_plugin("Qt5::QMacStylePlugin" QT_PLUGINS)
+ if (INSTALLED_QT_VERSION VERSION_EQUAL 5)
+ install_qt_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+ if(TARGET Qt5::QMacStylePlugin)
+ install_qt_plugin("Qt5::QMacStylePlugin" QT_PLUGINS)
+ endif()
+ else()
+ # FIXME: Minimize plugins for Qt6.
+ install_qt_plugins(QT_COMPONENTS QT_PLUGINS)
endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ${_qt_plugin_dir}\n")
@@ -66,7 +132,12 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
${COMPONENT})
elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
- install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+ if (INSTALLED_QT_VERSION VERSION_EQUAL 5)
+ install_qt_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+ else()
+ # FIXME: Minimize plugins for Qt6.
+ install_qt_plugins(QT_COMPONENTS QT_PLUGINS)
+ endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
@@ -75,8 +146,8 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
endif()
endif()
-get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
-get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+get_property(_Qt_Core_LOCATION TARGET Qt${INSTALLED_QT_VERSION}::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt_Core_LOCATION}" PATH)
if(APPLE)
get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
endif()
@@ -108,7 +179,7 @@ set(SRCS
WarningMessagesDialog.cxx
WarningMessagesDialog.h
)
-qt5_wrap_ui(UI_SRCS
+set(UI_SRCS
CMakeSetupDialog.ui
Compilers.ui
CrossCompiler.ui
@@ -117,7 +188,7 @@ qt5_wrap_ui(UI_SRCS
RegexExplorer.ui
WarningMessagesDialog.ui
)
-qt5_wrap_cpp(MOC_SRCS
+set(MOC_SRCS
AddCacheEntry.h
Compilers.h
CMakeSetupDialog.h
@@ -131,8 +202,18 @@ qt5_wrap_cpp(MOC_SRCS
RegexExplorer.h
WarningMessagesDialog.h
)
-qt5_add_resources(RC_SRCS CMakeSetup.qrc)
-add_library(CMakeGUIQRCLib OBJECT ${RC_SRCS})
+set(QRC_SRCS CMakeSetup.qrc)
+
+if (INSTALLED_QT_VERSION VERSION_LESS 6)
+ qt5_wrap_ui(UI_BUILT_SRCS ${UI_SRCS})
+ qt5_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS})
+ qt5_add_resources(QRC_BUILT_SRCS ${QRC_SRCS})
+else()
+ qt_wrap_ui(UI_BUILT_SRCS ${UI_SRCS})
+ qt_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS})
+ qt_add_resources(QRC_BUILT_SRCS ${QRC_SRCS})
+endif()
+add_library(CMakeGUIQRCLib OBJECT ${QRC_BUILT_SRCS})
if (FALSE) # CMake's bootstrap binary does not support automoc
set(CMAKE_AUTOMOC 1)
@@ -140,8 +221,8 @@ if (FALSE) # CMake's bootstrap binary does not support automoc
set(CMAKE_AUTOUIC 1)
else ()
list(APPEND SRCS
- ${UI_SRCS}
- ${MOC_SRCS})
+ ${UI_BUILT_SRCS}
+ ${MOC_BUILT_SRCS})
endif ()
if(USE_LGPL)
@@ -156,13 +237,14 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(CMakeGUILib STATIC ${SRCS})
# CMake_QT_EXTRA_LIBRARIES have to come before the main libraries on the link line
-target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES} Qt5::Core Qt5::Widgets)
+target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES}
+ Qt${INSTALLED_QT_VERSION}::Core Qt${INSTALLED_QT_VERSION}::Widgets)
add_library(CMakeGUIMainLib STATIC CMakeSetup.cxx)
target_link_libraries(CMakeGUIMainLib PUBLIC CMakeGUILib)
add_executable(cmake-gui WIN32 MACOSX_BUNDLE CMakeGUIExec.cxx ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeGUIMainLib Qt5::Core)
+target_link_libraries(cmake-gui CMakeGUIMainLib Qt${INSTALLED_QT_VERSION}::Core)
target_sources(CMakeGUIMainLib INTERFACE $<TARGET_OBJECTS:CMakeGUIQRCLib>)
if(WIN32)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index c1555a2..5debdb8 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -7,7 +7,6 @@
#include <QDir>
#include <QLocale>
#include <QString>
-#include <QTextCodec>
#include <QTranslator>
#include <QtPlugin>
@@ -122,9 +121,6 @@ int main(int argc, char** argv)
setlocale(LC_NUMERIC, "C");
- QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
- QTextCodec::setCodecForLocale(utf8_codec);
-
// tell the cmake library where cmake is
QDir cmExecDir(QApplication::applicationDirPath());
#if defined(Q_OS_MAC)
@@ -146,7 +142,7 @@ int main(int argc, char** argv)
QIcon appIcon;
appIcon.addFile(":/Icons/CMakeSetup32.png");
appIcon.addFile(":/Icons/CMakeSetup128.png");
- QApplication::setWindowIcon(appIcon);
+ QApplication::setWindowIcon(QIcon::fromTheme("cmake-gui", appIcon));
CMakeSetupDialog dialog;
dialog.show();
diff --git a/Source/QtDialog/EnvironmentDialog.cxx b/Source/QtDialog/EnvironmentDialog.cxx
index 846456c..d4f978c 100644
--- a/Source/QtDialog/EnvironmentDialog.cxx
+++ b/Source/QtDialog/EnvironmentDialog.cxx
@@ -81,7 +81,11 @@ bool EnvironmentSearchFilter::filterAcceptsRow(int row,
auto* model = this->sourceModel();
auto key =
model->data(model->index(row, 0, parent), Qt::DisplayRole).toString();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
+ return key.contains(this->filterRegularExpression());
+#else
return key.contains(this->filterRegExp());
+#endif
}
EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment,
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 22f5be1..7c9032e 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -47,7 +47,11 @@ protected:
// check all strings for a match
foreach (QString const& str, strs) {
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
+ if (str.contains(this->filterRegularExpression())) {
+#else
if (str.contains(this->filterRegExp())) {
+#endif
return true;
}
}
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index e68faba..ca65d13 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -1,20 +1,23 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-// FIXME: Port to QFileSystemModel from the deprecated QDirModel.
-// Be sure completion works when incrementally editing existing paths.
#define QT_DEPRECATED_WARNINGS_SINCE QT_VERSION_CHECK(5, 14, 0)
#include "QCMakeWidgets.h"
#include <utility>
-#include <QDirModel>
#include <QFileDialog>
#include <QFileInfo>
#include <QResizeEvent>
#include <QToolButton>
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+# include <QFileSystemModel>
+#else
+# include <QDirModel>
+#endif
+
QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var)
: QLineEdit(p)
, Variable(std::move(var))
@@ -93,8 +96,30 @@ void QCMakePathEditor::chooseFile()
}
}
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
+
+{
+ static QFileSystemModel* m = nullptr;
+ if (!m) {
+ m = new QFileSystemModel();
+ }
+ return m;
+}
+static QFileSystemModel* pathDirModel()
+{
+ static QFileSystemModel* m = nullptr;
+ if (!m) {
+ m = new QFileSystemModel();
+ m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
+ }
+ return m;
+}
+#else
// use same QDirModel for all completers
static QDirModel* fileDirModel()
+
{
static QDirModel* m = nullptr;
if (!m) {
@@ -111,12 +136,19 @@ static QDirModel* pathDirModel()
}
return m;
}
+#endif
QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
: QCompleter(o)
{
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
+ this->setModel(m);
+ m->setRootPath(QString());
+#else
QDirModel* m = dirs ? pathDirModel() : fileDirModel();
this->setModel(m);
+#endif
}
QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 8435740..0dc954a 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -467,7 +467,7 @@ bool DumpFile(std::string const& nmPath, const char* filename,
bool bindexplib::AddObjectFile(const char* filename)
{
- return DumpFile(NmPath, filename, this->Symbols, this->DataSymbols);
+ return DumpFile(this->NmPath, filename, this->Symbols, this->DataSymbols);
}
bool bindexplib::AddDefinitionFile(const char* filename)
@@ -511,5 +511,5 @@ void bindexplib::WriteFile(FILE* file)
void bindexplib::SetNmPath(std::string const& nm)
{
- NmPath = nm;
+ this->NmPath = nm;
}
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 231a2d6..ff2cc3e 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -5,11 +5,11 @@
#include <sstream>
#include <unordered_set>
-#include "cmCheckCustomOutputs.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmCustomCommandTypes.h"
#include "cmExecutionStatus.h"
+#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -188,17 +188,10 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
case doing_output:
case doing_outputs:
case doing_byproducts:
- if (!cmSystemTools::FileIsFullPath(copy)) {
+ if (!cmSystemTools::FileIsFullPath(copy) &&
+ cmGeneratorExpression::Find(copy) != 0) {
// This is an output to be generated, so it should be
- // under the build tree. CMake 2.4 placed this under the
- // source tree. However the only case that this change
- // will break is when someone writes
- //
- // add_custom_command(OUTPUT out.txt ...)
- //
- // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
- // This is fairly obscure so we can wait for someone to
- // complain.
+ // under the build tree.
filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/');
}
filename += copy;
@@ -215,8 +208,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
}
if (cmSystemTools::FileIsFullPath(filename)) {
- filename = cmSystemTools::CollapseFullPath(
- filename, status.GetMakefile().GetHomeOutputDirectory());
+ filename = cmSystemTools::CollapseFullPath(filename);
}
switch (doing) {
case doing_depfile:
@@ -304,26 +296,18 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
status.SetError("given APPEND option with no OUTPUT.");
return false;
}
-
- // Make sure the output names and locations are safe.
- if (!cmCheckCustomOutputs(output, "OUTPUT", status) ||
- !cmCheckCustomOutputs(outputs, "OUTPUTS", status) ||
- !cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
+ if (!implicit_depends.empty() && !depfile.empty() &&
+ mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ // Makefiles generators does not support both at the same time
+ status.SetError("IMPLICIT_DEPENDS and DEPFILE can not both be specified.");
return false;
}
// Check for an append request.
if (append) {
- if (mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends,
- commandLines)) {
- return true;
- }
-
- // No command for this output exists.
- status.SetError(
- cmStrCat("given APPEND option with output\n ", output[0],
- "\nwhich is not already a custom command output."));
- return false;
+ mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends,
+ commandLines);
+ return true;
}
if (uses_terminal && !job_pool.empty()) {
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index aa98d89..104065f 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -4,7 +4,6 @@
#include <utility>
-#include "cmCheckCustomOutputs.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -120,12 +119,16 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
break;
case doing_byproducts: {
std::string filename;
- if (!cmSystemTools::FileIsFullPath(copy)) {
+ if (!cmSystemTools::FileIsFullPath(copy) &&
+ cmGeneratorExpression::Find(copy) != 0) {
filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/');
}
filename += copy;
cmSystemTools::ConvertToUnixSlashes(filename);
- byproducts.push_back(cmSystemTools::CollapseFullPath(filename));
+ if (cmSystemTools::FileIsFullPath(filename)) {
+ filename = cmSystemTools::CollapseFullPath(filename);
+ }
+ byproducts.push_back(filename);
} break;
case doing_depends: {
std::string dep = copy;
@@ -206,11 +209,6 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
return false;
}
- // Make sure the byproduct names and locations are safe.
- if (!cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
- return false;
- }
-
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = mf.AddUtilityCommand(
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index 87000da..c192e2a 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -47,7 +47,8 @@ struct BinarySearcher
bool operator()(argument_type const& item) const
{
- return std::binary_search(m_range.begin(), m_range.end(), item);
+ return std::binary_search(this->m_range.begin(), this->m_range.end(),
+ item);
}
private:
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 0d33758..168d30e 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -26,7 +26,7 @@ public:
}
void Clear() { this->IsValueSet = false; }
bool IsSet() const { return this->IsValueSet; }
- T Get() const { return Value; }
+ T Get() const { return this->Value; }
private:
T Value;
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index 720f582..e9bf84a 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -37,7 +37,7 @@ public:
template <typename T>
CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member)
{
- cmArgumentParser<Result>::Bind(name, member);
+ this->cmArgumentParser<Result>::Bind(name, member);
return *this;
}
@@ -48,12 +48,12 @@ public:
{
this->Inputs.clear();
- return cmArgumentParser<Result>::Parse(cmMakeRange(args).advance(Advance),
- &this->Inputs, keywordsMissingValue,
- parsedKeywords);
+ return this->cmArgumentParser<Result>::Parse(
+ cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue,
+ parsedKeywords);
}
- const std::vector<std::string>& GetInputs() const { return Inputs; }
+ const std::vector<std::string>& GetInputs() const { return this->Inputs; }
protected:
mutable std::vector<std::string> Inputs;
@@ -74,7 +74,7 @@ public:
ArgumentParserWithOutputVariable& Bind(cm::static_string_view name,
T Result::*member)
{
- cmArgumentParser<Result>::Bind(name, member);
+ this->cmArgumentParser<Result>::Bind(name, member);
return *this;
}
@@ -84,7 +84,7 @@ public:
this->KeywordsMissingValue.clear();
this->ParsedKeywords.clear();
- return CMakePathArgumentParser<Result>::template Parse<Advance>(
+ return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
args, &this->KeywordsMissingValue, &this->ParsedKeywords);
}
@@ -250,9 +250,48 @@ bool HandleGetCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleSetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 3 || args.size() > 4) {
+ status.SetError("SET must be called with two or three arguments.");
+ return false;
+ }
+
+ if (args[1].empty()) {
+ status.SetError("Invalid name for path variable.");
+ return false;
+ }
+
+ static NormalizeParser const parser;
+
+ const auto arguments = parser.Parse(args);
+
+ if (parser.GetInputs().size() != 1) {
+ status.SetError("SET called with unexpected arguments.");
+ return false;
+ }
+
+ auto path =
+ cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
+
+ if (arguments.Normalize) {
+ path = path.Normal();
+ }
+
+ status.GetMakefile().AddDefinition(args[1], path.GenericString());
+
+ return true;
+}
+
bool HandleAppendCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
+ if (args[1].empty()) {
+ status.SetError("Invalid name for path variable.");
+ return false;
+ }
+
static OutputVariableParser const parser{};
const auto arguments = parser.Parse(args);
@@ -272,8 +311,8 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
return true;
}
-bool HandleConcatCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+bool HandleAppendStringCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
static OutputVariableParser const parser{};
@@ -546,16 +585,6 @@ bool HandleRelativePathCommand(std::vector<std::string> const& args,
});
}
-bool HandleProximatePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- return HandleTransformPathCommand(
- args, status,
- [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
- return path.Proximate(base);
- });
-}
-
bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -567,40 +596,6 @@ bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
true);
}
-bool HandleCMakePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- if (args.size() < 3 || args.size() > 4) {
- status.SetError("CMAKE_PATH must be called with two or three arguments.");
- return false;
- }
-
- static NormalizeParser const parser;
-
- const auto arguments = parser.Parse(args);
-
- if (parser.GetInputs().size() != 1) {
- status.SetError("CMAKE_PATH called with unexpected arguments.");
- return false;
- }
-
- if (args[1].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
-
- auto path =
- cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
-
- if (arguments.Normalize) {
- path = path.Normal();
- }
-
- status.GetMakefile().AddDefinition(args[1], path.GenericString());
-
- return true;
-}
-
bool HandleNativePathCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -737,12 +732,7 @@ bool HandleCompareCommand(std::vector<std::string> const& args,
return false;
}
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
-
- cmCMakePath path1(inputPath);
+ cmCMakePath path1(args[1]);
cmCMakePath path2(args[3]);
auto result = op->second(path1, path2);
@@ -987,17 +977,16 @@ bool cmCMakePathCommand(std::vector<std::string> const& args,
static cmSubcommandTable const subcommand{
{ "GET"_s, HandleGetCommand },
+ { "SET"_s, HandleSetCommand },
{ "APPEND"_s, HandleAppendCommand },
- { "CONCAT"_s, HandleConcatCommand },
+ { "APPEND_STRING"_s, HandleAppendStringCommand },
{ "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
{ "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
{ "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
{ "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
{ "NORMAL_PATH"_s, HandleNormalPathCommand },
{ "RELATIVE_PATH"_s, HandleRelativePathCommand },
- { "PROXIMATE_PATH"_s, HandleProximatePathCommand },
{ "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
- { "CMAKE_PATH"_s, HandleCMakePathCommand },
{ "NATIVE_PATH"_s, HandleNativePathCommand },
{ "CONVERT"_s, HandleConvertCommand },
{ "COMPARE"_s, HandleCompareCommand },
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index b7f08d2..1f99043 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -191,8 +191,7 @@ bool HandleVersionMode(std::vector<std::string> const& args,
return false;
}
- status.GetMakefile().SetPolicyVersion(version_min, version_max);
- return true;
+ return status.GetMakefile().SetPolicyVersion(version_min, version_max);
}
bool HandleGetWarningMode(std::vector<std::string> const& args,
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 8ebf6d2..9e3582c 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -550,6 +550,11 @@ void* CCONV cmAddSource(void* arg, void* arg2)
// Create the real cmSourceFile instance and copy over saved information.
cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath);
rsf->SetProperties(osf->Properties);
+ // In case the properties contain the GENERATED property,
+ // mark the real cmSourceFile as generated.
+ if (rsf->GetIsGenerated()) {
+ rsf->MarkAsGenerated();
+ }
for (std::string const& d : osf->Depends) {
rsf->AddDepend(d);
}
@@ -583,14 +588,12 @@ const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop)
{
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
- cmProp p = rsf->GetProperty(prop);
- return cmToCStr(p);
+ return cmToCStr(rsf->GetProperty(prop));
}
if (!strcmp(prop, "LOCATION")) {
return sf->FullPath.c_str();
}
- cmProp retVal = sf->Properties.GetPropertyValue(prop);
- return cmToCStr(retVal);
+ return cmToCStr(sf->Properties.GetPropertyValue(prop));
}
int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 8cf5ae9..6c1071d 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cctype>
+#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstdlib>
@@ -179,6 +180,7 @@ struct cmCTest::Private
// information for the --build-and-test options
std::string BinaryDir;
+ std::string TestDir;
std::string NotesFiles;
@@ -1017,6 +1019,17 @@ int cmCTest::ProcessSteps()
}
if (res != 0) {
cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest" << std::endl);
+ if (!this->Impl->OutputTestOutputOnTestFailure) {
+ const std::string lastTestLog =
+ this->GetBinaryDir() + "/Testing/Temporary/LastTest.log";
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Output from these tests are in: " << lastTestLog
+ << std::endl);
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Use \"--rerun-failed --output-on-failure\" to re-run the "
+ "failed cases verbosely."
+ << std::endl);
+ }
}
return res;
}
@@ -1313,11 +1326,11 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
if (result == cmsysProcess_State_Exited) {
*retVal = cmsysProcess_GetExitValue(cp);
if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) {
- OutputTestErrors(tempOutput);
+ this->OutputTestErrors(tempOutput);
}
} else if (result == cmsysProcess_State_Exception) {
if (this->Impl->OutputTestOutputOnTestFailure) {
- OutputTestErrors(tempOutput);
+ this->OutputTestErrors(tempOutput);
}
*retVal = cmsysProcess_GetExitException(cp);
std::string outerr = cmStrCat("\n*** Exception executing: ",
@@ -2048,6 +2061,13 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i++;
this->SetNotesFiles(args[i]);
return true;
+ } else if (this->CheckArgument(arg, "--test-dir"_s)) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--test-dir' requires an argument";
+ return false;
+ }
+ i++;
+ this->Impl->TestDir = std::string(args[i]);
}
cm::string_view noTestsPrefix = "--no-tests=";
@@ -2456,8 +2476,26 @@ int cmCTest::ExecuteTests()
handler->SetVerbose(this->Impl->Verbose);
handler->SetSubmitIndex(this->Impl->SubmitIndex);
}
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- if (!this->Initialize(cwd.c_str(), nullptr)) {
+
+ const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string workDir = currDir;
+ if (!this->Impl->TestDir.empty()) {
+ workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
+ }
+
+ if (currDir != workDir) {
+ cmCTestLog(this, OUTPUT,
+ "Internal ctest changing into directory: " << workDir
+ << std::endl);
+ if (cmSystemTools::ChangeDirectory(workDir) != 0) {
+ auto msg = "Failed to change working directory to \"" + workDir +
+ "\" : " + std::strerror(errno) + "\n";
+ cmCTestLog(this, ERROR_MESSAGE, msg);
+ return 1;
+ }
+ }
+
+ if (!this->Initialize(workDir.c_str(), nullptr)) {
res = 12;
cmCTestLog(this, ERROR_MESSAGE,
"Problem initializing the dashboard." << std::endl);
@@ -2465,6 +2503,10 @@ int cmCTest::ExecuteTests()
res = this->ProcessSteps();
}
this->Finalize();
+
+ if (currDir != workDir) {
+ cmSystemTools::ChangeDirectory(currDir);
+ }
}
if (res != 0) {
cmCTestLog(this, DEBUG,
@@ -2859,7 +2901,7 @@ bool cmCTest::GetFailover() const
bool cmCTest::GetTestProgressOutput() const
{
- return this->Impl->TestProgressOutput;
+ return this->Impl->TestProgressOutput && !GetExtraVerbose();
}
bool cmCTest::GetVerbose() const
diff --git a/Source/cmCheckCustomOutputs.cxx b/Source/cmCheckCustomOutputs.cxx
deleted file mode 100644
index 7645c88..0000000
--- a/Source/cmCheckCustomOutputs.cxx
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCheckCustomOutputs.h"
-
-#include "cmExecutionStatus.h"
-#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-
-bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
- cm::string_view keyword, cmExecutionStatus& status)
-{
- cmMakefile& mf = status.GetMakefile();
-
- for (std::string const& o : outputs) {
- // Make sure the file will not be generated into the source
- // directory during an out of source build.
- if (!mf.CanIWriteThisFile(o)) {
- status.SetError(
- cmStrCat("attempted to have a file\n ", o,
- "\nin a source directory as an output of custom command."));
- cmSystemTools::SetFatalErrorOccured();
- return false;
- }
-
- // Make sure the output file name has no invalid characters.
- std::string::size_type pos = o.find_first_of("#<>");
- if (pos != std::string::npos) {
- status.SetError(cmStrCat("called with ", keyword, " containing a \"",
- o[pos], "\". This character is not allowed."));
- return false;
- }
- }
-
- return true;
-}
diff --git a/Source/cmCheckCustomOutputs.h b/Source/cmCheckCustomOutputs.h
deleted file mode 100644
index 2752ed4..0000000
--- a/Source/cmCheckCustomOutputs.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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 <string>
-#include <vector>
-
-#include <cm/string_view>
-
-class cmExecutionStatus;
-
-bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
- cm::string_view keyword, cmExecutionStatus& status);
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index d4f5022..6d5e064 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -240,7 +240,7 @@ int cmCommandArgumentParserHelper::ParseString(std::string const& str,
this->CleanupParser();
- if (Verbose) {
+ if (this->Verbose) {
std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]"
<< std::endl;
}
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
new file mode 100644
index 0000000..cbedf0a
--- /dev/null
+++ b/Source/cmCommandLineArgument.h
@@ -0,0 +1,159 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+template <typename FunctionSignature>
+struct cmCommandLineArgument
+{
+ enum class Values
+ {
+ Zero,
+ One,
+ Two,
+ ZeroOrOne,
+ OneOrMore
+ };
+
+ std::string InvalidSyntaxMessage;
+ std::string InvalidValueMessage;
+ std::string Name;
+ Values Type;
+ std::function<FunctionSignature> StoreCall;
+
+ template <typename FunctionType>
+ cmCommandLineArgument(std::string n, Values t, FunctionType&& func)
+ : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ , InvalidValueMessage(cmStrCat("Invalid value used with ", n))
+ , Name(std::move(n))
+ , Type(t)
+ , StoreCall(std::forward<FunctionType>(func))
+ {
+ }
+
+ template <typename FunctionType>
+ cmCommandLineArgument(std::string n, std::string failedMsg, Values t,
+ FunctionType&& func)
+ : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ , InvalidValueMessage(std::move(failedMsg))
+ , Name(std::move(n))
+ , Type(t)
+ , StoreCall(std::forward<FunctionType>(func))
+ {
+ }
+
+ bool matches(std::string const& input) const
+ {
+ return (this->Type == Values::Zero) ? (input == this->Name)
+ : cmHasPrefix(input, this->Name);
+ }
+
+ template <typename T, typename... CallState>
+ bool parse(std::string const& input, T& index,
+ std::vector<std::string> const& allArgs,
+ CallState&&... state) const
+ {
+ enum class ParseMode
+ {
+ Valid,
+ Invalid,
+ SyntaxError,
+ ValueError
+ };
+ ParseMode parseState = ParseMode::Valid;
+
+ if (this->Type == Values::Zero) {
+ if (input.size() == this->Name.size()) {
+ parseState =
+ this->StoreCall(std::string{}, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ } else {
+ parseState = ParseMode::SyntaxError;
+ }
+
+ } else if (this->Type == Values::One || this->Type == Values::ZeroOrOne) {
+ if (input.size() == this->Name.size()) {
+ ++index;
+ if (index >= allArgs.size() || allArgs[index][0] == '-') {
+ if (this->Type == Values::ZeroOrOne) {
+ parseState =
+ this->StoreCall(std::string{}, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ } else {
+ parseState = ParseMode::ValueError;
+ }
+ } else {
+ parseState =
+ this->StoreCall(allArgs[index], std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ } else {
+ // parse the string to get the value
+ auto possible_value = cm::string_view(input).substr(this->Name.size());
+ if (possible_value.empty()) {
+ parseState = ParseMode::SyntaxError;
+ parseState = ParseMode::ValueError;
+ } else if (possible_value[0] == '=') {
+ possible_value.remove_prefix(1);
+ if (possible_value.empty()) {
+ parseState = ParseMode::ValueError;
+ } else {
+ parseState = this->StoreCall(std::string(possible_value),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ if (parseState == ParseMode::Valid) {
+ parseState = this->StoreCall(std::string(possible_value),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ } else if (this->Type == Values::Two) {
+ if (input.size() == this->Name.size()) {
+ if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' ||
+ allArgs[index + 2][0] == '-') {
+ parseState = ParseMode::ValueError;
+ } else {
+ index += 2;
+ parseState =
+ this->StoreCall(cmStrCat(allArgs[index - 1], ";", allArgs[index]),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ } else if (this->Type == Values::OneOrMore) {
+ if (input.size() == this->Name.size()) {
+ auto nextValueIndex = index + 1;
+ if (nextValueIndex >= allArgs.size() || allArgs[index + 1][0] == '-') {
+ parseState = ParseMode::ValueError;
+ } else {
+ std::string buffer = allArgs[nextValueIndex++];
+ while (nextValueIndex < allArgs.size() &&
+ allArgs[nextValueIndex][0] != '-') {
+ buffer = cmStrCat(buffer, ";", allArgs[nextValueIndex++]);
+ }
+ parseState =
+ this->StoreCall(buffer, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ }
+
+ if (parseState == ParseMode::SyntaxError) {
+ cmSystemTools::Error(this->InvalidSyntaxMessage);
+ } else if (parseState == ParseMode::ValueError) {
+ cmSystemTools::Error(this->InvalidValueMessage);
+ }
+ return (parseState == ParseMode::Valid);
+ }
+};
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c94f128..9e5b783 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -17,6 +17,7 @@
#include "cmBreakCommand.h"
#include "cmBuildCommand.h"
#include "cmCMakeMinimumRequired.h"
+#include "cmCMakePathCommand.h"
#include "cmCMakePolicyCommand.h"
#include "cmCommand.h"
#include "cmConfigureFileCommand.h"
@@ -118,11 +119,19 @@
void GetScriptingCommands(cmState* state)
{
- state->AddBuiltinCommand("break", cmBreakCommand);
+ state->AddFlowControlCommand("break", cmBreakCommand);
+ state->AddFlowControlCommand("continue", cmContinueCommand);
+ state->AddFlowControlCommand("foreach", cmForEachCommand);
+ state->AddFlowControlCommand("function", cmFunctionCommand);
+ state->AddFlowControlCommand("if", cmIfCommand);
+ state->AddFlowControlCommand("macro", cmMacroCommand);
+ state->AddFlowControlCommand("return", cmReturnCommand);
+ state->AddFlowControlCommand("while", cmWhileCommand);
+
state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
+ state->AddBuiltinCommand("cmake_path", cmCMakePathCommand);
state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
- state->AddBuiltinCommand("continue", cmContinueCommand);
state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
state->AddBuiltinCommand("file", cmFileCommand);
@@ -131,26 +140,21 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("find_package", cmFindPackage);
state->AddBuiltinCommand("find_path", cmFindPath);
state->AddBuiltinCommand("find_program", cmFindProgram);
- state->AddBuiltinCommand("foreach", cmForEachCommand);
- state->AddBuiltinCommand("function", cmFunctionCommand);
state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
state->AddBuiltinCommand("get_directory_property",
cmGetDirectoryPropertyCommand);
state->AddBuiltinCommand("get_filename_component",
cmGetFilenameComponentCommand);
state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
- state->AddBuiltinCommand("if", cmIfCommand);
state->AddBuiltinCommand("include", cmIncludeCommand);
state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
state->AddBuiltinCommand("list", cmListCommand);
- state->AddBuiltinCommand("macro", cmMacroCommand);
state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
state->AddBuiltinCommand("math", cmMathCommand);
state->AddBuiltinCommand("message", cmMessageCommand);
state->AddBuiltinCommand("option", cmOptionCommand);
state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
- state->AddBuiltinCommand("return", cmReturnCommand);
state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
state->AddBuiltinCommand("set", cmSetCommand);
state->AddBuiltinCommand("set_directory_properties",
@@ -159,7 +163,6 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("site_name", cmSiteNameCommand);
state->AddBuiltinCommand("string", cmStringCommand);
state->AddBuiltinCommand("unset", cmUnsetCommand);
- state->AddBuiltinCommand("while", cmWhileCommand);
state->AddUnexpectedCommand(
"else",
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 2b7c9f6..228cff7 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -27,7 +27,7 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
, GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
gt->LocalGenerator->GetGlobalGenerator()))
- , ConfigNames(LocalCommonGenerator->GetConfigNames())
+ , ConfigNames(this->LocalCommonGenerator->GetConfigNames())
{
}
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 201a9d9..6e1fac0 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -699,9 +699,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
} else {
// This is not a CMake target. Use the name given.
if (cmSystemTools::FileIsFullPath(item.Value)) {
- if (cmSystemTools::FileIsDirectory(item.Value)) {
+ if (cmSystemTools::IsPathToFramework(item.Value) &&
+ this->Makefile->IsOn("APPLE")) {
+ // This is a framework.
+ this->AddFrameworkItem(item.Value);
+ } else if (cmSystemTools::FileIsDirectory(item.Value)) {
// This is a directory.
- this->AddDirectoryItem(item.Value);
+ this->DropDirectoryItem(item.Value);
} else {
// Use the full path given to the library file.
this->Depends.push_back(item.Value);
@@ -1306,16 +1310,6 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
}
}
-void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
-{
- if (this->Makefile->IsOn("APPLE") &&
- cmSystemTools::IsPathToFramework(item)) {
- this->AddFrameworkItem(item);
- } else {
- this->DropDirectoryItem(item);
- }
-}
-
void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
{
// A full path to a directory was found as a link item. Warn the
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 543b6d7..ec8d73c 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -155,7 +155,6 @@ private:
void AddFullItem(BT<std::string> const& item);
bool CheckImplicitDirItem(std::string const& item);
void AddUserItem(BT<std::string> const& item, bool pathNotKnown);
- void AddDirectoryItem(std::string const& item);
void AddFrameworkItem(std::string const& item);
void DropDirectoryItem(std::string const& item);
bool CheckSharedLibNoSOName(std::string const& item);
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 1f22ce6..85a9d9c 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -525,7 +525,7 @@ void cmComputeTargetDepends::DisplayGraph(Graph const& graph,
void cmComputeTargetDepends::DisplaySideEffects()
{
fprintf(stderr, "The side effects are:\n");
- int n = static_cast<int>(SideEffects.size());
+ int n = static_cast<int>(this->SideEffects.size());
for (int depender_index = 0; depender_index < n; ++depender_index) {
cmGeneratorTarget const* depender = this->Targets[depender_index];
fprintf(stderr, "target %d is [%s]\n", depender_index,
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 14f10bd74..62bc526 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -271,10 +271,10 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
{
// Use the policy if it is set.
if (this->Policy12Status == cmPolicies::NEW) {
- return GetBooleanValue(newArg);
+ return this->GetBooleanValue(newArg);
}
if (this->Policy12Status == cmPolicies::OLD) {
- return GetBooleanValueOld(newArg, oneArg);
+ return this->GetBooleanValueOld(newArg, oneArg);
}
// Check policy only if old and new results differ.
@@ -367,7 +367,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
reducible = 0;
auto arg = newArgs.begin();
while (arg != newArgs.end()) {
- if (IsKeyword(keyParenL, *arg)) {
+ if (this->IsKeyword(keyParenL, *arg)) {
// search for the closing paren for this opening one
cmArgumentList::iterator argClose;
argClose = arg;
@@ -531,7 +531,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
argP1 = arg;
this->IncrementArguments(newArgs, argP1, argP2);
if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- IsKeyword(keyMATCHES, *argP1)) {
+ this->IsKeyword(keyMATCHES, *argP1)) {
def = this->GetDefinitionIfUnquoted(*arg);
if (!def) {
def = &arg->GetValue();
@@ -707,8 +707,8 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs,
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
argP1 = arg;
- IncrementArguments(newArgs, argP1, argP2);
- if (argP1 != newArgs.end() && IsKeyword(keyNOT, *arg)) {
+ this->IncrementArguments(newArgs, argP1, argP2);
+ if (argP1 != newArgs.end() && this->IsKeyword(keyNOT, *arg)) {
bool rhs = this->GetBooleanValueWithAutoDereference(
*argP1, errorString, status);
this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
@@ -735,8 +735,8 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs,
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
argP1 = arg;
- IncrementArguments(newArgs, argP1, argP2);
- if (argP1 != newArgs.end() && IsKeyword(keyAND, *argP1) &&
+ this->IncrementArguments(newArgs, argP1, argP2);
+ if (argP1 != newArgs.end() && this->IsKeyword(keyAND, *argP1) &&
argP2 != newArgs.end()) {
lhs =
this->GetBooleanValueWithAutoDereference(*arg, errorString, status);
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 68322cc..edd261d 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -3,11 +3,15 @@
#include "cmConfigureFileCommand.h"
#include <set>
+#include <sstream>
#include <cm/string_view>
#include <cmext/string_view>
+#include <sys/types.h>
+
#include "cmExecutionStatus.h"
+#include "cmFSPermissions.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmNewLineStyle.h"
@@ -60,7 +64,19 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
}
bool copyOnly = false;
bool escapeQuotes = false;
- bool use_source_permissions = true;
+ bool useSourcePermissions = false;
+ bool noSourcePermissions = false;
+ bool filePermissions = false;
+ std::vector<std::string> filePermissionOptions;
+
+ enum class Doing
+ {
+ DoingNone,
+ DoingFilePermissions,
+ DoneFilePermissions
+ };
+
+ Doing doing = Doing::DoingNone;
static std::set<cm::string_view> noopOptions = {
/* Legacy. */
@@ -78,6 +94,9 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
bool atOnly = false;
for (unsigned int i = 2; i < args.size(); ++i) {
if (args[i] == "COPYONLY") {
+ if (doing == Doing::DoingFilePermissions) {
+ doing = Doing::DoneFilePermissions;
+ }
copyOnly = true;
if (newLineStyle.IsValid()) {
status.SetError("COPYONLY could not be used in combination "
@@ -85,13 +104,49 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
return false;
}
} else if (args[i] == "ESCAPE_QUOTES") {
+ if (doing == Doing::DoingFilePermissions) {
+ doing = Doing::DoneFilePermissions;
+ }
escapeQuotes = true;
} else if (args[i] == "@ONLY") {
+ if (doing == Doing::DoingFilePermissions) {
+ doing = Doing::DoneFilePermissions;
+ }
atOnly = true;
} else if (args[i] == "NO_SOURCE_PERMISSIONS") {
- use_source_permissions = false;
+ if (doing == Doing::DoingFilePermissions) {
+ status.SetError(" given both FILE_PERMISSIONS and "
+ "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ noSourcePermissions = true;
+ } else if (args[i] == "USE_SOURCE_PERMISSIONS") {
+ if (doing == Doing::DoingFilePermissions) {
+ status.SetError(" given both FILE_PERMISSIONS and "
+ "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ useSourcePermissions = true;
+ } else if (args[i] == "FILE_PERMISSIONS") {
+ if (useSourcePermissions) {
+ status.SetError(" given both FILE_PERMISSIONS and "
+ "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ if (noSourcePermissions) {
+ status.SetError(" given both FILE_PERMISSIONS and "
+ "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+
+ if (doing == Doing::DoingNone) {
+ doing = Doing::DoingFilePermissions;
+ filePermissions = true;
+ }
} else if (noopOptions.find(args[i]) != noopOptions.end()) {
/* Ignore no-op options. */
+ } else if (doing == Doing::DoingFilePermissions) {
+ filePermissionOptions.push_back(args[i]);
} else {
unknown_args += " ";
unknown_args += args[i];
@@ -104,9 +159,53 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, msg);
}
- if (!status.GetMakefile().ConfigureFile(
- inputFile, outputFile, copyOnly, atOnly, escapeQuotes,
- use_source_permissions, newLineStyle)) {
+ if (useSourcePermissions && noSourcePermissions) {
+ status.SetError(" given both USE_SOURCE_PERMISSIONS and "
+ "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+
+ mode_t permisiions = 0;
+
+ if (filePermissions) {
+ if (filePermissionOptions.empty()) {
+ status.SetError(" given FILE_PERMISSIONS without any options.");
+ return false;
+ }
+
+ std::vector<std::string> invalidOptions;
+ for (auto const& e : filePermissionOptions) {
+ if (!cmFSPermissions::stringToModeT(e, permisiions)) {
+ invalidOptions.push_back(e);
+ }
+ }
+
+ if (!invalidOptions.empty()) {
+ std::ostringstream oss;
+ oss << " given invalid permission ";
+ for (auto i = 0u; i < invalidOptions.size(); i++) {
+ if (i == 0u) {
+ oss << "\"" << invalidOptions[i] << "\"";
+ } else {
+ oss << ",\"" << invalidOptions[i] << "\"";
+ }
+ }
+ oss << ".";
+ status.SetError(oss.str());
+ return false;
+ }
+ }
+
+ if (noSourcePermissions) {
+ permisiions |= cmFSPermissions::mode_owner_read;
+ permisiions |= cmFSPermissions::mode_owner_write;
+ permisiions |= cmFSPermissions::mode_group_read;
+ permisiions |= cmFSPermissions::mode_world_read;
+ }
+
+ if (!status.GetMakefile().ConfigureFile(inputFile, outputFile, copyOnly,
+ atOnly, escapeQuotes, permisiions,
+ newLineStyle)) {
status.SetError("Problem configuring file");
return false;
}
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
deleted file mode 100644
index e4d0cf1..0000000
--- a/Source/cmConnection.cxx
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmConnection.h"
-
-#include <cassert>
-#include <cstring>
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-
-struct write_req_t
-{
- uv_write_t req;
- uv_buf_t buf;
-};
-
-void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
- size_t suggested_size,
- uv_buf_t* buf)
-{
- (void)(handle);
-#ifndef __clang_analyzer__
- char* rawBuffer = new char[suggested_size];
- *buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
-#else
- (void)(suggested_size);
- (void)(buf);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
- const uv_buf_t* buf)
-{
- auto conn = static_cast<cmEventBasedConnection*>(stream->data);
- if (conn) {
- if (nread >= 0) {
- conn->ReadData(std::string(buf->base, buf->base + nread));
- } else {
- conn->OnDisconnect(static_cast<int>(nread));
- }
- }
-
- delete[](buf->base);
-}
-
-void cmEventBasedConnection::on_close(uv_handle_t* /*handle*/)
-{
-}
-
-void cmEventBasedConnection::on_write(uv_write_t* req, int status)
-{
- (void)(status);
-
- // Free req and buffer
- write_req_t* wr = reinterpret_cast<write_req_t*>(req);
- delete[](wr->buf.base);
- delete wr;
-}
-
-void cmEventBasedConnection::on_new_connection(uv_stream_t* stream, int status)
-{
- (void)(status);
- auto conn = static_cast<cmEventBasedConnection*>(stream->data);
-
- if (conn) {
- conn->Connect(stream);
- }
-}
-
-bool cmEventBasedConnection::IsOpen() const
-{
- return this->WriteStream != nullptr;
-}
-
-void cmEventBasedConnection::WriteData(const std::string& _data)
-{
-#ifndef NDEBUG
- auto curr_thread_id = uv_thread_self();
- assert(this->Server);
- assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
-#endif
-
-#ifndef __clang_analyzer__
- auto data = _data;
- assert(this->WriteStream.get());
- if (BufferStrategy) {
- data = BufferStrategy->BufferOutMessage(data);
- }
-
- auto ds = data.size();
-
- write_req_t* req = new write_req_t;
- req->req.data = this;
- req->buf = uv_buf_init(new char[ds], static_cast<unsigned int>(ds));
- memcpy(req->buf.base, data.c_str(), ds);
- uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
- on_write);
-#else
- (void)(_data);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::ReadData(const std::string& data)
-{
- this->RawReadBuffer += data;
- if (BufferStrategy) {
- std::string packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
- while (!packet.empty()) {
- ProcessRequest(packet);
- packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
- }
- } else {
- ProcessRequest(this->RawReadBuffer);
- this->RawReadBuffer.clear();
- }
-}
-
-cmEventBasedConnection::cmEventBasedConnection(
- cmConnectionBufferStrategy* bufferStrategy)
- : BufferStrategy(bufferStrategy)
-{
-}
-
-void cmEventBasedConnection::Connect(uv_stream_t* server)
-{
- (void)server;
- Server->OnConnected(nullptr);
-}
-
-void cmEventBasedConnection::OnDisconnect(int onerror)
-{
- (void)onerror;
- this->OnConnectionShuttingDown();
- if (this->Server) {
- this->Server->OnDisconnect(this);
- }
-}
-
-cmConnection::~cmConnection() = default;
-
-bool cmConnection::OnConnectionShuttingDown()
-{
- this->Server = nullptr;
- return true;
-}
-
-void cmConnection::SetServer(cmServerBase* s)
-{
- Server = s;
-}
-
-void cmConnection::ProcessRequest(const std::string& request)
-{
- Server->ProcessRequest(this, request);
-}
-
-bool cmConnection::OnServeStart(std::string* errString)
-{
- (void)errString;
- return true;
-}
-
-bool cmEventBasedConnection::OnConnectionShuttingDown()
-{
- if (this->WriteStream.get()) {
- this->WriteStream->data = nullptr;
- }
-
- WriteStream.reset();
-
- return true;
-}
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
deleted file mode 100644
index 5335a7f..0000000
--- a/Source/cmConnection.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* 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 <cstddef>
-#include <memory>
-#include <string>
-
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * Given a sequence of bytes with any kind of buffering, instances of this
- * class arrange logical chunks according to whatever the use case is for
- * the connection.
- */
-class cmConnectionBufferStrategy
-{
-public:
- virtual ~cmConnectionBufferStrategy();
-
- /***
- * Called whenever with an active raw buffer. If a logical chunk
- * becomes available, that chunk is returned and that portion is
- * removed from the rawBuffer
- *
- * @param rawBuffer in/out parameter. Receive buffer; the buffer strategy is
- * free to manipulate this buffer anyway it needs to.
- *
- * @return Next chunk from the stream. Returns the empty string if a chunk
- * isn't ready yet. Users of this interface should repeatedly call this
- * function until an empty string is returned since its entirely possible
- * multiple chunks come in a single raw buffer.
- */
- virtual std::string BufferMessage(std::string& rawBuffer) = 0;
-
- /***
- * Called to properly buffer an outgoing message.
- *
- * @param rawBuffer Message to format in the correct way
- *
- * @return Formatted message
- */
- virtual std::string BufferOutMessage(const std::string& rawBuffer) const
- {
- return rawBuffer;
- };
- /***
- * Resets the internal state of the buffering
- */
- virtual void clear();
-
- // TODO: There should be a callback / flag set for errors
-};
-
-class cmConnection
-{
-public:
- cmConnection() = default;
-
- cmConnection(cmConnection const&) = delete;
- cmConnection& operator=(cmConnection const&) = delete;
-
- virtual void WriteData(const std::string& data) = 0;
-
- virtual ~cmConnection();
-
- virtual bool OnConnectionShuttingDown();
-
- virtual bool IsOpen() const = 0;
-
- virtual void SetServer(cmServerBase* s);
-
- virtual void ProcessRequest(const std::string& request);
-
- virtual bool OnServeStart(std::string* pString);
-
-protected:
- cmServerBase* Server = nullptr;
-};
-
-/***
- * Abstraction of a connection; ties in event callbacks from libuv and notifies
- * the server when appropriate
- */
-class cmEventBasedConnection : public cmConnection
-{
-
-public:
- /***
- * @param bufferStrategy If no strategy is given, it will process the raw
- * chunks as they come in. The connection
- * owns the pointer given.
- */
- cmEventBasedConnection(cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
- virtual void Connect(uv_stream_t* server);
-
- virtual void ReadData(const std::string& data);
-
- bool IsOpen() const override;
-
- void WriteData(const std::string& data) override;
- bool OnConnectionShuttingDown() override;
-
- virtual void OnDisconnect(int errorCode);
-
- static void on_close(uv_handle_t* handle);
-
- template <typename T>
- static void on_close_delete(uv_handle_t* handle)
- {
- delete reinterpret_cast<T*>(handle);
- }
-
-protected:
- cm::uv_stream_ptr WriteStream;
-
- std::string RawReadBuffer;
-
- std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;
-
- static void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
-
- static void on_write(uv_write_t* req, int status);
-
- static void on_new_connection(uv_stream_t* stream, int status);
-
- static void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size,
- uv_buf_t* buf);
-};
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 9c4deea..3001ae0 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -125,9 +125,9 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
mf.AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function);
}
mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
- mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
+ mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTRIES", functionMapCode);
bool res = true;
- if (!mf.ConfigureFile(configFile, driver, false, true, false, true)) {
+ if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
res = false;
}
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index b1e63ba..b331862 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -36,7 +36,7 @@ static rhash cmCryptoHash_rhash_init(unsigned int id)
cmCryptoHash::cmCryptoHash(Algo algo)
: Id(cmCryptoHashAlgoToId[algo])
- , CTX(cmCryptoHash_rhash_init(Id))
+ , CTX(cmCryptoHash_rhash_init(this->Id))
{
}
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 60504ba..c67497a 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -6,45 +6,147 @@
#include <memory>
#include <utility>
+#include <cm/optional>
+#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
+#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTransformDepfile.h"
namespace {
-void AppendPaths(const std::vector<std::string>& inputs,
- cmGeneratorExpression const& ge, cmLocalGenerator* lg,
- std::string const& config, std::vector<std::string>& output)
+std::string EvaluateSplitConfigGenex(
+ cm::string_view input, cmGeneratorExpression const& ge, cmLocalGenerator* lg,
+ bool useOutputConfig, std::string const& outputConfig,
+ std::string const& commandConfig,
+ std::set<BT<std::pair<std::string, bool>>>* utils = nullptr)
{
- for (std::string const& in : inputs) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(in);
- std::vector<std::string> result =
- cmExpandedList(cge->Evaluate(lg, config));
- for (std::string& it : result) {
- cmSystemTools::ConvertToUnixSlashes(it);
- if (cmSystemTools::FileIsFullPath(it)) {
- it = cmSystemTools::CollapseFullPath(
- it, lg->GetMakefile()->GetHomeOutputDirectory());
+ std::string result;
+
+ while (!input.empty()) {
+ // Copy non-genex content directly to the result.
+ std::string::size_type pos = input.find("$<");
+ result += input.substr(0, pos);
+ if (pos == std::string::npos) {
+ break;
+ }
+ input = input.substr(pos);
+
+ // Find the balanced end of this regex.
+ size_t nestingLevel = 1;
+ for (pos = 2; pos < input.size(); ++pos) {
+ cm::string_view cur = input.substr(pos);
+ if (cmHasLiteralPrefix(cur, "$<")) {
+ ++nestingLevel;
+ ++pos;
+ continue;
+ }
+ if (cmHasLiteralPrefix(cur, ">")) {
+ --nestingLevel;
+ if (nestingLevel == 0) {
+ ++pos;
+ break;
+ }
+ }
+ }
+
+ // Split this genex from following input.
+ cm::string_view genex = input.substr(0, pos);
+ input = input.substr(pos);
+
+ // Convert an outer COMMAND_CONFIG or OUTPUT_CONFIG to the matching config.
+ std::string const* config =
+ useOutputConfig ? &outputConfig : &commandConfig;
+ if (nestingLevel == 0) {
+ static cm::string_view const COMMAND_CONFIG = "$<COMMAND_CONFIG:"_s;
+ static cm::string_view const OUTPUT_CONFIG = "$<OUTPUT_CONFIG:"_s;
+ if (cmHasPrefix(genex, COMMAND_CONFIG)) {
+ genex.remove_prefix(COMMAND_CONFIG.size());
+ genex.remove_suffix(1);
+ useOutputConfig = false;
+ config = &commandConfig;
+ } else if (cmHasPrefix(genex, OUTPUT_CONFIG)) {
+ genex.remove_prefix(OUTPUT_CONFIG.size());
+ genex.remove_suffix(1);
+ useOutputConfig = true;
+ config = &outputConfig;
+ }
+ }
+
+ // Evaluate this genex in the selected configuration.
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(std::string(genex));
+ result += cge->Evaluate(lg, *config);
+
+ // Record targets referenced by the genex.
+ if (utils) {
+ // FIXME: What is the proper condition for a cross-dependency?
+ bool const cross = !useOutputConfig;
+ for (cmGeneratorTarget* gt : cge->GetTargets()) {
+ utils->emplace(BT<std::pair<std::string, bool>>(
+ { gt->GetName(), cross }, cge->GetBacktrace()));
}
}
- cm::append(output, result);
}
+
+ return result;
+}
+
+std::vector<std::string> EvaluateDepends(std::vector<std::string> const& paths,
+ cmGeneratorExpression const& ge,
+ cmLocalGenerator* lg,
+ std::string const& outputConfig,
+ std::string const& commandConfig)
+{
+ std::vector<std::string> depends;
+ for (std::string const& p : paths) {
+ std::string const& ep =
+ EvaluateSplitConfigGenex(p, ge, lg, /*useOutputConfig=*/true,
+ /*outputConfig=*/outputConfig,
+ /*commandConfig=*/commandConfig);
+ cm::append(depends, cmExpandedList(ep));
+ }
+ for (std::string& p : depends) {
+ if (cmSystemTools::FileIsFullPath(p)) {
+ p = cmSystemTools::CollapseFullPath(p);
+ } else {
+ cmSystemTools::ConvertToUnixSlashes(p);
+ }
+ }
+ return depends;
+}
+
+std::vector<std::string> EvaluateOutputs(std::vector<std::string> const& paths,
+ cmGeneratorExpression const& ge,
+ cmLocalGenerator* lg,
+ std::string const& config)
+{
+ std::vector<std::string> outputs;
+ for (std::string const& p : paths) {
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
+ cm::append(outputs, lg->ExpandCustomCommandOutputPaths(*cge, config));
+ }
+ return outputs;
}
}
-cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
- std::string config,
- cmLocalGenerator* lg)
- : CC(cc)
- , Config(std::move(config))
+cmCustomCommandGenerator::cmCustomCommandGenerator(
+ cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
+ bool transformDepfile, cm::optional<std::string> crossConfig)
+ : CC(&cc)
+ , OutputConfig(crossConfig ? *crossConfig : config)
+ , CommandConfig(std::move(config))
, LG(lg)
, OldStyle(cc.GetEscapeOldStyle())
, MakeVars(cc.GetEscapeAllowMakeVars())
@@ -52,38 +154,87 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
{
cmGeneratorExpression ge(cc.GetBacktrace());
- const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
+ const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines();
for (cmCustomCommandLine const& cmdline : cmdlines) {
cmCustomCommandLine argv;
+ // For the command itself, we default to the COMMAND_CONFIG.
+ bool useOutputConfig = false;
for (std::string const& clarg : cmdline) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg);
- std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
- if (this->CC.GetCommandExpandLists()) {
+ std::string parsed_arg = EvaluateSplitConfigGenex(
+ clarg, ge, this->LG, useOutputConfig, this->OutputConfig,
+ this->CommandConfig, &this->Utilities);
+ if (this->CC->GetCommandExpandLists()) {
cm::append(argv, cmExpandedList(parsed_arg));
} else {
argv.push_back(std::move(parsed_arg));
}
+
+ // For remaining arguments, we default to the OUTPUT_CONFIG.
+ useOutputConfig = true;
}
- // Later code assumes at least one entry exists, but expanding
- // lists on an empty command may have left this empty.
- // FIXME: Should we define behavior for removing empty commands?
- if (argv.empty()) {
+ if (!argv.empty()) {
+ // If the command references an executable target by name,
+ // collect the target to add a target-level dependency on it.
+ cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front());
+ if (gt && gt->GetType() == cmStateEnums::EXECUTABLE) {
+ // FIXME: What is the proper condition for a cross-dependency?
+ bool const cross = true;
+ this->Utilities.emplace(BT<std::pair<std::string, bool>>(
+ { gt->GetName(), cross }, cc.GetBacktrace()));
+ }
+ } else {
+ // Later code assumes at least one entry exists, but expanding
+ // lists on an empty command may have left this empty.
+ // FIXME: Should we define behavior for removing empty commands?
argv.emplace_back();
}
this->CommandLines.push_back(std::move(argv));
}
- AppendPaths(cc.GetByproducts(), ge, this->LG, this->Config,
- this->Byproducts);
- AppendPaths(cc.GetDepends(), ge, this->LG, this->Config, this->Depends);
+ if (transformDepfile && !this->CommandLines.empty() &&
+ !cc.GetDepfile().empty() &&
+ this->LG->GetGlobalGenerator()->DepfileFormat()) {
+ cmCustomCommandLine argv;
+ argv.push_back(cmSystemTools::GetCMakeCommand());
+ argv.emplace_back("-E");
+ argv.emplace_back("cmake_transform_depfile");
+ switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
+ case cmDepfileFormat::GccDepfile:
+ argv.emplace_back("gccdepfile");
+ break;
+ case cmDepfileFormat::VsTlog:
+ argv.emplace_back("vstlog");
+ break;
+ }
+ if (this->LG->GetCurrentBinaryDirectory() ==
+ this->LG->GetBinaryDirectory()) {
+ argv.emplace_back("./");
+ } else {
+ argv.push_back(cmStrCat(this->LG->MaybeConvertToRelativePath(
+ this->LG->GetBinaryDirectory(),
+ this->LG->GetCurrentBinaryDirectory()),
+ '/'));
+ }
+ argv.push_back(this->GetFullDepfile());
+ argv.push_back(this->GetInternalDepfile());
+
+ this->CommandLines.push_back(std::move(argv));
+ }
+
+ this->Outputs =
+ EvaluateOutputs(cc.GetOutputs(), ge, this->LG, this->OutputConfig);
+ this->Byproducts =
+ EvaluateOutputs(cc.GetByproducts(), ge, this->LG, this->OutputConfig);
+ this->Depends = EvaluateDepends(cc.GetDepends(), ge, this->LG,
+ this->OutputConfig, this->CommandConfig);
- const std::string& workingdirectory = this->CC.GetWorkingDirectory();
+ const std::string& workingdirectory = this->CC->GetWorkingDirectory();
if (!workingdirectory.empty()) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(workingdirectory);
- this->WorkingDirectory = cge->Evaluate(this->LG, this->Config);
+ this->WorkingDirectory =
+ EvaluateSplitConfigGenex(workingdirectory, ge, this->LG, true,
+ this->OutputConfig, this->CommandConfig);
// Convert working directory to a full path.
if (!this->WorkingDirectory.empty()) {
std::string const& build_dir = this->LG->GetCurrentBinaryDirectory();
@@ -97,7 +248,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
{
- return static_cast<unsigned int>(this->CC.GetCommandLines().size());
+ return static_cast<unsigned int>(this->CommandLines.size());
}
void cmCustomCommandGenerator::FillEmulatorsWithArguments()
@@ -140,7 +291,7 @@ const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
(target->IsImported() ||
target->GetProperty("CROSSCOMPILING_EMULATOR") ||
!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
- return target->GetLocation(this->Config).c_str();
+ return target->GetLocation(this->CommandConfig).c_str();
}
return nullptr;
}
@@ -234,9 +385,43 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
}
}
+std::string cmCustomCommandGenerator::GetFullDepfile() const
+{
+ std::string depfile = this->CC->GetDepfile();
+ if (depfile.empty()) {
+ return "";
+ }
+
+ if (!cmSystemTools::FileIsFullPath(depfile)) {
+ depfile = cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/', depfile);
+ }
+ return cmSystemTools::CollapseFullPath(depfile);
+}
+
+std::string cmCustomCommandGenerator::GetInternalDepfile() const
+{
+ std::string depfile = this->GetFullDepfile();
+ if (depfile.empty()) {
+ return "";
+ }
+
+ cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+ std::string extension;
+ switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
+ case cmDepfileFormat::GccDepfile:
+ extension = ".d";
+ break;
+ case cmDepfileFormat::VsTlog:
+ extension = ".tlog";
+ break;
+ }
+ return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/",
+ hash.HashString(depfile), extension);
+}
+
const char* cmCustomCommandGenerator::GetComment() const
{
- return this->CC.GetComment();
+ return this->CC->GetComment();
}
std::string cmCustomCommandGenerator::GetWorkingDirectory() const
@@ -246,7 +431,7 @@ std::string cmCustomCommandGenerator::GetWorkingDirectory() const
std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
{
- return this->CC.GetOutputs();
+ return this->Outputs;
}
std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
@@ -258,3 +443,9 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
{
return this->Depends;
}
+
+std::set<BT<std::pair<std::string, bool>>> const&
+cmCustomCommandGenerator::GetUtilities() const
+{
+ return this->Utilities;
+}
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 412eba8..4be5b3f 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -4,26 +4,34 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <set>
#include <string>
+#include <utility>
#include <vector>
+#include <cm/optional>
+
#include "cmCustomCommandLines.h"
+#include "cmListFileCache.h"
class cmCustomCommand;
class cmLocalGenerator;
class cmCustomCommandGenerator
{
- cmCustomCommand const& CC;
- std::string Config;
+ cmCustomCommand const* CC;
+ std::string OutputConfig;
+ std::string CommandConfig;
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
cmCustomCommandLines CommandLines;
std::vector<std::vector<std::string>> EmulatorsWithArguments;
+ std::vector<std::string> Outputs;
std::vector<std::string> Byproducts;
std::vector<std::string> Depends;
std::string WorkingDirectory;
+ std::set<BT<std::pair<std::string, bool>>> Utilities;
void FillEmulatorsWithArguments();
std::vector<std::string> GetCrossCompilingEmulator(unsigned int c) const;
@@ -31,11 +39,14 @@ class cmCustomCommandGenerator
public:
cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config,
- cmLocalGenerator* lg);
+ cmLocalGenerator* lg, bool transformDepfile = true,
+ cm::optional<std::string> crossConfig = {});
cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete;
+ cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default;
cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) =
delete;
- cmCustomCommand const& GetCC() const { return this->CC; }
+ cmCustomCommandGenerator& operator=(cmCustomCommandGenerator&&) = default;
+ cmCustomCommand const& GetCC() const { return *(this->CC); }
unsigned int GetNumberOfCommands() const;
std::string GetCommand(unsigned int c) const;
void AppendArguments(unsigned int c, std::string& cmd) const;
@@ -44,5 +55,11 @@ public:
std::vector<std::string> const& GetOutputs() const;
std::vector<std::string> const& GetByproducts() const;
std::vector<std::string> const& GetDepends() const;
+ std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
bool HasOnlyEmptyCommandLines() const;
+ std::string GetFullDepfile() const;
+ std::string GetInternalDepfile() const;
+
+ const std::string& GetOutputConfig() const { return this->OutputConfig; }
+ const std::string& GetCommandConfig() const { return this->CommandConfig; }
};
diff --git a/Source/cmCustomCommandTypes.h b/Source/cmCustomCommandTypes.h
index 5c900ce..324da9e 100644
--- a/Source/cmCustomCommandTypes.h
+++ b/Source/cmCustomCommandTypes.h
@@ -27,10 +27,3 @@ enum class cmObjectLibraryCommands
Reject,
Accept
};
-
-/** Utility target output source file name. */
-struct cmUtilityOutput
-{
- std::string Name;
- std::string NameCMP0049;
-};
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index e6aef92..60e8cbf 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -7,6 +7,7 @@
#include "cmsys/FStream.hxx"
#include "cmFileTime.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmProperty.h"
@@ -215,16 +216,28 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// directory. We must do the same here.
std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i);
internalDepends << obj_i << '\n';
-
- for (std::string const& dep : dependencies) {
- makeDepends << obj_m << ": "
- << this->LocalGenerator->ConvertToMakefilePath(
- this->LocalGenerator->MaybeConvertToRelativePath(binDir,
- dep))
- << '\n';
- internalDepends << ' ' << dep << '\n';
+ if (!dependencies.empty()) {
+ const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->LineContinueDirective;
+ bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->SupportsLongLineDependencies();
+ if (supportLongLineDepend) {
+ makeDepends << obj_m << ':';
+ }
+ for (std::string const& dep : dependencies) {
+ std::string dependee = this->LocalGenerator->ConvertToMakefilePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
+ if (supportLongLineDepend) {
+ makeDepends << ' ' << lineContinue << ' ' << dependee;
+ } else {
+ makeDepends << obj_m << ": " << dependee << '\n';
+ }
+ internalDepends << ' ' << dep << '\n';
+ }
+ makeDepends << '\n';
}
- makeDepends << '\n';
return true;
}
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
new file mode 100644
index 0000000..ec31f68
--- /dev/null
+++ b/Source/cmDependsCompiler.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 "cmDependsCompiler.h"
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <utility>
+
+#include <cm/optional>
+#include <cm/string_view>
+#include <cm/vector>
+#include <cmext/string_view>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmFileTime.h"
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+bool cmDependsCompiler::CheckDependencies(
+ const std::string& internalDepFile, const std::vector<std::string>& depFiles,
+ cmDepends::DependencyMap& dependencies,
+ const std::function<bool(const std::string&)>& isValidPath)
+{
+ bool status = true;
+ bool forceReadDeps = true;
+
+ cmFileTime internalDepFileTime;
+ // read cached dependencies stored in internal file
+ if (cmSystemTools::FileExists(internalDepFile)) {
+ internalDepFileTime.Load(internalDepFile);
+ forceReadDeps = false;
+
+ // read current dependencies
+ cmsys::ifstream fin(internalDepFile.c_str());
+ if (fin) {
+ std::string line;
+ std::string depender;
+ std::vector<std::string>* currentDependencies = nullptr;
+ while (std::getline(fin, line)) {
+ if (line.empty() || line.front() == '#') {
+ continue;
+ }
+ // Drop carriage return character at the end
+ if (line.back() == '\r') {
+ line.pop_back();
+ if (line.empty()) {
+ continue;
+ }
+ }
+ // Check if this a depender line
+ if (line.front() != ' ') {
+ depender = std::move(line);
+ currentDependencies = &dependencies[depender];
+ continue;
+ }
+ // This is a dependee line
+ if (currentDependencies != nullptr) {
+ currentDependencies->emplace_back(line.substr(1));
+ }
+ }
+ fin.close();
+ }
+ }
+
+ // Now, update dependencies map with all new compiler generated
+ // dependencies files
+ cmFileTime depFileTime;
+ for (auto dep = depFiles.begin(); dep != depFiles.end(); dep++) {
+ const auto& source = *dep++;
+ const auto& target = *dep++;
+ const auto& format = *dep++;
+ const auto& depFile = *dep;
+
+ if (!cmSystemTools::FileExists(depFile)) {
+ continue;
+ }
+
+ if (!forceReadDeps) {
+ depFileTime.Load(depFile);
+ }
+ if (forceReadDeps || depFileTime.Compare(internalDepFileTime) >= 0) {
+ status = false;
+ if (this->Verbose) {
+ cmSystemTools::Stdout(cmStrCat("Dependencies file \"", depFile,
+ "\" is newer than depends file \"",
+ internalDepFile, "\".\n"));
+ }
+
+ std::vector<std::string> depends;
+ if (format == "custom"_s) {
+ std::string prefix;
+ if (this->LocalGenerator->GetCurrentBinaryDirectory() !=
+ this->LocalGenerator->GetBinaryDirectory()) {
+ prefix =
+ cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory()),
+ '/');
+ }
+
+ auto deps = cmReadGccDepfile(depFile.c_str(), prefix);
+ if (!deps) {
+ continue;
+ }
+
+ for (auto& entry : *deps) {
+ depends = std::move(entry.paths);
+ if (isValidPath) {
+ cm::erase_if(depends, isValidPath);
+ }
+ // copy depends for each target, except first one, which can be
+ // moved
+ for (auto index = entry.rules.size() - 1; index > 0; --index) {
+ dependencies[entry.rules[index]] = depends;
+ }
+ dependencies[entry.rules.front()] = std::move(depends);
+ }
+ } else {
+ if (format == "msvc"_s) {
+ cmsys::ifstream fin(depFile.c_str());
+ if (!fin) {
+ continue;
+ }
+
+ std::string line;
+ if (!isValidPath) {
+ // insert source as first dependency
+ depends.push_back(source);
+ }
+ while (cmSystemTools::GetLineFromStream(fin, line)) {
+ depends.emplace_back(std::move(line));
+ }
+ } else if (format == "gcc"_s) {
+ auto deps = cmReadGccDepfile(depFile.c_str());
+ if (!deps) {
+ continue;
+ }
+
+ // dependencies generated by the compiler contains only one target
+ depends = std::move(deps->front().paths);
+ if (depends.empty()) {
+ // unexpectedly empty, ignore it and continue
+ continue;
+ }
+
+ // depending of the effective format of the dependencies file
+ // generated by the compiler, the target can be wrongly identified
+ // as a dependency so remove it from the list
+ if (depends.front() == target) {
+ depends.erase(depends.begin());
+ }
+
+ // ensure source file is the first dependency
+ if (depends.front() != source) {
+ cm::erase(depends, source);
+ if (!isValidPath) {
+ depends.insert(depends.begin(), source);
+ }
+ } else if (isValidPath) {
+ // remove first dependency because it must not be filtered out
+ depends.erase(depends.begin());
+ }
+ } else {
+ // unknown format, ignore it
+ continue;
+ }
+
+ if (isValidPath) {
+ cm::erase_if(depends, isValidPath);
+ // insert source as first dependency
+ depends.insert(depends.begin(), source);
+ }
+
+ dependencies[target] = std::move(depends);
+ }
+ }
+ }
+
+ return status;
+}
+
+void cmDependsCompiler::WriteDependencies(
+ const cmDepends::DependencyMap& dependencies, std::ostream& makeDepends,
+ std::ostream& internalDepends)
+{
+ // dependencies file consumed by make tool
+ const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->LineContinueDirective;
+ bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->SupportsLongLineDependencies();
+ const auto& binDir = this->LocalGenerator->GetBinaryDirectory();
+ cmDepends::DependencyMap makeDependencies(dependencies);
+ std::unordered_set<cm::string_view> phonyTargets;
+
+ // external dependencies file
+ for (auto& node : makeDependencies) {
+ auto target = this->LocalGenerator->ConvertToMakefilePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first));
+ auto& deps = node.second;
+ std::transform(
+ deps.cbegin(), deps.cend(), deps.begin(),
+ [this, &binDir](const std::string& dep) {
+ return this->LocalGenerator->ConvertToMakefilePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
+ });
+
+ bool first_dep = true;
+ if (supportLongLineDepend) {
+ makeDepends << target << ": ";
+ }
+ for (const auto& dep : deps) {
+ if (supportLongLineDepend) {
+ if (first_dep) {
+ first_dep = false;
+ makeDepends << dep;
+ } else {
+ makeDepends << ' ' << lineContinue << " " << dep;
+ }
+ } else {
+ makeDepends << target << ": " << dep << std::endl;
+ }
+
+ phonyTargets.emplace(dep.data(), dep.length());
+ }
+ makeDepends << std::endl << std::endl;
+ }
+
+ // add phony targets
+ for (const auto& target : phonyTargets) {
+ makeDepends << std::endl << target << ':' << std::endl;
+ }
+
+ // internal dependencies file
+ for (const auto& node : dependencies) {
+ internalDepends << node.first << std::endl;
+ for (const auto& dep : node.second) {
+ internalDepends << ' ' << dep << std::endl;
+ }
+ internalDepends << std::endl;
+ }
+}
+
+void cmDependsCompiler::ClearDependencies(
+ const std::vector<std::string>& depFiles)
+{
+ for (auto dep = depFiles.begin(); dep != depFiles.end(); dep++) {
+ dep += 3;
+ cmSystemTools::RemoveFile(*dep);
+ }
+}
diff --git a/Source/cmDependsCompiler.h b/Source/cmDependsCompiler.h
new file mode 100644
index 0000000..838156d
--- /dev/null
+++ b/Source/cmDependsCompiler.h
@@ -0,0 +1,60 @@
+/* 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 <iosfwd>
+#include <string>
+#include <vector>
+
+#include "cmDepends.h"
+
+class cmLocalUnixMakefileGenerator3;
+
+/** \class cmDepends
+ * \brief Dependencies files manager.
+ *
+ * This class is responsible for maintaining a compiler_depends.make file in
+ * the build tree corresponding to an object file.
+ */
+class cmDependsCompiler
+{
+public:
+ cmDependsCompiler() = default;
+ ~cmDependsCompiler() = default;
+
+ /** should this be verbose in its output */
+ void SetVerbose(bool verb) { this->Verbose = verb; }
+
+ /** Set the local generator for the directory in which we are
+ scanning dependencies. This is not a full local generator; it
+ has been setup to do relative path conversions for the current
+ directory. */
+ void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
+ {
+ this->LocalGenerator = lg;
+ }
+
+ /** Read dependencies for the target file. Return true if
+ dependencies didn't changed and false if not.
+ Up-to-date Dependencies will be stored in deps. */
+ bool CheckDependencies(
+ const std::string& internalDepFile,
+ const std::vector<std::string>& depFiles,
+ cmDepends::DependencyMap& dependencies,
+ const std::function<bool(const std::string&)>& isValidPath);
+
+ /** Write dependencies for the target file. */
+ void WriteDependencies(const cmDepends::DependencyMap& dependencies,
+ std::ostream& makeDepends,
+ std::ostream& internalDepends);
+
+ /** Clear dependencies for the target so they will be regenerated. */
+ void ClearDependencies(const std::vector<std::string>& depFiles);
+
+private:
+ bool Verbose = false;
+ cmLocalUnixMakefileGenerator3* LocalGenerator = nullptr;
+};
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index a239418..1a06f31 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -12,6 +12,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -320,14 +321,28 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
internalDepends << obj_i << "\n " << src << '\n';
- for (std::string const& i : info.Includes) {
- makeDepends << obj_m << ": "
- << cmSystemTools::ConvertToOutputPath(
- this->MaybeConvertToRelativePath(binDir, i))
- << '\n';
- internalDepends << ' ' << i << '\n';
+ if (!info.Includes.empty()) {
+ const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->LineContinueDirective;
+ bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>(
+ this->LocalGenerator->GetGlobalGenerator())
+ ->SupportsLongLineDependencies();
+ if (supportLongLineDepend) {
+ makeDepends << obj_m << ':';
+ }
+ for (std::string const& i : info.Includes) {
+ std::string dependee = cmSystemTools::ConvertToOutputPath(
+ this->MaybeConvertToRelativePath(binDir, i));
+ if (supportLongLineDepend) {
+ makeDepends << ' ' << lineContinue << ' ' << dependee;
+ } else {
+ makeDepends << obj_m << ": " << dependee << '\n';
+ }
+ internalDepends << ' ' << i << '\n';
+ }
+ makeDepends << '\n';
}
- makeDepends << '\n';
// Write module requirements to the output stream.
for (std::string const& i : info.Requires) {
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 1bc453d..3619ade 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -194,7 +194,7 @@ void cmDocumentation::addCTestStandardDocSections()
{
// This is currently done for backward compatibility reason
// We may suppress some of these.
- addCMakeStandardDocSections();
+ this->addCMakeStandardDocSections();
}
void cmDocumentation::addCPackStandardDocSections()
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index a8d81f7..deffdb6 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -379,7 +379,7 @@ private:
// Fix the byte order of the header.
if (this->NeedSwap) {
- ByteSwap(x);
+ this->ByteSwap(x);
}
return true;
}
@@ -387,7 +387,7 @@ private:
{
if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
this->NeedSwap) {
- ByteSwap(x);
+ this->ByteSwap(x);
}
return !this->Stream->fail();
}
@@ -395,7 +395,7 @@ private:
{
if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
this->NeedSwap) {
- ByteSwap(x);
+ this->ByteSwap(x);
}
return !this->Stream->fail();
}
@@ -573,7 +573,7 @@ std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries(
dyn.d_un.d_val = static_cast<tagtype>(entry.second);
if (this->NeedSwap) {
- ByteSwap(dyn);
+ this->ByteSwap(dyn);
}
char* pdyn = reinterpret_cast<char*>(&dyn);
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index cbae4e5..113751a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -707,7 +707,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
break;
}
input.replace(pos, endPos - pos + 1, targetName);
- lastPos = endPos;
+ lastPos = pos + targetName.size();
}
pos = 0;
@@ -924,13 +924,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.17 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.18 (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.6...3.17)\n";
+ << "cmake_policy(VERSION 2.6...3.18)\n";
/* clang-format on */
}
diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx
index 56dfc6c..cc8b8b7 100644
--- a/Source/cmExprParserHelper.cxx
+++ b/Source/cmExprParserHelper.cxx
@@ -42,20 +42,22 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
try {
int res = cmExpr_yyparse(yyscanner);
if (res != 0) {
- std::string e = cmStrCat("cannot parse the expression: \"", InputBuffer,
- "\": ", ErrorString, '.');
+ std::string e =
+ cmStrCat("cannot parse the expression: \"", this->InputBuffer,
+ "\": ", this->ErrorString, '.');
this->SetError(std::move(e));
}
} catch (std::runtime_error const& fail) {
- std::string e = cmStrCat("cannot evaluate the expression: \"", InputBuffer,
- "\": ", fail.what(), '.');
+ std::string e = cmStrCat("cannot evaluate the expression: \"",
+ this->InputBuffer, "\": ", fail.what(), '.');
this->SetError(std::move(e));
} catch (std::out_of_range const&) {
- std::string e = "cannot evaluate the expression: \"" + InputBuffer +
+ std::string e = "cannot evaluate the expression: \"" + this->InputBuffer +
"\": a numeric value is out of range.";
this->SetError(std::move(e));
} catch (...) {
- std::string e = "cannot parse the expression: \"" + InputBuffer + "\".";
+ std::string e =
+ "cannot parse the expression: \"" + this->InputBuffer + "\".";
this->SetError(std::move(e));
}
cmExpr_yylex_destroy(yyscanner);
@@ -63,7 +65,7 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
return 0;
}
- if (Verbose) {
+ if (this->Verbose) {
std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]"
<< std::endl;
}
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index 3ade67b..311a2ef 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -52,8 +52,8 @@ public:
//! Generate the project files, the Makefiles have already been generated
virtual void Generate() = 0;
- void SetName(const std::string& n) { Name = n; }
- std::string GetName() const { return Name; }
+ void SetName(const std::string& n) { this->Name = n; }
+ std::string GetName() const { return this->Name; }
virtual bool Open(const std::string& bindir, const std::string& projectName,
bool dryRun);
@@ -104,7 +104,7 @@ public:
CreateExternalMakefileProjectGenerator() const override
{
std::unique_ptr<cmExternalMakefileProjectGenerator> p(new T);
- p->SetName(GetName());
+ p->SetName(this->GetName());
return p;
}
};
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 87b8f9b..800db8a 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -112,10 +112,10 @@ void Tree::InsertPath(const std::vector<std::string>& split,
const std::string& fileName)
{
if (start == split.size()) {
- files.insert(fileName);
+ this->files.insert(fileName);
return;
}
- for (Tree& folder : folders) {
+ for (Tree& folder : this->folders) {
if (folder.path == split[start]) {
if (start + 1 < split.size()) {
folder.InsertPath(split, start + 1, fileName);
@@ -131,19 +131,19 @@ void Tree::InsertPath(const std::vector<std::string>& split,
newFolder.path = split[start];
if (start + 1 < split.size()) {
newFolder.InsertPath(split, start + 1, fileName);
- folders.push_back(newFolder);
+ this->folders.push_back(newFolder);
return;
}
// last part of split
newFolder.files.insert(fileName);
- folders.push_back(newFolder);
+ this->folders.push_back(newFolder);
}
void Tree::BuildVirtualFolder(cmXMLWriter& xml) const
{
xml.StartElement("Option");
std::string virtualFolders = "CMake Files\\;";
- for (Tree const& folder : folders) {
+ for (Tree const& folder : this->folders) {
folder.BuildVirtualFolderImpl(virtualFolders, "");
}
xml.Attribute("virtualFolders", virtualFolders);
@@ -153,15 +153,15 @@ void Tree::BuildVirtualFolder(cmXMLWriter& xml) const
void Tree::BuildVirtualFolderImpl(std::string& virtualFolders,
const std::string& prefix) const
{
- virtualFolders += "CMake Files\\" + prefix + path + "\\;";
- for (Tree const& folder : folders) {
- folder.BuildVirtualFolderImpl(virtualFolders, prefix + path + "\\");
+ virtualFolders += "CMake Files\\" + prefix + this->path + "\\;";
+ for (Tree const& folder : this->folders) {
+ folder.BuildVirtualFolderImpl(virtualFolders, prefix + this->path + "\\");
}
}
void Tree::BuildUnit(cmXMLWriter& xml, const std::string& fsPath) const
{
- for (std::string const& f : files) {
+ for (std::string const& f : this->files) {
xml.StartElement("Unit");
xml.Attribute("filename", fsPath + f);
@@ -171,7 +171,7 @@ void Tree::BuildUnit(cmXMLWriter& xml, const std::string& fsPath) const
xml.EndElement();
}
- for (Tree const& folder : folders) {
+ for (Tree const& folder : this->folders) {
folder.BuildUnitImpl(xml, "", fsPath);
}
}
@@ -180,20 +180,21 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml,
const std::string& virtualFolderPath,
const std::string& fsPath) const
{
- for (std::string const& f : files) {
+ for (std::string const& f : this->files) {
xml.StartElement("Unit");
- xml.Attribute("filename", cmStrCat(fsPath, path, "/", f));
+ xml.Attribute("filename", cmStrCat(fsPath, this->path, "/", f));
xml.StartElement("Option");
- xml.Attribute("virtualFolder",
- cmStrCat("CMake Files\\", virtualFolderPath, path, "\\"));
+ xml.Attribute(
+ "virtualFolder",
+ cmStrCat("CMake Files\\", virtualFolderPath, this->path, "\\"));
xml.EndElement();
xml.EndElement();
}
- for (Tree const& folder : folders) {
- folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, path, "\\"),
- cmStrCat(fsPath, path, "/"));
+ for (Tree const& folder : this->folders) {
+ folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, this->path, "\\"),
+ cmStrCat(fsPath, this->path, "/"));
}
}
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 95cfb0a..549b08b 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -64,7 +64,7 @@ void cmExtraCodeLiteGenerator::Generate()
for (auto const& it : projectMap) {
cmLocalGenerator* lg = it.second[0];
const cmMakefile* mf = lg->GetMakefile();
- this->ConfigName = GetConfigurationName(mf);
+ this->ConfigName = this->GetConfigurationName(mf);
if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) {
workspaceOutputDir = lg->GetCurrentBinaryDirectory();
@@ -89,9 +89,9 @@ void cmExtraCodeLiteGenerator::Generate()
std::vector<std::string> ProjectNames;
if (targetsAreProjects) {
- ProjectNames = CreateProjectsByTarget(&xml);
+ ProjectNames = this->CreateProjectsByTarget(&xml);
} else {
- ProjectNames = CreateProjectsByProjectMaps(&xml);
+ ProjectNames = this->CreateProjectsByProjectMaps(&xml);
}
xml.StartElement("BuildMatrix");
@@ -142,7 +142,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
xml->Attribute("Active", "No");
xml->EndElement();
- CreateNewProjectFile(lt.get(), filename);
+ this->CreateNewProjectFile(lt.get(), filename);
break;
default:
break;
@@ -268,7 +268,7 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
cmMakefile* makefile = lg->GetMakefile();
for (const auto& target : lg->GetGeneratorTargets()) {
projectType =
- CollectSourceFiles(makefile, target.get(), cFiles, otherFiles);
+ this->CollectSourceFiles(makefile, target.get(), cFiles, otherFiles);
}
}
@@ -276,8 +276,8 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
// their relative path)
std::string projectPath = cmSystemTools::GetFilenamePath(filename);
- CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
- projectType, "");
+ this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
+ projectType, "");
xml.EndElement(); // CodeLite_Project
}
@@ -402,7 +402,7 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
const std::string& projectType, const std::string& targetName)
{
cmXMLWriter& xml(*_xml);
- FindMatchingHeaderfiles(cFiles, otherFiles);
+ this->FindMatchingHeaderfiles(cFiles, otherFiles);
// Create 2 virtual folders: src and include
// and place all the implementation files into the src
// folder, the rest goes to the include folder
@@ -498,10 +498,10 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
xml.StartElement("CustomBuild");
xml.Attribute("Enabled", "yes");
- xml.Element("RebuildCommand", GetRebuildCommand(mf, targetName));
- xml.Element("CleanCommand", GetCleanCommand(mf, targetName));
- xml.Element("BuildCommand", GetBuildCommand(mf, targetName));
- xml.Element("SingleFileCommand", GetSingleFileBuildCommand(mf));
+ xml.Element("RebuildCommand", this->GetRebuildCommand(mf, targetName));
+ xml.Element("CleanCommand", this->GetCleanCommand(mf, targetName));
+ xml.Element("BuildCommand", this->GetBuildCommand(mf, targetName));
+ xml.Element("SingleFileCommand", this->GetSingleFileBuildCommand(mf));
xml.Element("PreprocessFileCommand");
xml.Element("WorkingDirectory", "$(WorkspacePath)");
xml.EndElement(); // CustomBuild
@@ -570,14 +570,14 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
std::map<std::string, cmSourceFile*> cFiles;
std::set<std::string> otherFiles;
- projectType = CollectSourceFiles(mf, gt, cFiles, otherFiles);
+ projectType = this->CollectSourceFiles(mf, gt, cFiles, otherFiles);
// Get the project path ( we need it later to convert files to
// their relative path)
std::string projectPath = cmSystemTools::GetFilenamePath(filename);
- CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
- projectType, targetName);
+ this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
+ projectType, targetName);
xml.EndElement(); // CodeLite_Project
}
@@ -648,7 +648,7 @@ std::string cmExtraCodeLiteGenerator::GetCleanCommand(
{
std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
std::ostringstream ss;
- std::string buildcommand = GetBuildCommand(mf, "");
+ std::string buildcommand = this->GetBuildCommand(mf, "");
if (!targetName.empty() && generator == "Ninja") {
ss << buildcommand << " -t clean " << targetName;
} else {
@@ -660,8 +660,8 @@ std::string cmExtraCodeLiteGenerator::GetCleanCommand(
std::string cmExtraCodeLiteGenerator::GetRebuildCommand(
const cmMakefile* mf, const std::string& targetName) const
{
- return GetCleanCommand(mf, targetName) + " && " +
- GetBuildCommand(mf, targetName);
+ return this->GetCleanCommand(mf, targetName) + " && " +
+ this->GetBuildCommand(mf, targetName);
}
std::string cmExtraCodeLiteGenerator::GetSingleFileBuildCommand(
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 7c36144..a92f6e3 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -132,7 +132,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile(
// doesn't currently support these settings per build system, only project
// wide
MapSourceFileFlags sourceFileFlags;
- AppendAllTargets(lgs, mf, fout, sourceFileFlags);
+ this->AppendAllTargets(lgs, mf, fout, sourceFileFlags);
// End of build_systems
fout << "\n\t]";
@@ -349,6 +349,11 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
if (language.empty()) {
language = "C";
}
+
+ // Explicitly add the explicit language flag before any other flag
+ // so user flags can override it.
+ gtgt->AddExplicitLanguageFlags(flags, *source);
+
std::string const& config =
lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index 1e4f3b6..e208ca8 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -41,7 +41,7 @@ CMakeFiles::CMakeFiles(cmFileAPI& fileAPI, unsigned long version)
, CMakeModules(cmSystemTools::GetCMakeRoot() + "/Modules")
, TopSource(this->FileAPI.GetCMakeInstance()->GetHomeDirectory())
, TopBuild(this->FileAPI.GetCMakeInstance()->GetHomeOutputDirectory())
- , OutOfSource(TopBuild != TopSource)
+ , OutOfSource(this->TopBuild != this->TopSource)
{
static_cast<void>(this->Version);
}
@@ -50,7 +50,7 @@ Json::Value CMakeFiles::Dump()
{
Json::Value cmakeFiles = Json::objectValue;
cmakeFiles["paths"] = this->DumpPaths();
- cmakeFiles["inputs"] = DumpInputs();
+ cmakeFiles["inputs"] = this->DumpInputs();
return cmakeFiles;
}
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index 3ba943a..ddae527 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -44,7 +44,7 @@ Cache::Cache(cmFileAPI& fileAPI, unsigned long version)
Json::Value Cache::Dump()
{
Json::Value cache = Json::objectValue;
- cache["entries"] = DumpEntries();
+ cache["entries"] = this->DumpEntries();
return cache;
}
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 4a53c8a..7fcc3dc 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -145,7 +145,7 @@ class JBTIndex
{
public:
JBTIndex() = default;
- explicit operator bool() const { return Index != None; }
+ explicit operator bool() const { return this->Index != None; }
Json::ArrayIndex Index = None;
static Json::ArrayIndex const None = static_cast<Json::ArrayIndex>(-1);
};
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 8a3aad2..9815d9d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -2290,7 +2291,7 @@ void AddEvaluationFile(const std::string& inputName,
const std::string& targetName,
const std::string& outputExpr,
const std::string& condition, bool inputIsContent,
- cmExecutionStatus& status)
+ mode_t permissions, cmExecutionStatus& status)
{
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
@@ -2304,7 +2305,7 @@ void AddEvaluationFile(const std::string& inputName,
status.GetMakefile().AddEvaluationFile(
inputName, targetName, std::move(outputCge), std::move(conditionCge),
- inputIsContent);
+ permissions, inputIsContent);
}
bool HandleGenerateCommand(std::vector<std::string> const& args,
@@ -2314,49 +2315,156 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
- if (args[1] != "OUTPUT") {
+
+ struct Arguments
+ {
+ std::string Output;
+ std::string Input;
+ std::string Content;
+ std::string Condition;
+ std::string Target;
+ bool NoSourcePermissions = false;
+ bool UseSourcePermissions = false;
+ std::vector<std::string> FilePermissions;
+ };
+
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("INPUT"_s, &Arguments::Input)
+ .Bind("CONTENT"_s, &Arguments::Content)
+ .Bind("CONDITION"_s, &Arguments::Condition)
+ .Bind("TARGET"_s, &Arguments::Target)
+ .Bind("NO_SOURCE_PERMISSIONS"_s, &Arguments::NoSourcePermissions)
+ .Bind("USE_SOURCE_PERMISSIONS"_s, &Arguments::UseSourcePermissions)
+ .Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions);
+
+ std::vector<std::string> unparsedArguments;
+ std::vector<std::string> keywordsMissingValues;
+ std::vector<std::string> parsedKeywords;
+ Arguments const arguments =
+ parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments,
+ &keywordsMissingValues, &parsedKeywords);
+
+ if (!keywordsMissingValues.empty()) {
status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
- std::string condition;
- std::string target;
-
- for (std::size_t i = 5; i < args.size();) {
- const std::string& arg = args[i++];
+ if (!unparsedArguments.empty()) {
+ status.SetError("Unknown argument to GENERATE subcommand.");
+ return false;
+ }
- if (args.size() - i == 0) {
- status.SetError("Incorrect arguments to GENERATE subcommand.");
- return false;
+ bool mandatoryOptionsSpecified = false;
+ if (parsedKeywords.size() > 1) {
+ const bool outputOprionSpecified = parsedKeywords[0] == "OUTPUT"_s;
+ const bool inputOrContentSpecified =
+ parsedKeywords[1] == "INPUT"_s || parsedKeywords[1] == "CONTENT"_s;
+ if (outputOprionSpecified && inputOrContentSpecified) {
+ mandatoryOptionsSpecified = true;
}
+ }
+ if (!mandatoryOptionsSpecified) {
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
+ return false;
+ }
+
+ const bool conditionOptionSpecified =
+ std::find(parsedKeywords.begin(), parsedKeywords.end(), "CONDITION"_s) !=
+ parsedKeywords.end();
+ if (conditionOptionSpecified && arguments.Condition.empty()) {
+ status.SetError("CONDITION of sub-command GENERATE must not be empty "
+ "if specified.");
+ return false;
+ }
- const std::string& value = args[i++];
+ const bool targetOptionSpecified =
+ std::find(parsedKeywords.begin(), parsedKeywords.end(), "TARGET"_s) !=
+ parsedKeywords.end();
+ if (targetOptionSpecified && arguments.Target.empty()) {
+ status.SetError("TARGET of sub-command GENERATE must not be empty "
+ "if specified.");
+ return false;
+ }
- if (value.empty()) {
- status.SetError(
- arg + " of sub-command GENERATE must not be empty if specified.");
+ const bool outputOptionSpecified =
+ std::find(parsedKeywords.begin(), parsedKeywords.end(), "OUTPUT"_s) !=
+ parsedKeywords.end();
+ if (outputOptionSpecified && parsedKeywords[0] != "OUTPUT"_s) {
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
+ return false;
+ }
+
+ const bool inputIsContent = parsedKeywords[1] != "INPUT"_s;
+ if (inputIsContent && parsedKeywords[1] != "CONTENT") {
+ status.SetError("Unknown argument to GENERATE subcommand.");
+ }
+
+ std::string input = arguments.Input;
+ if (inputIsContent) {
+ input = arguments.Content;
+ }
+
+ if (arguments.NoSourcePermissions && arguments.UseSourcePermissions) {
+ status.SetError("given both NO_SOURCE_PERMISSIONS and "
+ "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+
+ if (!arguments.FilePermissions.empty()) {
+ if (arguments.NoSourcePermissions) {
+ status.SetError("given both NO_SOURCE_PERMISSIONS and "
+ "FILE_PERMISSIONS. Only one option allowed.");
return false;
}
+ if (arguments.UseSourcePermissions) {
+ status.SetError("given both USE_SOURCE_PERMISSIONS and "
+ "FILE_PERMISSIONS. Only one option allowed.");
+ return false;
+ }
+ }
- if (arg == "CONDITION") {
- condition = value;
- } else if (arg == "TARGET") {
- target = value;
- } else {
- status.SetError("Unknown argument to GENERATE subcommand.");
+ if (arguments.UseSourcePermissions) {
+ if (inputIsContent) {
+ status.SetError("given USE_SOURCE_PERMISSIONS without a file INPUT.");
return false;
}
}
- std::string output = args[2];
- const bool inputIsContent = args[3] != "INPUT";
- if (inputIsContent && args[3] != "CONTENT") {
- status.SetError("Incorrect arguments to GENERATE subcommand.");
- return false;
+ mode_t permisiions = 0;
+ if (arguments.NoSourcePermissions) {
+ permisiions |= cmFSPermissions::mode_owner_read;
+ permisiions |= cmFSPermissions::mode_owner_write;
+ permisiions |= cmFSPermissions::mode_group_read;
+ permisiions |= cmFSPermissions::mode_world_read;
+ }
+
+ if (!arguments.FilePermissions.empty()) {
+ std::vector<std::string> invalidOptions;
+ for (auto const& e : arguments.FilePermissions) {
+ if (!cmFSPermissions::stringToModeT(e, permisiions)) {
+ invalidOptions.push_back(e);
+ }
+ }
+ if (!invalidOptions.empty()) {
+ std::ostringstream oss;
+ oss << "given invalid permission ";
+ for (auto i = 0u; i < invalidOptions.size(); i++) {
+ if (i == 0u) {
+ oss << "\"" << invalidOptions[i] << "\"";
+ } else {
+ oss << ",\"" << invalidOptions[i] << "\"";
+ }
+ }
+ oss << ".";
+ status.SetError(oss.str());
+ return false;
+ }
}
- std::string input = args[4];
- AddEvaluationFile(input, target, output, condition, inputIsContent, status);
+ AddEvaluationFile(input, arguments.Target, arguments.Output,
+ arguments.Condition, inputIsContent, permisiions, status);
return true;
}
@@ -2902,17 +3010,60 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
bool HandleConfigureCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- if (args.size() < 5) {
- status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ struct Arguments
+ {
+ std::string Output;
+ std::string Content;
+ bool EscapeQuotes = false;
+ bool AtOnly = false;
+ std::string NewlineStyle;
+ };
+
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("CONTENT"_s, &Arguments::Content)
+ .Bind("ESCAPE_QUOTES"_s, &Arguments::EscapeQuotes)
+ .Bind("@ONLY"_s, &Arguments::AtOnly)
+ .Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle);
+
+ std::vector<std::string> unrecognizedArguments;
+ std::vector<std::string> keywordsMissingArguments;
+ std::vector<std::string> parsedKeywords;
+ auto parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+ &keywordsMissingArguments, &parsedKeywords);
+
+ auto argIt = unrecognizedArguments.begin();
+ if (argIt != unrecognizedArguments.end()) {
+ status.SetError(
+ cmStrCat("CONFIGURE Unrecognized argument: \"", *argIt, "\""));
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
- if (args[1] != "OUTPUT") {
- status.SetError("Incorrect arguments to CONFIGURE subcommand.");
- return false;
+
+ std::vector<std::string> mandatoryOptions{ "OUTPUT", "CONTENT" };
+ for (auto const& e : mandatoryOptions) {
+ const bool optionHasNoValue =
+ std::find(keywordsMissingArguments.begin(),
+ keywordsMissingArguments.end(),
+ e) != keywordsMissingArguments.end();
+ if (optionHasNoValue) {
+ status.SetError(cmStrCat("CONFIGURE ", e, " option needs a value."));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
}
- if (args[3] != "CONTENT") {
- status.SetError("Incorrect arguments to CONFIGURE subcommand.");
- return false;
+
+ for (auto const& e : mandatoryOptions) {
+ const bool optionGiven =
+ std::find(parsedKeywords.begin(), parsedKeywords.end(), e) !=
+ parsedKeywords.end();
+ if (!optionGiven) {
+ status.SetError(cmStrCat("CONFIGURE ", e, " option is mandatory."));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
}
std::string errorMessage;
@@ -2922,28 +3073,9 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
return false;
}
- bool escapeQuotes = false;
- bool atOnly = false;
- for (unsigned int i = 5; i < args.size(); ++i) {
- if (args[i] == "@ONLY") {
- atOnly = true;
- } else if (args[i] == "ESCAPE_QUOTES") {
- escapeQuotes = true;
- } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
- args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" ||
- args[i] == "DOS") {
- /* Options handled by NewLineStyle member above. */
- } else {
- status.SetError(
- cmStrCat("CONFIGURE Unrecognized argument \"", args[i], "\""));
- return false;
- }
- }
-
// Check for generator expressions
- const std::string input = args[4];
std::string outputFile = cmSystemTools::CollapseFullPath(
- args[2], status.GetMakefile().GetCurrentBinaryDirectory());
+ parsedArgs.Output, status.GetMakefile().GetCurrentBinaryDirectory());
std::string::size_type pos = outputFile.find_first_of("<>");
if (pos != std::string::npos) {
@@ -2992,12 +3124,13 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
fout.SetCopyIfDifferent(true);
// copy input to output and expand variables from input at the same time
- std::stringstream sin(input, std::ios::in);
+ std::stringstream sin(parsedArgs.Content, std::ios::in);
std::string inLine;
std::string outLine;
while (cmSystemTools::GetLineFromStream(sin, inLine)) {
outLine.clear();
- makeFile.ConfigureString(inLine, outLine, atOnly, escapeQuotes);
+ makeFile.ConfigureString(inLine, outLine, parsedArgs.AtOnly,
+ parsedArgs.EscapeQuotes);
fout << outLine << newLineCharacters;
}
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
deleted file mode 100644
index 8cfdb2d..0000000
--- a/Source/cmFileMonitor.cxx
+++ /dev/null
@@ -1,383 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFileMonitor.h"
-
-#include <cassert>
-#include <cstddef>
-#include <unordered_map>
-#include <utility>
-
-#include <cm/memory>
-
-#include "cmsys/SystemTools.hxx"
-
-namespace {
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
- int events, int status);
-void on_fs_close(uv_handle_t* handle);
-} // namespace
-
-class cmIBaseWatcher
-{
-public:
- virtual ~cmIBaseWatcher() = default;
-
- virtual void Trigger(const std::string& pathSegment, int events,
- int status) const = 0;
- virtual std::string Path() const = 0;
- virtual uv_loop_t* Loop() const = 0;
-
- virtual void StartWatching() = 0;
- virtual void StopWatching() = 0;
-
- virtual std::vector<std::string> WatchedFiles() const = 0;
- virtual std::vector<std::string> WatchedDirectories() const = 0;
-};
-
-class cmVirtualDirectoryWatcher : public cmIBaseWatcher
-{
-public:
- ~cmVirtualDirectoryWatcher() override = default;
-
- cmIBaseWatcher* Find(const std::string& ps)
- {
- const auto i = this->Children.find(ps);
- return (i == this->Children.end()) ? nullptr : i->second.get();
- }
-
- void Trigger(const std::string& pathSegment, int events,
- int status) const final
- {
- if (pathSegment.empty()) {
- for (auto const& child : this->Children) {
- child.second->Trigger(std::string(), events, status);
- }
- } else {
- const auto i = this->Children.find(pathSegment);
- if (i != this->Children.end()) {
- i->second->Trigger(std::string(), events, status);
- }
- }
- }
-
- void StartWatching() override
- {
- for (auto const& child : this->Children) {
- child.second->StartWatching();
- }
- }
-
- void StopWatching() override
- {
- for (auto const& child : this->Children) {
- child.second->StopWatching();
- }
- }
-
- std::vector<std::string> WatchedFiles() const final
- {
- std::vector<std::string> result;
- for (auto const& child : this->Children) {
- for (std::string const& f : child.second->WatchedFiles()) {
- result.push_back(f);
- }
- }
- return result;
- }
-
- std::vector<std::string> WatchedDirectories() const override
- {
- std::vector<std::string> result;
- for (auto const& child : this->Children) {
- for (std::string const& dir : child.second->WatchedDirectories()) {
- result.push_back(dir);
- }
- }
- return result;
- }
-
- void Reset() { this->Children.clear(); }
-
- void AddChildWatcher(const std::string& ps, cmIBaseWatcher* watcher)
- {
- assert(!ps.empty());
- assert(this->Children.find(ps) == this->Children.end());
- assert(watcher);
-
- this->Children.emplace(ps, std::unique_ptr<cmIBaseWatcher>(watcher));
- }
-
-private:
- std::unordered_map<std::string, std::unique_ptr<cmIBaseWatcher>>
- Children; // owned!
-};
-
-// Root of all the different (on windows!) root directories:
-class cmRootWatcher : public cmVirtualDirectoryWatcher
-{
-public:
- cmRootWatcher(uv_loop_t* loop)
- : mLoop(loop)
- {
- assert(loop);
- }
-
- std::string Path() const final
- {
- assert(false);
- return std::string();
- }
- uv_loop_t* Loop() const final { return this->mLoop; }
-
-private:
- uv_loop_t* const mLoop; // no ownership!
-};
-
-// Real directories:
-class cmRealDirectoryWatcher : public cmVirtualDirectoryWatcher
-{
-public:
- cmRealDirectoryWatcher(cmVirtualDirectoryWatcher* p, const std::string& ps)
- : Parent(p)
- , PathSegment(ps)
- {
- assert(p);
- assert(!ps.empty());
-
- p->AddChildWatcher(ps, this);
- }
-
- void StartWatching() final
- {
- if (!this->Handle) {
- this->Handle = new uv_fs_event_t;
-
- uv_fs_event_init(this->Loop(), this->Handle);
- this->Handle->data = this;
- uv_fs_event_start(this->Handle, &on_directory_change, Path().c_str(), 0);
- }
- cmVirtualDirectoryWatcher::StartWatching();
- }
-
- void StopWatching() final
- {
- if (this->Handle) {
- uv_fs_event_stop(this->Handle);
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(this->Handle))) {
- uv_close(reinterpret_cast<uv_handle_t*>(this->Handle), &on_fs_close);
- }
- this->Handle = nullptr;
- }
- cmVirtualDirectoryWatcher::StopWatching();
- }
-
- uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
- std::vector<std::string> WatchedDirectories() const override
- {
- std::vector<std::string> result = { Path() };
- for (std::string const& dir :
- cmVirtualDirectoryWatcher::WatchedDirectories()) {
- result.push_back(dir);
- }
- return result;
- }
-
-protected:
- cmVirtualDirectoryWatcher* const Parent;
- const std::string PathSegment;
-
-private:
- uv_fs_event_t* Handle = nullptr; // owner!
-};
-
-// Root directories:
-class cmRootDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
- cmRootDirectoryWatcher(cmRootWatcher* p, const std::string& ps)
- : cmRealDirectoryWatcher(p, ps)
- {
- }
-
- std::string Path() const final { return this->PathSegment; }
-};
-
-// Normal directories below root:
-class cmDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
- cmDirectoryWatcher(cmRealDirectoryWatcher* p, const std::string& ps)
- : cmRealDirectoryWatcher(p, ps)
- {
- }
-
- std::string Path() const final
- {
- return this->Parent->Path() + this->PathSegment + "/";
- }
-};
-
-class cmFileWatcher : public cmIBaseWatcher
-{
-public:
- cmFileWatcher(cmRealDirectoryWatcher* p, const std::string& ps,
- cmFileMonitor::Callback cb)
- : Parent(p)
- , PathSegment(ps)
- , CbList({ std::move(cb) })
- {
- assert(p);
- assert(!ps.empty());
- p->AddChildWatcher(ps, this);
- }
-
- void StartWatching() final {}
-
- void StopWatching() final {}
-
- void AppendCallback(cmFileMonitor::Callback const& cb)
- {
- this->CbList.push_back(cb);
- }
-
- std::string Path() const final
- {
- return this->Parent->Path() + this->PathSegment;
- }
-
- std::vector<std::string> WatchedDirectories() const final { return {}; }
-
- std::vector<std::string> WatchedFiles() const final
- {
- return { this->Path() };
- }
-
- void Trigger(const std::string& ps, int events, int status) const final
- {
- assert(ps.empty());
- assert(status == 0);
- static_cast<void>(ps);
-
- const std::string path = this->Path();
- for (cmFileMonitor::Callback const& cb : this->CbList) {
- cb(path, events, status);
- }
- }
-
- uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
-private:
- cmRealDirectoryWatcher* Parent;
- const std::string PathSegment;
- std::vector<cmFileMonitor::Callback> CbList;
-};
-
-namespace {
-
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
- int events, int status)
-{
- const cmIBaseWatcher* const watcher =
- static_cast<const cmIBaseWatcher*>(handle->data);
- const std::string pathSegment(filename ? filename : "");
- watcher->Trigger(pathSegment, events, status);
-}
-
-void on_fs_close(uv_handle_t* handle)
-{
- delete reinterpret_cast<uv_fs_event_t*>(handle);
-}
-
-} // namespace
-
-cmFileMonitor::cmFileMonitor(uv_loop_t* l)
- : Root(cm::make_unique<cmRootWatcher>(l))
-{
-}
-
-cmFileMonitor::~cmFileMonitor() = default;
-
-void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
- Callback const& cb)
-{
- for (std::string const& p : paths) {
- std::vector<std::string> pathSegments;
- cmsys::SystemTools::SplitPath(p, pathSegments, true);
- const bool pathIsFile = !cmsys::SystemTools::FileIsDirectory(p);
-
- const size_t segmentCount = pathSegments.size();
- if (segmentCount < 2) { // Expect at least rootdir and filename
- continue;
- }
- cmVirtualDirectoryWatcher* currentWatcher = this->Root.get();
- for (size_t i = 0; i < segmentCount; ++i) {
- assert(currentWatcher);
-
- const bool fileSegment = (i == segmentCount - 1 && pathIsFile);
- const bool rootSegment = (i == 0);
- assert(
- !(fileSegment &&
- rootSegment)); // Can not be both filename and root part of the path!
-
- const std::string& currentSegment = pathSegments[i];
- if (currentSegment.empty()) {
- continue;
- }
-
- cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment);
- if (!nextWatcher) {
- if (rootSegment) { // Root part
- assert(currentWatcher == this->Root.get());
- nextWatcher =
- new cmRootDirectoryWatcher(this->Root.get(), currentSegment);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- } else if (fileSegment) { // File part
- assert(currentWatcher != this->Root.get());
- nextWatcher = new cmFileWatcher(
- dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
- currentSegment, cb);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- } else { // Any normal directory in between
- nextWatcher = new cmDirectoryWatcher(
- dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
- currentSegment);
- assert(currentWatcher->Find(currentSegment) == nextWatcher);
- }
- } else {
- if (fileSegment) {
- auto filePtr = dynamic_cast<cmFileWatcher*>(nextWatcher);
- assert(filePtr);
- filePtr->AppendCallback(cb);
- continue;
- }
- }
- currentWatcher = dynamic_cast<cmVirtualDirectoryWatcher*>(nextWatcher);
- }
- }
- this->Root->StartWatching();
-}
-
-void cmFileMonitor::StopMonitoring()
-{
- this->Root->StopWatching();
- this->Root->Reset();
-}
-
-std::vector<std::string> cmFileMonitor::WatchedFiles() const
-{
- std::vector<std::string> result;
- if (this->Root) {
- result = this->Root->WatchedFiles();
- }
- return result;
-}
-
-std::vector<std::string> cmFileMonitor::WatchedDirectories() const
-{
- std::vector<std::string> result;
- if (this->Root) {
- result = this->Root->WatchedDirectories();
- }
- return result;
-}
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
deleted file mode 100644
index fc75b0c..0000000
--- a/Source/cmFileMonitor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 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 <cm3p/uv.h>
-
-class cmRootWatcher;
-
-class cmFileMonitor
-{
-
-public:
- cmFileMonitor(uv_loop_t* l);
- ~cmFileMonitor();
-
- cmFileMonitor(cmFileMonitor const&) = delete;
- cmFileMonitor& operator=(cmFileMonitor const&) = delete;
-
- using Callback = std::function<void(const std::string&, int, int)>;
- void MonitorPaths(const std::vector<std::string>& paths, Callback const& cb);
- void StopMonitoring();
-
- std::vector<std::string> WatchedFiles() const;
- std::vector<std::string> WatchedDirectories() const;
-
-private:
- std::unique_ptr<cmRootWatcher> Root;
-};
diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx
index bb3f610..6b52230 100644
--- a/Source/cmFilePathChecksum.cxx
+++ b/Source/cmFilePathChecksum.cxx
@@ -16,15 +16,16 @@ cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir,
std::string const& projectSrcDir,
std::string const& projectBinDir)
{
- setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir);
+ this->setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir,
+ projectBinDir);
}
cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile)
{
- setupParentDirs(makefile->GetCurrentSourceDirectory(),
- makefile->GetCurrentBinaryDirectory(),
- makefile->GetHomeDirectory(),
- makefile->GetHomeOutputDirectory());
+ this->setupParentDirs(makefile->GetCurrentSourceDirectory(),
+ makefile->GetCurrentBinaryDirectory(),
+ makefile->GetHomeDirectory(),
+ makefile->GetHomeOutputDirectory());
}
void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir,
@@ -81,5 +82,5 @@ std::string cmFilePathChecksum::get(std::string const& filePath) const
std::string cmFilePathChecksum::getPart(std::string const& filePath,
size_t length) const
{
- return get(filePath).substr(0, length);
+ return this->get(filePath).substr(0, length);
}
diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx
index d8fe24c..bd896f5 100644
--- a/Source/cmFileTimes.cxx
+++ b/Source/cmFileTimes.cxx
@@ -62,14 +62,14 @@ public:
cmFileTimes::cmFileTimes() = default;
cmFileTimes::cmFileTimes(std::string const& fileName)
{
- Load(fileName);
+ this->Load(fileName);
}
cmFileTimes::~cmFileTimes() = default;
bool cmFileTimes::Load(std::string const& fileName)
{
std::unique_ptr<Times> ptr;
- if (IsValid()) {
+ if (this->IsValid()) {
// Invalidate this and re-use times
ptr.swap(this->times);
} else {
@@ -103,7 +103,7 @@ bool cmFileTimes::Load(std::string const& fileName)
bool cmFileTimes::Store(std::string const& fileName) const
{
- if (!IsValid()) {
+ if (!this->IsValid()) {
return false;
}
diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h
index f1916f7..50d64fd 100644
--- a/Source/cmFileTimes.h
+++ b/Source/cmFileTimes.h
@@ -19,7 +19,7 @@ public:
~cmFileTimes();
//! @return true, if file times were loaded successfully
- bool IsValid() const { return (times != nullptr); }
+ bool IsValid() const { return (this->times != nullptr); }
//! Try to load the file times from @a fileName and @return IsValid()
bool Load(std::string const& fileName);
//! Stores the file times at @a fileName (if IsValid())
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index dee91d7..d2f9619 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -182,7 +182,7 @@ void cmFindCommon::SelectDefaultSearchModes()
{ this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } }
};
- for (auto& path : search_paths) {
+ for (auto const& path : search_paths) {
cmProp def = this->Makefile->GetDefinition(path.second);
if (def) {
path.first = !cmIsOn(*def);
@@ -289,7 +289,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
{
std::vector<std::string> ignoreVec;
- GetIgnoredPaths(ignoreVec);
+ this->GetIgnoredPaths(ignoreVec);
ignore.insert(ignoreVec.begin(), ignoreVec.end());
}
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index b87dfe3..49b1bd7 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -31,7 +31,7 @@ cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
// cmFindLibraryCommand
bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
- this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a library.";
this->CMakePathName = "LIBRARY";
if (!this->ParseArguments(argsIn)) {
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 92b1e80..3b7cf4c 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -144,7 +144,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]);
}
- this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugMode = this->ComputeIfDebugModeWanted();
this->DebugBuffer.clear();
// Lookup target architecture, if any.
@@ -534,7 +534,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
loadedPackage = true;
} else {
// The package was not loaded. Report errors.
- if (HandlePackageMode(HandlePackageModeType::Module)) {
+ if (this->HandlePackageMode(HandlePackageModeType::Module)) {
loadedPackage = true;
}
}
@@ -2070,8 +2070,8 @@ public:
void SetSort(cmFindPackageCommand::SortOrderType o,
cmFindPackageCommand::SortDirectionType d)
{
- SortOrder = o;
- SortDirection = d;
+ this->SortOrder = o;
+ this->SortDirection = d;
}
protected:
@@ -2102,8 +2102,8 @@ private:
// before testing the matches check if there is a specific sorting order to
// perform
if (this->SortOrder != cmFindPackageCommand::None) {
- cmFindPackageCommand::Sort(matches.begin(), matches.end(), SortOrder,
- SortDirection);
+ cmFindPackageCommand::Sort(matches.begin(), matches.end(),
+ this->SortOrder, this->SortDirection);
}
for (std::string const& i : matches) {
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 4bab469..bece33b 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -22,7 +22,7 @@ cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
// cmFindPathCommand
bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
{
- this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a file.";
this->CMakePathName = "INCLUDE";
if (!this->ParseArguments(argsIn)) {
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 77728ec..5bb4234 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -152,7 +152,7 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
- this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugMode = this->ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a program.";
this->CMakePathName = "PROGRAM";
// call cmFindBase::ParseArguments
@@ -171,7 +171,7 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
return true;
}
- std::string const result = FindProgram();
+ std::string const result = this->FindProgram();
if (!result.empty()) {
// Save the value in the cache
this->Makefile->AddCacheDefinition(this->VariableName, result,
@@ -198,7 +198,7 @@ std::string cmFindProgramCommand::FindProgram()
std::string program;
if (this->SearchAppBundleFirst || this->SearchAppBundleOnly) {
- program = FindAppBundle();
+ program = this->FindAppBundle();
}
if (program.empty() && !this->SearchAppBundleOnly) {
program = this->FindNormalProgram();
@@ -274,7 +274,7 @@ std::string cmFindProgramCommand::FindAppBundle()
cmSystemTools::FindDirectory(appName, this->SearchPaths, true);
if (!appPath.empty()) {
- std::string executable = GetBundleExecutable(appPath);
+ std::string executable = this->GetBundleExecutable(appPath);
if (!executable.empty()) {
return cmSystemTools::CollapseFullPath(executable);
}
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 71c82d6..1359009 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -163,8 +163,11 @@ bool cmFunctionFunctionBlocker::Replay(
f.FilePath = this->GetStartingContext().FilePath;
f.Line = this->GetStartingContext().Line;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f));
- return true;
+ return mf.GetState()->AddScriptedCommand(
+ this->Args.front(),
+ BT<cmState::Command>(std::move(f),
+ mf.GetBacktrace().Push(this->GetStartingContext())),
+ mf);
}
} // anonymous namespace
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 957896f..c782bcd 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -27,23 +27,30 @@ bool cmGccDepfileLexerHelper::readFile(const char* filePath)
if (!file) {
return false;
}
- newEntry();
+ this->newEntry();
yyscan_t scanner;
cmGccDepfile_yylex_init(&scanner);
cmGccDepfile_yyset_extra(this, scanner);
cmGccDepfile_yyrestart(file, scanner);
cmGccDepfile_yylex(scanner);
cmGccDepfile_yylex_destroy(scanner);
- sanitizeContent();
+ this->sanitizeContent();
fclose(file);
- return true;
+ return this->HelperState != State::Failed;
}
void cmGccDepfileLexerHelper::newEntry()
{
+ if (this->HelperState == State::Rule && !this->Content.empty()) {
+ if (!this->Content.back().rules.empty() &&
+ !this->Content.back().rules.back().empty()) {
+ this->HelperState = State::Failed;
+ }
+ return;
+ }
this->HelperState = State::Rule;
this->Content.emplace_back();
- newRule();
+ this->newRule();
}
void cmGccDepfileLexerHelper::newRule()
@@ -56,20 +63,22 @@ void cmGccDepfileLexerHelper::newRule()
void cmGccDepfileLexerHelper::newDependency()
{
- // printf("NEW DEP\n");
+ if (this->HelperState == State::Failed) {
+ return;
+ }
this->HelperState = State::Dependency;
- if (this->Content.back().paths.empty() ||
- !this->Content.back().paths.back().empty()) {
- this->Content.back().paths.emplace_back();
+ auto& entry = this->Content.back();
+ if (entry.paths.empty() || !entry.paths.back().empty()) {
+ entry.paths.emplace_back();
}
}
void cmGccDepfileLexerHelper::newRuleOrDependency()
{
if (this->HelperState == State::Rule) {
- newRule();
- } else {
- newDependency();
+ this->newRule();
+ } else if (this->HelperState == State::Dependency) {
+ this->newDependency();
}
}
@@ -93,6 +102,8 @@ void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
}
dst = &dep->paths.back();
} break;
+ case State::Failed:
+ return;
}
dst->append(s);
}
diff --git a/Source/cmGccDepfileLexerHelper.h b/Source/cmGccDepfileLexerHelper.h
index 07ca61d..91132f5 100644
--- a/Source/cmGccDepfileLexerHelper.h
+++ b/Source/cmGccDepfileLexerHelper.h
@@ -29,7 +29,8 @@ private:
enum class State
{
Rule,
- Dependency
+ Dependency,
+ Failed,
};
State HelperState = State::Rule;
};
diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx
index 9d70ede..8253375 100644
--- a/Source/cmGccDepfileReader.cxx
+++ b/Source/cmGccDepfileReader.cxx
@@ -4,15 +4,43 @@
#include <type_traits>
#include <utility>
+#include <vector>
+
+#include <cm/optional>
#include "cmGccDepfileLexerHelper.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
-cmGccDepfileContent cmReadGccDepfile(const char* filePath)
+cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath,
+ const std::string& prefix)
{
- cmGccDepfileContent result;
cmGccDepfileLexerHelper helper;
- if (helper.readFile(filePath)) {
- result = std::move(helper).extractContent();
+ if (!helper.readFile(filePath)) {
+ return cm::nullopt;
+ }
+ auto deps = cm::make_optional(std::move(helper).extractContent());
+
+ for (auto& dep : *deps) {
+ for (auto& rule : dep.rules) {
+ if (!prefix.empty() && !cmSystemTools::FileIsFullPath(rule)) {
+ rule = cmStrCat(prefix, rule);
+ }
+ if (cmSystemTools::FileIsFullPath(rule)) {
+ rule = cmSystemTools::CollapseFullPath(rule);
+ }
+ cmSystemTools::ConvertToLongPath(rule);
+ }
+ for (auto& path : dep.paths) {
+ if (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) {
+ path = cmStrCat(prefix, path);
+ }
+ if (cmSystemTools::FileIsFullPath(path)) {
+ path = cmSystemTools::CollapseFullPath(path);
+ }
+ cmSystemTools::ConvertToLongPath(path);
+ }
}
- return result;
+
+ return deps;
}
diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h
index 395dd77..c8a3748 100644
--- a/Source/cmGccDepfileReader.h
+++ b/Source/cmGccDepfileReader.h
@@ -2,6 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <string>
+
+#include <cm/optional>
+
#include "cmGccDepfileReaderTypes.h"
-cmGccDepfileContent cmReadGccDepfile(const char* filePath);
+/*
+ * Read dependencies file and append prefix to all relative paths
+ */
+cm::optional<cmGccDepfileContent> cmReadGccDepfile(
+ const char* filePath, const std::string& prefix = {});
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2768547..43f384a 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -14,11 +14,11 @@
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
- : OriginalLocale(getloc())
+ : OriginalLocale(this->getloc())
{
#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
- imbue(std::locale(OriginalLocale, new codecvt(encoding)));
+ this->imbue(std::locale(this->OriginalLocale, new codecvt(encoding)));
}
#else
static_cast<void>(encoding);
@@ -28,7 +28,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
bool quiet, Encoding encoding)
: cmGeneratedFileStreamBase(name)
- , Stream(TempName.c_str())
+ , Stream(this->TempName.c_str())
{
// Check if the file opened.
if (!*this && !quiet) {
@@ -37,7 +37,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
}
#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
- imbue(std::locale(getloc(), new codecvt(encoding)));
+ this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
}
#else
static_cast<void>(encoding);
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index e223f15..a1fce55 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
, Backtrace(std::move(backtrace))
, TransitivePropertiesOnly(false)
{
- Initialize();
+ this->Initialize();
}
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
@@ -42,7 +42,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
, Backtrace()
, TransitivePropertiesOnly(false)
{
- Initialize();
+ this->Initialize();
}
void cmGeneratorExpressionDAGChecker::Initialize()
@@ -52,7 +52,7 @@ void cmGeneratorExpressionDAGChecker::Initialize()
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||
- if (CheckResult == DAG &&
+ if (this->CheckResult == DAG &&
(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*)
#undef TEST_TRANSITIVE_PROPERTY_METHOD
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 9e5023d..ec44df3 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -15,20 +15,21 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
-#include "cmSourceFileLocationKind.h"
#include "cmSystemTools.h"
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
std::string input, std::string target,
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070)
+ bool inputIsContent, mode_t permissions,
+ cmPolicies::PolicyStatus policyStatusCMP0070)
: Input(std::move(input))
, Target(std::move(target))
, OutputFileExpr(std::move(outputFileExpr))
, Condition(std::move(condition))
, InputIsContent(inputIsContent)
, PolicyStatusCMP0070(policyStatusCMP0070)
+ , Permissions(permissions)
{
}
@@ -38,7 +39,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(
std::map<std::string, std::string>& outputFiles, mode_t perm)
{
std::string rawCondition = this->Condition->GetInput();
- cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target);
+ cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
if (!rawCondition.empty()) {
std::string condResult =
this->Condition->Evaluate(lg, config, target, nullptr, nullptr, lang);
@@ -94,16 +95,12 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
{
std::vector<std::string> enabledLanguages;
cmGlobalGenerator* gg = lg->GetGlobalGenerator();
- cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target);
+ cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
gg->GetEnabledLanguages(enabledLanguages);
for (std::string const& le : enabledLanguages) {
std::string const name = this->GetOutputFileName(lg, target, config, le);
- cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(
- name, false, cmSourceFileLocationKind::Known);
- // Tell TraceDependencies that the file is not expected to exist
- // on disk yet. We generate it after that runs.
- sf->SetProperty("GENERATED", "1");
+ cmSourceFile* sf = lg->GetMakefile()->GetOrCreateGeneratedSource(name);
// Tell the build system generators that there is no build rule
// to generate the file.
@@ -116,14 +113,15 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
{
- mode_t perm = 0;
std::string inputContent;
if (this->InputIsContent) {
inputContent = this->Input;
} else {
const std::string inputFileName = this->GetInputFileName(lg);
lg->GetMakefile()->AddCMakeDependFile(inputFileName);
- cmSystemTools::GetPermissions(inputFileName.c_str(), perm);
+ if (!this->Permissions) {
+ cmSystemTools::GetPermissions(inputFileName.c_str(), this->Permissions);
+ }
cmsys::ifstream fin(inputFileName.c_str());
if (!fin) {
std::ostringstream e;
@@ -157,7 +155,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
for (std::string const& le : enabledLanguages) {
for (std::string const& li : allConfigs) {
- this->Generate(lg, li, le, inputExpression.get(), outputFiles, perm);
+ this->Generate(lg, li, le, inputExpression.get(), outputFiles,
+ this->Permissions);
if (cmSystemTools::GetFatalErrorOccured()) {
return;
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 2cd35ae..5ad5e23 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -24,7 +24,8 @@ public:
std::string input, std::string target,
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070);
+ bool inputIsContent, mode_t permissions,
+ cmPolicies::PolicyStatus policyStatusCMP0070);
void Generate(cmLocalGenerator* lg);
@@ -59,4 +60,5 @@ private:
std::vector<std::string> Files;
const bool InputIsContent;
cmPolicies::PolicyStatus PolicyStatusCMP0070;
+ mode_t Permissions;
};
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 3e7737e..af2afd6 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -60,7 +60,7 @@ struct TextContent : public cmGeneratorExpressionEvaluator
void Extend(size_t length) { this->Length += length; }
- size_t GetLength() { return this->Length; }
+ size_t GetLength() const { return this->Length; }
private:
const char* Content;
diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx
index a7f090a..b8c38c0 100644
--- a/Source/cmGeneratorExpressionLexer.cxx
+++ b/Source/cmGeneratorExpressionLexer.cxx
@@ -35,14 +35,14 @@ std::vector<cmGeneratorExpressionToken> cmGeneratorExpressionLexer::Tokenize(
2);
upto = c + 2;
++c;
- SawBeginExpression = true;
+ this->SawBeginExpression = true;
}
break;
case '>':
InsertText(upto, c, result);
result.emplace_back(cmGeneratorExpressionToken::EndExpression, c, 1);
upto = c + 1;
- SawGeneratorExpression = SawBeginExpression;
+ this->SawGeneratorExpression = this->SawBeginExpression;
break;
case ':':
InsertText(upto, c, result);
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 4ca7405..e40316e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -677,7 +677,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
}
static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (!compilerIdValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
@@ -805,7 +805,7 @@ struct PlatformIdNode : public cmGeneratorExpressionNode
return parameters.front().empty() ? "1" : "0";
}
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (param == platformId) {
return "1";
}
@@ -901,7 +901,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
return std::string();
}
context->HadContextSensitiveCondition = true;
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (context->Config.empty()) {
if (param.empty()) {
return "1";
@@ -927,7 +927,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
return "1";
}
@@ -995,7 +995,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
return context->Language;
}
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (context->Language == param) {
return "1";
}
@@ -1101,7 +1101,7 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode
return context->Language;
}
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (context->Language == param) {
return "1";
}
@@ -1129,7 +1129,7 @@ struct LinkerId
}
static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
- for (auto& param : parameters) {
+ for (auto const& param : parameters) {
if (!linkerIdValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
"Expression syntax not recognized.");
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index c2c9ef7..794c1a1 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -22,7 +22,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser(
void cmGeneratorExpressionParser::Parse(
cmGeneratorExpressionEvaluatorVector& result)
{
- it = this->Tokens.begin();
+ this->it = this->Tokens.begin();
while (this->it != this->Tokens.end()) {
this->ParseContent(result);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index c299dad..17d211e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -24,9 +24,7 @@
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
-#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
-#include "cmCustomCommandLines.h"
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
@@ -254,7 +252,7 @@ EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
{
EvaluatedTargetPropertyEntries out;
out.Entries.reserve(in.size());
- for (auto& entry : in) {
+ for (auto const& entry : in) {
out.Entries.emplace_back(EvaluateTargetPropertyEntry(
thisTarget, config, lang, dagChecker, *entry));
}
@@ -332,7 +330,7 @@ cmGeneratorTarget::~cmGeneratorTarget() = default;
const std::string& cmGeneratorTarget::GetSourcesProperty() const
{
std::vector<std::string> values;
- for (auto& se : this->SourceEntries) {
+ for (auto const& se : this->SourceEntries) {
values.push_back(se->GetInput());
}
static std::string value;
@@ -559,7 +557,7 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
// Frameworks created by multi config generators can have a special
// framework postfix.
- frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
+ frameworkPostfix = this->GetFrameworkMultiConfigPostfix(config);
if (!frameworkPostfix.empty()) {
postfix = &frameworkPostfix;
}
@@ -578,7 +576,7 @@ std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
if (!this->IsImported() && postfix &&
(this->IsFrameworkOnApple() &&
- !GetGlobalGenerator()->IsMultiConfig())) {
+ !this->GetGlobalGenerator()->IsMultiConfig())) {
postfix = nullptr;
}
}
@@ -992,9 +990,8 @@ cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const
bool cmGeneratorTarget::GetLanguageStandardRequired(
std::string const& lang) const
{
- cmProp p =
- this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED");
- return cmIsOn(p);
+ return cmIsOn(
+ this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED"));
}
void cmGeneratorTarget::GetModuleDefinitionSources(
@@ -1539,10 +1536,14 @@ bool processSources(cmGeneratorTarget const* tgt,
for (std::string& src : entry.Values) {
cmSourceFile* sf = mf->GetOrCreateSource(src);
std::string e;
- std::string fullPath = sf->ResolveFullPath(&e);
+ std::string w;
+ std::string fullPath = sf->ResolveFullPath(&e, &w);
+ cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
+ if (!w.empty()) {
+ cm->IssueMessage(MessageType::AUTHOR_WARNING, w, tgt->GetBacktrace());
+ }
if (fullPath.empty()) {
if (!e.empty()) {
- cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace());
}
return contextDependent;
@@ -2500,9 +2501,9 @@ public:
}
}
- bool GetHadLinkLanguageSensitiveCondition()
+ bool GetHadLinkLanguageSensitiveCondition() const
{
- return HadLinkLanguageSensitiveCondition;
+ return this->HadLinkLanguageSensitiveCondition;
}
private:
@@ -2888,9 +2889,6 @@ private:
bool IsUtility(std::string const& dep);
void CheckCustomCommand(cmCustomCommand const& cc);
void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
- void FollowCommandDepends(cmCustomCommand const& cc,
- const std::string& config,
- std::set<std::string>& emitted);
};
cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
@@ -2986,7 +2984,8 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
auto i = this->NameMap.lower_bound(name);
if (i == this->NameMap.end() || i->first != name) {
// Check if we know how to generate this file.
- cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+ cmSourcesWithOutput sources =
+ this->LocalGenerator->GetSourcesWithOutput(name);
// If we failed to find a target or source and we have a relative path, it
// might be a valid source if made relative to the current binary
// directory.
@@ -2996,7 +2995,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
fullname = cmSystemTools::CollapseFullPath(
fullname, this->Makefile->GetHomeOutputDirectory());
- sources = this->Makefile->GetSourcesWithOutput(fullname);
+ sources = this->LocalGenerator->GetSourcesWithOutput(fullname);
}
i = this->NameMap.emplace_hint(i, name, sources);
}
@@ -3065,7 +3064,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
} else {
// The original name of the dependency was not a full path. It
// must name a target, so add the target-level dependency.
- this->GeneratorTarget->Target->AddUtility(util, false);
+ this->GeneratorTarget->Target->AddUtility(util, true);
return true;
}
}
@@ -3076,71 +3075,28 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
{
- // Transform command names that reference targets built in this
- // project to corresponding target-level dependencies.
- cmGeneratorExpression ge(cc.GetBacktrace());
-
- // Add target-level dependencies referenced by generator expressions.
- std::set<cmGeneratorTarget*> targets;
-
- for (cmCustomCommandLine const& cCmdLine : cc.GetCommandLines()) {
- std::string const& command = cCmdLine.front();
- // Check for a target with this name.
- if (cmGeneratorTarget* t =
- this->LocalGenerator->FindGeneratorTargetToUse(command)) {
- if (t->GetType() == cmStateEnums::EXECUTABLE) {
- // The command refers to an executable target built in
- // this project. Add the target-level dependency to make
- // sure the executable is up to date before this custom
- // command possibly runs.
- this->GeneratorTarget->Target->AddUtility(command, true);
+ // Collect dependencies referenced by all configurations.
+ std::set<std::string> depends;
+ for (std::string const& config :
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
+ for (cmCustomCommandGenerator const& ccg :
+ this->LocalGenerator->MakeCustomCommandGenerators(cc, config)) {
+ // Collect target-level dependencies referenced in command lines.
+ for (auto const& util : ccg.GetUtilities()) {
+ this->GeneratorTarget->Target->AddUtility(util);
}
- }
- // Check for target references in generator expressions.
- std::vector<std::string> const& configs =
- this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- for (std::string const& c : configs) {
- for (std::string const& cl : cCmdLine) {
- const std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(cl);
- cge->SetQuiet(true);
- cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), c);
- std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
- targets.insert(geTargets.begin(), geTargets.end());
- }
+ // Collect file-level dependencies referenced in DEPENDS.
+ depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
}
}
- for (cmGeneratorTarget* target : targets) {
- this->GeneratorTarget->Target->AddUtility(target->GetName(), true);
- }
-
- // Queue the custom command dependencies.
- std::set<std::string> emitted;
- std::vector<std::string> const& configs =
- this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- for (std::string const& conf : configs) {
- this->FollowCommandDepends(cc, conf, emitted);
- }
-}
-
-void cmTargetTraceDependencies::FollowCommandDepends(
- cmCustomCommand const& cc, const std::string& config,
- std::set<std::string>& emitted)
-{
- cmCustomCommandGenerator ccg(cc, config,
- this->GeneratorTarget->LocalGenerator);
-
- const std::vector<std::string>& depends = ccg.GetDepends();
-
+ // Queue file-level dependencies.
for (std::string const& dep : depends) {
- if (emitted.insert(dep).second) {
- if (!this->IsUtility(dep)) {
- // The dependency does not name a target and may be a file we
- // know how to generate. Queue it.
- this->FollowName(dep);
- }
+ if (!this->IsUtility(dep)) {
+ // The dependency does not name a target and may be a file we
+ // know how to generate. Queue it.
+ this->FollowName(dep);
}
}
}
@@ -3200,6 +3156,30 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
}
}
+void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
+ cmSourceFile const& sf) const
+{
+ cmProp lang = sf.GetProperty("LANGUAGE");
+ if (!lang) {
+ return;
+ }
+
+ switch (this->GetPolicyStatusCMP0119()) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ // The OLD behavior is to not add explicit language flags.
+ return;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ // The NEW behavior is to add explicit language flags.
+ break;
+ }
+
+ this->LocalGenerator->AppendFeatureOptions(flags, *lang,
+ "EXPLICIT_LANGUAGE");
+}
+
void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
{
const std::string& property = this->GetSafeProperty("CUDA_ARCHITECTURES");
@@ -3298,7 +3278,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
flags += " --cuda-gpu-arch=sm_" + architecture.name;
if (!architecture.real) {
- Makefile->IssueMessage(
+ this->Makefile->IssueMessage(
MessageType::WARNING,
"Clang doesn't support disabling CUDA real code generation.");
}
@@ -4988,7 +4968,7 @@ void cmGeneratorTarget::GetFullNameInternal(
// the base, because the suffix ends up being used in Xcode's
// EXECUTABLE_SUFFIX attribute.
if (this->IsFrameworkOnApple() &&
- GetGlobalGenerator()->GetName() == "Xcode") {
+ this->GetGlobalGenerator()->GetName() == "Xcode") {
targetSuffix = &configPostfix;
} else {
outBase += configPostfix;
@@ -7059,7 +7039,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
return &impl;
}
-bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+bool cmGeneratorTarget::GetConfigCommonSourceFilesForXcode(
std::vector<cmSourceFile*>& files) const
{
std::vector<std::string> const& configs =
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2517b72..8fe70ab 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -430,8 +430,9 @@ public:
/** Get source files common to all configurations and diagnose cases
with per-config sources. Excludes sources added by a TARGET_OBJECTS
- generator expression. */
- bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+ generator expression. Do not use outside the Xcode generator. */
+ bool GetConfigCommonSourceFilesForXcode(
+ std::vector<cmSourceFile*>& files) const;
bool HaveBuildTreeRPATH(const std::string& config) const;
@@ -447,6 +448,9 @@ public:
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
+ void AddExplicitLanguageFlags(std::string& flags,
+ cmSourceFile const& sf) const;
+
void AddCUDAArchitectureFlags(std::string& flags) const;
void AddCUDAToolkitFlags(std::string& flags) const;
@@ -581,7 +585,8 @@ public:
std::string PdbDir;
bool empty() const
{
- return OutDir.empty() && ImpDir.empty() && PdbDir.empty();
+ return this->OutDir.empty() && this->ImpDir.empty() &&
+ this->PdbDir.empty();
}
};
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index c2098c0..7fbd479 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -50,6 +50,10 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
return false;
}
++i;
+ if (i == args.end()) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
}
// OK, now we have the directory to process, we just get the requested
@@ -67,27 +71,30 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
return true;
}
+ if (i->empty()) {
+ status.SetError("given empty string for the property name to get");
+ return false;
+ }
+
const char* prop = nullptr;
- if (!i->empty()) {
- if (*i == "DEFINITIONS") {
- switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) {
- case cmPolicies::WARN:
- status.GetMakefile().IssueMessage(
- MessageType::AUTHOR_WARNING,
- cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- StoreResult(status.GetMakefile(), variable,
- status.GetMakefile().GetDefineFlagsCMP0059());
- return true;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- break;
- }
+ if (*i == "DEFINITIONS") {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) {
+ case cmPolicies::WARN:
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ StoreResult(status.GetMakefile(), variable,
+ status.GetMakefile().GetDefineFlagsCMP0059());
+ return true;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
}
- prop = cmToCStr(dir->GetProperty(*i));
}
+ prop = cmToCStr(dir->GetProperty(*i));
StoreResult(status.GetMakefile(), variable, prop);
return true;
}
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 3a5b39d..cb657f9 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -172,7 +172,7 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
std::vector<cmMakefile*> source_file_directory_makefiles;
bool file_scopes_handled =
- SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
@@ -280,8 +280,9 @@ bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
// Get the property.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- cmProp p = cm->GetState()->GetGlobalProperty(propertyName);
- return StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(p));
+ return StoreResult(
+ infoType, status.GetMakefile(), variable,
+ cmToCStr(cm->GetState()->GetGlobalProperty(propertyName)));
}
bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -327,8 +328,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
}
// Get the property.
- cmProp p = mf->GetProperty(propertyName);
- return StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(p));
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ cmToCStr(mf->GetProperty(propertyName)));
}
bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -358,15 +359,14 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
}
return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
}
- cmProp prop_cstr = nullptr;
cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
cmMessenger* messenger = status.GetMakefile().GetMessenger();
- prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
- if (!prop_cstr) {
- prop_cstr = target->GetProperty(propertyName);
+ cmProp prop = target->GetComputedProperty(propertyName, messenger, bt);
+ if (!prop) {
+ prop = target->GetProperty(propertyName);
}
return StoreResult(infoType, status.GetMakefile(), variable,
- prop_cstr ? prop_cstr->c_str() : nullptr);
+ cmToCStr(prop));
}
status.SetError(cmStrCat("could not find TARGET ", name,
". Perhaps it has not yet been created."));
@@ -391,7 +391,7 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
if (cmSourceFile* sf =
directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
return StoreResult(infoType, status.GetMakefile(), variable,
- sf->GetPropertyForUser(propertyName));
+ cmToCStr(sf->GetPropertyForUser(propertyName)));
}
status.SetError(
cmStrCat("given SOURCE name that could not be found or created: ",
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 5395bc8..5301b66 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -4,6 +4,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
@@ -34,7 +35,7 @@ bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
std::vector<cmMakefile*> source_file_directory_makefiles;
bool file_scopes_handled =
- SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
@@ -57,14 +58,14 @@ bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
}
if (sf) {
- const char* prop = nullptr;
+ cmProp prop = nullptr;
if (!args[property_arg_index].empty()) {
prop = sf->GetPropertyForUser(args[property_arg_index]);
}
if (prop) {
// Set the value on the original Makefile scope, not the scope of the
// requested directory.
- status.GetMakefile().AddDefinition(var, prop);
+ status.GetMakefile().AddDefinition(var, *prop);
return true;
}
}
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index a8f8f57..a7658f2 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -62,7 +62,7 @@ void cmGhsMultiTargetGenerator::Generate()
// Get the name of the executable to generate.
this->TargetNameReal =
this->GeneratorTarget->GetExecutableNames(this->ConfigName).Real;
- if (cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) {
+ if (this->cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) {
this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION;
} else {
this->TagType = GhsMultiGpj::PROGRAM;
@@ -631,7 +631,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
}
} else {
std::vector<cmSourceFile const*> customCommands;
- if (ComputeCustomCommandOrder(customCommands)) {
+ if (this->ComputeCustomCommandOrder(customCommands)) {
std::string message = "The custom commands for target [" +
this->GeneratorTarget->GetName() + "] had a cycle.\n";
cmSystemTools::Error(message);
@@ -721,8 +721,7 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
{
- cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
- if (p) {
+ if (cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app")) {
return cmIsOn(*p);
}
std::vector<cmSourceFile*> sources;
@@ -746,7 +745,7 @@ bool cmGhsMultiTargetGenerator::ComputeCustomCommandOrder(
this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
for (cmSourceFile const* si : customCommands) {
- bool r = VisitCustomCommand(temp, perm, order, si);
+ bool r = this->VisitCustomCommand(temp, perm, order, si);
if (r) {
return r;
}
@@ -763,9 +762,9 @@ bool cmGhsMultiTargetGenerator::VisitCustomCommand(
/* set temporary mark; check if revisit*/
if (temp.insert(si).second) {
for (auto& di : si->GetCustomCommand()->GetDepends()) {
- cmSourceFile const* sf = this->GeneratorTarget->GetLocalGenerator()
- ->GetMakefile()
- ->GetSourceFileWithOutput(di);
+ cmSourceFile const* sf =
+ this->GeneratorTarget->GetLocalGenerator()->GetSourceFileWithOutput(
+ di);
/* if sf exists then visit */
if (sf && this->VisitCustomCommand(temp, perm, order, sf)) {
return true;
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 06943e7..996fcff 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -26,6 +26,15 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm)
this->DefineWindowsNULL = true;
this->PassMakeflags = true;
this->UnixCD = false;
+
+ /*
+ * Borland Make does not support long line depend rule, as we have tested
+ * generate one source file includes 40000 header files, and generate
+ * depend.make in one line(use line continued tag), and error occured:
+ * ** Fatal CMakeFiles\main.dir\depend.make 1224: Rule line too long **
+ * we disable long line dependencies rule generation for Borland make
+ */
+ this->ToolSupportsLongLineDependencies = false;
}
void cmGlobalBorlandMakefileGenerator::EnableLanguage(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index fc40d63..63aaf27 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1821,6 +1821,7 @@ void cmGlobalGenerator::ClearGeneratorMembers()
this->RuleHashes.clear();
this->DirectoryContentMap.clear();
this->BinaryDirectories.clear();
+ this->GeneratedFiles.clear();
}
void cmGlobalGenerator::ComputeTargetObjectDirectory(
@@ -2146,6 +2147,16 @@ void cmGlobalGenerator::AddInstallComponent(const std::string& component)
}
}
+void cmGlobalGenerator::MarkAsGeneratedFile(const std::string& filepath)
+{
+ this->GeneratedFiles.insert(filepath);
+}
+
+bool cmGlobalGenerator::IsGeneratedFile(const std::string& filepath)
+{
+ return this->GeneratedFiles.find(filepath) != this->GeneratedFiles.end();
+}
+
void cmGlobalGenerator::EnableInstallTarget()
{
this->InstallTargetEnabled = true;
@@ -2608,7 +2619,7 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
}
void cmGlobalGenerator::AddGlobalTarget_EditCache(
- std::vector<GlobalTargetInfo>& targets)
+ std::vector<GlobalTargetInfo>& targets) const
{
const char* editCacheTargetName = this->GetEditCacheTargetName();
if (!editCacheTargetName) {
@@ -2642,7 +2653,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
}
void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
- std::vector<GlobalTargetInfo>& targets)
+ std::vector<GlobalTargetInfo>& targets) const
{
const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
if (!rebuildCacheTargetName) {
@@ -2765,7 +2776,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
}
}
-std::string cmGlobalGenerator::GetPredefinedTargetsFolder()
+std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const
{
cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"PREDEFINED_TARGETS_FOLDER");
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index c106258..86fb228 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -11,9 +11,11 @@
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
+#include <cm/optional>
#include <cmext/algorithm>
#include "cm_codecvt.hxx"
@@ -26,6 +28,7 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
+#include "cmTransformDepfile.h"
#if !defined(CMAKE_BOOTSTRAP)
# include <cm3p/json/value.h>
@@ -66,17 +69,17 @@ struct GeneratedMakeCommand
void Add(T&&... args)
{
// iterate the args and append each one
- AppendStrs(PrimaryCommand, std::forward<T>(args)...);
+ AppendStrs(this->PrimaryCommand, std::forward<T>(args)...);
}
// Add each value in the iterators as a separate element to the vector
void Add(std::vector<std::string>::const_iterator start,
std::vector<std::string>::const_iterator end)
{
- cm::append(PrimaryCommand, start, end);
+ cm::append(this->PrimaryCommand, start, end);
}
- std::string Printable() const { return cmJoin(PrimaryCommand, " "); }
+ std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
std::vector<std::string> PrimaryCommand;
bool RequiresOutputForward = false;
@@ -288,6 +291,11 @@ public:
void AddInstallComponent(const std::string& component);
+ /** Mark the (absolute path to a) file as generated. */
+ void MarkAsGeneratedFile(const std::string& filepath);
+ /** Determine if the absolute filepath belongs to a generated file. */
+ bool IsGeneratedFile(const std::string& filepath);
+
const std::set<std::string>* GetInstallComponents() const
{
return &this->InstallComponents;
@@ -452,6 +460,10 @@ public:
virtual bool ShouldStripResourcePath(cmMakefile*) const;
virtual bool SupportsCustomCommandDepfile() const { return false; }
+ virtual cm::optional<cmDepfileFormat> DepfileFormat() const
+ {
+ return cm::nullopt;
+ }
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
@@ -489,7 +501,7 @@ public:
cmSourceFile* sf) const;
#if !defined(CMAKE_BOOTSTRAP)
- cmFileLockPool& GetFileLockPool() { return FileLockPool; }
+ cmFileLockPool& GetFileLockPool() { return this->FileLockPool; }
#endif
bool GetConfigureDoneCMP0026() const
@@ -568,8 +580,9 @@ protected:
void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
- void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets);
- void AddGlobalTarget_RebuildCache(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
+ void AddGlobalTarget_RebuildCache(
+ std::vector<GlobalTargetInfo>& targets) const;
void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
@@ -595,7 +608,7 @@ protected:
cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
- std::string GetPredefinedTargetsFolder();
+ std::string GetPredefinedTargetsFolder() const;
enum class FindMakeProgramStage
{
@@ -726,6 +739,8 @@ private:
std::map<std::string, std::string> RealPaths;
+ std::unordered_set<std::string> GeneratedFiles;
+
#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
cmFileLockPool FileLockPool;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index c08c9cf..0ddfe77 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -366,7 +366,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
target->GetType() == cmStateEnums::MODULE_LIBRARY ||
target->GetType() == cmStateEnums::SHARED_LIBRARY ||
(target->GetType() == cmStateEnums::GLOBAL_TARGET &&
- target->GetName() != GetInstallTargetName())) {
+ target->GetName() != this->GetInstallTargetName())) {
continue;
}
fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
@@ -415,7 +415,7 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
target->GetType() == cmStateEnums::MODULE_LIBRARY ||
target->GetType() == cmStateEnums::SHARED_LIBRARY ||
(target->GetType() == cmStateEnums::GLOBAL_TARGET &&
- target->GetName() != GetInstallTargetName())) {
+ target->GetName() != this->GetInstallTargetName())) {
continue;
}
@@ -427,13 +427,13 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
this->WriteFileHeader(fbld);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
std::vector<cmGeneratorTarget const*> build;
- if (ComputeTargetBuildOrder(target, build)) {
+ if (this->ComputeTargetBuildOrder(target, build)) {
cmSystemTools::Error(
cmStrCat("The inter-target dependency graph for target [",
target->GetName(), "] had a cycle.\n"));
} else {
for (auto& tgt : build) {
- WriteProjectLine(fbld, tgt, root, rootBinaryDir);
+ this->WriteProjectLine(fbld, tgt, root, rootBinaryDir);
}
}
fbld.Close();
@@ -471,12 +471,12 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
if (!t->IsInBuildSystem()) {
continue;
}
- if (!IsExcluded(t->GetLocalGenerator(), t)) {
+ if (!this->IsExcluded(t->GetLocalGenerator(), t)) {
defaultTargets.push_back(t);
}
}
std::vector<cmGeneratorTarget const*> build;
- if (ComputeTargetBuildOrder(defaultTargets, build)) {
+ if (this->ComputeTargetBuildOrder(defaultTargets, build)) {
std::string message = "The inter-target dependency graph for project [" +
root->GetProjectName() + "] had a cycle.\n";
cmSystemTools::Error(message);
@@ -694,7 +694,7 @@ bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
cmGeneratorTarget const* tgt, std::vector<cmGeneratorTarget const*>& build)
{
std::vector<cmGeneratorTarget const*> t{ tgt };
- return ComputeTargetBuildOrder(t, build);
+ return this->ComputeTargetBuildOrder(t, build);
}
bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
@@ -704,8 +704,8 @@ bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
std::set<cmGeneratorTarget const*> temp;
std::set<cmGeneratorTarget const*> perm;
- for (auto ti : tgt) {
- bool r = VisitTarget(temp, perm, build, ti);
+ for (auto const ti : tgt) {
+ bool r = this->VisitTarget(temp, perm, build, ti);
if (r) {
return r;
}
@@ -726,7 +726,7 @@ bool cmGlobalGhsMultiGenerator::VisitTarget(
* in the same order */
OrderedTargetDependSet sortedTargets(this->GetTargetDirectDepends(ti),
"");
- for (auto& di : sortedTargets) {
+ for (auto const& di : sortedTargets) {
if (this->VisitTarget(temp, perm, order, di)) {
return true;
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 02ffaf7..4f17408 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -34,6 +34,7 @@
#include "cmOutputConverter.h"
#include "cmProperty.h"
#include "cmRange.h"
+#include "cmScanDepFormat.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
@@ -55,6 +56,52 @@ std::string const cmGlobalNinjaGenerator::SHELL_NOOP = "cd .";
std::string const cmGlobalNinjaGenerator::SHELL_NOOP = ":";
#endif
+bool operator==(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return lhs.Target == rhs.Target && lhs.Config == rhs.Config &&
+ lhs.GenexOutput == rhs.GenexOutput;
+}
+
+bool operator!=(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return !(lhs == rhs);
+}
+
+bool operator<(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return lhs.Target < rhs.Target ||
+ (lhs.Target == rhs.Target &&
+ (lhs.Config < rhs.Config ||
+ (lhs.Config == rhs.Config && lhs.GenexOutput < rhs.GenexOutput)));
+}
+
+bool operator>(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return rhs < lhs;
+}
+
+bool operator<=(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return !(lhs > rhs);
+}
+
+bool operator>=(
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& lhs,
+ const cmGlobalNinjaGenerator::ByConfig::TargetDependsClosureKey& rhs)
+{
+ return rhs <= lhs;
+}
+
void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count)
{
for (int i = 0; i < count; ++i) {
@@ -135,7 +182,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path)
else
std::replace(result.begin(), result.end(), '/', '\\');
#endif
- result = EncodeLiteral(result);
+ result = this->EncodeLiteral(result);
cmSystemTools::ReplaceString(result, " ", "$ ");
cmSystemTools::ReplaceString(result, ":", "$:");
return result;
@@ -167,7 +214,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Write explicit outputs
for (std::string const& output : build.Outputs) {
- buildStr += cmStrCat(' ', EncodePath(output));
+ buildStr += cmStrCat(' ', this->EncodePath(output));
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(output);
}
@@ -176,7 +223,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.ImplicitOuts.empty()) {
buildStr += " |";
for (std::string const& implicitOut : build.ImplicitOuts) {
- buildStr += cmStrCat(' ', EncodePath(implicitOut));
+ buildStr += cmStrCat(' ', this->EncodePath(implicitOut));
}
}
buildStr += ':';
@@ -191,14 +238,14 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
// Write explicit dependencies.
for (std::string const& explicitDep : build.ExplicitDeps) {
- arguments += cmStrCat(' ', EncodePath(explicitDep));
+ arguments += cmStrCat(' ', this->EncodePath(explicitDep));
}
// Write implicit dependencies.
if (!build.ImplicitDeps.empty()) {
arguments += " |";
for (std::string const& implicitDep : build.ImplicitDeps) {
- arguments += cmStrCat(' ', EncodePath(implicitDep));
+ arguments += cmStrCat(' ', this->EncodePath(implicitDep));
}
}
@@ -206,7 +253,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.OrderOnlyDeps.empty()) {
arguments += " ||";
for (std::string const& orderOnlyDep : build.OrderOnlyDeps) {
- arguments += cmStrCat(' ', EncodePath(orderOnlyDep));
+ arguments += cmStrCat(' ', this->EncodePath(orderOnlyDep));
}
}
@@ -284,11 +331,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
#endif
vars["COMMAND"] = std::move(cmd);
}
- vars["DESC"] = EncodeLiteral(description);
+ vars["DESC"] = this->EncodeLiteral(description);
if (restat) {
vars["restat"] = "1";
}
- if (uses_terminal && SupportsConsolePool()) {
+ if (uses_terminal && this->SupportsConsolePool()) {
vars["pool"] = "console";
} else if (!job_pool.empty()) {
vars["pool"] = job_pool;
@@ -315,7 +362,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
cmNinjaRule rule("COPY_OSX_CONTENT");
- rule.Command = cmStrCat(CMakeCmd(), " -E copy $in $out");
+ rule.Command = cmStrCat(this->CMakeCmd(), " -E copy $in $out");
rule.Description = "Copying OS X Content $out";
rule.Comment = "Rule for copying OS X bundle content file.";
this->AddRule(rule);
@@ -508,6 +555,7 @@ void cmGlobalNinjaGenerator::Generate()
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
this->DisableCleandead = false;
+ this->DiagnosedCxxModuleSupport = false;
this->PolicyCMP0058 =
this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
@@ -708,6 +756,37 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
return true;
}
+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.");
+ }
+ if (this->NinjaSupportsDyndeps) {
+ return true;
+ }
+ if (diagnose) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "The Ninja generator does not support C++20 modules "
+ "using Ninja version \n"
+ " " << this->NinjaVersion << "\n"
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required."
+ ;
+ /* clang-format on */
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ return false;
+}
+
bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
{
if (this->NinjaSupportsDyndeps) {
@@ -719,7 +798,8 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
e <<
"The Ninja generator does not support Fortran using Ninja version\n"
" " << this->NinjaVersion << "\n"
- "due to lack of required features. Ninja 1.10 or higher is required."
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -738,7 +818,9 @@ bool cmGlobalNinjaGenerator::CheckISPC(cmMakefile* mf) const
e <<
"The Ninja generator does not support ISPC using Ninja version\n"
" " << this->NinjaVersion << "\n"
- "due to lack of required features. Ninja 1.10 or higher is required."
+ "due to lack of required features. "
+ "Ninja " << RequiredNinjaVersionForMultipleOutputs() <<
+ " or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -985,8 +1067,8 @@ static void EnsureTrailingSlash(std::string& path)
std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
const std::string& path) const
{
- auto const f = ConvertToNinjaPathCache.find(path);
- if (f != ConvertToNinjaPathCache.end()) {
+ auto const f = this->ConvertToNinjaPathCache.find(path);
+ if (f != this->ConvertToNinjaPathCache.end()) {
return f->second;
}
@@ -998,7 +1080,7 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
#endif
- return ConvertToNinjaPathCache.emplace(path, std::move(convPath))
+ return this->ConvertToNinjaPathCache.emplace(path, std::move(convPath))
.first->second;
}
@@ -1056,7 +1138,7 @@ void cmGlobalNinjaGenerator::CloseCompileCommandsStream()
}
}
-void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
+void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) const
{
os << "# CMAKE generated file: DO NOT EDIT!\n"
<< "# Generated by \"" << this->GetName() << "\""
@@ -1070,12 +1152,13 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
cmNinjaDeps orderOnlyDeps;
std::copy(asd.second.begin(), asd.second.end(),
std::back_inserter(orderOnlyDeps));
- WriteCustomCommandBuild(/*command=*/"", /*description=*/"",
- "Assume dependencies for generated source file.",
- /*depfile*/ "", /*job_pool*/ "",
- /*uses_terminal*/ false,
- /*restat*/ true, cmNinjaDeps(1, asd.first), "",
- cmNinjaDeps(), orderOnlyDeps);
+ this->WriteCustomCommandBuild(
+ /*command=*/"", /*description=*/"",
+ "Assume dependencies for generated source file.",
+ /*depfile*/ "", /*job_pool*/ "",
+ /*uses_terminal*/ false,
+ /*restat*/ true, cmNinjaDeps(1, asd.first), "", cmNinjaDeps(),
+ orderOnlyDeps);
}
}
@@ -1087,7 +1170,7 @@ std::string cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
void cmGlobalNinjaGenerator::AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
- const std::string& config, cmNinjaTargetDepends depends)
+ const std::string& config, cmNinjaTargetDepends depends) const
{
// for frameworks, we want the real name, not smple name
// frameworks always appear versioned, and the build.ninja
@@ -1100,7 +1183,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target, config));
+ outputs.push_back(this->OrderDependsTargetForTarget(target, config));
break;
}
}
@@ -1112,7 +1195,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
}
case cmStateEnums::OBJECT_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target, config));
+ outputs.push_back(this->OrderDependsTargetForTarget(target, config));
break;
}
}
@@ -1193,23 +1276,30 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
- const std::string& config)
+ const std::string& config, const std::string& fileConfig, bool genexOutput)
{
cmNinjaOuts outs;
- this->AppendTargetDependsClosure(target, outs, config, true);
+ this->AppendTargetDependsClosure(target, outs, config, fileConfig,
+ genexOutput, true);
cm::append(outputs, outs);
}
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmGeneratorTarget const* target, cmNinjaOuts& outputs,
- const std::string& config, bool omit_self)
+ const std::string& config, const std::string& fileConfig, bool genexOutput,
+ bool omit_self)
{
// try to locate the target in the cache
- auto find = this->Configs[config].TargetDependsClosures.lower_bound(target);
+ ByConfig::TargetDependsClosureKey key{
+ target,
+ config,
+ genexOutput,
+ };
+ auto find = this->Configs[fileConfig].TargetDependsClosures.lower_bound(key);
- if (find == this->Configs[config].TargetDependsClosures.end() ||
- find->first != target) {
+ if (find == this->Configs[fileConfig].TargetDependsClosures.end() ||
+ find->first != key) {
// We now calculate the closure outputs by inspecting the dependent
// targets recursively.
// For that we have to distinguish between a local result set that is only
@@ -1219,18 +1309,27 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmNinjaOuts this_outs; // this will be the new cache entry
for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
- if (!dep_target->IsInBuildSystem() ||
- (target->GetType() != cmStateEnums::UTILITY &&
- dep_target->GetType() != cmStateEnums::UTILITY &&
- this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
+ if (!dep_target->IsInBuildSystem()) {
continue;
}
- // Collect the dependent targets for _this_ target
- this->AppendTargetDependsClosure(dep_target, this_outs, config, false);
+ if (!this->IsSingleConfigUtility(target) &&
+ !this->IsSingleConfigUtility(dep_target) &&
+ this->EnableCrossConfigBuild() && !dep_target.IsCross() &&
+ !genexOutput) {
+ continue;
+ }
+
+ if (dep_target.IsCross()) {
+ this->AppendTargetDependsClosure(dep_target, this_outs, fileConfig,
+ fileConfig, genexOutput, false);
+ } else {
+ this->AppendTargetDependsClosure(dep_target, this_outs, config,
+ fileConfig, genexOutput, false);
+ }
}
- find = this->Configs[config].TargetDependsClosures.emplace_hint(
- find, target, std::move(this_outs));
+ find = this->Configs[fileConfig].TargetDependsClosures.emplace_hint(
+ find, key, std::move(this_outs));
}
// now fill the outputs of the final result from the newly generated cache
@@ -1413,7 +1512,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
configDeps.emplace_back(build.Outputs.front());
for (DirectoryTarget::Target const& t : dt.Targets) {
- if (!IsExcludedFromAllInConfig(t, config)) {
+ if (!this->IsExcludedFromAllInConfig(t, config)) {
this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config,
DependOnTargetArtifact);
}
@@ -1626,7 +1725,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
{
cmNinjaRule rule("RERUN_CMAKE");
rule.Command =
- cmStrCat(CMakeCmd(), " --regenerate-during-build -S",
+ cmStrCat(this->CMakeCmd(), " --regenerate-during-build -S",
lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL),
" -B",
@@ -1651,7 +1750,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
// Use 'console' pool to get non buffered output of the CMake re-run call
// Available since Ninja 1.5
- if (SupportsConsolePool()) {
+ if (this->SupportsConsolePool()) {
reBuild.Variables["pool"] = "console";
}
@@ -1660,7 +1759,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
{
cmNinjaRule rule("VERIFY_GLOBS");
rule.Command =
- cmStrCat(CMakeCmd(), " -P ",
+ cmStrCat(this->CMakeCmd(), " -P ",
lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
cmOutputConverter::SHELL));
rule.Description = "Re-checking globbed directories...";
@@ -1721,8 +1820,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
build.Comment = "A missing CMake input file is not an error.";
std::set_difference(std::make_move_iterator(reBuild.ImplicitDeps.begin()),
std::make_move_iterator(reBuild.ImplicitDeps.end()),
- CustomCommandOutputs.begin(),
- CustomCommandOutputs.end(),
+ this->CustomCommandOutputs.begin(),
+ this->CustomCommandOutputs.end(),
std::back_inserter(build.Outputs));
this->WriteBuild(os, build);
}
@@ -1806,7 +1905,8 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
fout << " file(REMOVE_RECURSE\n";
for (std::string const& acf : it->second.AdditionalCleanFiles) {
fout << " "
- << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
+ << cmOutputConverter::EscapeForCMake(
+ this->ConvertToNinjaPath(acf))
<< '\n';
}
fout << " )\n";
@@ -1821,7 +1921,7 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmNinjaRule rule("CLEAN_ADDITIONAL");
rule.Command = cmStrCat(
- CMakeCmd(), " -DCONFIG=$CONFIG -P ",
+ this->CMakeCmd(), " -DCONFIG=$CONFIG -P ",
lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel),
cmOutputConverter::SHELL));
rule.Description = "Cleaning additional files...";
@@ -1838,13 +1938,13 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
build.Outputs.front() = this->BuildAlias(
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()), config);
build.Variables["CONFIG"] = config;
- WriteBuild(os, build);
+ this->WriteBuild(os, build);
}
if (this->IsMultiConfig()) {
build.Outputs.front() =
this->NinjaOutputPath(this->GetAdditionalCleanTargetName());
build.Variables["CONFIG"] = "";
- WriteBuild(os, build);
+ this->WriteBuild(os, build);
}
}
// Return success
@@ -1854,13 +1954,13 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
// -- Additional clean target
- bool additionalFiles = WriteTargetCleanAdditional(os);
+ bool additionalFiles = this->WriteTargetCleanAdditional(os);
// -- Default clean target
// Write rule
{
cmNinjaRule rule("CLEAN");
- rule.Command = cmStrCat(NinjaCmd(), " $FILE_ARG -t clean $TARGETS");
+ rule.Command = cmStrCat(this->NinjaCmd(), " $FILE_ARG -t clean $TARGETS");
rule.Description = "Cleaning all built files...";
rule.Comment = "Rule for cleaning all built files.";
WriteRule(*this->RulesFileStream, rule);
@@ -1961,13 +2061,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
build.Outputs.emplace_back(
this->ConvertToNinjaPath(GetByproductsForCleanTargetName()));
build.ExplicitDeps = this->ByproductsForCleanTarget;
- WriteBuild(os, build);
+ this->WriteBuild(os, build);
for (auto const& config : configs) {
build.Outputs.front() = this->BuildAlias(
this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config);
build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget;
- WriteBuild(os, build);
+ this->WriteBuild(os, build);
}
}
}
@@ -1976,7 +2076,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
{
cmNinjaRule rule("HELP");
- rule.Command = cmStrCat(NinjaCmd(), " -t targets");
+ rule.Command = cmStrCat(this->NinjaCmd(), " -t targets");
rule.Description = "All primary targets available:";
rule.Comment = "Rule for printing all primary targets available.";
WriteRule(*this->RulesFileStream, rule);
@@ -1985,7 +2085,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
cmNinjaBuild build("HELP");
build.Comment = "Print all primary targets available.";
build.Outputs.push_back(this->NinjaOutputPath("help"));
- WriteBuild(os, build);
+ this->WriteBuild(os, build);
}
}
@@ -2016,6 +2116,8 @@ void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
cmStripSuffixIfExists(path, this->OutputPathPrefix);
}
+#if !defined(CMAKE_BOOTSTRAP)
+
/*
We use the following approach to support Fortran. Each target already
@@ -2095,16 +2197,6 @@ Compilation of source files within a target is split into the following steps:
(because the latter consumes the module).
*/
-struct cmSourceInfo
-{
- // Set of provided and required modules.
- std::set<std::string> Provides;
- std::set<std::string> Requires;
-
- // Set of files included in the translation unit.
- std::set<std::string> Includes;
-};
-
static std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
std::string const& arg_tdi, std::string const& arg_pp);
@@ -2112,6 +2204,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd)
{
std::string arg_tdi;
+ std::string arg_src;
std::string arg_pp;
std::string arg_dep;
std::string arg_obj;
@@ -2120,6 +2213,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
for (std::string const& arg : cmMakeRange(argBeg, argEnd)) {
if (cmHasLiteralPrefix(arg, "--tdi=")) {
arg_tdi = arg.substr(6);
+ } else if (cmHasLiteralPrefix(arg, "--src=")) {
+ arg_src = arg.substr(6);
} else if (cmHasLiteralPrefix(arg, "--pp=")) {
arg_pp = arg.substr(5);
} else if (cmHasLiteralPrefix(arg, "--dep=")) {
@@ -2160,6 +2255,9 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
cmSystemTools::Error("-E cmake_ninja_depends requires value for --lang=");
return 1;
}
+ if (arg_src.empty()) {
+ arg_src = cmStrCat("<", arg_obj, " input file>");
+ }
std::unique_ptr<cmSourceInfo> info;
if (arg_lang == "Fortran") {
@@ -2176,6 +2274,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
return 1;
}
+ info->PrimaryOutput = arg_obj;
+
{
cmGeneratedFileStream depfile(arg_dep);
depfile << cmSystemTools::ConvertToUnixOutputPath(arg_pp) << ":";
@@ -2185,24 +2285,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
depfile << "\n";
}
- Json::Value ddi(Json::objectValue);
- ddi["object"] = arg_obj;
-
- Json::Value& ddi_provides = ddi["provides"] = Json::arrayValue;
- for (std::string const& provide : info->Provides) {
- ddi_provides.append(provide);
- }
- Json::Value& ddi_requires = ddi["requires"] = Json::arrayValue;
- for (std::string const& r : info->Requires) {
- // Require modules not provided in the same source.
- if (!info->Provides.count(r)) {
- ddi_requires.append(r);
- }
- }
-
- cmGeneratedFileStream ddif(arg_ddi);
- ddif << ddi;
- if (!ddif) {
+ if (!cmScanDepFormat_P1689_Write(arg_ddi, arg_src, *info)) {
cmSystemTools::Error(
cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
return 1;
@@ -2260,26 +2343,35 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
}
auto info = cm::make_unique<cmSourceInfo>();
- info->Provides = finfo.Provides;
- info->Requires = finfo.Requires;
- info->Includes = finfo.Includes;
+ for (std::string const& provide : finfo.Provides) {
+ cmSourceReqInfo src_info;
+ src_info.LogicalName = provide;
+ src_info.CompiledModulePath = provide;
+ info->Provides.emplace_back(src_info);
+ }
+ for (std::string const& require : finfo.Requires) {
+ // Require modules not provided in the same source.
+ if (finfo.Provides.count(require)) {
+ continue;
+ }
+ cmSourceReqInfo src_info;
+ src_info.LogicalName = require;
+ src_info.CompiledModulePath = require;
+ info->Requires.emplace_back(src_info);
+ }
+ for (std::string const& include : finfo.Includes) {
+ info->Includes.push_back(include);
+ }
return info;
}
-struct cmDyndepObjectInfo
-{
- std::string Object;
- std::vector<std::string> Provides;
- std::vector<std::string> Requires;
-};
-
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,
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
- std::string const& arg_lang)
+ std::string const& arg_lang, std::string const& arg_modmapfmt)
{
// Setup path conversions.
{
@@ -2294,34 +2386,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
this->LocalGenerators.push_back(std::move(lgd));
}
- std::vector<cmDyndepObjectInfo> objects;
+ std::vector<cmSourceInfo> objects;
for (std::string const& arg_ddi : arg_ddis) {
- // Load the ddi file and compute the module file paths it provides.
- Json::Value ddio;
- Json::Value const& ddi = ddio;
- cmsys::ifstream ddif(arg_ddi.c_str(), std::ios::in | std::ios::binary);
- Json::Reader reader;
- if (!reader.parse(ddif, ddio, false)) {
- cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
- arg_ddi,
- reader.getFormattedErrorMessages()));
+ cmSourceInfo info;
+ if (!cmScanDepFormat_P1689_Parse(arg_ddi, &info)) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ddi file ", arg_ddi));
return false;
}
-
- cmDyndepObjectInfo info;
- info.Object = ddi["object"].asString();
- Json::Value const& ddi_provides = ddi["provides"];
- if (ddi_provides.isArray()) {
- for (auto const& ddi_provide : ddi_provides) {
- info.Provides.push_back(ddi_provide.asString());
- }
- }
- Json::Value const& ddi_requires = ddi["requires"];
- if (ddi_requires.isArray()) {
- for (auto const& ddi_require : ddi_requires) {
- info.Requires.push_back(ddi_require.asString());
- }
- }
objects.push_back(std::move(info));
}
@@ -2352,11 +2424,12 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
Json::Value tm = Json::objectValue;
- for (cmDyndepObjectInfo const& object : objects) {
- for (std::string const& p : object.Provides) {
- std::string const mod = cmStrCat(module_dir, p);
- mod_files[p] = mod;
- tm[p] = mod;
+ for (cmSourceInfo const& object : objects) {
+ for (auto const& p : object.Provides) {
+ std::string const mod = cmStrCat(
+ module_dir, cmSystemTools::GetFilenameName(p.CompiledModulePath));
+ mod_files[p.LogicalName] = mod;
+ tm[p.LogicalName] = mod;
}
}
@@ -2366,15 +2439,16 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
{
cmNinjaBuild build("dyndep");
build.Outputs.emplace_back("");
- for (cmDyndepObjectInfo const& object : objects) {
- build.Outputs[0] = object.Object;
+ for (cmSourceInfo const& object : objects) {
+ build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput);
build.ImplicitOuts.clear();
- for (std::string const& p : object.Provides) {
- build.ImplicitOuts.push_back(this->ConvertToNinjaPath(mod_files[p]));
+ for (auto const& p : object.Provides) {
+ build.ImplicitOuts.push_back(
+ this->ConvertToNinjaPath(mod_files[p.LogicalName]));
}
build.ImplicitDeps.clear();
- for (std::string const& r : object.Requires) {
- auto mit = mod_files.find(r);
+ for (auto const& r : object.Requires) {
+ auto mit = mod_files.find(r.LogicalName);
if (mit != mod_files.end()) {
build.ImplicitDeps.push_back(this->ConvertToNinjaPath(mit->second));
}
@@ -2384,6 +2458,48 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
build.Variables.emplace("restat", "1");
}
+ if (arg_modmapfmt.empty()) {
+ // nothing to do.
+ } else {
+ std::stringstream mm;
+ if (arg_modmapfmt == "gcc") {
+ // Documented in GCC's documentation. The format is a series of lines
+ // with a module name and the associated filename separated by
+ // spaces. The first line may use `$root` as the module name to
+ // specify a "repository root". That is used to anchor any relative
+ // paths present in the file (CMake should never generate any).
+
+ // Write the root directory to use for module paths.
+ mm << "$root .\n";
+
+ for (auto const& l : object.Provides) {
+ auto m = mod_files.find(l.LogicalName);
+ if (m != mod_files.end()) {
+ mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second)
+ << "\n";
+ }
+ }
+ for (auto const& r : object.Requires) {
+ auto m = mod_files.find(r.LogicalName);
+ if (m != mod_files.end()) {
+ mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second)
+ << "\n";
+ }
+ }
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep does not understand the ",
+ arg_modmapfmt, " module map format"));
+ return false;
+ }
+
+ // XXX(modmap): If changing this path construction, change
+ // `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
+ // corresponding file path.
+ cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap"));
+ mmf << mm.str();
+ }
+
this->WriteBuild(ddf, build);
}
}
@@ -2398,11 +2514,6 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
return true;
}
-bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
-{
- return !this->CrossConfigs.empty();
-}
-
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd)
{
@@ -2412,6 +2523,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::string arg_dd;
std::string arg_lang;
std::string arg_tdi;
+ std::string arg_modmapfmt;
std::vector<std::string> arg_ddis;
for (std::string const& arg : arg_full) {
if (cmHasLiteralPrefix(arg, "--tdi=")) {
@@ -2420,6 +2532,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
arg_lang = arg.substr(7);
} else if (cmHasLiteralPrefix(arg, "--dd=")) {
arg_dd = arg.substr(5);
+ } else if (cmHasLiteralPrefix(arg, "--modmapfmt=")) {
+ arg_modmapfmt = arg.substr(12);
} else if (!cmHasLiteralPrefix(arg, "--") &&
cmHasLiteralSuffix(arg, ".ddi")) {
arg_ddis.push_back(arg);
@@ -2478,12 +2592,19 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
if (!ggd ||
!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)) {
+ module_dir, linked_target_dirs, arg_lang, arg_modmapfmt)) {
return 1;
}
return 0;
}
+#endif
+
+bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
+{
+ return !this->CrossConfigs.empty();
+}
+
void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
const std::string& prefix, const std::string& config,
const std::string& suffix, std::string& dir)
@@ -2501,6 +2622,13 @@ std::set<std::string> cmGlobalNinjaGenerator::GetCrossConfigs(
return result;
}
+bool cmGlobalNinjaGenerator::IsSingleConfigUtility(
+ cmGeneratorTarget const* target) const
+{
+ return target->GetType() == cmStateEnums::UTILITY &&
+ !this->PerConfigUtilityTargets.count(target->GetName());
+}
+
const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE =
"CMakeFiles/common.ninja";
const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja";
@@ -2651,30 +2779,17 @@ void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
{
- this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_BUILD_TYPE");
- this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_CROSS_CONFIGS");
- this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_CONFIGS");
- return this->ReadCacheEntriesForBuild(*this->Makefiles.front()->GetState());
-}
-
-std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
-{
- return "";
-}
-
-bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
- const cmState& state)
-{
std::vector<std::string> configsVec;
- cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CONFIGURATION_TYPES"),
- configsVec);
+ cmExpandList(
+ this->Makefiles.front()->GetSafeDefinition("CMAKE_CONFIGURATION_TYPES"),
+ configsVec);
if (configsVec.empty()) {
configsVec.emplace_back();
}
std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
this->DefaultFileConfig =
- state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE");
+ this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_BUILD_TYPE");
if (this->DefaultFileConfig.empty()) {
this->DefaultFileConfig = configsVec.front();
}
@@ -2689,8 +2804,9 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
}
std::vector<std::string> crossConfigsVec;
- cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"),
- crossConfigsVec);
+ cmExpandList(
+ this->Makefiles.front()->GetSafeDefinition("CMAKE_CROSS_CONFIGS"),
+ crossConfigsVec);
auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
if (!crossConfigs) {
std::ostringstream msg;
@@ -2703,7 +2819,7 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
this->CrossConfigs = *crossConfigs;
auto defaultConfigsString =
- state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS");
+ this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_CONFIGS");
if (defaultConfigsString.empty()) {
defaultConfigsString = this->DefaultFileConfig;
}
@@ -2737,6 +2853,11 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
return true;
}
+std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
+{
+ return "";
+}
+
std::string cmGlobalNinjaMultiGenerator::OrderDependsTargetForTarget(
cmGeneratorTarget const* target, const std::string& config) const
{
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index b668773..fd8542f 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -24,6 +24,7 @@
#include "cmNinjaTypes.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
+#include "cmTransformDepfile.h"
class cmCustomCommand;
class cmGeneratorTarget;
@@ -31,7 +32,6 @@ class cmLinkLineComputer;
class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
-class cmState;
class cmStateDirectory;
class cmake;
struct cmDocumentationEntry;
@@ -150,7 +150,7 @@ public:
static void WriteDefault(std::ostream& os, const cmNinjaDeps& targets,
const std::string& comment = "");
- bool IsGCCOnWindows() const { return UsingGCCOnWindows; }
+ bool IsGCCOnWindows() const { return this->UsingGCCOnWindows; }
public:
cmGlobalNinjaGenerator(cmake* cm);
@@ -211,6 +211,10 @@ public:
const char* GetCleanTargetName() const override { return "clean"; }
bool SupportsCustomCommandDepfile() const override { return true; }
+ cm::optional<cmDepfileFormat> DepfileFormat() const override
+ {
+ return cmDepfileFormat::GccDepfile;
+ }
virtual cmGeneratedFileStream* GetImplFileStream(
const std::string& /*config*/) const
@@ -248,7 +252,7 @@ public:
: GG(gg)
{
}
- std::string operator()(std::string const& path)
+ std::string operator()(std::string const& path) const
{
return this->GG->ConvertToNinjaPath(path);
}
@@ -319,17 +323,21 @@ public:
void AppendTargetOutputs(cmGeneratorTarget const* target,
cmNinjaDeps& outputs, const std::string& config,
- cmNinjaTargetDepends depends);
+ cmNinjaTargetDepends depends) const;
void AppendTargetDepends(cmGeneratorTarget const* target,
cmNinjaDeps& outputs, const std::string& config,
const std::string& fileConfig,
cmNinjaTargetDepends depends);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
cmNinjaDeps& outputs,
- const std::string& config);
+ const std::string& config,
+ const std::string& fileConfig,
+ bool genexOutput);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
cmNinjaOuts& outputs,
- const std::string& config, bool omit_self);
+ const std::string& config,
+ const std::string& fileConfig,
+ bool genexOutput, bool omit_self);
void AppendDirectoryForConfig(const std::string& prefix,
const std::string& config,
@@ -346,7 +354,10 @@ public:
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
- int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
+ int GetRuleCmdLength(const std::string& name)
+ {
+ return this->RuleCmdLength[name];
+ }
void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
const std::string& config);
@@ -385,15 +396,13 @@ public:
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
- 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,
- std::string const& arg_dd,
- std::vector<std::string> const& arg_ddis,
- std::string const& module_dir,
- std::vector<std::string> const& linked_target_dirs,
- std::string const& arg_lang);
+ 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,
+ std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
+ std::string const& module_dir,
+ std::vector<std::string> const& linked_target_dirs,
+ std::string const& arg_lang, std::string const& arg_modmapfmt);
virtual std::string BuildAlias(const std::string& alias,
const std::string& /*config*/) const
@@ -425,6 +434,20 @@ public:
return this->DefaultConfigs;
}
+ const std::set<std::string>& GetPerConfigUtilityTargets() const
+ {
+ return this->PerConfigUtilityTargets;
+ }
+
+ void AddPerConfigUtilityTarget(const std::string& name)
+ {
+ this->PerConfigUtilityTargets.insert(name);
+ }
+
+ bool IsSingleConfigUtility(cmGeneratorTarget const* target) const;
+
+ bool CheckCxxModuleSupport();
+
protected:
void Generate() override;
@@ -462,7 +485,7 @@ private:
void CleanMetaData();
/// Write the common disclaimer text at the top of each build file.
- void WriteDisclaimer(std::ostream& os);
+ void WriteDisclaimer(std::ostream& os) const;
void WriteAssumedSourceDependencies();
@@ -518,6 +541,9 @@ private:
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
+ /// Utility targets which have per-config outputs
+ std::set<std::string> PerConfigUtilityTargets;
+
struct TargetAlias
{
cmGeneratorTarget* GeneratorTarget;
@@ -542,6 +568,8 @@ private:
bool NinjaSupportsMultipleOutputs = false;
bool NinjaSupportsMetadataOnRegeneration = false;
+ bool DiagnosedCxxModuleSupport = false;
+
private:
void InitOutputPathPrefix();
@@ -557,7 +585,14 @@ private:
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
- std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+ struct TargetDependsClosureKey
+ {
+ cmGeneratorTarget const* Target;
+ std::string Config;
+ bool GenexOutput;
+ };
+
+ std::map<TargetDependsClosureKey, cmNinjaOuts> TargetDependsClosures;
TargetAliasMap TargetAliases;
@@ -566,6 +601,19 @@ private:
std::map<std::string, ByConfig> Configs;
cmNinjaDeps ByproductsForCleanTarget;
+
+ friend bool operator==(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
+ friend bool operator!=(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
+ friend bool operator<(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
+ friend bool operator>(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
+ friend bool operator<=(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
+ friend bool operator>=(const ByConfig::TargetDependsClosureKey& lhs,
+ const ByConfig::TargetDependsClosureKey& rhs);
};
class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator
@@ -651,8 +699,6 @@ public:
std::string GetDefaultBuildConfig() const override;
- bool ReadCacheEntriesForBuild(const cmState& state) override;
-
bool SupportsDefaultBuildType() const override { return true; }
bool SupportsCrossConfigs() const override { return true; }
bool SupportsDefaultConfigs() const override { return true; }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 2c934e1..97384cd 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -44,6 +44,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
#endif
this->IncludeDirective = "include";
+ this->LineContinueDirective = "\\\n";
this->DefineWindowsNULL = false;
this->PassMakeflags = false;
this->UnixCD = true;
@@ -589,10 +590,16 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
}
makeCommand.Add(this->SelectMakeProgram(makeProgram));
+ // Explicitly tell the make tool to use the Makefile written by
+ // cmLocalUnixMakefileGenerator3::WriteLocalMakefile
+ makeCommand.Add("-f");
+ makeCommand.Add("Makefile");
+
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add("-j");
- if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add(std::to_string(jobs));
+ if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
+ makeCommand.Add("-j");
+ } else {
+ makeCommand.Add("-j" + std::to_string(jobs));
}
}
@@ -831,7 +838,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
for (const auto& gt : lg->GetGeneratorTargets()) {
cmLocalGenerator* tlg = gt->GetLocalGenerator();
- if (!gt->IsInBuildSystem() || IsExcluded(lg.get(), gt.get())) {
+ if (!gt->IsInBuildSystem() || this->IsExcluded(lg.get(), gt.get())) {
continue;
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 77d0827..c15f491 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -93,6 +93,12 @@ public:
*/
static bool SupportsPlatform() { return false; }
+ /**
+ * Utilized to determine if this generator
+ * supports DEPFILE option.
+ */
+ bool SupportsCustomCommandDepfile() const override { return true; }
+
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
@@ -127,6 +133,18 @@ public:
void WriteConvenienceRules(std::ostream& ruleFileStream,
std::set<std::string>& emitted);
+ // Make tool supports dependency files generated by compiler
+ bool SupportsCompilerDependencies()
+ {
+ return this->ToolSupportsCompilerDependencies;
+ }
+
+ // Make tool supports long line dependencies
+ bool SupportsLongLineDependencies()
+ {
+ return this->ToolSupportsLongLineDependencies;
+ }
+
/** Get the command to use for a target that has no rule. This is
used for multiple output dependencies and for cmake_force. */
std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
@@ -170,6 +188,7 @@ public:
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
std::string IncludeDirective;
+ std::string LineContinueDirective;
bool DefineWindowsNULL;
bool PassMakeflags;
bool UnixCD;
@@ -218,6 +237,14 @@ protected:
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
+ // Specify if the make tool is able to consume dependency files
+ // generated by the compiler
+ bool ToolSupportsCompilerDependencies = true;
+
+ // some Make generator, such as Borland not support long line dependencies,
+ // we add SupportsLongLineDependencies to predicate.
+ bool ToolSupportsLongLineDependencies = true;
+
// Some make programs (Borland) do not keep a rule if there are no
// dependencies or commands. This is a problem for creating rules
// that might not do anything but might have other dependencies
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 6267205..75cd714 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -380,9 +380,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::string project = target->GetName();
std::string location = *expath;
- cmProp p = target->GetProperty("VS_PROJECT_TYPE");
- this->WriteExternalProject(fout, project, location, cmToCStr(p),
- target->GetUtilities());
+ this->WriteExternalProject(
+ fout, project, location,
+ cmToCStr(target->GetProperty("VS_PROJECT_TYPE")),
+ target->GetUtilities());
written = true;
} else {
cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index d6a7afa..3e2d92d 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -25,6 +25,7 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
#endif
cm->GetState()->SetWatcomWMake(true);
this->IncludeDirective = "!include";
+ this->LineContinueDirective = "&\n";
this->DefineWindowsNULL = true;
this->UnixCD = false;
this->MakeSilentFlag = "-h";
@@ -37,7 +38,6 @@ void cmGlobalWatcomWMakeGenerator::EnableLanguage(
mf->AddDefinition("WATCOM", "1");
mf->AddDefinition("CMAKE_QUOTE_INCLUDE_PATHS", "1");
mf->AddDefinition("CMAKE_MANGLE_OBJECT_FILE_NAMES", "1");
- mf->AddDefinition("CMAKE_MAKE_LINE_CONTINUE", "&");
mf->AddDefinition("CMAKE_MAKE_SYMBOLIC_RULE", ".SYMBOLIC");
mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl386");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl386");
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index df45b35..8a1ccd1 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -504,16 +504,15 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
}
}
- if (this->XcodeBuildSystem >= BuildSystem::Twelve) {
+ if ((this->XcodeBuildSystem >= BuildSystem::Twelve) ||
+ (jobs != cmake::NO_BUILD_PARALLEL_LEVEL)) {
makeCommand.Add("-parallelizeTargets");
}
makeCommand.Add("-configuration", (config.empty() ? "Debug" : config));
- if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add("-jobs");
- if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add(std::to_string(jobs));
- }
+ if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
+ (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
+ makeCommand.Add("-jobs", std::to_string(jobs));
}
if (this->XcodeVersion >= 70) {
@@ -775,7 +774,9 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
this->TargetGroup.clear();
this->FileRefs.clear();
this->ExternalLibRefs.clear();
+ this->EmbeddedLibRefs.clear();
this->FileRefToBuildFileMap.clear();
+ this->FileRefToEmbedBuildFileMap.clear();
this->CommandsVisited.clear();
}
@@ -941,6 +942,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
default:
break;
}
+
+ // Explicitly add the explicit language flag before any other flag
+ // so user flags can override it.
+ gtgt->AddExplicitLanguageFlags(flags, *sf);
+
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
@@ -1202,7 +1208,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
}
}
// Make a copy so that we can override it later
- std::string path = fullpath;
+ std::string path = cmSystemTools::CollapseFullPath(fullpath);
// Compute the extension without leading '.'.
std::string ext = cmSystemTools::GetFilenameLastExtension(path);
if (!ext.empty()) {
@@ -1382,7 +1388,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
// organize the sources
std::vector<cmSourceFile*> commonSourceFiles;
- if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(commonSourceFiles)) {
return false;
}
@@ -1647,6 +1653,14 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
}
}
+ // Allow empty source file list for iOS Sticker packs
+ if (const char* productType = GetTargetProductType(gtgt)) {
+ if (strcmp(productType,
+ "com.apple.product-type.app-extension.messages-sticker-pack") ==
+ 0)
+ return;
+ }
+
// Add an empty source file to the target that compiles with the
// linker language. This should convince Xcode to choose the proper
// language.
@@ -1738,7 +1752,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
gtgt, postbuild);
} else {
std::vector<cmSourceFile*> classes;
- if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(classes)) {
return;
}
// add all the sources
@@ -1798,6 +1812,10 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
if (frameworkBuildPhase) {
buildPhases->AddObject(frameworkBuildPhase);
}
+
+ // When this build phase is present, it must be last. More build phases may
+ // be added later for embedding things and they will insert themselves just
+ // before this last build phase.
if (postBuildPhase) {
buildPhases->AddObject(postBuildPhase);
}
@@ -1807,7 +1825,7 @@ void cmGlobalXCodeGenerator::CreateRunScriptBuildPhases(
cmXCodeObject* buildPhases, cmGeneratorTarget const* gt)
{
std::vector<cmSourceFile*> sources;
- if (!gt->GetConfigCommonSourceFiles(sources)) {
+ if (!gt->GetConfigCommonSourceFilesForXcode(sources)) {
return;
}
auto& visited = this->CommandsVisited[gt];
@@ -2953,7 +2971,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
std::vector<cmSourceFile*> sources;
- if (!gtgt->GetConfigCommonSourceFiles(sources)) {
+ if (!gtgt->GetConfigCommonSourceFilesForXcode(sources)) {
return nullptr;
}
@@ -3228,36 +3246,43 @@ void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
if (!attr) {
settings->AddAttribute(attribute, value);
} else {
- if (value->GetType() != cmXCodeObject::OBJECT_LIST &&
- value->GetType() != cmXCodeObject::STRING) {
- cmSystemTools::Error("Unsupported value type for appending: " +
- std::string(attribute));
- return;
- }
- if (attr->GetType() == cmXCodeObject::OBJECT_LIST) {
- if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
- for (auto* obj : value->GetObjectList()) {
- attr->AddObject(obj);
- }
- } else {
- attr->AddObject(value);
- }
- } else if (attr->GetType() == cmXCodeObject::STRING) {
- if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
- // Add old value as a list item to new object list
- // and replace the attribute with the new list
- value->PrependObject(attr);
- settings->AddAttribute(attribute, value);
- } else {
- std::string newValue =
- cmStrCat(attr->GetString(), ' ', value->GetString());
- attr->SetString(newValue);
- }
- } else {
- cmSystemTools::Error("Unsupported attribute type for appending: " +
- std::string(attribute));
+ this->AppendBuildSettingAttribute(settings, attribute, attr, value);
+ }
+ }
+}
+
+void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
+ cmXCodeObject* settings, const char* attribute, cmXCodeObject* attr,
+ cmXCodeObject* value)
+{
+ if (value->GetType() != cmXCodeObject::OBJECT_LIST &&
+ value->GetType() != cmXCodeObject::STRING) {
+ cmSystemTools::Error("Unsupported value type for appending: " +
+ std::string(attribute));
+ return;
+ }
+ if (attr->GetType() == cmXCodeObject::OBJECT_LIST) {
+ if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
+ for (auto* obj : value->GetObjectList()) {
+ attr->AddObject(obj);
}
+ } else {
+ attr->AddObject(value);
+ }
+ } else if (attr->GetType() == cmXCodeObject::STRING) {
+ if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
+ // Add old value as a list item to new object list
+ // and replace the attribute with the new list
+ value->PrependObject(attr);
+ settings->AddAttribute(attribute, value);
+ } else {
+ std::string newValue =
+ cmStrCat(attr->GetString(), ' ', value->GetString());
+ attr->SetString(newValue);
}
+ } else {
+ cmSystemTools::Error("Unsupported attribute type for appending: " +
+ std::string(attribute));
}
}
@@ -3280,6 +3305,24 @@ void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
}
}
+void cmGlobalXCodeGenerator::InheritBuildSettingAttribute(
+ cmXCodeObject* target, const char* attribute)
+{
+ cmXCodeObject* configurationList =
+ target->GetAttribute("buildConfigurationList")->GetObject();
+ cmXCodeObject* buildConfigs =
+ configurationList->GetAttribute("buildConfigurations");
+ for (auto obj : buildConfigs->GetObjectList()) {
+ cmXCodeObject* settings = obj->GetAttribute("buildSettings");
+ if (cmXCodeObject* attr = settings->GetAttribute(attribute)) {
+ BuildObjectListOrString inherited(this, true);
+ inherited.Add("$(inherited)");
+ this->AppendBuildSettingAttribute(settings, attribute, attr,
+ inherited.CreateList());
+ }
+ }
+}
+
void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
{
cmGeneratorTarget* gt = target->GetTarget();
@@ -3596,11 +3639,11 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
for (auto& libDir : linkSearchPaths) {
libSearchPaths.Add(this->XCodeEscapePath(libDir));
}
- // Add paths defined in project-wide build settings
- libSearchPaths.Add("$(inherited)");
- this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
- libSearchPaths.CreateList(),
- configName);
+ if (!libSearchPaths.IsEmpty()) {
+ this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
+ libSearchPaths.CreateList(),
+ configName);
+ }
}
// add framework search paths
@@ -3611,11 +3654,11 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
for (auto& fwDir : frameworkSearchPaths) {
fwSearchPaths.Add(this->XCodeEscapePath(fwDir));
}
- // Add paths defined in project-wide build settings
- fwSearchPaths.Add("$(inherited)");
- this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
- fwSearchPaths.CreateList(),
- configName);
+ if (!fwSearchPaths.IsEmpty()) {
+ this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
+ fwSearchPaths.CreateList(),
+ configName);
+ }
}
// now add the left-over link libraries
@@ -3666,6 +3709,130 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
}
}
+void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target)
+{
+ cmGeneratorTarget* gt = target->GetTarget();
+ if (!gt) {
+ cmSystemTools::Error("Error no target on xobject\n");
+ return;
+ }
+ if (!gt->IsInBuildSystem()) {
+ return;
+ }
+ bool isFrameworkTarget = gt->IsFrameworkOnApple();
+ bool isBundleTarget = gt->GetPropertyAsBool("MACOSX_BUNDLE");
+ bool isCFBundleTarget = gt->IsCFBundleOnApple();
+ if (!(isFrameworkTarget || isBundleTarget || isCFBundleTarget)) {
+ return;
+ }
+ cmProp files = gt->GetProperty("XCODE_EMBED_FRAMEWORKS");
+ if (!files) {
+ return;
+ }
+
+ // Create an "Embedded Frameworks" build phase
+ auto* copyFilesBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
+ std::string copyFilesBuildPhaseName = "Embed Frameworks";
+ std::string destinationFrameworks = "10";
+ copyFilesBuildPhase->SetComment(copyFilesBuildPhaseName);
+ copyFilesBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
+ this->CreateString(destinationFrameworks));
+ copyFilesBuildPhase->AddAttribute(
+ "name", this->CreateString(copyFilesBuildPhaseName));
+ if (cmProp fwEmbedPath = gt->GetProperty("XCODE_EMBED_FRAMEWORKS_PATH")) {
+ copyFilesBuildPhase->AddAttribute("dstPath",
+ this->CreateString(*fwEmbedPath));
+ } else {
+ copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString(""));
+ }
+ copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ // Collect all embedded frameworks and add them to build phase
+ std::vector<std::string> relFiles = cmExpandedList(*files);
+ for (std::string const& relFile : relFiles) {
+ cmXCodeObject* buildFile{ nullptr };
+ std::string filePath = relFile;
+ auto* genTarget = FindGeneratorTarget(relFile);
+ if (genTarget) {
+ // This is a target - get it's product path reference
+ auto* xcTarget = FindXCodeTarget(genTarget);
+ if (!xcTarget) {
+ cmSystemTools::Error("Can not find a target for " +
+ genTarget->GetName());
+ continue;
+ }
+ // Add the target output file as a build reference for other targets
+ // to link against
+ auto* fileRefObject = xcTarget->GetAttribute("productReference");
+ if (!fileRefObject) {
+ cmSystemTools::Error("Target " + genTarget->GetName() +
+ " is missing product reference");
+ continue;
+ }
+ auto it = FileRefToEmbedBuildFileMap.find(fileRefObject);
+ if (it == FileRefToEmbedBuildFileMap.end()) {
+ buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildFile->AddAttribute("fileRef", fileRefObject);
+ FileRefToEmbedBuildFileMap[fileRefObject] = buildFile;
+ } else {
+ buildFile = it->second;
+ }
+ } else if (cmSystemTools::IsPathToFramework(relFile)) {
+ // This is a regular string path - create file reference
+ auto it = EmbeddedLibRefs.find(relFile);
+ if (it == EmbeddedLibRefs.end()) {
+ cmXCodeObject* fileRef =
+ this->CreateXCodeFileReferenceFromPath(relFile, gt, "", nullptr);
+ if (fileRef) {
+ buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildFile->SetComment(fileRef->GetComment());
+ buildFile->AddAttribute("fileRef",
+ this->CreateObjectReference(fileRef));
+ }
+ if (!buildFile) {
+ cmSystemTools::Error("Can't create build file for " + relFile);
+ continue;
+ }
+ this->EmbeddedLibRefs.emplace(filePath, buildFile);
+ } else {
+ buildFile = it->second;
+ }
+ }
+ if (!buildFile) {
+ cmSystemTools::Error("Can't find a build file for " + relFile);
+ continue;
+ }
+ // Set build file configuration
+ cmXCodeObject* settings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ const auto& rmHeadersProp =
+ gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY");
+ if (cmIsOn(rmHeadersProp)) {
+ attrs->AddObject(this->CreateString("RemoveHeadersOnCopy"));
+ }
+ const auto& codeSignProp =
+ gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY");
+ if (cmIsOn(codeSignProp)) {
+ attrs->AddObject(this->CreateString("CodeSignOnCopy"));
+ }
+ settings->AddAttributeIfNotEmpty("ATTRIBUTES", attrs);
+ buildFile->AddAttributeIfNotEmpty("settings", settings);
+ if (!buildFiles->HasObject(buildFile)) {
+ buildFiles->AddObject(buildFile);
+ }
+ }
+ copyFilesBuildPhase->AddAttribute("files", buildFiles);
+ auto* buildPhases = target->GetAttribute("buildPhases");
+ // Insert embed build phase right before the post-build command
+ buildPhases->InsertObject(buildPhases->GetObjectCount() - 1,
+ copyFilesBuildPhase);
+}
+
bool cmGlobalXCodeGenerator::CreateGroups(
std::vector<cmLocalGenerator*>& generators)
{
@@ -4044,7 +4211,16 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
// loop over all targets and add link and depend info
for (auto t : targets) {
this->AddDependAndLinkInformation(t);
+ this->AddEmbeddedFrameworks(t);
+ // Inherit project-wide values for any target-specific search paths.
+ this->InheritBuildSettingAttribute(t, "HEADER_SEARCH_PATHS");
+ this->InheritBuildSettingAttribute(t, "SYSTEM_HEADER_SEARCH_PATHS");
+ this->InheritBuildSettingAttribute(t, "FRAMEWORK_SEARCH_PATHS");
+ this->InheritBuildSettingAttribute(t, "SYSTEM_FRAMEWORK_SEARCH_PATHS");
+ this->InheritBuildSettingAttribute(t, "LIBRARY_SEARCH_PATHS");
+ this->InheritBuildSettingAttribute(t, "LD_RUNPATH_SEARCH_PATHS");
}
+
if (this->XcodeBuildSystem == BuildSystem::One) {
this->CreateXCodeDependHackMakefile(targets);
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 8ff6846..1ab56e2 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -186,11 +186,17 @@ private:
cmGeneratorTarget* gtgt);
void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr,
cmXCodeObject* value);
+ void AppendBuildSettingAttribute(cmXCodeObject* settings,
+ const char* attribute, cmXCodeObject* attr,
+ cmXCodeObject* value);
void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr,
cmXCodeObject* value,
const std::string& configName);
+ void InheritBuildSettingAttribute(cmXCodeObject* target,
+ const char* attribute);
cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt);
void AddDependAndLinkInformation(cmXCodeObject* target);
+ void AddEmbeddedFrameworks(cmXCodeObject* target);
void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
cmXCodeObject* buildSettings,
const std::string& configName);
@@ -329,8 +335,10 @@ private:
std::map<std::string, cmXCodeObject*> TargetGroup;
std::map<std::string, cmXCodeObject*> FileRefs;
std::map<std::string, cmXCodeObject*> ExternalLibRefs;
+ std::map<std::string, cmXCodeObject*> EmbeddedLibRefs;
std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
+ std::map<cmXCodeObject*, cmXCodeObject*> FileRefToEmbedBuildFileMap;
std::vector<std::string> Architectures;
std::string ObjectDirArchDefault;
std::string ObjectDirArch;
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index cf4ba93..92ffe29 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -131,8 +131,8 @@ cmGraphVizWriter::~cmGraphVizWriter()
void cmGraphVizWriter::VisitGraph(std::string const&)
{
- this->WriteHeader(GlobalFileStream, this->GraphName);
- this->WriteLegend(GlobalFileStream);
+ this->WriteHeader(this->GlobalFileStream, this->GraphName);
+ this->WriteLegend(this->GlobalFileStream);
}
void cmGraphVizWriter::OnItem(cmLinkItem const& item)
@@ -141,8 +141,9 @@ void cmGraphVizWriter::OnItem(cmLinkItem const& item)
return;
}
- NodeNames[item.AsStr()] = cmStrCat(GraphNodePrefix, NextNodeId);
- ++NextNodeId;
+ this->NodeNames[item.AsStr()] =
+ cmStrCat(this->GraphNodePrefix, this->NextNodeId);
+ ++this->NextNodeId;
this->WriteNode(this->GlobalFileStream, item);
}
@@ -191,12 +192,13 @@ void cmGraphVizWriter::VisitLink(cmLinkItem const& depender,
this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
if (this->GeneratePerTarget) {
- PerTargetConnections[depender].emplace_back(depender, dependee, scopeType);
+ this->PerTargetConnections[depender].emplace_back(depender, dependee,
+ scopeType);
}
if (this->GenerateDependers) {
- TargetDependersConnections[dependee].emplace_back(dependee, depender,
- scopeType);
+ this->TargetDependersConnections[dependee].emplace_back(dependee, depender,
+ scopeType);
}
}
@@ -307,12 +309,12 @@ void cmGraphVizWriter::Write()
}
if (this->GeneratePerTarget) {
- WritePerTargetConnections<DependeesDir>(PerTargetConnections);
+ this->WritePerTargetConnections<DependeesDir>(this->PerTargetConnections);
}
if (this->GenerateDependers) {
- WritePerTargetConnections<DependersDir>(TargetDependersConnections,
- ".dependers");
+ this->WritePerTargetConnections<DependersDir>(
+ this->TargetDependersConnections, ".dependers");
}
}
@@ -336,7 +338,8 @@ void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
bool const visited = visitedItems.find(dstItem) != visitedItems.cend();
if (!visited) {
visitedItems.insert(dstItem);
- FindAllConnections(connectionMap, dstItem, extendedCons, visitedItems);
+ this->FindAllConnections(connectionMap, dstItem, extendedCons,
+ visitedItems);
}
}
}
@@ -346,7 +349,8 @@ void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
Connections& extendedCons)
{
std::set<cmLinkItem> visitedItems = { rootItem };
- FindAllConnections(connectionMap, rootItem, extendedCons, visitedItems);
+ this->FindAllConnections(connectionMap, rootItem, extendedCons,
+ visitedItems);
}
template <typename DirFunc>
@@ -358,7 +362,7 @@ void cmGraphVizWriter::WritePerTargetConnections(
for (auto const& conPerTarget : connections) {
const cmLinkItem& rootItem = conPerTarget.first;
Connections& extendedCons = extendedConnections[conPerTarget.first];
- FindAllConnections(connections, rootItem, extendedCons);
+ this->FindAllConnections(connections, rootItem, extendedCons);
}
for (auto const& conPerTarget : extendedConnections) {
@@ -451,7 +455,7 @@ void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
auto const& itemName = item.AsStr();
auto const& nodeName = this->NodeNames[itemName];
- auto const itemNameWithAliases = ItemNameWithAliases(itemName);
+ auto const itemNameWithAliases = this->ItemNameWithAliases(itemName);
auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index ae801bb..ce1f030 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -21,6 +21,7 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
static std::map<std::string, cmPolicies::PolicyID> DeprecatedModules;
if (DeprecatedModules.empty()) {
DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
+ DeprecatedModules["WriteCompilerDetectionHeader"] = cmPolicies::CMP0120;
}
if (args.empty() || args.size() > 4) {
@@ -146,11 +147,24 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
std::string listFile = cmSystemTools::CollapseFullPath(
fname, status.GetMakefile().GetCurrentSourceDirectory());
- if (optional && !cmSystemTools::FileExists(listFile)) {
+
+ const bool fileDoesnotExist = !cmSystemTools::FileExists(listFile);
+ const bool fileIsDirectory = cmSystemTools::FileIsDirectory(listFile);
+ if (fileDoesnotExist || fileIsDirectory) {
if (!resultVarName.empty()) {
status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND");
}
- return true;
+ if (optional) {
+ return true;
+ }
+ if (fileDoesnotExist) {
+ status.SetError(cmStrCat("could not find requested file:\n ", fname));
+ return false;
+ }
+ if (fileIsDirectory) {
+ status.SetError(cmStrCat("requested file is a directory:\n ", fname));
+ return false;
+ }
}
bool readit =
@@ -163,9 +177,7 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
}
if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) {
- std::string m = cmStrCat("could not find load file:\n"
- " ",
- fname);
+ std::string m = cmStrCat("could not load requested file:\n ", fname);
status.SetError(m);
return false;
}
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 175e7cf..0b45f28 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -27,7 +27,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
, Optional(optional)
{
// We need per-config actions if destination have generator expressions.
- if (cmGeneratorExpression::Find(Destination) != std::string::npos) {
+ if (cmGeneratorExpression::Find(this->Destination) != std::string::npos) {
this->ActionsPerConfig = true;
}
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 6e3508c..3683ada 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -122,10 +122,10 @@ size_t cmInstallExportGenerator::GetMaxConfigLength() const
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
{
// Skip empty sets.
- if (ExportSet->GetTargetExports().empty()) {
+ if (this->ExportSet->GetTargetExports().empty()) {
std::ostringstream e;
- e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName()
- << "\"";
+ e << "INSTALL(EXPORT) given unknown export \""
+ << this->ExportSet->GetName() << "\"";
cmSystemTools::Error(e.str());
return;
}
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index ad2f84e..c45000d 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -26,7 +26,7 @@ cmInstallFilesGenerator::cmInstallFilesGenerator(
, Optional(optional)
{
// We need per-config actions if the destination has generator expressions.
- if (cmGeneratorExpression::Find(Destination) != std::string::npos) {
+ if (cmGeneratorExpression::Find(this->Destination) != std::string::npos) {
this->ActionsPerConfig = true;
}
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index 7cdf3b4..ce2472d 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -22,7 +22,7 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(
, AllowGenex(false)
{
// We need per-config actions if the script has generator expressions.
- if (cmGeneratorExpression::Find(Script) != std::string::npos) {
+ if (cmGeneratorExpression::Find(this->Script) != std::string::npos) {
this->ActionsPerConfig = true;
}
}
diff --git a/Source/cmJsonObjectDictionary.h b/Source/cmJsonObjectDictionary.h
deleted file mode 100644
index 8a2b529..0000000
--- a/Source/cmJsonObjectDictionary.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kARTIFACTS_KEY = "artifacts";
-static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
-static const std::string kCOMPILE_FLAGS_KEY = "compileFlags";
-static const std::string kCONFIGURATIONS_KEY = "configurations";
-static const std::string kDEFINES_KEY = "defines";
-static const std::string kFILE_GROUPS_KEY = "fileGroups";
-static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath";
-static const std::string kFULL_NAME_KEY = "fullName";
-static const std::string kINCLUDE_PATH_KEY = "includePath";
-static const std::string kIS_CMAKE_KEY = "isCMake";
-static const std::string kIS_GENERATED_KEY = "isGenerated";
-static const std::string kIS_SYSTEM_KEY = "isSystem";
-static const std::string kIS_TEMPORARY_KEY = "isTemporary";
-static const std::string kKEY_KEY = "key";
-static const std::string kLANGUAGE_KEY = "language";
-static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage";
-static const std::string kLINK_FLAGS_KEY = "linkFlags";
-static const std::string kLINK_LANGUAGE_FLAGS_KEY = "linkLanguageFlags";
-static const std::string kLINK_LIBRARIES_KEY = "linkLibraries";
-static const std::string kLINK_PATH_KEY = "linkPath";
-static const std::string kNAME_KEY = "name";
-static const std::string kPATH_KEY = "path";
-static const std::string kPROJECTS_KEY = "projects";
-static const std::string kPROPERTIES_KEY = "properties";
-static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
-static const std::string kSOURCES_KEY = "sources";
-static const std::string kSYSROOT_KEY = "sysroot";
-static const std::string kTARGETS_KEY = "targets";
-static const std::string kTYPE_KEY = "type";
-static const std::string kVALUE_KEY = "value";
-static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
-static const std::string kINSTALL_PATHS = "installPaths";
-static const std::string kCTEST_NAME = "ctestName";
-static const std::string kCTEST_COMMAND = "ctestCommand";
-static const std::string kCTEST_INFO = "ctestInfo";
-static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion";
-static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided";
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
deleted file mode 100644
index 3a7ae0c..0000000
--- a/Source/cmJsonObjects.cxx
+++ /dev/null
@@ -1,692 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmJsonObjects.h" // IWYU pragma: keep
-
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <functional>
-#include <limits>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <cmext/algorithm>
-
-#include "cmGeneratorExpression.h"
-#include "cmGeneratorTarget.h"
-#include "cmGlobalGenerator.h"
-#include "cmInstallGenerator.h"
-#include "cmInstallSubdirectoryGenerator.h"
-#include "cmInstallTargetGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmLinkLineComputer.h"
-#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
-#include "cmProperty.h"
-#include "cmPropertyMap.h"
-#include "cmSourceFile.h"
-#include "cmState.h"
-#include "cmStateDirectory.h"
-#include "cmStateSnapshot.h"
-#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmTarget.h"
-#include "cmTest.h"
-#include "cmake.h"
-
-namespace {
-
-std::vector<std::string> getConfigurations(const cmake* cm)
-{
- std::vector<std::string> configurations;
- const auto& makefiles = cm->GetGlobalGenerator()->GetMakefiles();
- if (makefiles.empty()) {
- return configurations;
- }
-
- return makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-}
-
-bool hasString(const Json::Value& v, const std::string& s)
-{
- return !v.isNull() &&
- std::any_of(v.begin(), v.end(),
- [s](const Json::Value& i) { return i.asString() == s; });
-}
-
-template <class T>
-Json::Value fromStringList(const T& in)
-{
- Json::Value result = Json::arrayValue;
- for (std::string const& i : in) {
- result.append(i);
- }
- return result;
-}
-
-} // namespace
-
-void cmGetCMakeInputs(const cmGlobalGenerator* gg,
- const std::string& sourceDir,
- const std::string& buildDir,
- std::vector<std::string>* internalFiles,
- std::vector<std::string>* explicitFiles,
- std::vector<std::string>* tmpFiles)
-{
- const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
- auto const& makefiles = gg->GetMakefiles();
- for (const auto& mf : makefiles) {
- for (std::string const& lf : mf->GetListFiles()) {
-
- const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
- const bool isInternal = (startOfFile == cmakeRootDir);
- const bool isTemporary =
- !isInternal && (cmHasPrefix(lf, buildDir + '/'));
-
- std::string toAdd = lf;
- if (!sourceDir.empty()) {
- const std::string& relative =
- cmSystemTools::RelativePath(sourceDir, lf);
- if (toAdd.size() > relative.size()) {
- toAdd = relative;
- }
- }
-
- if (isInternal) {
- if (internalFiles) {
- internalFiles->push_back(std::move(toAdd));
- }
- } else {
- if (isTemporary) {
- if (tmpFiles) {
- tmpFiles->push_back(std::move(toAdd));
- }
- } else {
- if (explicitFiles) {
- explicitFiles->push_back(std::move(toAdd));
- }
- }
- }
- }
- }
-}
-
-Json::Value cmDumpCMakeInputs(const cmake* cm)
-{
- const cmGlobalGenerator* gg = cm->GetGlobalGenerator();
- const std::string& buildDir = cm->GetHomeOutputDirectory();
- const std::string& sourceDir = cm->GetHomeDirectory();
-
- std::vector<std::string> internalFiles;
- std::vector<std::string> explicitFiles;
- std::vector<std::string> tmpFiles;
- cmGetCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles,
- &tmpFiles);
-
- Json::Value array = Json::arrayValue;
-
- Json::Value tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = true;
- tmp[kIS_TEMPORARY_KEY] = false;
- tmp[kSOURCES_KEY] = fromStringList(internalFiles);
- array.append(tmp);
-
- tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = false;
- tmp[kIS_TEMPORARY_KEY] = false;
- tmp[kSOURCES_KEY] = fromStringList(explicitFiles);
- array.append(tmp);
-
- tmp = Json::objectValue;
- tmp[kIS_CMAKE_KEY] = false;
- tmp[kIS_TEMPORARY_KEY] = true;
- tmp[kSOURCES_KEY] = fromStringList(tmpFiles);
- array.append(tmp);
-
- return array;
-}
-
-class LanguageData
-{
-public:
- bool operator==(const LanguageData& other) const;
-
- void SetDefines(const std::set<std::string>& defines);
-
- bool IsGenerated = false;
- std::string Language;
- std::string Flags;
- std::vector<std::string> Defines;
- std::vector<std::pair<std::string, bool>> IncludePathList;
-};
-
-bool LanguageData::operator==(const LanguageData& other) const
-{
- return Language == other.Language && Defines == other.Defines &&
- Flags == other.Flags && IncludePathList == other.IncludePathList &&
- IsGenerated == other.IsGenerated;
-}
-
-void LanguageData::SetDefines(const std::set<std::string>& defines)
-{
- std::vector<std::string> result;
- result.reserve(defines.size());
- for (std::string const& i : defines) {
- result.push_back(i);
- }
- std::sort(result.begin(), result.end());
- Defines = std::move(result);
-}
-
-namespace std {
-
-template <>
-struct hash<LanguageData>
-{
- std::size_t operator()(const LanguageData& in) const
- {
- using std::hash;
- size_t result =
- hash<std::string>()(in.Language) ^ hash<std::string>()(in.Flags);
- for (auto const& i : in.IncludePathList) {
- result = result ^
- (hash<std::string>()(i.first) ^
- (i.second ? std::numeric_limits<size_t>::max() : 0));
- }
- for (auto const& i : in.Defines) {
- result = result ^ hash<std::string>()(i);
- }
- result =
- result ^ (in.IsGenerated ? std::numeric_limits<size_t>::max() : 0);
- return result;
- }
-};
-
-} // namespace std
-
-static Json::Value DumpSourceFileGroup(const LanguageData& data,
- const std::vector<std::string>& files,
- const std::string& baseDir)
-{
- Json::Value result = Json::objectValue;
-
- if (!data.Language.empty()) {
- result[kLANGUAGE_KEY] = data.Language;
- if (!data.Flags.empty()) {
- result[kCOMPILE_FLAGS_KEY] = data.Flags;
- }
- if (!data.IncludePathList.empty()) {
- Json::Value includes = Json::arrayValue;
- for (auto const& i : data.IncludePathList) {
- Json::Value tmp = Json::objectValue;
- tmp[kPATH_KEY] = i.first;
- if (i.second) {
- tmp[kIS_SYSTEM_KEY] = i.second;
- }
- includes.append(tmp);
- }
- result[kINCLUDE_PATH_KEY] = includes;
- }
- if (!data.Defines.empty()) {
- result[kDEFINES_KEY] = fromStringList(data.Defines);
- }
- }
-
- result[kIS_GENERATED_KEY] = data.IsGenerated;
-
- Json::Value sourcesValue = Json::arrayValue;
- for (auto const& i : files) {
- const std::string relPath = cmSystemTools::RelativePath(baseDir, i);
- sourcesValue.append(relPath.size() < i.size() ? relPath : i);
- }
-
- result[kSOURCES_KEY] = sourcesValue;
- return result;
-}
-
-static Json::Value DumpSourceFilesList(
- cmGeneratorTarget* target, const std::string& config,
- const std::map<std::string, LanguageData>& languageDataMap)
-{
- // Collect sourcefile groups:
-
- std::vector<cmSourceFile*> files;
- target->GetSourceFiles(files, config);
-
- std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
- for (cmSourceFile* file : files) {
- LanguageData fileData;
- fileData.Language = file->GetOrDetermineLanguage();
- if (!fileData.Language.empty()) {
- const LanguageData& ld = languageDataMap.at(fileData.Language);
- cmLocalGenerator* lg = target->GetLocalGenerator();
- cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
- fileData.Language);
-
- std::string compileFlags = ld.Flags;
- const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(compileFlags,
- genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
- }
- const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
- lg->AppendCompileOptions(
- compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
- }
- fileData.Flags = compileFlags;
-
- // Add include directories from source file properties.
- std::vector<std::string> includes;
-
- const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
- const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
- lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
-
- for (const auto& include : includes) {
- fileData.IncludePathList.emplace_back(
- include,
- target->IsSystemIncludeDirectory(include, config,
- fileData.Language));
- }
- }
-
- fileData.IncludePathList.insert(fileData.IncludePathList.end(),
- ld.IncludePathList.begin(),
- ld.IncludePathList.end());
-
- const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- std::set<std::string> defines;
- if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
- lg->AppendDefines(
- defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
- }
-
- const std::string defPropName =
- "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- if (cmProp config_defs = file->GetProperty(defPropName)) {
- lg->AppendDefines(
- defines,
- genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
- }
-
- defines.insert(ld.Defines.begin(), ld.Defines.end());
-
- fileData.SetDefines(defines);
- }
-
- fileData.IsGenerated = file->GetIsGenerated();
- std::vector<std::string>& groupFileList = fileGroups[fileData];
- groupFileList.push_back(file->ResolveFullPath());
- }
-
- const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory();
- Json::Value result = Json::arrayValue;
- for (auto const& it : fileGroups) {
- Json::Value group = DumpSourceFileGroup(it.first, it.second, baseDir);
- if (!group.isNull()) {
- result.append(group);
- }
- }
-
- return result;
-}
-
-static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kCTEST_NAME] = testInfo->GetName();
-
- // Concat command entries together. After the first should be the arguments
- // for the command
- std::string command;
- for (auto const& cmd : testInfo->GetCommand()) {
- command.append(cmd);
- command.append(" ");
- }
-
- // Remove any config specific variables from the output.
- result[kCTEST_COMMAND] =
- cmGeneratorExpression::Evaluate(command, lg, config);
-
- // Build up the list of properties that may have been specified
- Json::Value properties = Json::arrayValue;
- for (auto& prop : testInfo->GetProperties().GetList()) {
- Json::Value entry = Json::objectValue;
- entry[kKEY_KEY] = prop.first;
-
- // Remove config variables from the value too.
- entry[kVALUE_KEY] =
- cmGeneratorExpression::Evaluate(prop.second, lg, config);
- properties.append(entry);
- }
- result[kPROPERTIES_KEY] = properties;
-
- return result;
-}
-
-static void DumpMakefileTests(cmLocalGenerator* lg, const std::string& config,
- Json::Value* result)
-{
- auto mf = lg->GetMakefile();
- std::vector<cmTest*> tests;
- mf->GetTests(config, tests);
- for (auto test : tests) {
- Json::Value tmp = DumpCTestInfo(lg, test, config);
- if (!tmp.isNull()) {
- result->append(tmp);
- }
- }
-}
-
-static Json::Value DumpCTestProjectList(const cmake* cm,
- std::string const& config)
-{
- Json::Value result = Json::arrayValue;
-
- auto globalGen = cm->GetGlobalGenerator();
-
- for (const auto& projectIt : globalGen->GetProjectMap()) {
- Json::Value pObj = Json::objectValue;
- pObj[kNAME_KEY] = projectIt.first;
-
- Json::Value tests = Json::arrayValue;
-
- // Gather tests for every generator
- for (const auto& lg : projectIt.second) {
- // Make sure they're generated.
- lg->GenerateTestFiles();
- DumpMakefileTests(lg, config, &tests);
- }
-
- pObj[kCTEST_INFO] = tests;
-
- result.append(pObj);
- }
-
- return result;
-}
-
-static Json::Value DumpCTestConfiguration(const cmake* cm,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = config;
-
- result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config);
-
- return result;
-}
-
-static Json::Value DumpCTestConfigurationsList(const cmake* cm)
-{
- Json::Value result = Json::arrayValue;
-
- for (const std::string& c : getConfigurations(cm)) {
- result.append(DumpCTestConfiguration(cm, c));
- }
-
- return result;
-}
-
-Json::Value cmDumpCTestInfo(const cmake* cm)
-{
- Json::Value result = Json::objectValue;
- result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm);
- return result;
-}
-
-static Json::Value DumpTarget(cmGeneratorTarget* target,
- const std::string& config)
-{
- cmLocalGenerator* lg = target->GetLocalGenerator();
-
- const cmStateEnums::TargetType type = target->GetType();
- const std::string typeName = cmState::GetTargetTypeName(type);
-
- Json::Value ttl = Json::arrayValue;
- ttl.append("EXECUTABLE");
- ttl.append("STATIC_LIBRARY");
- ttl.append("SHARED_LIBRARY");
- ttl.append("MODULE_LIBRARY");
- ttl.append("OBJECT_LIBRARY");
- ttl.append("UTILITY");
- ttl.append("INTERFACE_LIBRARY");
-
- if (!hasString(ttl, typeName) || target->IsImported()) {
- return Json::Value();
- }
-
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = target->GetName();
- result[kIS_GENERATOR_PROVIDED_KEY] =
- target->Target->GetIsGeneratorProvided();
- result[kTYPE_KEY] = typeName;
- result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory();
- result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory();
-
- if (type == cmStateEnums::INTERFACE_LIBRARY) {
- return result;
- }
-
- result[kFULL_NAME_KEY] = target->GetFullName(config);
-
- if (target->Target->GetHaveInstallRule()) {
- result[kHAS_INSTALL_RULE] = true;
-
- Json::Value installPaths = Json::arrayValue;
- for (const auto& installGenerator :
- target->Makefile->GetInstallGenerators()) {
- auto installTargetGenerator =
- dynamic_cast<cmInstallTargetGenerator*>(installGenerator.get());
- if (installTargetGenerator != nullptr &&
- installTargetGenerator->GetTarget()->Target == target->Target) {
- auto dest = installTargetGenerator->GetDestination(config);
-
- std::string installPath;
- if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) {
- installPath = dest;
- } else {
- installPath = cmStrCat(
- target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/',
- dest);
- }
-
- installPaths.append(installPath);
- }
- }
-
- result[kINSTALL_PATHS] = installPaths;
- }
-
- if (target->HaveWellDefinedOutputFiles()) {
- Json::Value artifacts = Json::arrayValue;
- artifacts.append(
- target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact));
- if (target->HasImportLibrary(config)) {
- artifacts.append(
- target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
- }
- if (target->IsDLLPlatform()) {
- const cmGeneratorTarget::OutputInfo* output =
- target->GetOutputInfo(config);
- if (output && !output->PdbDir.empty()) {
- artifacts.append(output->PdbDir + '/' + target->GetPDBName(config));
- }
- }
- result[kARTIFACTS_KEY] = artifacts;
-
- result[kLINKER_LANGUAGE_KEY] = target->GetLinkerLanguage(config);
-
- std::string linkLibs;
- std::string linkFlags;
- std::string linkLanguageFlags;
- std::string frameworkPath;
- std::string linkPath;
- cmLinkLineComputer linkLineComputer(lg,
- lg->GetStateSnapshot().GetDirectory());
- lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
- linkFlags, frameworkPath, linkPath, target);
-
- linkLibs = cmTrimWhitespace(linkLibs);
- linkFlags = cmTrimWhitespace(linkFlags);
- linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
- frameworkPath = cmTrimWhitespace(frameworkPath);
- linkPath = cmTrimWhitespace(linkPath);
-
- if (!cmTrimWhitespace(linkLibs).empty()) {
- result[kLINK_LIBRARIES_KEY] = linkLibs;
- }
- if (!cmTrimWhitespace(linkFlags).empty()) {
- result[kLINK_FLAGS_KEY] = linkFlags;
- }
- if (!cmTrimWhitespace(linkLanguageFlags).empty()) {
- result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags;
- }
- if (!frameworkPath.empty()) {
- result[kFRAMEWORK_PATH_KEY] = frameworkPath;
- }
- if (!linkPath.empty()) {
- result[kLINK_PATH_KEY] = linkPath;
- }
- const std::string sysroot =
- lg->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT");
- if (!sysroot.empty()) {
- result[kSYSROOT_KEY] = sysroot;
- }
- }
-
- std::set<std::string> languages;
- target->GetLanguages(languages, config);
- std::map<std::string, LanguageData> languageDataMap;
-
- for (std::string const& lang : languages) {
- LanguageData& ld = languageDataMap[lang];
- ld.Language = lang;
- lg->GetTargetCompileFlags(target, config, lang, ld.Flags);
- std::set<std::string> defines;
- lg->GetTargetDefines(target, config, lang, defines);
- ld.SetDefines(defines);
- std::vector<std::string> includePathList;
- lg->GetIncludeDirectories(includePathList, target, lang, config);
- for (std::string const& i : includePathList) {
- ld.IncludePathList.emplace_back(
- i, target->IsSystemIncludeDirectory(i, config, lang));
- }
- }
-
- Json::Value sourceGroupsValue =
- DumpSourceFilesList(target, config, languageDataMap);
- if (!sourceGroupsValue.empty()) {
- result[kFILE_GROUPS_KEY] = sourceGroupsValue;
- }
-
- return result;
-}
-
-static Json::Value DumpTargetsList(
- const std::vector<cmLocalGenerator*>& generators, const std::string& config)
-{
- Json::Value result = Json::arrayValue;
-
- std::vector<cmGeneratorTarget*> targetList;
- for (auto const& lgIt : generators) {
- cm::append(targetList, lgIt->GetGeneratorTargets());
- }
- std::sort(targetList.begin(), targetList.end());
-
- for (cmGeneratorTarget* target : targetList) {
- Json::Value tmp = DumpTarget(target, config);
- if (!tmp.isNull()) {
- result.append(tmp);
- }
- }
-
- return result;
-}
-
-static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
-{
- Json::Value result = Json::arrayValue;
-
- auto globalGen = cm->GetGlobalGenerator();
-
- for (auto const& projectIt : globalGen->GetProjectMap()) {
- Json::Value pObj = Json::objectValue;
- pObj[kNAME_KEY] = projectIt.first;
-
- // All Projects must have at least one local generator
- assert(!projectIt.second.empty());
- const cmLocalGenerator* lg = projectIt.second.at(0);
-
- // Project structure information:
- const cmMakefile* mf = lg->GetMakefile();
- auto minVersion = mf->GetSafeDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
- pObj[kMINIMUM_CMAKE_VERSION] = minVersion;
- pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory();
- pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory();
- pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config);
-
- // For a project-level install rule it might be defined in any of its
- // associated generators.
- bool hasInstallRule = false;
- for (const auto generator : projectIt.second) {
- for (const auto& installGen :
- generator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen.get())) {
- hasInstallRule = true;
- break;
- }
- }
-
- if (hasInstallRule) {
- break;
- }
- }
-
- pObj[kHAS_INSTALL_RULE] = hasInstallRule;
-
- result.append(pObj);
- }
-
- return result;
-}
-
-static Json::Value DumpConfiguration(const cmake* cm,
- const std::string& config)
-{
- Json::Value result = Json::objectValue;
- result[kNAME_KEY] = config;
-
- result[kPROJECTS_KEY] = DumpProjectList(cm, config);
-
- return result;
-}
-
-static Json::Value DumpConfigurationsList(const cmake* cm)
-{
- Json::Value result = Json::arrayValue;
-
- for (std::string const& c : getConfigurations(cm)) {
- result.append(DumpConfiguration(cm, c));
- }
-
- return result;
-}
-
-Json::Value cmDumpCodeModel(const cmake* cm)
-{
- Json::Value result = Json::objectValue;
- result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm);
- return result;
-}
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
deleted file mode 100644
index 80a4834..0000000
--- a/Source/cmJsonObjects.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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 <string>
-#include <vector>
-
-#include <cm3p/json/value.h>
-
-class cmake;
-class cmGlobalGenerator;
-
-extern void cmGetCMakeInputs(const cmGlobalGenerator* gg,
- const std::string& sourceDir,
- const std::string& buildDir,
- std::vector<std::string>* internalFiles,
- std::vector<std::string>* explicitFiles,
- std::vector<std::string>* tmpFiles);
-
-extern Json::Value cmDumpCodeModel(const cmake* cm);
-extern Json::Value cmDumpCTestInfo(const cmake* cm);
-extern Json::Value cmDumpCMakeInputs(const cmake* cm);
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index d70176d..616bf7e 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -133,9 +133,9 @@ public:
return iterator(const_cast<cmLinkedTree*>(this), 0);
}
- iterator Push(iterator it) { return Push_impl(it, T()); }
+ iterator Push(iterator it) { return this->Push_impl(it, T()); }
- iterator Push(iterator it, T t) { return Push_impl(it, std::move(t)); }
+ iterator Push(iterator it, T t) { return this->Push_impl(it, std::move(t)); }
bool IsLast(iterator it) { return it.Position == this->Data.size(); }
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index a2c14bd..53c871b 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -609,9 +609,9 @@ public:
bool Validate(std::size_t count) override
{
- decltype(Indexes) indexes;
+ decltype(this->Indexes) indexes;
- for (auto index : Indexes) {
+ for (auto index : this->Indexes) {
indexes.push_back(this->NormalizeIndex(index, count));
}
this->Indexes = std::move(indexes);
@@ -750,7 +750,7 @@ bool HandleTransformCommand(std::vector<std::string> const& args,
{
}
- operator const std::string&() const { return Name; }
+ operator const std::string&() const { return this->Name; }
std::string Name;
int Arity = 0;
@@ -1093,8 +1093,9 @@ protected:
public:
cmStringSorter(Compare compare, CaseSensitivity caseSensitivity,
Order desc = Order::ASCENDING)
- : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) }
- , sortMethod(GetComparisonFunction(compare))
+ : filters{ this->GetCompareFilter(compare),
+ this->GetCaseFilter(caseSensitivity) }
+ , sortMethod(this->GetComparisonFunction(compare))
, descending(desc == Order::DESCENDING)
{
}
@@ -1102,7 +1103,7 @@ public:
std::string ApplyFilter(const std::string& argument)
{
std::string result = argument;
- for (auto filter : filters) {
+ for (auto filter : this->filters) {
if (filter != nullptr) {
result = filter(result);
}
@@ -1112,13 +1113,13 @@ public:
bool operator()(const std::string& a, const std::string& b)
{
- std::string af = ApplyFilter(a);
- std::string bf = ApplyFilter(b);
+ std::string af = this->ApplyFilter(a);
+ std::string bf = this->ApplyFilter(b);
bool result;
- if (descending) {
- result = sortMethod(bf, af);
+ if (this->descending) {
+ result = this->sortMethod(bf, af);
} else {
- result = sortMethod(af, bf);
+ result = this->sortMethod(af, bf);
}
return result;
}
@@ -1424,7 +1425,7 @@ public:
bool operator()(const std::string& target)
{
- return regex.find(target) ^ includeMatches;
+ return this->regex.find(target) ^ this->includeMatches;
}
private:
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 70ef5af..36a1372 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -30,6 +30,7 @@ struct cmListFileParser
bool ParseFunction(const char* name, long line);
bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
+ cm::optional<cmListFileContext> CheckNesting();
cmListFile* ListFile;
cmListFileBacktrace Backtrace;
cmMessenger* Messenger;
@@ -104,7 +105,7 @@ bool cmListFileParser::ParseFile(const char* filename)
return false;
}
- return Parse();
+ return this->Parse();
}
bool cmListFileParser::ParseString(const char* str,
@@ -117,7 +118,7 @@ bool cmListFileParser::ParseString(const char* str,
return false;
}
- return Parse();
+ return this->Parse();
}
bool cmListFileParser::Parse()
@@ -158,6 +159,17 @@ bool cmListFileParser::Parse()
return false;
}
}
+
+ // Check if all functions are nested properly.
+ if (auto badNesting = this->CheckNesting()) {
+ this->Messenger->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Flow control statements are not properly nested.",
+ this->Backtrace.Push(*badNesting));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
return true;
}
@@ -317,6 +329,112 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
return true;
}
+namespace {
+enum class NestingStateEnum
+{
+ If,
+ Else,
+ While,
+ Foreach,
+ Function,
+ Macro,
+};
+
+struct NestingState
+{
+ NestingStateEnum State;
+ cmListFileContext Context;
+};
+
+bool TopIs(std::vector<NestingState>& stack, NestingStateEnum state)
+{
+ return !stack.empty() && stack.back().State == state;
+}
+}
+
+cm::optional<cmListFileContext> cmListFileParser::CheckNesting()
+{
+ std::vector<NestingState> stack;
+
+ for (auto const& func : this->ListFile->Functions) {
+ auto const& name = func.LowerCaseName();
+ if (name == "if") {
+ stack.push_back({
+ NestingStateEnum::If,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ });
+ } else if (name == "elseif") {
+ if (!TopIs(stack, NestingStateEnum::If)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.back() = {
+ NestingStateEnum::If,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ };
+ } else if (name == "else") {
+ if (!TopIs(stack, NestingStateEnum::If)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.back() = {
+ NestingStateEnum::Else,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ };
+ } else if (name == "endif") {
+ if (!TopIs(stack, NestingStateEnum::If) &&
+ !TopIs(stack, NestingStateEnum::Else)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.pop_back();
+ } else if (name == "while") {
+ stack.push_back({
+ NestingStateEnum::While,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ });
+ } else if (name == "endwhile") {
+ if (!TopIs(stack, NestingStateEnum::While)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.pop_back();
+ } else if (name == "foreach") {
+ stack.push_back({
+ NestingStateEnum::Foreach,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ });
+ } else if (name == "endforeach") {
+ if (!TopIs(stack, NestingStateEnum::Foreach)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.pop_back();
+ } else if (name == "function") {
+ stack.push_back({
+ NestingStateEnum::Function,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ });
+ } else if (name == "endfunction") {
+ if (!TopIs(stack, NestingStateEnum::Function)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.pop_back();
+ } else if (name == "macro") {
+ stack.push_back({
+ NestingStateEnum::Macro,
+ cmListFileContext::FromCommandContext(func, this->FileName),
+ });
+ } else if (name == "endmacro") {
+ if (!TopIs(stack, NestingStateEnum::Macro)) {
+ return cmListFileContext::FromCommandContext(func, this->FileName);
+ }
+ stack.pop_back();
+ }
+ }
+
+ if (!stack.empty()) {
+ return stack.back().Context;
+ }
+
+ return cm::nullopt;
+}
+
// We hold either the bottom scope of a directory or a call/file context.
// Discriminate these cases via the parent pointer.
struct cmListFileBacktrace::Entry
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 727fc60..98cb4a7 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -89,6 +89,14 @@ public:
{
}
+#if __cplusplus < 201703L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L)
+ cmListFileContext(const cmListFileContext& /*other*/) = default;
+ cmListFileContext(cmListFileContext&& /*other*/) = default;
+
+ cmListFileContext& operator=(const cmListFileContext& /*other*/) = default;
+ cmListFileContext& operator=(cmListFileContext&& /*other*/) = delete;
+#endif
+
static cmListFileContext FromCommandContext(
cmCommandContext const& lfcc, std::string const& fileName,
cm::optional<std::string> deferId = {})
@@ -241,7 +249,7 @@ public:
BTs(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace())
: Value(std::move(v))
{
- Backtraces.emplace_back(std::move(bt));
+ this->Backtraces.emplace_back(std::move(bt));
}
T Value;
std::vector<cmListFileBacktrace> Backtraces;
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 5790e16..adebe02 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -24,6 +24,7 @@
#include "cmCommand.h"
#include "cmDynamicLoader.h"
#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -36,8 +37,6 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
-class cmListFileBacktrace;
-
namespace {
const char* LastName = nullptr;
@@ -256,10 +255,12 @@ bool cmLoadCommandCommand(std::vector<std::string> const& args,
// if the symbol is found call it to set the name on the
// function blocker
if (initFunction) {
- status.GetMakefile().GetState()->AddScriptedCommand(
+ return status.GetMakefile().GetState()->AddScriptedCommand(
args[0],
- cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
- return true;
+ BT<cmState::Command>(
+ cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)),
+ status.GetMakefile().GetBacktrace()),
+ status.GetMakefile());
}
status.SetError("Attempt to load command failed. "
"No init function found.");
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 2239192..86eddc2 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmLocalGenerator.h"
#include <algorithm>
+#include <array>
#include <cassert>
#include <cstdio>
#include <cstdlib>
@@ -16,9 +17,11 @@
#include <cm/memory>
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
+#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -279,7 +282,7 @@ static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs,
});
}
-void cmLocalGenerator::TraceDependencies()
+void cmLocalGenerator::TraceDependencies() const
{
// Generate the rule files for each target.
const auto& targets = this->GetGeneratorTargets();
@@ -823,16 +826,13 @@ cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const
return this->Makefile->GetStateSnapshot();
}
-const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
- const std::string& prop)
+cmProp cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
+ const std::string& prop)
{
- cmProp p;
if (target) {
- p = target->GetProperty(prop);
- } else {
- p = this->Makefile->GetProperty(prop);
+ return target->GetProperty(prop);
}
- return p ? p->c_str() : nullptr;
+ return this->Makefile->GetProperty(prop);
}
std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -1129,9 +1129,8 @@ cmTarget* cmLocalGenerator::AddUtilityCommand(
detail::AddUtilityCommand(
*this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target,
- this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends,
- commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
- job_pool, stdPipesUTF8);
+ workingDir, byproducts, depends, commandLines, escapeOldStyle, comment,
+ uses_terminal, command_expand_lists, job_pool, stdPipesUTF8);
return target;
}
@@ -2498,8 +2497,10 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
target->GetSourceFiles(sources, config);
const std::string configUpper = cmSystemTools::UpperCase(config);
+ static const std::array<std::string, 4> langs = { { "C", "CXX", "OBJC",
+ "OBJCXX" } };
- for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
+ for (const std::string& lang : langs) {
auto langSources = std::count_if(
sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
return lang == sf->GetLanguage() &&
@@ -2606,11 +2607,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
if (editAndContinueDebugInfo || msvc2008OrLess) {
- CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
- { ".pdb", ".idb" });
+ this->CopyPchCompilePdb(config, target, *ReuseFrom,
+ reuseTarget, { ".pdb", ".idb" });
} else if (enableDebuggingInformation) {
- CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
- { ".pdb" });
+ this->CopyPchCompilePdb(config, target, *ReuseFrom,
+ reuseTarget, { ".pdb" });
}
}
@@ -2633,14 +2634,16 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
// Add pchHeader to source files, which will
// be grouped as "Precompile Header File"
auto pchHeader_sf = this->Makefile->GetOrCreateSource(
- pchHeader, true, cmSourceFileLocationKind::Known);
+ pchHeader, false, cmSourceFileLocationKind::Known);
std::string err;
pchHeader_sf->ResolveFullPath(&err);
-
- // The pch file is generated, but mark it as not generated
- // so that a clean operation will not remove it from disk
- pchHeader_sf->SetProperty("GENERATED", "0");
-
+ if (!err.empty()) {
+ std::ostringstream msg;
+ msg << "Unable to resolve full path of PCH-header '" << pchHeader
+ << "' assigned to target " << target->GetName()
+ << ", although its path is supposed to be known!";
+ this->IssueMessage(MessageType::FATAL_ERROR, msg.str());
+ }
target->AddSource(pchHeader);
}
}
@@ -2769,8 +2772,15 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
inline void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file,
std::string const& sf_full_path,
cmProp beforeInclude,
- cmProp afterInclude)
+ cmProp afterInclude, cmProp uniqueIdName)
{
+
+ if (uniqueIdName && !uniqueIdName->empty()) {
+ unity_file << "#undef " << *uniqueIdName << "\n"
+ << "#define " << *uniqueIdName << " unity_"
+ << cmSystemTools::ComputeStringMD5(sf_full_path) << "\n";
+ }
+
if (beforeInclude) {
unity_file << *beforeInclude << "\n";
}
@@ -2791,6 +2801,8 @@ std::vector<std::string> AddUnityFilesModeAuto(
batchSize = filtered_sources.size();
}
+ cmProp uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID");
+
std::vector<std::string> unity_files;
for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
itemsLeft > 0; itemsLeft -= chunk, ++batch) {
@@ -2814,7 +2826,7 @@ std::vector<std::string> AddUnityFilesModeAuto(
cmSourceFile* sf = filtered_sources[begin];
RegisterUnitySources(target, sf, filename);
IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
- afterInclude);
+ afterInclude, uniqueIdName);
}
}
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
@@ -2845,6 +2857,8 @@ std::vector<std::string> AddUnityFilesModeGroup(
}
}
+ cmProp uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID");
+
for (auto const& item : explicit_mapping) {
auto const& name = item.first;
std::string filename = cmStrCat(filename_base, "unity_", name,
@@ -2860,7 +2874,7 @@ std::vector<std::string> AddUnityFilesModeGroup(
for (cmSourceFile* sf : item.second) {
RegisterUnitySources(target, sf, filename);
IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
- afterInclude);
+ afterInclude, uniqueIdName);
}
}
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
@@ -3233,7 +3247,7 @@ std::string cmLocalGenerator::GetProjectName() const
}
std::string cmLocalGenerator::ConstructComment(
- cmCustomCommandGenerator const& ccg, const char* default_comment)
+ cmCustomCommandGenerator const& ccg, const char* default_comment) const
{
// Check for a comment provided with the command.
if (ccg.GetComment()) {
@@ -3549,11 +3563,11 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
// we don't end up having:
// CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
- cmProp psExtension = source.GetProperty("PCH_EXTENSION");
+ cmProp pchExtension = source.GetProperty("PCH_EXTENSION");
const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
- if (unitySourceFile || psExtension || isPchObject) {
- if (psExtension) {
- customOutputExtension = psExtension->c_str();
+ if (unitySourceFile || pchExtension || isPchObject) {
+ if (pchExtension) {
+ customOutputExtension = pchExtension->c_str();
}
cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
@@ -3791,7 +3805,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
- mf->ConfigureFile(inFile, fname, false, false, false, true);
+ mf->ConfigureFile(inFile, fname, false, false, false);
}
void cmLocalGenerator::GenerateFrameworkInfoPList(
@@ -3826,42 +3840,99 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
- mf->ConfigureFile(inFile, fname, false, false, false, true);
+ mf->ConfigureFile(inFile, fname, false, false, false);
}
namespace {
+cm::string_view CustomOutputRoleKeyword(cmLocalGenerator::OutputRole role)
+{
+ return (role == cmLocalGenerator::OutputRole::Primary ? "OUTPUT"_s
+ : "BYPRODUCTS"_s);
+}
+
void CreateGeneratedSource(cmLocalGenerator& lg, const std::string& output,
+ cmLocalGenerator::OutputRole role,
cmCommandOrigin origin,
const cmListFileBacktrace& lfbt)
{
- if (cmGeneratorExpression::Find(output) == std::string::npos) {
- // Outputs without generator expressions from the project are already
- // created and marked as generated. Do not mark them again, because
- // other commands might have overwritten the property.
- if (origin == cmCommandOrigin::Generator) {
- lg.GetMakefile()->GetOrCreateGeneratedSource(output);
- }
- } else {
+ if (cmGeneratorExpression::Find(output) != std::string::npos) {
lg.GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
"Generator expressions in custom command outputs are not implemented!",
lfbt);
+ return;
+ }
+
+ // Make sure the file will not be generated into the source
+ // directory during an out of source build.
+ if (!lg.GetMakefile()->CanIWriteThisFile(output)) {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(CustomOutputRoleKeyword(role), " path\n ", output,
+ "\nin a source directory as an output of custom command."),
+ lfbt);
+ return;
+ }
+
+ // Make sure the output file name has no invalid characters.
+ std::string::size_type pos = output.find_first_of("#<>");
+ if (pos != std::string::npos) {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(CustomOutputRoleKeyword(role), " containing a \"", output[pos],
+ "\" is not allowed."),
+ lfbt);
+ return;
+ }
+
+ // Outputs without generator expressions from the project are already
+ // created and marked as generated. Do not mark them again, because
+ // other commands might have overwritten the property.
+ if (origin == cmCommandOrigin::Generator) {
+ lg.GetMakefile()->GetOrCreateGeneratedSource(output);
}
}
-void CreateGeneratedSources(cmLocalGenerator& lg,
- const std::vector<std::string>& outputs,
- cmCommandOrigin origin,
- const cmListFileBacktrace& lfbt)
+std::string ComputeCustomCommandRuleFileName(cmLocalGenerator& lg,
+ cmListFileBacktrace const& bt,
+ std::string const& output)
{
- for (std::string const& o : outputs) {
- CreateGeneratedSource(lg, o, origin, lfbt);
+ // If the output path has no generator expressions, use it directly.
+ if (cmGeneratorExpression::Find(output) == std::string::npos) {
+ return output;
+ }
+
+ // The output path contains a generator expression, but we must choose
+ // a single source file path to which to attach the custom command.
+ // Use some heuristics to provie a nice-looking name when possible.
+
+ // If the only genex is $<CONFIG>, replace that gracefully.
+ {
+ std::string simple = output;
+ cmSystemTools::ReplaceString(simple, "$<CONFIG>", "(CONFIG)");
+ if (cmGeneratorExpression::Find(simple) == std::string::npos) {
+ return simple;
+ }
}
+
+ // If the genex evaluates to the same value in all configurations, use that.
+ {
+ std::vector<std::string> allConfigOutputs =
+ lg.ExpandCustomCommandOutputGenex(output, bt);
+ if (allConfigOutputs.size() == 1) {
+ return allConfigOutputs.front();
+ }
+ }
+
+ // Fall back to a deterministic unique name.
+ cmCryptoHash h(cmCryptoHash::AlgoSHA256);
+ return cmStrCat(lg.GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ h.HashString(output).substr(0, 16));
}
cmSourceFile* AddCustomCommand(
cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
- const std::vector<std::string>& outputs,
+ cmCommandOrigin origin, const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends, const std::string& main_dependency,
const cmImplicitDependsList& implicit_depends,
@@ -3898,7 +3969,8 @@ cmSourceFile* AddCustomCommand(
cmGlobalGenerator* gg = lg.GetGlobalGenerator();
// Construct a rule file associated with the first output produced.
- std::string outName = gg->GenerateRuleFile(outputs[0]);
+ std::string outName = gg->GenerateRuleFile(
+ ComputeCustomCommandRuleFileName(lg, lfbt, outputs[0]));
// Check if the rule file already exists.
file = mf->GetSource(outName, cmSourceFileLocationKind::Known);
@@ -3941,10 +4013,38 @@ cmSourceFile* AddCustomCommand(
cc->SetJobPool(job_pool);
file->SetCustomCommand(std::move(cc));
- mf->AddSourceOutputs(file, outputs, byproducts);
+ lg.AddSourceOutputs(file, outputs, cmLocalGenerator::OutputRole::Primary,
+ lfbt, origin);
+ lg.AddSourceOutputs(file, byproducts,
+ cmLocalGenerator::OutputRole::Byproduct, lfbt, origin);
}
return file;
}
+
+bool AnyOutputMatches(const std::string& name,
+ const std::vector<std::string>& outputs)
+{
+ for (std::string const& output : outputs) {
+ std::string::size_type pos = output.rfind(name);
+ // If the output matches exactly
+ if (pos != std::string::npos && pos == output.size() - name.size() &&
+ (pos == 0 || output[pos - 1] == '/')) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AnyTargetCommandOutputMatches(
+ const std::string& name, const std::vector<cmCustomCommand>& commands)
+{
+ for (cmCustomCommand const& command : commands) {
+ if (AnyOutputMatches(name, command.GetByproducts())) {
+ return true;
+ }
+ }
+ return false;
+}
}
namespace detail {
@@ -3960,11 +4060,6 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
const std::string& job_pool,
bool command_expand_lists, bool stdPipesUTF8)
{
- cmMakefile* mf = lg.GetMakefile();
-
- // Always create the byproduct sources and mark them generated.
- CreateGeneratedSources(lg, byproducts, origin, lfbt);
-
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt,
@@ -3987,7 +4082,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
break;
}
- mf->AddTargetByproducts(target, byproducts);
+ lg.AddTargetByproducts(target, byproducts, lfbt, origin);
}
cmSourceFile* AddCustomCommandToOutput(
@@ -4001,14 +4096,11 @@ cmSourceFile* AddCustomCommandToOutput(
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
const std::string& job_pool, bool stdPipesUTF8)
{
- // Always create the output sources and mark them generated.
- CreateGeneratedSources(lg, outputs, origin, lfbt);
- CreateGeneratedSources(lg, byproducts, origin, lfbt);
-
- return AddCustomCommand(
- lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends,
- commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool, stdPipesUTF8);
+ return AddCustomCommand(lg, lfbt, origin, outputs, byproducts, depends,
+ main_dependency, implicit_depends, commandLines,
+ comment, workingDir, replace, escapeOldStyle,
+ uses_terminal, command_expand_lists, depfile,
+ job_pool, stdPipesUTF8);
}
void AppendCustomCommandToOutput(cmLocalGenerator& lg,
@@ -4019,7 +4111,22 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg,
const cmCustomCommandLines& commandLines)
{
// Lookup an existing command.
- if (cmSourceFile* sf = lg.GetMakefile()->GetSourceFileWithOutput(output)) {
+ cmSourceFile* sf = nullptr;
+ if (cmGeneratorExpression::Find(output) == std::string::npos) {
+ sf = lg.GetSourceFileWithOutput(output);
+ } else {
+ // This output path has a generator expression. Evaluate it to
+ // find the output for any configurations.
+ for (std::string const& out :
+ lg.ExpandCustomCommandOutputGenex(output, lfbt)) {
+ sf = lg.GetSourceFileWithOutput(out);
+ if (sf) {
+ break;
+ }
+ }
+ }
+
+ if (sf) {
if (cmCustomCommand* cc = sf->GetCustomCommand()) {
cc->AppendCommands(commandLines);
cc->AppendDepends(depends);
@@ -4031,14 +4138,14 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg,
// No existing command found.
lg.GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("Attempt to append to output\n ", output,
+ cmStrCat("Attempt to APPEND to custom command with output\n ", output,
"\nwhich is not already a custom command output."),
lfbt);
}
void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
cmCommandOrigin origin, cmTarget* target,
- const cmUtilityOutput& force, const char* workingDir,
+ const char* workingDir,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
@@ -4046,29 +4153,27 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
bool uses_terminal, bool command_expand_lists,
const std::string& job_pool, bool stdPipesUTF8)
{
- // Always create the byproduct sources and mark them generated.
- CreateGeneratedSource(lg, force.Name, origin, lfbt);
- CreateGeneratedSources(lg, byproducts, origin, lfbt);
-
// Use an empty comment to avoid generation of default comment.
if (!comment) {
comment = "";
}
+ // Create the generated symbolic output name of the utility target.
+ std::string output =
+ lg.CreateUtilityOutput(target->GetName(), byproducts, lfbt);
+
std::string no_main_dependency;
cmImplicitDependsList no_implicit_depends;
cmSourceFile* rule = AddCustomCommand(
- lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency,
+ lg, lfbt, origin, { output }, byproducts, depends, no_main_dependency,
no_implicit_depends, commandLines, comment, workingDir,
/*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists,
/*depfile=*/"", job_pool, stdPipesUTF8);
if (rule) {
- lg.GetMakefile()->AddTargetByproducts(target, byproducts);
+ lg.AddTargetByproducts(target, byproducts, lfbt, origin);
}
- if (!force.NameCMP0049.empty()) {
- target->AddSource(force.NameCMP0049);
- }
+ target->AddSource(output);
}
std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target)
@@ -4119,3 +4224,247 @@ std::vector<std::string> ComputeISPCExtraObjects(
return computedObjects;
}
}
+
+cmSourcesWithOutput cmLocalGenerator::GetSourcesWithOutput(
+ const std::string& name) const
+{
+ // Linear search? Also see GetSourceFileWithOutput for detail.
+ if (!cmSystemTools::FileIsFullPath(name)) {
+ cmSourcesWithOutput sources;
+ sources.Target = this->LinearGetTargetWithOutput(name);
+ sources.Source = this->LinearGetSourceFileWithOutput(
+ name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
+ return sources;
+ }
+ // Otherwise we use an efficient lookup map.
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end()) {
+ return o->second.Sources;
+ }
+ return {};
+}
+
+cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput(
+ const std::string& name, cmSourceOutputKind kind) const
+{
+ // If the queried path is not absolute we use the backward compatible
+ // linear-time search for an output with a matching suffix.
+ if (!cmSystemTools::FileIsFullPath(name)) {
+ bool byproduct = false;
+ return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
+ }
+ // Otherwise we use an efficient lookup map.
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end() &&
+ (!o->second.Sources.SourceIsByproduct ||
+ kind == cmSourceOutputKind::OutputOrByproduct)) {
+ // Source file could also be null pointer for example if we found the
+ // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
+ // command of a target, or a not yet created custom command.
+ return o->second.Sources.Source;
+ }
+ return nullptr;
+}
+
+std::string cmLocalGenerator::CreateUtilityOutput(
+ std::string const& targetName, std::vector<std::string> const&,
+ cmListFileBacktrace const&)
+{
+ std::string force =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", targetName);
+ // The output is not actually created so mark it symbolic.
+ if (cmSourceFile* sf = this->Makefile->GetOrCreateGeneratedSource(force)) {
+ sf->SetProperty("SYMBOLIC", "1");
+ } else {
+ cmSystemTools::Error("Could not get source file entry for " + force);
+ }
+ return force;
+}
+
+std::vector<cmCustomCommandGenerator>
+cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
+ std::string const& config)
+{
+ std::vector<cmCustomCommandGenerator> ccgs;
+ ccgs.emplace_back(cc, config, this);
+ return ccgs;
+}
+
+std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
+ cmCompiledGeneratorExpression const& cge, std::string const& config)
+{
+ std::vector<std::string> paths = cmExpandedList(cge.Evaluate(this, config));
+ for (std::string& p : paths) {
+ p = cmSystemTools::CollapseFullPath(p, this->GetCurrentBinaryDirectory());
+ }
+ return paths;
+}
+
+std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputGenex(
+ std::string const& o, cmListFileBacktrace const& bt)
+{
+ std::vector<std::string> allConfigOutputs;
+ cmGeneratorExpression ge(bt);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(o);
+ std::vector<std::string> configs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+ for (std::string const& config : configs) {
+ std::vector<std::string> configOutputs =
+ this->ExpandCustomCommandOutputPaths(*cge, config);
+ allConfigOutputs.reserve(allConfigOutputs.size() + configOutputs.size());
+ std::move(configOutputs.begin(), configOutputs.end(),
+ std::back_inserter(allConfigOutputs));
+ }
+ auto endUnique =
+ cmRemoveDuplicates(allConfigOutputs.begin(), allConfigOutputs.end());
+ allConfigOutputs.erase(endUnique, allConfigOutputs.end());
+ return allConfigOutputs;
+}
+
+void cmLocalGenerator::AddTargetByproducts(
+ cmTarget* target, const std::vector<std::string>& byproducts,
+ cmListFileBacktrace const& bt, cmCommandOrigin origin)
+{
+ for (std::string const& o : byproducts) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->UpdateOutputToSourceMap(o, target, bt, origin);
+ continue;
+ }
+
+ // This byproduct path has a generator expression. Evaluate it to
+ // register the byproducts for all configurations.
+ for (std::string const& b : this->ExpandCustomCommandOutputGenex(o, bt)) {
+ this->UpdateOutputToSourceMap(b, target, bt, cmCommandOrigin::Generator);
+ }
+ }
+}
+
+void cmLocalGenerator::AddSourceOutputs(
+ cmSourceFile* source, const std::vector<std::string>& outputs,
+ OutputRole role, cmListFileBacktrace const& bt, cmCommandOrigin origin)
+{
+ for (std::string const& o : outputs) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->UpdateOutputToSourceMap(o, source, role, bt, origin);
+ continue;
+ }
+
+ // This output path has a generator expression. Evaluate it to
+ // register the outputs for all configurations.
+ for (std::string const& out :
+ this->ExpandCustomCommandOutputGenex(o, bt)) {
+ this->UpdateOutputToSourceMap(out, source, role, bt,
+ cmCommandOrigin::Generator);
+ }
+ }
+}
+
+void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& byproduct,
+ cmTarget* target,
+ cmListFileBacktrace const& bt,
+ cmCommandOrigin origin)
+{
+ SourceEntry entry;
+ entry.Sources.Target = target;
+
+ auto pr = this->OutputToSource.emplace(byproduct, entry);
+ if (pr.second) {
+ CreateGeneratedSource(*this, byproduct, OutputRole::Byproduct, origin, bt);
+ } else {
+ SourceEntry& current = pr.first->second;
+ // Has the target already been set?
+ if (!current.Sources.Target) {
+ current.Sources.Target = target;
+ } else {
+ // Multiple custom commands/targets produce the same output (source file
+ // or target). See also comment in other UpdateOutputToSourceMap
+ // overload.
+ //
+ // TODO: Warn the user about this case.
+ }
+ }
+}
+
+void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& output,
+ cmSourceFile* source,
+ OutputRole role,
+ cmListFileBacktrace const& bt,
+ cmCommandOrigin origin)
+{
+ SourceEntry entry;
+ entry.Sources.Source = source;
+ entry.Sources.SourceIsByproduct = role == OutputRole::Byproduct;
+
+ auto pr = this->OutputToSource.emplace(output, entry);
+ if (pr.second) {
+ CreateGeneratedSource(*this, output, role, origin, bt);
+ } else {
+ SourceEntry& current = pr.first->second;
+ // Outputs take precedence over byproducts
+ if (!current.Sources.Source ||
+ (current.Sources.SourceIsByproduct && role == OutputRole::Primary)) {
+ current.Sources.Source = source;
+ current.Sources.SourceIsByproduct = false;
+ } else {
+ // Multiple custom commands produce the same output but may
+ // be attached to a different source file (MAIN_DEPENDENCY).
+ // LinearGetSourceFileWithOutput would return the first one,
+ // so keep the mapping for the first one.
+ //
+ // TODO: Warn the user about this case. However, the VS 8 generator
+ // triggers it for separate generate.stamp rules in ZERO_CHECK and
+ // individual targets.
+ }
+ }
+}
+
+cmTarget* cmLocalGenerator::LinearGetTargetWithOutput(
+ const std::string& name) const
+{
+ // We go through the ordered vector of targets to get reproducible results
+ // should multiple names match.
+ for (cmTarget* t : this->Makefile->GetOrderedTargets()) {
+ // Does the output of any command match the source file name?
+ if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
+ return t;
+ }
+ if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
+ return t;
+ }
+ if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
+ return t;
+ }
+ }
+ return nullptr;
+}
+
+cmSourceFile* cmLocalGenerator::LinearGetSourceFileWithOutput(
+ const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
+{
+ // Outputs take precedence over byproducts.
+ byproduct = false;
+ cmSourceFile* fallback = nullptr;
+
+ // Look through all the source files that have custom commands and see if the
+ // custom command has the passed source file as an output.
+ for (const auto& src : this->Makefile->GetSourceFiles()) {
+ // Does this source file have a custom command?
+ if (src->GetCustomCommand()) {
+ // Does the output of the custom command match the source file name?
+ if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
+ // Return the first matching output.
+ return src.get();
+ }
+ if (kind == cmSourceOutputKind::OutputOrByproduct) {
+ if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
+ // Do not return the source yet as there might be a matching output.
+ fallback = src.get();
+ }
+ }
+ }
+ }
+
+ // Did we find a byproduct?
+ byproduct = fallback != nullptr;
+ return fallback;
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 22d3599..91dd8ae 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -22,7 +22,9 @@
#include "cmProperty.h"
#include "cmStateSnapshot.h"
+class cmCompiledGeneratorExpression;
class cmComputeLinkInformation;
+class cmCustomCommand;
class cmCustomCommandGenerator;
class cmCustomCommandLines;
class cmGeneratorTarget;
@@ -36,6 +38,31 @@ class cmState;
class cmTarget;
class cmake;
+/** Flag if byproducts shall also be considered. */
+enum class cmSourceOutputKind
+{
+ OutputOnly,
+ OutputOrByproduct
+};
+
+/** What scanner to use for dependencies lookup. */
+enum class cmDependencyScannerKind
+{
+ CMake,
+ Compiler
+};
+
+/** Target and source file which have a specific output. */
+struct cmSourcesWithOutput
+{
+ /** Target with byproduct. */
+ cmTarget* Target = nullptr;
+
+ /** Source file with output or byproduct. */
+ cmSourceFile* Source = nullptr;
+ bool SourceIsByproduct = false;
+};
+
/** \class cmLocalGenerator
* \brief Create required build files for a directory.
*
@@ -59,7 +86,7 @@ public:
/**
* Calls TraceVSDependencies() on all targets of this generator.
*/
- void TraceDependencies();
+ void TraceDependencies() const;
virtual void AddHelperCommands() {}
@@ -337,6 +364,55 @@ public:
bool command_expand_lists = false, const std::string& job_pool = "",
bool stdPipesUTF8 = false);
+ virtual std::string CreateUtilityOutput(
+ std::string const& targetName, std::vector<std::string> const& byproducts,
+ cmListFileBacktrace const& bt);
+
+ virtual std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
+ cmCustomCommand const& cc, std::string const& config);
+
+ std::vector<std::string> ExpandCustomCommandOutputPaths(
+ cmCompiledGeneratorExpression const& cge, std::string const& config);
+ std::vector<std::string> ExpandCustomCommandOutputGenex(
+ std::string const& o, cmListFileBacktrace const& bt);
+
+ /**
+ * Add target byproducts.
+ */
+ void AddTargetByproducts(cmTarget* target,
+ const std::vector<std::string>& byproducts,
+ cmListFileBacktrace const& bt,
+ cmCommandOrigin origin);
+
+ enum class OutputRole
+ {
+ Primary,
+ Byproduct,
+ };
+
+ /**
+ * Add source file outputs.
+ */
+ void AddSourceOutputs(cmSourceFile* source,
+ std::vector<std::string> const& outputs,
+ OutputRole role, cmListFileBacktrace const& bt,
+ cmCommandOrigin origin);
+
+ /**
+ * Return the target if the provided source name is a byproduct of a utility
+ * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
+ * Return the source file which has the provided source name as output.
+ */
+ cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
+
+ /**
+ * Is there a source file that has the provided source name as an output?
+ * If so then return it.
+ */
+ cmSourceFile* GetSourceFileWithOutput(
+ const std::string& name,
+ cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
+
std::string GetProjectName() const;
/** Compute the language used to compile the given source file. */
@@ -405,7 +481,7 @@ public:
const std::string& fname);
/** Construct a comment for a custom command. */
std::string ConstructComment(cmCustomCommandGenerator const& ccg,
- const char* default_comment = "");
+ const char* default_comment = "") const;
// Compute object file names.
std::string GetObjectFileNameWithoutTarget(
const cmSourceFile& source, std::string const& dir_max,
@@ -473,8 +549,7 @@ public:
void CreateEvaluationFileOutputs(const std::string& config);
void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
- const char* GetRuleLauncher(cmGeneratorTarget* target,
- const std::string& prop);
+ cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop);
protected:
//! put all the libraries for a target on into the given stream
@@ -532,6 +607,36 @@ protected:
bool BackwardsCompatibilityFinal;
private:
+ /**
+ * See LinearGetSourceFileWithOutput for background information
+ */
+ cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
+
+ /**
+ * Generalized old version of GetSourceFileWithOutput kept for
+ * backward-compatibility. It implements a linear search and supports
+ * relative file paths. It is used as a fall back by GetSourceFileWithOutput
+ * and GetSourcesWithOutput.
+ */
+ cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
+ cmSourceOutputKind kind,
+ bool& byproduct) const;
+ struct SourceEntry
+ {
+ cmSourcesWithOutput Sources;
+ };
+
+ // A map for fast output to input look up.
+ using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
+ OutputToSourceMap OutputToSource;
+
+ void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target,
+ cmListFileBacktrace const& bt,
+ cmCommandOrigin origin);
+ void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
+ OutputRole role, cmListFileBacktrace const& bt,
+ cmCommandOrigin origin);
+
void AddSharedFlags(std::string& flags, const std::string& lang,
bool shared);
bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
@@ -587,7 +692,7 @@ void AppendCustomCommandToOutput(cmLocalGenerator& lg,
void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
cmCommandOrigin origin, cmTarget* target,
- const cmUtilityOutput& force, const char* workingDir,
+ const char* workingDir,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index ad782ee..5a747e5 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -10,6 +10,8 @@
#include <sstream>
#include <utility>
+#include <cmext/string_view>
+
#include "cmsys/FStream.hxx"
#include "cmCryptoHash.h"
@@ -22,7 +24,9 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmNinjaTargetGenerator.h"
+#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -553,9 +557,13 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
std::string launcher = this->MakeCustomLauncher(ccg);
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
+ std::string c = ccg.GetCommand(i);
+ if (c.empty()) {
+ continue;
+ }
cmdLines.push_back(launcher +
this->ConvertToOutputFormat(
- ccg.GetCommand(i),
+ c,
gg->IsMultiConfig() ? cmOutputConverter::NINJAMULTI
: cmOutputConverter::SHELL));
@@ -565,71 +573,253 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
}
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
- cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps,
- const std::string& config)
+ cmCustomCommand const* cc, const std::set<cmGeneratorTarget*>& targets,
+ const std::string& fileConfig)
{
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
- if (gg->SeenCustomCommand(cc, config)) {
+ if (gg->SeenCustomCommand(cc, fileConfig)) {
return;
}
- cmCustomCommandGenerator ccg(*cc, config, this);
+ auto ccgs = this->MakeCustomCommandGenerators(*cc, fileConfig);
+ for (cmCustomCommandGenerator const& ccg : ccgs) {
+ cmNinjaDeps orderOnlyDeps;
- const std::vector<std::string>& outputs = ccg.GetOutputs();
- const std::vector<std::string>& byproducts = ccg.GetByproducts();
-
- bool symbolic = false;
- for (std::string const& output : outputs) {
- if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
- if (sf->GetPropertyAsBool("SYMBOLIC")) {
- symbolic = true;
- break;
+ // A custom command may appear on multiple targets. However, some build
+ // systems exist where the target dependencies on some of the targets are
+ // overspecified, leading to a dependency cycle. If we assume all target
+ // dependencies are a superset of the true target dependencies for this
+ // custom command, we can take the set intersection of all target
+ // dependencies to obtain a correct dependency list.
+ //
+ // FIXME: This won't work in certain obscure scenarios involving indirect
+ // dependencies.
+ auto j = targets.begin();
+ assert(j != targets.end());
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
+ *j, orderOnlyDeps, ccg.GetOutputConfig(), fileConfig, ccgs.size() > 1);
+ std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end());
+ ++j;
+
+ for (; j != targets.end(); ++j) {
+ std::vector<std::string> jDeps;
+ std::vector<std::string> depsIntersection;
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
+ *j, jDeps, ccg.GetOutputConfig(), fileConfig, ccgs.size() > 1);
+ std::sort(jDeps.begin(), jDeps.end());
+ std::set_intersection(orderOnlyDeps.begin(), orderOnlyDeps.end(),
+ jDeps.begin(), jDeps.end(),
+ std::back_inserter(depsIntersection));
+ orderOnlyDeps = depsIntersection;
+ }
+
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
+ const std::vector<std::string>& byproducts = ccg.GetByproducts();
+
+ bool symbolic = false;
+ for (std::string const& output : outputs) {
+ if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
+ if (sf->GetPropertyAsBool("SYMBOLIC")) {
+ symbolic = true;
+ break;
+ }
+ }
+ }
+
+ cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
+ std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
+ gg->MapToNinjaPath());
+ std::transform(byproducts.begin(), byproducts.end(),
+ ninjaOutputs.begin() + outputs.size(),
+ gg->MapToNinjaPath());
+
+ for (std::string const& ninjaOutput : ninjaOutputs) {
+ gg->SeenCustomCommandOutput(ninjaOutput);
+ }
+
+ cmNinjaDeps ninjaDeps;
+ this->AppendCustomCommandDeps(ccg, ninjaDeps, fileConfig);
+
+ std::vector<std::string> cmdLines;
+ this->AppendCustomCommandLines(ccg, cmdLines);
+
+ if (cmdLines.empty()) {
+ cmNinjaBuild build("phony");
+ build.Comment = "Phony custom command for " + ninjaOutputs[0];
+ build.Outputs = std::move(ninjaOutputs);
+ build.ExplicitDeps = std::move(ninjaDeps);
+ build.OrderOnlyDeps = orderOnlyDeps;
+ gg->WriteBuild(this->GetImplFileStream(fileConfig), build);
+ } else {
+ std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
+ // Hash full path to make unique.
+ customStep += '-';
+ cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+ customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
+
+ std::string depfile = cc->GetDepfile();
+ if (!depfile.empty()) {
+ switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
+ case cmPolicies::WARN:
+ if (this->GetCurrentBinaryDirectory() !=
+ this->GetBinaryDirectory() ||
+ this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0116")) {
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
+ cc->GetBacktrace());
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ cmSystemTools::MakeDirectory(
+ cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
+ depfile = ccg.GetInternalDepfile();
+ break;
+ }
}
+
+ gg->WriteCustomCommandBuild(
+ this->BuildCommandLine(cmdLines, customStep),
+ this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
+ depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
+ /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig,
+ ninjaDeps, orderOnlyDeps);
}
}
+}
-#if 0
-# error TODO: Once CC in an ExternalProject target must provide the \
- file of each imported target that has an add_dependencies pointing \
- at us. How to know which ExternalProject step actually provides it?
-#endif
- cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
- std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
- gg->MapToNinjaPath());
- std::transform(byproducts.begin(), byproducts.end(),
- ninjaOutputs.begin() + outputs.size(), gg->MapToNinjaPath());
+namespace {
+bool HasUniqueByproducts(cmLocalGenerator& lg,
+ std::vector<std::string> const& byproducts,
+ cmListFileBacktrace const& bt)
+{
+ std::vector<std::string> configs =
+ lg.GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+ cmGeneratorExpression ge(bt);
+ for (std::string const& p : byproducts) {
+ if (cmGeneratorExpression::Find(p) == std::string::npos) {
+ return false;
+ }
+ std::set<std::string> seen;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
+ for (std::string const& config : configs) {
+ for (std::string const& b :
+ lg.ExpandCustomCommandOutputPaths(*cge, config)) {
+ if (!seen.insert(b).second) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
- for (std::string const& ninjaOutput : ninjaOutputs) {
- gg->SeenCustomCommandOutput(ninjaOutput);
+bool HasUniqueOutputs(std::vector<cmCustomCommandGenerator> const& ccgs)
+{
+ std::set<std::string> allOutputs;
+ std::set<std::string> allByproducts;
+ for (cmCustomCommandGenerator const& ccg : ccgs) {
+ for (std::string const& output : ccg.GetOutputs()) {
+ if (!allOutputs.insert(output).second) {
+ return false;
+ }
+ }
+ for (std::string const& byproduct : ccg.GetByproducts()) {
+ if (!allByproducts.insert(byproduct).second) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+}
+
+std::string cmLocalNinjaGenerator::CreateUtilityOutput(
+ std::string const& targetName, std::vector<std::string> const& byproducts,
+ cmListFileBacktrace const& bt)
+{
+ // In Ninja Multi-Config, we can only produce cross-config utility
+ // commands if all byproducts are per-config.
+ if (!this->GetGlobalGenerator()->IsMultiConfig() ||
+ !HasUniqueByproducts(*this, byproducts, bt)) {
+ return this->cmLocalGenerator::CreateUtilityOutput(targetName, byproducts,
+ bt);
+ }
+
+ std::string const base = cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", targetName, '-');
+ // The output is not actually created so mark it symbolic.
+ for (std::string const& config :
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
+ std::string const force = cmStrCat(base, config);
+ if (cmSourceFile* sf = this->Makefile->GetOrCreateGeneratedSource(force)) {
+ sf->SetProperty("SYMBOLIC", "1");
+ } else {
+ cmSystemTools::Error("Could not get source file entry for " + force);
+ }
}
+ this->GetGlobalNinjaGenerator()->AddPerConfigUtilityTarget(targetName);
+ return cmStrCat(base, "$<CONFIG>"_s);
+}
+
+std::vector<cmCustomCommandGenerator>
+cmLocalNinjaGenerator::MakeCustomCommandGenerators(
+ cmCustomCommand const& cc, std::string const& fileConfig)
+{
+ cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator();
- cmNinjaDeps ninjaDeps;
- this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
+ bool transformDepfile = false;
+ switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
+ case cmPolicies::OLD:
+ case cmPolicies::WARN:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ transformDepfile = true;
+ break;
+ }
- std::vector<std::string> cmdLines;
- this->AppendCustomCommandLines(ccg, cmdLines);
+ // Start with the build graph's configuration.
+ std::vector<cmCustomCommandGenerator> ccgs;
+ ccgs.emplace_back(cc, fileConfig, this, transformDepfile);
- if (cmdLines.empty()) {
- cmNinjaBuild build("phony");
- build.Comment = "Phony custom command for " + ninjaOutputs[0];
- build.Outputs = std::move(ninjaOutputs);
- build.ExplicitDeps = std::move(ninjaDeps);
- build.OrderOnlyDeps = orderOnlyDeps;
- gg->WriteBuild(this->GetImplFileStream(config), build);
- } else {
- std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
- // Hash full path to make unique.
- customStep += '-';
- cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
- customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
+ // Consider adding cross configurations.
+ if (!gg->EnableCrossConfigBuild()) {
+ return ccgs;
+ }
+
+ // Outputs and byproducts must be expressed using generator expressions.
+ for (std::string const& output : cc.GetOutputs()) {
+ if (cmGeneratorExpression::Find(output) == std::string::npos) {
+ return ccgs;
+ }
+ }
+ for (std::string const& byproduct : cc.GetByproducts()) {
+ if (cmGeneratorExpression::Find(byproduct) == std::string::npos) {
+ return ccgs;
+ }
+ }
- gg->WriteCustomCommandBuild(
- this->BuildCommandLine(cmdLines, customStep),
- this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
- cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(),
- /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
- ninjaDeps, orderOnlyDeps);
+ // Tentatively add the other cross configurations.
+ for (std::string const& config : gg->GetCrossConfigs(fileConfig)) {
+ if (fileConfig != config) {
+ ccgs.emplace_back(cc, fileConfig, this, transformDepfile, config);
+ }
+ }
+
+ // If outputs and byproducts are not unique to each configuration,
+ // drop the cross configurations.
+ if (!HasUniqueOutputs(ccgs)) {
+ ccgs.erase(ccgs.begin() + 1, ccgs.end());
}
+
+ return ccgs;
}
void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
@@ -645,42 +835,13 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
}
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
- const std::string& config)
+ const std::string& fileConfig)
{
for (cmCustomCommand const* customCommand : this->CustomCommands) {
auto i = this->CustomCommandTargets.find(customCommand);
assert(i != this->CustomCommandTargets.end());
- // A custom command may appear on multiple targets. However, some build
- // systems exist where the target dependencies on some of the targets are
- // overspecified, leading to a dependency cycle. If we assume all target
- // dependencies are a superset of the true target dependencies for this
- // custom command, we can take the set intersection of all target
- // dependencies to obtain a correct dependency list.
- //
- // FIXME: This won't work in certain obscure scenarios involving indirect
- // dependencies.
- auto j = i->second.begin();
- assert(j != i->second.end());
- std::vector<std::string> ccTargetDeps;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
- *j, ccTargetDeps, config);
- std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
- ++j;
-
- for (; j != i->second.end(); ++j) {
- std::vector<std::string> jDeps;
- std::vector<std::string> depsIntersection;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps,
- config);
- std::sort(jDeps.begin(), jDeps.end());
- std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
- jDeps.begin(), jDeps.end(),
- std::back_inserter(depsIntersection));
- ccTargetDeps = depsIntersection;
- }
-
- this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config);
+ this->WriteCustomCommandBuildStatement(i->first, i->second, fileConfig);
}
}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index e81402c..87d5e53 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "cmListFileCache.h"
#include "cmLocalCommonGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
@@ -70,6 +71,13 @@ public:
const std::string& fileConfig,
cmNinjaTargetDepends depends);
+ std::string CreateUtilityOutput(std::string const& targetName,
+ std::vector<std::string> const& byproducts,
+ cmListFileBacktrace const& bt) override;
+
+ std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
+ cmCustomCommand const& cc, std::string const& config) override;
+
void AddCustomCommandTarget(cmCustomCommand const* cc,
cmGeneratorTarget* target);
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
@@ -99,9 +107,9 @@ private:
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
- void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
- const cmNinjaDeps& orderOnlyDeps,
- const std::string& config);
+ void WriteCustomCommandBuildStatement(
+ cmCustomCommand const* cc, const std::set<cmGeneratorTarget*>& targets,
+ const std::string& config);
void WriteCustomCommandBuildStatements(const std::string& config);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c877cf8..df7952c 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -5,18 +5,23 @@
#include <algorithm>
#include <cassert>
#include <cstdio>
+#include <functional>
#include <sstream>
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
+#include "cmCMakePath.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
+#include "cmDependsCompiler.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
@@ -50,8 +55,9 @@
# include "cmDependsJava.h"
#endif
+namespace {
// Helper function used below.
-static std::string cmSplitExtension(std::string const& in, std::string& base)
+std::string cmSplitExtension(std::string const& in, std::string& base)
{
std::string ext;
std::string::size_type dot_pos = in.rfind('.');
@@ -65,6 +71,43 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
return ext;
}
+// Helper predicate for removing absolute paths that don't point to the
+// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
+// is set ON, to only consider in-project dependencies during the build.
+class NotInProjectDir
+{
+public:
+ // Constructor with the source and binary directory's path
+ NotInProjectDir(cm::string_view sourceDir, cm::string_view binaryDir)
+ : SourceDir(sourceDir)
+ , BinaryDir(binaryDir)
+ {
+ }
+
+ // Operator evaluating the predicate
+ bool operator()(const std::string& p) const
+ {
+ auto path = cmCMakePath(p).Normal();
+
+ // Keep all relative paths:
+ if (path.IsRelative()) {
+ return false;
+ }
+
+ // If it's an absolute path, check if it starts with the source
+ // directory:
+ return !(cmCMakePath(this->SourceDir).IsPrefix(path) ||
+ cmCMakePath(this->BinaryDir).IsPrefix(path));
+ }
+
+private:
+ // The path to the source directory
+ cm::string_view SourceDir;
+ // The path to the binary directory
+ cm::string_view BinaryDir;
+};
+}
+
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmGlobalGenerator* gg, cmMakefile* mf)
: cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory())
@@ -552,8 +595,10 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
}
}
- // Write the list of commands.
- os << cmWrap("\t", commands, "", "\n") << "\n";
+ if (!commands.empty()) {
+ // Write the list of commands.
+ os << cmWrap("\t", commands, "", "\n") << "\n";
+ }
if (symbolic && !this->IsWatcomWMake()) {
os << ".PHONY : " << tgt << "\n";
}
@@ -960,7 +1005,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
std::string launcher;
// Short-circuit if there is no launcher.
- const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
+ cmProp val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
if (cmNonempty(val)) {
// Expand rule variables referenced in the given launcher command.
cmRulePlaceholderExpander::RuleVariables vars;
@@ -980,7 +1025,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
}
vars.Output = output.c_str();
- launcher = val;
+ launcher = *val;
rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
if (!launcher.empty()) {
launcher += " ";
@@ -1298,91 +1343,153 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
cmSystemTools::Error("Target DependInfo.cmake file not found");
}
+ bool status = true;
+
// Check if any multiple output pairs have a missing file.
this->CheckMultipleOutputs(verbose);
std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
- std::string const internalDependFile = targetDir + "/depend.internal";
- std::string const dependFile = targetDir + "/depend.make";
-
- // If the target DependInfo.cmake file has changed since the last
- // time dependencies were scanned then force rescanning. This may
- // happen when a new source file is added and CMake regenerates the
- // project but no other sources were touched.
- bool needRescanDependInfo = false;
- cmFileTimeCache* ftc =
- this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
- {
- int result;
- if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
- if (verbose) {
- cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
- "\" is newer than depender \"",
- internalDependFile, "\".\n"));
+ if (!this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
+ // dependencies are managed by CMake itself
+
+ std::string const internalDependFile = targetDir + "/depend.internal";
+ std::string const dependFile = targetDir + "/depend.make";
+
+ // If the target DependInfo.cmake file has changed since the last
+ // time dependencies were scanned then force rescanning. This may
+ // happen when a new source file is added and CMake regenerates the
+ // project but no other sources were touched.
+ bool needRescanDependInfo = false;
+ cmFileTimeCache* ftc =
+ this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
+ {
+ int result;
+ if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
+ if (verbose) {
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
+ }
+ needRescanDependInfo = true;
}
- needRescanDependInfo = true;
}
- }
- // If the directory information is newer than depend.internal, include dirs
- // may have changed. In this case discard all old dependencies.
- bool needRescanDirInfo = false;
- {
- std::string dirInfoFile =
- cmStrCat(this->GetCurrentBinaryDirectory(),
- "/CMakeFiles/CMakeDirectoryInformation.cmake");
- int result;
- if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
- result < 0) {
- if (verbose) {
- cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
- "\" is newer than depender \"",
- internalDependFile, "\".\n"));
+ // If the directory information is newer than depend.internal, include
+ // dirs may have changed. In this case discard all old dependencies.
+ bool needRescanDirInfo = false;
+ {
+ std::string dirInfoFile =
+ cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeDirectoryInformation.cmake");
+ int result;
+ if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
+ result < 0) {
+ if (verbose) {
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
+ }
+ needRescanDirInfo = true;
}
- needRescanDirInfo = true;
+ }
+
+ // Check the implicit dependencies to see if they are up to date.
+ // The build.make file may have explicit dependencies for the object
+ // files but these will not affect the scanning process so they need
+ // not be considered.
+ cmDepends::DependencyMap validDependencies;
+ bool needRescanDependencies = false;
+ if (!needRescanDirInfo) {
+ cmDependsC checker;
+ checker.SetVerbose(verbose);
+ checker.SetFileTimeCache(ftc);
+ // cmDependsC::Check() fills the vector validDependencies() with the
+ // dependencies for those files where they are still valid, i.e.
+ // neither the files themselves nor any files they depend on have
+ // changed. We don't do that if the CMakeDirectoryInformation.cmake
+ // file has changed, because then potentially all dependencies have
+ // changed. This information is given later on to cmDependsC, which
+ // then only rescans the files where it did not get valid dependencies
+ // via this dependency vector. This means that in the normal case, when
+ // only few or one file have been edited, then also only this one file
+ // is actually scanned again, instead of all files for this target.
+ needRescanDependencies =
+ !checker.Check(dependFile, internalDependFile, validDependencies);
+ }
+
+ if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
+ // The dependencies must be regenerated.
+ std::string targetName = cmSystemTools::GetFilenameName(targetDir);
+ targetName = targetName.substr(0, targetName.length() - 4);
+ std::string message =
+ cmStrCat("Scanning dependencies of target ", targetName);
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
+ cmsysTerminal_Color_ForegroundBold,
+ message.c_str(), true, color);
+
+ status = this->ScanDependencies(targetDir, dependFile,
+ internalDependFile, validDependencies);
}
}
- // Check the implicit dependencies to see if they are up to date.
- // The build.make file may have explicit dependencies for the object
- // files but these will not affect the scanning process so they need
- // not be considered.
- cmDepends::DependencyMap validDependencies;
- bool needRescanDependencies = false;
- if (!needRescanDirInfo) {
- cmDependsC checker;
- checker.SetVerbose(verbose);
- checker.SetFileTimeCache(ftc);
- // cmDependsC::Check() fills the vector validDependencies() with the
- // dependencies for those files where they are still valid, i.e. neither
- // the files themselves nor any files they depend on have changed.
- // We don't do that if the CMakeDirectoryInformation.cmake file has
- // changed, because then potentially all dependencies have changed.
- // This information is given later on to cmDependsC, which then only
- // rescans the files where it did not get valid dependencies via this
- // dependency vector. This means that in the normal case, when only
- // few or one file have been edited, then also only this one file is
- // actually scanned again, instead of all files for this target.
- needRescanDependencies =
- !checker.Check(dependFile, internalDependFile, validDependencies);
- }
-
- if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
- // The dependencies must be regenerated.
- std::string targetName = cmSystemTools::GetFilenameName(targetDir);
- targetName = targetName.substr(0, targetName.length() - 4);
- std::string message =
- cmStrCat("Scanning dependencies of target ", targetName);
- cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
- cmsysTerminal_Color_ForegroundBold,
- message.c_str(), true, color);
-
- return this->ScanDependencies(targetDir, dependFile, internalDependFile,
- validDependencies);
+ auto depends =
+ this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
+ if (!depends.empty()) {
+ // dependencies are managed by compiler
+ auto depFiles = cmExpandedList(depends, true);
+ std::string const internalDepFile =
+ targetDir + "/compiler_depend.internal";
+ std::string const depFile = targetDir + "/compiler_depend.make";
+ cmDepends::DependencyMap dependencies;
+ cmDependsCompiler depsManager;
+ bool projectOnly = cmIsOn(
+ this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_IN_PROJECT_ONLY"));
+
+ depsManager.SetVerbose(verbose);
+ depsManager.SetLocalGenerator(this);
+
+ if (!depsManager.CheckDependencies(
+ internalDepFile, depFiles, dependencies,
+ projectOnly ? NotInProjectDir(this->GetSourceDirectory(),
+ this->GetBinaryDirectory())
+ : std::function<bool(const std::string&)>())) {
+ // regenerate dependencies files
+ std::string targetName =
+ cmCMakePath(targetDir).GetFileName().RemoveExtension().GenericString();
+ auto message = cmStrCat(
+ "Consolidate compiler generated dependencies of target ", targetName);
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
+ cmsysTerminal_Color_ForegroundBold,
+ message.c_str(), true, color);
+
+ // Open the make depends file. This should be copy-if-different
+ // because the make tool may try to reload it needlessly otherwise.
+ cmGeneratedFileStream ruleFileStream(
+ depFile, false, this->GlobalGenerator->GetMakefileEncoding());
+ ruleFileStream.SetCopyIfDifferent(true);
+ if (!ruleFileStream) {
+ return false;
+ }
+
+ // Open the cmake dependency tracking file. This should not be
+ // copy-if-different because dependencies are re-scanned when it is
+ // older than the DependInfo.cmake.
+ cmGeneratedFileStream internalRuleFileStream(
+ internalDepFile, false, this->GlobalGenerator->GetMakefileEncoding());
+ if (!internalRuleFileStream) {
+ return false;
+ }
+
+ this->WriteDisclaimer(ruleFileStream);
+ this->WriteDisclaimer(internalRuleFileStream);
+
+ depsManager.WriteDependencies(dependencies, ruleFileStream,
+ internalRuleFileStream);
+ }
}
// The dependencies are already up-to-date.
- return true;
+ return status;
}
bool cmLocalUnixMakefileGenerator3::ScanDependencies(
@@ -1721,178 +1828,207 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
cmDepends clearer;
clearer.SetVerbose(verbose);
for (std::string const& file : files) {
- std::string dir = cmSystemTools::GetFilenamePath(file);
+ auto snapshot = mf->GetState()->CreateBaseSnapshot();
+ cmMakefile lmf(mf->GetGlobalGenerator(), snapshot);
+ lmf.ReadListFile(file);
- // Clear the implicit dependency makefile.
- std::string dependFile = dir + "/depend.make";
- clearer.Clear(dependFile);
+ if (!lmf.GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
+ std::string dir = cmSystemTools::GetFilenamePath(file);
- // Remove the internal dependency check file to force
- // regeneration.
- std::string internalDependFile = dir + "/depend.internal";
- cmSystemTools::RemoveFile(internalDependFile);
- }
-}
-
-namespace {
-// Helper predicate for removing absolute paths that don't point to the
-// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
-// is set ON, to only consider in-project dependencies during the build.
-class NotInProjectDir
-{
-public:
- // Constructor with the source and binary directory's path
- NotInProjectDir(std::string sourceDir, std::string binaryDir)
- : SourceDir(std::move(sourceDir))
- , BinaryDir(std::move(binaryDir))
- {
- }
+ // Clear the implicit dependency makefile.
+ std::string dependFile = dir + "/depend.make";
+ clearer.Clear(dependFile);
- // Operator evaluating the predicate
- bool operator()(const std::string& path) const
- {
- // Keep all relative paths:
- if (!cmSystemTools::FileIsFullPath(path)) {
- return false;
+ // Remove the internal dependency check file to force
+ // regeneration.
+ std::string internalDependFile = dir + "/depend.internal";
+ cmSystemTools::RemoveFile(internalDependFile);
}
- // If it's an absolute path, check if it starts with the source
- // directory:
- return (
- !(IsInDirectory(SourceDir, path) || IsInDirectory(BinaryDir, path)));
- }
-private:
- // Helper function used by the predicate
- static bool IsInDirectory(const std::string& baseDir,
- const std::string& testDir)
- {
- // First check if the test directory "starts with" the base directory:
- if (!cmHasPrefix(testDir, baseDir)) {
- return false;
+ auto depsFiles = lmf.GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
+ if (!depsFiles.empty()) {
+ auto dir = cmCMakePath(file).GetParentPath();
+ // Clear the implicit dependency makefile.
+ auto depFile = cmCMakePath(dir).Append("compiler_depend.make");
+ clearer.Clear(depFile.GenericString());
+
+ // Remove the internal dependency check file
+ auto internalDepFile =
+ cmCMakePath(dir).Append("compiler_depend.internal");
+ cmSystemTools::RemoveFile(internalDepFile.GenericString());
+
+ // Touch timestamp file to force dependencies regeneration
+ auto DepTimestamp = cmCMakePath(dir).Append("compiler_depend.ts");
+ cmSystemTools::Touch(DepTimestamp.GenericString(), true);
+
+ // clear the dependencies files generated by the compiler
+ std::vector<std::string> dependencies = cmExpandedList(depsFiles);
+ cmDependsCompiler depsManager;
+ depsManager.SetVerbose(verbose);
+ depsManager.ClearDependencies(dependencies);
}
- // If it does, then check that it's either the same string, or that the
- // next character is a slash:
- return ((testDir.size() == baseDir.size()) ||
- (testDir[baseDir.size()] == '/'));
}
-
- // The path to the source directory
- std::string SourceDir;
- // The path to the binary directory
- std::string BinaryDir;
-};
}
void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
std::ostream& cmakefileStream, cmGeneratorTarget* target)
{
- ImplicitDependLanguageMap const& implicitLangs =
- this->GetImplicitDepends(target);
+ // To enable dependencies filtering
+ cmakefileStream << "\n"
+ << "# Consider dependencies only in project.\n"
+ << "set(CMAKE_DEPENDS_IN_PROJECT_ONLY "
+ << (cmIsOn(this->Makefile->GetSafeDefinition(
+ "CMAKE_DEPENDS_IN_PROJECT_ONLY"))
+ ? "ON"
+ : "OFF")
+ << ")\n\n";
+
+ auto const& implicitLangs =
+ this->GetImplicitDepends(target, cmDependencyScannerKind::CMake);
// list the languages
- cmakefileStream
- << "# The set of languages for which implicit dependencies are needed:\n";
+ cmakefileStream << "# The set of languages for which implicit "
+ "dependencies are needed:\n";
cmakefileStream << "set(CMAKE_DEPENDS_LANGUAGES\n";
for (auto const& implicitLang : implicitLangs) {
cmakefileStream << " \"" << implicitLang.first << "\"\n";
}
cmakefileStream << " )\n";
- // now list the files for each language
- cmakefileStream
- << "# The set of files for implicit dependencies of each language:\n";
- for (auto const& implicitLang : implicitLangs) {
- cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << implicitLang.first
- << "\n";
- ImplicitDependFileMap const& implicitPairs = implicitLang.second;
-
- // for each file pair
- for (auto const& implicitPair : implicitPairs) {
- for (auto const& di : implicitPair.second) {
- cmakefileStream << " \"" << di << "\" ";
- cmakefileStream << "\"" << implicitPair.first << "\"\n";
+ if (!implicitLangs.empty()) {
+ // now list the files for each language
+ cmakefileStream
+ << "# The set of files for implicit dependencies of each language:\n";
+ for (auto const& implicitLang : implicitLangs) {
+ const auto& lang = implicitLang.first;
+
+ cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << lang << "\n";
+ auto const& implicitPairs = implicitLang.second;
+
+ // for each file pair
+ for (auto const& implicitPair : implicitPairs) {
+ for (auto const& di : implicitPair.second) {
+ cmakefileStream << " \"" << di << "\" ";
+ cmakefileStream << "\"" << implicitPair.first << "\"\n";
+ }
}
- }
- cmakefileStream << " )\n";
-
- // Tell the dependency scanner what compiler is used.
- std::string cidVar =
- cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
- cmProp cid = this->Makefile->GetDefinition(cidVar);
- if (cmNonempty(cid)) {
- cmakefileStream << "set(CMAKE_" << implicitLang.first
- << "_COMPILER_ID \"" << *cid << "\")\n";
- }
+ cmakefileStream << " )\n";
- if (implicitLang.first == "Fortran") {
- std::string smodSep =
- this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
- std::string smodExt =
- this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
- cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
- << "\")\n";
- cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
- << "\")\n";
- }
+ // Tell the dependency scanner what compiler is used.
+ std::string cidVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID");
+ cmProp cid = this->Makefile->GetDefinition(cidVar);
+ if (cmNonempty(cid)) {
+ cmakefileStream << "set(CMAKE_" << lang << "_COMPILER_ID \"" << *cid
+ << "\")\n";
+ }
- // Build a list of preprocessor definitions for the target.
- std::set<std::string> defines;
- this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
- defines);
- if (!defines.empty()) {
- /* clang-format off */
+ if (lang == "Fortran") {
+ std::string smodSep =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
+ std::string smodExt =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
+ cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
+ << "\")\n";
+ cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
+ << "\")\n";
+ }
+
+ // Build a list of preprocessor definitions for the target.
+ std::set<std::string> defines;
+ this->GetTargetDefines(target, this->GetConfigName(), lang, defines);
+ if (!defines.empty()) {
+ /* clang-format off */
cmakefileStream
<< "\n"
<< "# Preprocessor definitions for this target.\n"
- << "set(CMAKE_TARGET_DEFINITIONS_" << implicitLang.first << "\n";
- /* clang-format on */
- for (std::string const& define : defines) {
- cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
- << "\n";
+ << "set(CMAKE_TARGET_DEFINITIONS_" << lang << "\n";
+ /* clang-format on */
+ for (std::string const& define : defines) {
+ cmakefileStream << " " << cmOutputConverter::EscapeForCMake(define)
+ << "\n";
+ }
+ cmakefileStream << " )\n";
+ }
+
+ // Target-specific include directories:
+ cmakefileStream << "\n"
+ << "# The include file search paths:\n";
+ cmakefileStream << "set(CMAKE_" << lang << "_TARGET_INCLUDE_PATH\n";
+ std::vector<std::string> includes;
+
+ this->GetIncludeDirectories(includes, target, lang,
+ this->GetConfigName());
+ std::string const& binaryDir = this->GetState()->GetBinaryDirectory();
+ if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
+ std::string const& sourceDir = this->GetState()->GetSourceDirectory();
+ cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
+ }
+ for (std::string const& include : includes) {
+ cmakefileStream << " \""
+ << this->MaybeConvertToRelativePath(binaryDir, include)
+ << "\"\n";
}
cmakefileStream << " )\n";
}
- // Target-specific include directories:
- cmakefileStream << "\n"
- << "# The include file search paths:\n";
- cmakefileStream << "set(CMAKE_" << implicitLang.first
- << "_TARGET_INCLUDE_PATH\n";
- std::vector<std::string> includes;
-
- this->GetIncludeDirectories(includes, target, implicitLang.first,
- this->GetConfigName());
- std::string binaryDir = this->GetState()->GetBinaryDirectory();
- if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
- std::string const& sourceDir = this->GetState()->GetSourceDirectory();
- cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
+ // Store include transform rule properties. Write the directory
+ // rules first because they may be overridden by later target rules.
+ std::vector<std::string> transformRules;
+ if (cmProp xform =
+ this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
+ cmExpandList(*xform, transformRules);
}
- for (std::string const& include : includes) {
- cmakefileStream << " \""
- << this->MaybeConvertToRelativePath(binaryDir, include)
- << "\"\n";
+ if (cmProp xform =
+ target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
+ cmExpandList(*xform, transformRules);
+ }
+ if (!transformRules.empty()) {
+ cmakefileStream << "\nset(CMAKE_INCLUDE_TRANSFORMS\n";
+ for (std::string const& tr : transformRules) {
+ cmakefileStream << " " << cmOutputConverter::EscapeForCMake(tr)
+ << "\n";
+ }
+ cmakefileStream << " )\n";
}
- cmakefileStream << " )\n";
}
- // Store include transform rule properties. Write the directory
- // rules first because they may be overridden by later target rules.
- std::vector<std::string> transformRules;
- if (cmProp xform =
- this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
- }
- if (cmProp xform =
- target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
- }
- if (!transformRules.empty()) {
- cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
- for (std::string const& tr : transformRules) {
- cmakefileStream << " " << cmOutputConverter::EscapeForCMake(tr) << "\n";
+ auto const& compilerLangs =
+ this->GetImplicitDepends(target, cmDependencyScannerKind::Compiler);
+
+ // list the dependency files managed by the compiler
+ cmakefileStream << "\n# The set of dependency files which are needed:\n";
+ cmakefileStream << "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
+ for (auto const& compilerLang : compilerLangs) {
+ auto const& compilerPairs = compilerLang.second;
+ if (compilerLang.first == "CUSTOM"_s) {
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << R"( "" ")"
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << R"(" "custom" ")"
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), src)
+ << "\"\n";
+ }
+ }
+ } else {
+ auto depFormat = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << " \"" << src << "\" \""
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << "\" \"" << depFormat << "\" \""
+ << this->MaybeConvertToRelativePath(
+ this->GetBinaryDirectory(), compilerPair.first)
+ << ".d\"\n";
+ }
+ }
}
- cmakefileStream << " )\n";
}
+ cmakefileStream << " )\n";
}
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
@@ -2049,16 +2185,18 @@ std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(
}
cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
-cmLocalUnixMakefileGenerator3::GetImplicitDepends(const cmGeneratorTarget* tgt)
+cmLocalUnixMakefileGenerator3::GetImplicitDepends(
+ const cmGeneratorTarget* tgt, cmDependencyScannerKind scanner)
{
- return this->ImplicitDepends[tgt->GetName()];
+ return this->ImplicitDepends[tgt->GetName()][scanner];
}
void cmLocalUnixMakefileGenerator3::AddImplicitDepends(
const cmGeneratorTarget* tgt, const std::string& lang,
- const std::string& obj, const std::string& src)
+ const std::string& obj, const std::string& src,
+ cmDependencyScannerKind scanner)
{
- this->ImplicitDepends[tgt->GetName()][lang][obj].push_back(src);
+ this->ImplicitDepends[tgt->GetName()][scanner][lang][obj].push_back(src);
}
void cmLocalUnixMakefileGenerator3::CreateCDCommand(
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 8286d67..14dd0ba 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -13,6 +13,7 @@
#include "cmDepends.h"
#include "cmLocalCommonGenerator.h"
+#include "cmLocalGenerator.h"
class cmCustomCommand;
class cmCustomCommandGenerator;
@@ -152,23 +153,21 @@ public:
// File pairs for implicit dependency scanning. The key of the map
// is the depender and the value is the explicit dependee.
- struct ImplicitDependFileMap : public cmDepends::DependencyMap
- {
- };
- struct ImplicitDependLanguageMap
- : public std::map<std::string, ImplicitDependFileMap>
- {
- };
- struct ImplicitDependTargetMap
- : public std::map<std::string, ImplicitDependLanguageMap>
- {
- };
+ using ImplicitDependFileMap = cmDepends::DependencyMap;
+ using ImplicitDependLanguageMap =
+ std::map<std::string, ImplicitDependFileMap>;
+ using ImplicitDependScannerMap =
+ std::map<cmDependencyScannerKind, ImplicitDependLanguageMap>;
+ using ImplicitDependTargetMap =
+ std::map<std::string, ImplicitDependScannerMap>;
ImplicitDependLanguageMap const& GetImplicitDepends(
- cmGeneratorTarget const* tgt);
+ cmGeneratorTarget const* tgt,
+ cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
- void AddImplicitDepends(cmGeneratorTarget const* tgt,
- const std::string& lang, const std::string& obj,
- const std::string& src);
+ void AddImplicitDepends(
+ cmGeneratorTarget const* tgt, const std::string& lang,
+ const std::string& obj, const std::string& src,
+ cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
// write the target rules for the local Makefile into the stream
void WriteLocalAllRules(std::ostream& ruleFileStream);
@@ -178,11 +177,11 @@ public:
/** Get whether to create rules to generate preprocessed and
assembly sources. This could be converted to a variable lookup
later. */
- bool GetCreatePreprocessedSourceRules()
+ bool GetCreatePreprocessedSourceRules() const
{
return !this->SkipPreprocessedSourceRules;
}
- bool GetCreateAssemblySourceRules()
+ bool GetCreateAssemblySourceRules() const
{
return !this->SkipAssemblySourceRules;
}
diff --git a/Source/cmMSVC60LinkLineComputer.cxx b/Source/cmMSVC60LinkLineComputer.cxx
index 74c9435..8cf3765 100644
--- a/Source/cmMSVC60LinkLineComputer.cxx
+++ b/Source/cmMSVC60LinkLineComputer.cxx
@@ -36,5 +36,5 @@ std::string cmMSVC60LinkLineComputer::ConvertToLinkReference(
}
#endif
- return cmLinkLineComputer::ConvertToLinkReference(lib);
+ return this->cmLinkLineComputer::ConvertToLinkReference(lib);
}
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 98f88c1..8c4b2a7 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -171,8 +171,11 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
f.Functions = std::move(functions);
f.FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
- return true;
+ return mf.GetState()->AddScriptedCommand(
+ this->Args[0],
+ BT<cmState::Command>(std::move(f),
+ mf.GetBacktrace().Push(this->GetStartingContext())),
+ mf);
}
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 0e4f888..e4c8e4b 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -29,15 +29,12 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_sys_stat.h"
-
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h" // IWYU pragma: keep
#include "cmExportBuildFileGenerator.h"
-#include "cmFSPermissions.h"
#include "cmFileLockPool.h"
#include "cmFunctionBlocker.h"
#include "cmGeneratedFileStream.h"
@@ -72,8 +69,6 @@
class cmMessenger;
-using namespace cmFSPermissions;
-
cmDirectoryId::cmDirectoryId(std::string s)
: String(std::move(s))
{
@@ -870,13 +865,14 @@ void cmMakefile::EnforceDirectoryLevelRules() const
void cmMakefile::AddEvaluationFile(
const std::string& inputFile, const std::string& targetName,
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
- std::unique_ptr<cmCompiledGeneratorExpression> condition,
+ std::unique_ptr<cmCompiledGeneratorExpression> condition, mode_t permissions,
bool inputIsContent)
{
this->EvaluationFiles.push_back(
cm::make_unique<cmGeneratorExpressionEvaluationFile>(
inputFile, targetName, std::move(outputName), std::move(condition),
- inputIsContent, this->GetPolicyStatus(cmPolicies::CMP0070)));
+ inputIsContent, permissions,
+ this->GetPolicyStatus(cmPolicies::CMP0070)));
}
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
@@ -939,8 +935,6 @@ void cmMakefile::DoGenerate(cmLocalGenerator& lg)
action.Value(lg, action.Backtrace);
}
this->GeneratorActionsInvoked = true;
- this->DelayedOutputFiles.clear();
- this->DelayedOutputFilesHaveGenex = false;
// go through all configured files and see which ones still exist.
// we don't want cmake to re-run if a configured file is created and deleted
@@ -984,7 +978,7 @@ struct BacktraceGuard
this->Backtrace = std::move(current);
}
- ~BacktraceGuard() { this->Backtrace = std::move(Previous); }
+ ~BacktraceGuard() { this->Backtrace = std::move(this->Previous); }
private:
cmListFileBacktrace& Backtrace;
@@ -1104,7 +1098,7 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
}
// Always create the byproduct sources and mark them generated.
- this->CreateGeneratedByproducts(byproducts);
+ this->CreateGeneratedOutputs(byproducts);
// Strings could be moved into the callback function with C++14.
cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1163,7 +1157,7 @@ void cmMakefile::AddCustomCommandToOutput(
// Always create the output sources and mark them generated.
this->CreateGeneratedOutputs(outputs);
- this->CreateGeneratedByproducts(byproducts);
+ this->CreateGeneratedOutputs(byproducts);
// Strings could be moved into the callback function with C++14.
cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1222,9 +1216,10 @@ void cmMakefile::AddCustomCommandOldStyle(
};
// Each output must get its own copy of this rule.
- cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|"
- "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
- "hm|hpp|hxx|in|txx|inl)$");
+ cmsys::RegularExpression sourceFiles(
+ "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|cu|m|mm|"
+ "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
+ "hm|hpp|hxx|in|txx|inl)$");
// Choose whether to use a main dependency.
if (sourceFiles.find(source)) {
@@ -1247,16 +1242,11 @@ void cmMakefile::AddCustomCommandOldStyle(
}
}
-bool cmMakefile::AppendCustomCommandToOutput(
+void cmMakefile::AppendCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines)
{
- // Check as good as we can if there will be a command for this output.
- if (!this->MightHaveCustomCommand(output)) {
- return false;
- }
-
// Validate custom commands.
if (this->ValidateCustomCommand(commandLines)) {
// Dispatch command creation to allow generator expressions in outputs.
@@ -1267,29 +1257,6 @@ bool cmMakefile::AppendCustomCommandToOutput(
implicit_depends, commandLines);
});
}
-
- return true;
-}
-
-cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
-{
- std::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
- "/CMakeFiles/", target->GetName());
- std::string forceCMP0049 = target->GetSourceCMP0049(force);
- {
- cmSourceFile* sf = nullptr;
- if (!forceCMP0049.empty()) {
- sf = this->GetOrCreateSource(forceCMP0049, false,
- cmSourceFileLocationKind::Known);
- }
- // The output is not actually created so mark it symbolic.
- if (sf) {
- sf->SetProperty("SYMBOLIC", "1");
- } else {
- cmSystemTools::Error("Could not get source file entry for " + force);
- }
- }
- return { std::move(force), std::move(forceCMP0049) };
}
cmTarget* cmMakefile::AddUtilityCommand(
@@ -1308,12 +1275,8 @@ cmTarget* cmMakefile::AddUtilityCommand(
return target;
}
- // Get the output name of the utility target and mark it generated.
- cmUtilityOutput force = this->GetUtilityOutput(target);
- this->GetOrCreateGeneratedSource(force.Name);
-
// Always create the byproduct sources and mark them generated.
- this->CreateGeneratedByproducts(byproducts);
+ this->CreateGeneratedOutputs(byproducts);
// Strings could be moved into the callback function with C++14.
cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1324,8 +1287,8 @@ cmTarget* cmMakefile::AddUtilityCommand(
[=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
BacktraceGuard guard(this->Backtrace, lfbt);
detail::AddUtilityCommand(lg, lfbt, cmCommandOrigin::Project, target,
- force, GetCStrOrNull(workingStr), byproducts,
- depends, commandLines, escapeOldStyle,
+ GetCStrOrNull(workingStr), byproducts, depends,
+ commandLines, escapeOldStyle,
GetCStrOrNull(commentStr), uses_terminal,
command_expand_lists, job_pool, stdPipesUTF8);
});
@@ -1496,15 +1459,14 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
// Include transform property. There is no per-config version.
{
const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
- cmProp p = parent->GetProperty(prop);
- this->SetProperty(prop, cmToCStr(p));
+ this->SetProperty(prop, cmToCStr(parent->GetProperty(prop)));
}
// compile definitions property and per-config versions
cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
- cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
- this->SetProperty("COMPILE_DEFINITIONS", cmToCStr(p));
+ this->SetProperty("COMPILE_DEFINITIONS",
+ cmToCStr(parent->GetProperty("COMPILE_DEFINITIONS")));
std::vector<std::string> configs =
this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
for (std::string const& config : configs) {
@@ -1516,12 +1478,11 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
}
// labels
- cmProp p = parent->GetProperty("LABELS");
- this->SetProperty("LABELS", cmToCStr(p));
+ this->SetProperty("LABELS", cmToCStr(parent->GetProperty("LABELS")));
// link libraries
- p = parent->GetProperty("LINK_LIBRARIES");
- this->SetProperty("LINK_LIBRARIES", cmToCStr(p));
+ this->SetProperty("LINK_LIBRARIES",
+ cmToCStr(parent->GetProperty("LINK_LIBRARIES")));
// the initial project name
this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -2038,7 +1999,7 @@ void cmMakefile::RemoveDefinition(const std::string& name)
#endif
}
-void cmMakefile::RemoveCacheDefinition(const std::string& name)
+void cmMakefile::RemoveCacheDefinition(const std::string& name) const
{
this->GetState()->RemoveCacheEntry(name);
}
@@ -2154,213 +2115,6 @@ cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
}
namespace {
-bool AnyOutputMatches(const std::string& name,
- const std::vector<std::string>& outputs)
-{
- for (std::string const& output : outputs) {
- std::string::size_type pos = output.rfind(name);
- // If the output matches exactly
- if (pos != std::string::npos && pos == output.size() - name.size() &&
- (pos == 0 || output[pos - 1] == '/')) {
- return true;
- }
- }
- return false;
-}
-
-bool AnyTargetCommandOutputMatches(
- const std::string& name, const std::vector<cmCustomCommand>& commands)
-{
- for (cmCustomCommand const& command : commands) {
- if (AnyOutputMatches(name, command.GetByproducts())) {
- return true;
- }
- }
- return false;
-}
-}
-
-cmTarget* cmMakefile::LinearGetTargetWithOutput(const std::string& name) const
-{
- // We go through the ordered vector of targets to get reproducible results
- // should multiple names match.
- for (cmTarget* t : this->OrderedTargets) {
- // Does the output of any command match the source file name?
- if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
- return t;
- }
- if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
- return t;
- }
- if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
- return t;
- }
- }
- return nullptr;
-}
-
-cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
- const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
-{
- // Outputs take precedence over byproducts.
- byproduct = false;
- cmSourceFile* fallback = nullptr;
-
- // Look through all the source files that have custom commands and see if the
- // custom command has the passed source file as an output.
- for (const auto& src : this->SourceFiles) {
- // Does this source file have a custom command?
- if (src->GetCustomCommand()) {
- // Does the output of the custom command match the source file name?
- if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
- // Return the first matching output.
- return src.get();
- }
- if (kind == cmSourceOutputKind::OutputOrByproduct) {
- if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
- // Do not return the source yet as there might be a matching output.
- fallback = src.get();
- }
- }
- }
- }
-
- // Did we find a byproduct?
- byproduct = fallback != nullptr;
- return fallback;
-}
-
-cmSourcesWithOutput cmMakefile::GetSourcesWithOutput(
- const std::string& name) const
-{
- // Linear search? Also see GetSourceFileWithOutput for detail.
- if (!cmSystemTools::FileIsFullPath(name)) {
- cmSourcesWithOutput sources;
- sources.Target = this->LinearGetTargetWithOutput(name);
- sources.Source = this->LinearGetSourceFileWithOutput(
- name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
- return sources;
- }
- // Otherwise we use an efficient lookup map.
- auto o = this->OutputToSource.find(name);
- if (o != this->OutputToSource.end()) {
- return o->second.Sources;
- }
- return {};
-}
-
-cmSourceFile* cmMakefile::GetSourceFileWithOutput(
- const std::string& name, cmSourceOutputKind kind) const
-{
- // If the queried path is not absolute we use the backward compatible
- // linear-time search for an output with a matching suffix.
- if (!cmSystemTools::FileIsFullPath(name)) {
- bool byproduct = false;
- return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
- }
- // Otherwise we use an efficient lookup map.
- auto o = this->OutputToSource.find(name);
- if (o != this->OutputToSource.end() &&
- (!o->second.Sources.SourceIsByproduct ||
- kind == cmSourceOutputKind::OutputOrByproduct)) {
- // Source file could also be null pointer for example if we found the
- // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
- // command of a target, or a not yet created custom command.
- return o->second.Sources.Source;
- }
- return nullptr;
-}
-
-bool cmMakefile::MightHaveCustomCommand(const std::string& name) const
-{
- if (this->DelayedOutputFilesHaveGenex ||
- cmGeneratorExpression::Find(name) != std::string::npos) {
- // Could be more restrictive, but for now we assume that there could always
- // be a match when generator expressions are involved.
- return true;
- }
- // Also see LinearGetSourceFileWithOutput.
- if (!cmSystemTools::FileIsFullPath(name)) {
- return AnyOutputMatches(name, this->DelayedOutputFiles);
- }
- // Otherwise we use an efficient lookup map.
- auto o = this->OutputToSource.find(name);
- if (o != this->OutputToSource.end()) {
- return o->second.SourceMightBeOutput;
- }
- return false;
-}
-
-void cmMakefile::AddTargetByproducts(
- cmTarget* target, const std::vector<std::string>& byproducts)
-{
- for (std::string const& o : byproducts) {
- this->UpdateOutputToSourceMap(o, target);
- }
-}
-
-void cmMakefile::AddSourceOutputs(cmSourceFile* source,
- const std::vector<std::string>& outputs,
- const std::vector<std::string>& byproducts)
-{
- for (std::string const& o : outputs) {
- this->UpdateOutputToSourceMap(o, source, false);
- }
- for (std::string const& o : byproducts) {
- this->UpdateOutputToSourceMap(o, source, true);
- }
-}
-
-void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct,
- cmTarget* target)
-{
- SourceEntry entry;
- entry.Sources.Target = target;
-
- auto pr = this->OutputToSource.emplace(byproduct, entry);
- if (!pr.second) {
- SourceEntry& current = pr.first->second;
- // Has the target already been set?
- if (!current.Sources.Target) {
- current.Sources.Target = target;
- } else {
- // Multiple custom commands/targets produce the same output (source file
- // or target). See also comment in other UpdateOutputToSourceMap
- // overload.
- //
- // TODO: Warn the user about this case.
- }
- }
-}
-
-void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
- cmSourceFile* source, bool byproduct)
-{
- SourceEntry entry;
- entry.Sources.Source = source;
- entry.Sources.SourceIsByproduct = byproduct;
- entry.SourceMightBeOutput = !byproduct;
-
- auto pr = this->OutputToSource.emplace(output, entry);
- if (!pr.second) {
- SourceEntry& current = pr.first->second;
- // Outputs take precedence over byproducts
- if (!current.Sources.Source ||
- (current.Sources.SourceIsByproduct && !byproduct)) {
- current.Sources.Source = source;
- current.Sources.SourceIsByproduct = false;
- current.SourceMightBeOutput = true;
- } else {
- // Multiple custom commands produce the same output but may
- // be attached to a different source file (MAIN_DEPENDENCY).
- // LinearGetSourceFileWithOutput would return the first one,
- // so keep the mapping for the first one.
- //
- // TODO: Warn the user about this case. However, the VS 8 generator
- // triggers it for separate generate.stamp rules in ZERO_CHECK and
- // individual targets.
- }
- }
}
#if !defined(CMAKE_BOOTSTRAP)
@@ -2685,7 +2439,7 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const
bool cmMakefile::PlatformIsAppleEmbedded() const
{
- return GetAppleSDKType() != AppleSDK::MacOS;
+ return this->GetAppleSDKType() != AppleSDK::MacOS;
}
const char* cmMakefile::GetSONameFlag(const std::string& language) const
@@ -2696,7 +2450,7 @@ const char* cmMakefile::GetSONameFlag(const std::string& language) const
name += language;
}
name += "_FLAG";
- return cmToCStr(GetDefinition(name));
+ return cmToCStr(this->GetDefinition(name));
}
bool cmMakefile::CanIWriteThisFile(std::string const& fileName) const
@@ -2719,7 +2473,7 @@ const std::string& cmMakefile::GetRequiredDefinition(
const std::string& name) const
{
static std::string const empty;
- const std::string* def = GetDefinition(name);
+ const std::string* def = this->GetDefinition(name);
if (!def) {
cmSystemTools::Error("Error required internal CMake variable not "
"set, cmake may not be built correctly.\n"
@@ -2779,7 +2533,7 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const
const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
{
static std::string const empty;
- const std::string* def = GetDefinition(name);
+ const std::string* def = this->GetDefinition(name);
if (!def) {
return empty;
}
@@ -2845,24 +2599,24 @@ const std::string& cmMakefile::ExpandVariablesInString(
// Suppress variable watches to avoid calling hooks twice. Suppress new
// dereferences since the OLD behavior is still what is actually used.
this->SuppressSideEffects = true;
- newError = ExpandVariablesInStringNew(newErrorstr, newResult,
- escapeQuotes, noEscapes, atOnly,
- filename, line, replaceAt);
+ newError = this->ExpandVariablesInStringNew(
+ newErrorstr, newResult, escapeQuotes, noEscapes, atOnly, filename,
+ line, replaceAt);
this->SuppressSideEffects = false;
CM_FALLTHROUGH;
}
case cmPolicies::OLD:
- mtype =
- ExpandVariablesInStringOld(errorstr, source, escapeQuotes, noEscapes,
- atOnly, filename, line, removeEmpty, true);
+ mtype = this->ExpandVariablesInStringOld(errorstr, source, escapeQuotes,
+ noEscapes, atOnly, filename,
+ line, removeEmpty, true);
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// Messaging here would be *very* verbose.
case cmPolicies::NEW:
- mtype =
- ExpandVariablesInStringNew(errorstr, source, escapeQuotes, noEscapes,
- atOnly, filename, line, replaceAt);
+ mtype = this->ExpandVariablesInStringNew(errorstr, source, escapeQuotes,
+ noEscapes, atOnly, filename,
+ line, replaceAt);
break;
}
@@ -3055,7 +2809,7 @@ void cmMakefile::SetRecursionDepth(int recursionDepth)
this->RecursionDepth = recursionDepth;
}
-std::string cmMakefile::NewDeferId()
+std::string cmMakefile::NewDeferId() const
{
return this->GetGlobalGenerator()->NewDeferId();
}
@@ -3629,11 +3383,7 @@ cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
bool generated,
cmSourceFileLocationKind kind)
{
- auto sf = cm::make_unique<cmSourceFile>(this, sourceName, kind);
- if (generated) {
- sf->SetProperty("GENERATED", "1");
- }
-
+ auto sf = cm::make_unique<cmSourceFile>(this, sourceName, generated, kind);
auto name =
this->GetCMakeInstance()->StripExtension(sf->GetLocation().GetName());
#if defined(_WIN32) || defined(__APPLE__)
@@ -3665,7 +3415,7 @@ cmSourceFile* cmMakefile::GetOrCreateGeneratedSource(
{
cmSourceFile* sf =
this->GetOrCreateSource(sourceName, true, cmSourceFileLocationKind::Known);
- sf->SetProperty("GENERATED", "1");
+ sf->MarkAsGenerated(); // In case we did not create the source file.
return sf;
}
@@ -3675,38 +3425,10 @@ void cmMakefile::CreateGeneratedOutputs(
for (std::string const& o : outputs) {
if (cmGeneratorExpression::Find(o) == std::string::npos) {
this->GetOrCreateGeneratedSource(o);
- this->AddDelayedOutput(o);
- } else {
- this->DelayedOutputFilesHaveGenex = true;
}
}
}
-void cmMakefile::CreateGeneratedByproducts(
- const std::vector<std::string>& byproducts)
-{
- for (std::string const& o : byproducts) {
- if (cmGeneratorExpression::Find(o) == std::string::npos) {
- this->GetOrCreateGeneratedSource(o);
- }
- }
-}
-
-void cmMakefile::AddDelayedOutput(std::string const& output)
-{
- // Note that this vector might contain the output names in a different order
- // than in source file iteration order.
- this->DelayedOutputFiles.push_back(output);
-
- SourceEntry entry;
- entry.SourceMightBeOutput = true;
-
- auto pr = this->OutputToSource.emplace(output, entry);
- if (!pr.second) {
- pr.first->second.SourceMightBeOutput = true;
- }
-}
-
void cmMakefile::AddTargetObject(std::string const& tgtName,
std::string const& objFile)
{
@@ -4094,8 +3816,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
int cmMakefile::ConfigureFile(const std::string& infile,
const std::string& outfile, bool copyonly,
bool atOnly, bool escapeQuotes,
- bool use_source_permissions,
- cmNewLineStyle newLine)
+ mode_t permissions, cmNewLineStyle newLine)
{
int res = 1;
if (!this->CanIWriteThisFile(outfile)) {
@@ -4117,12 +3838,8 @@ int cmMakefile::ConfigureFile(const std::string& infile,
// output files that now don't exist.
this->AddCMakeOutputFile(soutfile);
- mode_t perm = 0;
- if (!use_source_permissions) {
- perm = perm | mode_owner_read | mode_owner_write | mode_group_read |
- mode_world_read;
- } else {
- cmSystemTools::GetPermissions(sinfile, perm);
+ if (permissions == 0) {
+ cmSystemTools::GetPermissions(sinfile, permissions);
}
std::string::size_type pos = soutfile.rfind('/');
@@ -4137,7 +3854,7 @@ int cmMakefile::ConfigureFile(const std::string& infile,
cmSystemTools::GetLastSystemError());
return 0;
}
- if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+ if (!cmSystemTools::SetPermissions(soutfile, permissions)) {
this->IssueMessage(MessageType::FATAL_ERROR,
cmSystemTools::GetLastSystemError());
return 0;
@@ -4194,7 +3911,7 @@ int cmMakefile::ConfigureFile(const std::string& infile,
cmSystemTools::GetLastSystemError());
res = 0;
} else {
- if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+ if (!cmSystemTools::SetPermissions(soutfile, permissions)) {
this->IssueMessage(MessageType::FATAL_ERROR,
cmSystemTools::GetLastSystemError());
res = 0;
@@ -4283,7 +4000,7 @@ cmTest* cmMakefile::GetTest(const std::string& testName) const
}
void cmMakefile::GetTests(const std::string& config,
- std::vector<cmTest*>& tests)
+ std::vector<cmTest*>& tests) const
{
for (const auto& generator : this->GetTestGenerators()) {
if (generator->TestsForConfig(config)) {
@@ -4633,7 +4350,7 @@ cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id,
return this->StateSnapshot.GetPolicy(id, parent_scope);
}
-bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
+bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var) const
{
// Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting.
if (cmProp val = this->GetDefinition(var)) {
@@ -4670,7 +4387,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
// Deprecate old policies, especially those that require a lot
// of code to maintain the old behavior.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0075 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4738,7 +4455,7 @@ bool cmMakefile::HasCMP0054AlreadyBeenReported(
return !this->CMP0054ReportedIds.insert(context).second;
}
-void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
+void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm) const
{
/* Record the setting of every policy. */
using PolicyID = cmPolicies::PolicyID;
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index c7940fb..60b66a2 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -20,6 +20,8 @@
#include "cmsys/RegularExpression.hxx"
+#include "cm_sys_stat.h"
+
#include "cmAlgorithms.h"
#include "cmCustomCommandTypes.h"
#include "cmListFileCache.h"
@@ -59,24 +61,6 @@ class cmTestGenerator;
class cmVariableWatch;
class cmake;
-/** Flag if byproducts shall also be considered. */
-enum class cmSourceOutputKind
-{
- OutputOnly,
- OutputOrByproduct
-};
-
-/** Target and source file which have a specific output. */
-struct cmSourcesWithOutput
-{
- /** Target with byproduct. */
- cmTarget* Target = nullptr;
-
- /** Source file with output or byproduct. */
- cmSourceFile* Source = nullptr;
- bool SourceIsByproduct = false;
-};
-
/** A type-safe wrapper for a string representing a directory id. */
class cmDirectoryId
{
@@ -225,25 +209,12 @@ public:
const std::string& source,
const cmCustomCommandLines& commandLines,
const char* comment);
- bool AppendCustomCommandToOutput(
+ void AppendCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines);
/**
- * Add target byproducts.
- */
- void AddTargetByproducts(cmTarget* target,
- const std::vector<std::string>& byproducts);
-
- /**
- * Add source file outputs.
- */
- void AddSourceOutputs(cmSourceFile* source,
- const std::vector<std::string>& outputs,
- const std::vector<std::string>& byproducts);
-
- /**
* Add a define flag to the build.
*/
void AddDefineFlag(std::string const& definition);
@@ -272,11 +243,6 @@ public:
bool excludeFromAll = false);
/**
- * Return the utility target output source file name and the CMP0049 name.
- */
- cmUtilityOutput GetUtilityOutput(cmTarget* target);
-
- /**
* Dispatch adding a utility to the build. A utility target is a command
* that is run every time the target is built.
*/
@@ -326,7 +292,7 @@ public:
const char* doc, cmStateEnums::CacheEntryType type,
bool force = false)
{
- AddCacheDefinition(name, value.c_str(), doc, type, force);
+ this->AddCacheDefinition(name, value.c_str(), doc, type, force);
}
/**
@@ -335,7 +301,7 @@ public:
*/
void RemoveDefinition(const std::string& name);
//! Remove a definition from the cache.
- void RemoveCacheDefinition(const std::string& name);
+ void RemoveCacheDefinition(const std::string& name) const;
/**
* Specify the name of the project for this build.
@@ -376,7 +342,7 @@ public:
bool parent_scope = false) const;
bool SetPolicyVersion(std::string const& version_min,
std::string const& version_max);
- void RecordPolicies(cmPolicies::PolicyMap& pm);
+ void RecordPolicies(cmPolicies::PolicyMap& pm) const;
//@}
/** Helper class to push and pop policies automatically. */
@@ -430,8 +396,7 @@ public:
}
const char* GetIncludeRegularExpression() const
{
- cmProp p = this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
- return p ? p->c_str() : nullptr;
+ return cmToCStr(this->GetProperty("INCLUDE_REGULAR_EXPRESSION"));
}
/**
@@ -690,8 +655,7 @@ public:
*/
int ConfigureFile(const std::string& infile, const std::string& outfile,
bool copyonly, bool atOnly, bool escapeQuotes,
- bool use_source_permissions,
- cmNewLineStyle = cmNewLineStyle());
+ mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
/**
* Print a command's invocation
@@ -753,20 +717,10 @@ public:
return this->SourceFiles;
}
- /**
- * Return the target if the provided source name is a byproduct of a utility
- * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
- * Return the source file which has the provided source name as output.
- */
- cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
-
- /**
- * Is there a source file that has the provided source name as an output?
- * If so then return it.
- */
- cmSourceFile* GetSourceFileWithOutput(
- const std::string& name,
- cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
+ std::vector<cmTarget*> const& GetOrderedTargets() const
+ {
+ return this->OrderedTargets;
+ }
//! Add a new cmTest to the list of tests for this makefile.
cmTest* CreateTest(const std::string& testName);
@@ -779,7 +733,7 @@ public:
/**
* Get all tests that run under the given configuration.
*/
- void GetTests(const std::string& config, std::vector<cmTest*>& tests);
+ void GetTests(const std::string& config, std::vector<cmTest*>& tests) const;
/**
* Return a location of a file in cmake or custom modules directory
@@ -926,7 +880,7 @@ public:
return this->SystemIncludeDirectories;
}
- bool PolicyOptionalWarningEnabled(std::string const& var);
+ bool PolicyOptionalWarningEnabled(std::string const& var) const;
void PushLoopBlock();
void PopLoopBlock();
@@ -945,7 +899,7 @@ public:
const std::string& inputFile, const std::string& targetName,
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent);
+ mode_t permissions, bool inputIsContent);
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
GetEvaluationFiles() const;
@@ -967,7 +921,7 @@ public:
int GetRecursionDepth() const;
void SetRecursionDepth(int recursionDepth);
- std::string NewDeferId();
+ std::string NewDeferId() const;
bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
bool DeferCancelCall(std::string const& id);
cm::optional<std::string> DeferGetCallIds() const;
@@ -983,8 +937,7 @@ protected:
mutable cmTargetMap Targets;
std::map<std::string, std::string> AliasTargets;
- using TargetsVec = std::vector<cmTarget*>;
- TargetsVec OrderedTargets;
+ std::vector<cmTarget*> OrderedTargets;
std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
@@ -1129,48 +1082,9 @@ private:
bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
- void CreateGeneratedByproducts(const std::vector<std::string>& byproducts);
std::vector<BT<GeneratorAction>> GeneratorActions;
bool GeneratorActionsInvoked = false;
- bool DelayedOutputFilesHaveGenex = false;
- std::vector<std::string> DelayedOutputFiles;
-
- void AddDelayedOutput(std::string const& output);
-
- /**
- * See LinearGetSourceFileWithOutput for background information
- */
- cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
-
- /**
- * Generalized old version of GetSourceFileWithOutput kept for
- * backward-compatibility. It implements a linear search and supports
- * relative file paths. It is used as a fall back by GetSourceFileWithOutput
- * and GetSourcesWithOutput.
- */
- cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
- cmSourceOutputKind kind,
- bool& byproduct) const;
-
- struct SourceEntry
- {
- cmSourcesWithOutput Sources;
- bool SourceMightBeOutput = false;
- };
-
- // A map for fast output to input look up.
- using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
- OutputToSourceMap OutputToSource;
-
- void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
- void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
- bool byproduct);
-
- /**
- * Return if the provided source file might have a custom command.
- */
- bool MightHaveCustomCommand(const std::string& name) const;
bool CheckSystemVars;
bool CheckCMP0000;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 871878c..1750e37 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -232,10 +233,10 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
std::string launcher;
- const char* val = this->LocalGenerator->GetRuleLauncher(
- this->GeneratorTarget, "RULE_LAUNCH_LINK");
+ cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+ "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -591,10 +592,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string launcher;
- const char* val = this->LocalGenerator->GetRuleLauncher(
- this->GeneratorTarget, "RULE_LAUNCH_LINK");
+ cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+ "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index b32ea6a..ce64e2c 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -366,10 +367,10 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
std::string launcher;
- const char* val = this->LocalGenerator->GetRuleLauncher(
- this->GeneratorTarget, "RULE_LAUNCH_LINK");
+ cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+ "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -816,10 +817,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.LanguageCompileFlags = langFlags.c_str();
std::string launcher;
- const char* val = this->LocalGenerator->GetRuleLauncher(
- this->GeneratorTarget, "RULE_LAUNCH_LINK");
+ cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+ "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index c6d6c99..adf40b0 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -12,7 +12,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
@@ -23,6 +25,7 @@
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalCommonGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmMakefileExecutableTargetGenerator.h"
@@ -68,7 +71,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
this->CMP0113New = true;
break;
}
- MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
+ this->MacOSXContentGenerator =
+ cm::make_unique<MacOSXContentGeneratorType>(this);
}
cmMakefileTargetGenerator::~cmMakefileTargetGenerator() = default;
@@ -325,28 +329,80 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(), dependFileNameFull))
- << "\n\n";
+ << "\n";
- if (!this->NoRuleMessages) {
- // Include the progress variables for the target.
+ std::string depsUseCompiler = "CMAKE_DEPENDS_USE_COMPILER";
+ if (!this->Makefile->IsDefinitionSet(depsUseCompiler) ||
+ this->Makefile->IsOn(depsUseCompiler)) {
+ std::string compilerDependFile =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
*this->BuildFileStream
- << "# Include the progress variables for this target.\n"
+ << "# Include any dependencies generated by the "
+ "compiler for this target.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetBinaryDirectory(),
- this->ProgressFileNameFull))
+ this->LocalGenerator->GetBinaryDirectory(), compilerDependFile))
<< "\n\n";
- }
- // make sure the depend file exists
- if (!cmSystemTools::FileExists(dependFileNameFull)) {
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(
- dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
- depFileStream << "# Empty dependencies file for "
+ compilerDependFile, false, this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# Empty compiler generated dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built.\n";
+ // remove internal dependency file
+ cmSystemTools::RemoveFile(
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.internal"));
+
+ std::string compilerDependTimestamp =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
+ if (!cmSystemTools::FileExists(compilerDependTimestamp)) {
+ // Write a dependency timestamp file.
+ cmGeneratedFileStream timestampFileStream(
+ compilerDependTimestamp, false,
+ this->GlobalGenerator->GetMakefileEncoding());
+ timestampFileStream
+ << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Timestamp file for compiler generated dependencies "
+ "management for "
+ << this->GeneratorTarget->GetName() << ".\n";
+ }
+
+ // deactivate no longer needed legacy dependency files
+ // Write an empty dependency file.
+ cmGeneratedFileStream legacyDepFileStream(
+ dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
+ legacyDepFileStream
+ << "# Empty dependencies file for " << this->GeneratorTarget->GetName()
+ << ".\n"
+ << "# This may be replaced when dependencies are built.\n";
+ // remove internal dependency file
+ cmSystemTools::RemoveFile(
+ cmStrCat(this->TargetBuildDirectoryFull, "/depend.internal"));
+ } else {
+ // make sure the depend file exists
+ if (!cmSystemTools::FileExists(dependFileNameFull)) {
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(
+ dependFileNameFull, false,
+ this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# Empty dependencies file for "
+ << this->GeneratorTarget->GetName() << ".\n"
+ << "# This may be replaced when dependencies are built.\n";
+ }
+ }
+
+ if (!this->NoRuleMessages) {
+ // Include the progress variables for the target.
+ *this->BuildFileStream
+ << "# Include the progress variables for this target.\n"
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->ProgressFileNameFull))
+ << "\n\n";
}
// Open the flags file. This should be copy-if-different because the
@@ -472,6 +528,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
return;
}
+ // Use compiler to generate dependencies, if supported.
+ bool compilerGenerateDeps =
+ this->GlobalGenerator->SupportsCompilerDependencies() &&
+ cmIsOn(this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_DEPENDS_USE_COMPILER")));
+ auto scanner = compilerGenerateDeps ? cmDependencyScannerKind::Compiler
+ : cmDependencyScannerKind::CMake;
+
// Get the full path name of the object file.
std::string const& objectName =
this->GeneratorTarget->GetObjectName(&source);
@@ -511,7 +575,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string srcFullPath =
cmSystemTools::CollapseFullPath(source.GetFullPath());
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
- objFullPath, srcFullPath);
+ objFullPath, srcFullPath, scanner);
this->LocalGenerator->AppendRuleDepend(depends,
this->FlagFileNameFull.c_str());
@@ -553,8 +617,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
depends.push_back(
this->GeneratorTarget->GetPchFile(config, lang, arch));
}
- this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
- objFullPath, pchHeader);
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, lang, objFullPath, pchHeader, scanner);
}
}
@@ -573,6 +637,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Build the set of compiler flags.
std::string flags;
+ // Explicitly add the explicit language flag before any other flag
+ // so user flags can override it.
+ this->GeneratorTarget->AddExplicitLanguageFlags(flags, source);
+
// Add language-specific flags.
std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
this->LocalGenerator->AppendFlags(flags, langFlags);
@@ -693,7 +761,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
source.GetFullPath(), cmOutputConverter::SHELL);
// Construct the build message.
- std::vector<std::string> no_commands;
+ std::vector<std::string> no_depends;
std::vector<std::string> commands;
// add in a progress call if needed
@@ -787,13 +855,34 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
"$(" + lang + "_INCLUDES)");
vars.Includes = includesString.c_str();
+ std::string dependencyTarget;
+ std::string shellDependencyFile;
+ std::string dependencyTimestamp;
+ if (compilerGenerateDeps) {
+ dependencyTarget = this->LocalGenerator->EscapeForShell(
+ this->LocalGenerator->ConvertToMakefilePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(), relativeObj)));
+ vars.DependencyTarget = dependencyTarget.c_str();
+
+ auto depFile = cmStrCat(obj, ".d");
+ shellDependencyFile = this->LocalGenerator->ConvertToOutputFormat(
+ depFile, cmOutputConverter::SHELL);
+ vars.DependencyFile = shellDependencyFile.c_str();
+ this->CleanFiles.insert(depFile);
+
+ dependencyTimestamp = this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"));
+ }
+
// At the moment, it is assumed that C, C++, Fortran, and CUDA have both
// assembly and preprocessor capabilities. The same is true for the
// ability to export compile commands
bool lang_has_preprocessor =
((lang == "C") || (lang == "CXX") || (lang == "OBJC") ||
(lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") ||
- lang == "ISPC");
+ lang == "ISPC" || lang == "ASM");
bool const lang_has_assembly = lang_has_preprocessor;
bool const lang_can_export_cmds = lang_has_preprocessor;
@@ -824,7 +913,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmExpandList(compileRule, compileCommands);
}
- if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
+ if (this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS") &&
lang_can_export_cmds && compileCommands.size() == 1) {
std::string compileCommand = compileCommands[0];
@@ -875,15 +964,21 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Maybe insert an include-what-you-use runner.
- if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
- std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
- cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ if (!compileCommands.empty() &&
+ (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
std::string const tidy_prop = lang + "_CLANG_TIDY";
cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
- std::string const cpplint_prop = lang + "_CPPLINT";
- cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
- std::string const cppcheck_prop = lang + "_CPPCHECK";
- cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ cmProp iwyu = nullptr;
+ cmProp cpplint = nullptr;
+ cmProp cppcheck = nullptr;
+ if (lang == "C" || lang == "CXX") {
+ std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
+ iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ std::string const cpplint_prop = lang + "_CPPLINT";
+ cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ std::string const cppcheck_prop = lang + "_CPPCHECK";
+ cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ }
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
cmNonempty(cppcheck)) {
std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
@@ -945,10 +1040,57 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string launcher;
{
- const char* val = this->LocalGenerator->GetRuleLauncher(
+ cmProp val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_COMPILE");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
+ }
+ }
+
+ std::string flagsWithDeps(flags);
+
+ if (compilerGenerateDeps) {
+ // Injects dependency computation
+ auto depFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_DEPFILE_FLAGS_", lang));
+
+ if (!depFlags.empty()) {
+ // Add dependency flags
+ rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
+ depFlags, vars);
+ flagsWithDeps.append(1, ' ');
+ flagsWithDeps.append(depFlags);
+ }
+ vars.Flags = flagsWithDeps.c_str();
+
+ const auto& extraCommands = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
+ if (!extraCommands.empty()) {
+ auto commandList = cmExpandedList(extraCommands);
+ compileCommands.insert(compileCommands.end(), commandList.cbegin(),
+ commandList.cend());
+ }
+
+ const auto& depFormat = this->Makefile->GetRequiredDefinition(
+ cmStrCat("CMAKE_", lang, "_DEPFILE_FORMAT"));
+
+ if (depFormat == "msvc"_s) {
+ // compiler must be launched through a wrapper to pick-up dependencies
+ std::string depFilter =
+ "$(CMAKE_COMMAND) -E cmake_cl_compile_depends ";
+ depFilter += cmStrCat("--dep-file=", shellDependencyFile);
+ depFilter +=
+ cmStrCat(" --working-dir=",
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ cmOutputConverter::SHELL));
+ const auto& prefix = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_CL_SHOWINCLUDES_PREFIX"));
+ depFilter += cmStrCat(" --filter-prefix=",
+ this->LocalGenerator->ConvertToOutputFormat(
+ prefix, cmOutputConverter::SHELL));
+ depFilter += " -- ";
+ compileCommands.front().insert(0, depFilter);
}
}
@@ -977,8 +1119,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmExpandList(evaluated_outputs, outputs);
}
}
- if (!ispcHeaderRelative
- .empty()) { // can't move ispcHeader as vars is using it
+ if (!ispcHeaderRelative.empty()) {
+ // can't move ispcHeader as vars is using it
outputs.emplace_back(ispcHeaderRelative);
}
@@ -986,10 +1128,19 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
+ if (compilerGenerateDeps) {
+ depends.push_back(dependencyTimestamp);
+ }
+
// Write the rule.
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
commands);
+ if (compilerGenerateDeps) {
+ // set back flags without dependency generation
+ vars.Flags = flags.c_str();
+ }
+
bool do_preprocess_rules = lang_has_preprocessor &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
bool do_assembly_rules =
@@ -1386,10 +1537,10 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
std::string registerFileCmd;
- // The generated register file contains macros that when expanded register
- // the device routines. Because the routines are the same for all
- // architectures the register file will be the same too. Thus generate it
- // only on the first invocation to reduce overhead.
+ // The generated register file contains macros that when expanded
+ // register the device routines. Because the routines are the same for
+ // all architectures the register file will be the same too. Thus
+ // generate it only on the first invocation to reduce overhead.
if (fatbinaryDepends.size() == 1) {
std::string registerFileRel =
this->LocalGenerator->MaybeConvertToRelativePath(
@@ -1424,7 +1575,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
fatbinaryOutputRel, fatbinaryDepends,
{ fatbinaryCommand }, false);
- // Compile the stub that registers the kernels and contains the fatbinaries.
+ // Compile the stub that registers the kernels and contains the
+ // fatbinaries.
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
@@ -1481,6 +1633,16 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
std::vector<std::string> depends;
this->LocalGenerator->AppendCustomDepend(depends, ccg);
+ if (!ccg.GetCC().GetDepfile().empty()) {
+ // Add dependency over timestamp file for dependencies management
+ auto dependTimestamp = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts")));
+
+ depends.push_back(dependTimestamp);
+ }
+
// Write the rule.
const std::vector<std::string>& outputs = ccg.GetOutputs();
bool symbolic = this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs,
@@ -1517,6 +1679,15 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
objFullPath, srcFullPath);
}
+ // Setup implicit depend for depfile if any
+ if (!ccg.GetCC().GetDepfile().empty()) {
+ std::string objFullPath = cmSystemTools::CollapseFullPath(
+ outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, "CUSTOM", objFullPath, ccg.GetFullDepfile(),
+ cmDependencyScannerKind::Compiler);
+ }
+
this->CustomCommandOutputs.insert(outputs.begin(), outputs.end());
}
@@ -1542,12 +1713,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
<< this->GeneratorTarget->GetName() << "\n"
<< variableName << " =";
std::string object;
- std::string lineContinue;
- if (cmProp p = this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE")) {
- lineContinue = *p;
- } else {
- lineContinue = "\\";
- }
+ const auto& lineContinue = this->GlobalGenerator->LineContinueDirective;
cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
@@ -1555,7 +1721,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) {
continue;
}
- *this->BuildFileStream << " " << lineContinue << "\n";
+ *this->BuildFileStream << " " << lineContinue;
*this->BuildFileStream
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
obj, useWatcomQuote);
@@ -1578,7 +1744,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
for (std::string const& obj : this->ExternalObjects) {
object =
this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, obj);
- *this->BuildFileStream << " " << lineContinue << "\n";
+ *this->BuildFileStream << " " << lineContinue;
*this->BuildFileStream
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
obj, useWatcomQuote);
@@ -1842,9 +2008,9 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
if (size_t const limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
// Compute the total length of our list of object files with room
// for argument separation and quoting. This does not convert paths
- // relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so the
- // actual list will likely be much shorter than this. However, in the
- // worst case all objects will remain as absolute paths.
+ // relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so
+ // the actual list will likely be much shorter than this. However, in
+ // the worst case all objects will remain as absolute paths.
size_t length = 0;
for (std::string const& obj : this->Objects) {
length += obj.size() + 3;
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 6c18e48..a885b17 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
@@ -36,10 +37,42 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
*this->BuildFileStream << "# Utility rule file for "
<< this->GeneratorTarget->GetName() << ".\n\n";
+ const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
+ ? "$(CMAKE_BINARY_DIR)/"
+ : "");
+
+ // Include the dependencies for the target.
+ std::string dependFile =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
+ *this->BuildFileStream
+ << "# Include any custom commands dependencies for this target.\n"
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(), dependFile))
+ << "\n\n";
+ if (!cmSystemTools::FileExists(dependFile)) {
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(
+ dependFile, false, this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# Empty custom commands generated dependencies file for "
+ << this->GeneratorTarget->GetName() << ".\n"
+ << "# This may be replaced when dependencies are built.\n";
+ }
+
+ std::string dependTimestamp =
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
+ if (!cmSystemTools::FileExists(dependTimestamp)) {
+ // Write a dependency timestamp file.
+ cmGeneratedFileStream depFileStream(
+ dependTimestamp, false, this->GlobalGenerator->GetMakefileEncoding());
+ depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Timestamp file for custom commands dependencies "
+ "management for "
+ << this->GeneratorTarget->GetName() << ".\n";
+ }
+
if (!this->NoRuleMessages) {
- const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
- ? "$(CMAKE_BINARY_DIR)/"
- : "");
// Include the progress variables for the target.
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx
index a121332..28baeb6 100644
--- a/Source/cmNewLineStyle.cxx
+++ b/Source/cmNewLineStyle.cxx
@@ -8,13 +8,13 @@ cmNewLineStyle::cmNewLineStyle() = default;
bool cmNewLineStyle::IsValid() const
{
- return NewLineStyle != Invalid;
+ return this->NewLineStyle != Invalid;
}
bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
std::string& errorString)
{
- NewLineStyle = Invalid;
+ this->NewLineStyle = Invalid;
for (size_t i = 0; i < args.size(); i++) {
if (args[i] == "NEWLINE_STYLE") {
@@ -22,11 +22,11 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
if (args.size() > styleIndex) {
std::string const& eol = args[styleIndex];
if (eol == "LF" || eol == "UNIX") {
- NewLineStyle = LF;
+ this->NewLineStyle = LF;
return true;
}
if (eol == "CRLF" || eol == "WIN32" || eol == "DOS") {
- NewLineStyle = CRLF;
+ this->NewLineStyle = CRLF;
return true;
}
errorString = "NEWLINE_STYLE sets an unknown style, only LF, "
@@ -43,7 +43,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
std::string cmNewLineStyle::GetCharacters() const
{
- switch (NewLineStyle) {
+ switch (this->NewLineStyle) {
case Invalid:
return "";
case LF:
@@ -56,10 +56,10 @@ std::string cmNewLineStyle::GetCharacters() const
void cmNewLineStyle::SetStyle(Style style)
{
- NewLineStyle = style;
+ this->NewLineStyle = style;
}
cmNewLineStyle::Style cmNewLineStyle::GetStyle() const
{
- return NewLineStyle;
+ return this->NewLineStyle;
}
diff --git a/Source/cmNinjaLinkLineComputer.cxx b/Source/cmNinjaLinkLineComputer.cxx
index 7fbeeea..2304ad2 100644
--- a/Source/cmNinjaLinkLineComputer.cxx
+++ b/Source/cmNinjaLinkLineComputer.cxx
@@ -18,5 +18,5 @@ cmNinjaLinkLineComputer::cmNinjaLinkLineComputer(
std::string cmNinjaLinkLineComputer::ConvertToLinkReference(
std::string const& lib) const
{
- return GG->ConvertToNinjaPath(lib);
+ return this->GG->ConvertToNinjaPath(lib);
}
diff --git a/Source/cmNinjaLinkLineDeviceComputer.cxx b/Source/cmNinjaLinkLineDeviceComputer.cxx
index 84c1b37..f66e2f5 100644
--- a/Source/cmNinjaLinkLineDeviceComputer.cxx
+++ b/Source/cmNinjaLinkLineDeviceComputer.cxx
@@ -16,5 +16,5 @@ cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer(
std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference(
std::string const& lib) const
{
- return GG->ConvertToNinjaPath(lib);
+ return this->GG->ConvertToNinjaPath(lib);
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index ccb959b..620b8ff 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -49,7 +49,7 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
// on Windows the output dir is already needed at compile time
// ensure the directory exists (OutDir test)
for (auto const& config : this->GetConfigNames()) {
- EnsureDirectoryExists(target->GetDirectory(config));
+ this->EnsureDirectoryExists(target->GetDirectory(config));
}
}
@@ -266,10 +266,10 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS";
std::string launcher;
- const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+ cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -306,7 +306,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
{
const cmMakefile* mf = this->GetMakefile();
- cmNinjaRule rule(LanguageLinkerCudaDeviceRule(config));
+ cmNinjaRule rule(this->LanguageLinkerCudaDeviceRule(config));
rule.Command = this->GetLocalGenerator()->BuildCommandLine(
{ cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"),
" -arch=$ARCH $REGISTER -o=$out $in") });
@@ -334,13 +334,13 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
compileCmd, vars);
- rule.Name = LanguageLinkerCudaDeviceCompileRule(config);
+ rule.Name = this->LanguageLinkerCudaDeviceCompileRule(config);
rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd });
rule.Comment = "Rule for compiling CUDA device stubs.";
rule.Description = "Compiling CUDA device stub $out";
this->GetGlobalGenerator()->AddRule(rule);
- rule.Name = LanguageLinkerCudaFatbinaryRule(config);
+ rule.Name = this->LanguageLinkerCudaFatbinaryRule(config);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(
{ cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"),
" -64 -cmdline=--compile-only -compress-all -link "
@@ -385,7 +385,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
- cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar);
+ cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
if (flag) {
responseFlag = *flag;
@@ -452,10 +452,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
}
std::string launcher;
- const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+ cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -673,7 +673,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
std::string targetOutputReal =
- ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt);
+ this->ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt);
if (firstForConfig) {
globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
@@ -730,7 +730,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements(
this->GetGlobalGenerator()->ConfigDirectory(config));
const std::string ninjaOutputDir = this->ConvertToNinjaPath(objectDir);
- cmNinjaBuild fatbinary(LanguageLinkerCudaFatbinaryRule(config));
+ cmNinjaBuild fatbinary(this->LanguageLinkerCudaFatbinaryRule(config));
// Link device code for each architecture.
for (const std::string& architectureKind : architectures) {
@@ -744,7 +744,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements(
cmStrCat(" -im=profile=sm_", architecture, ",file=", cubin);
fatbinary.ExplicitDeps.emplace_back(cubin);
- cmNinjaBuild dlink(LanguageLinkerCudaDeviceRule(config));
+ cmNinjaBuild dlink(this->LanguageLinkerCudaDeviceRule(config));
dlink.ExplicitDeps = explicitDeps;
dlink.Outputs = { cubin };
dlink.Variables["ARCH"] = cmStrCat("sm_", architecture);
@@ -767,7 +767,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements(
fatbinary);
// Compile the stub that registers the kernels and contains the fatbinaries.
- cmNinjaBuild dcompile(LanguageLinkerCudaDeviceCompileRule(config));
+ cmNinjaBuild dcompile(this->LanguageLinkerCudaDeviceCompileRule(config));
dcompile.Outputs = { output };
dcompile.ExplicitDeps = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") };
dcompile.Variables["FATBIN"] =
@@ -787,7 +787,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
- std::string targetOutputImplib = ConvertToNinjaPath(
+ std::string targetOutputImplib = this->ConvertToNinjaPath(
genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
if (config != fileConfig) {
@@ -806,7 +806,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
.empty() &&
targetOutputImplib ==
- ConvertToNinjaPath(genTarget->GetFullPath(
+ this->ConvertToNinjaPath(genTarget->GetFullPath(
fileConfig, cmStateEnums::ImportLibraryArtifact))) {
return;
}
@@ -882,16 +882,16 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
- EnsureParentDirectoryExists(impLibPath);
+ this->EnsureParentDirectoryExists(impLibPath);
}
const std::string objPath =
- cmStrCat(GetGeneratorTarget()->GetSupportDirectory(),
+ cmStrCat(this->GetGeneratorTarget()->GetSupportDirectory(),
globalGen->ConfigDirectory(config));
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
- EnsureDirectoryExists(objPath);
+ this->EnsureDirectoryExists(objPath);
this->SetMsvcTargetPdbVariable(vars, config);
@@ -933,21 +933,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
cmGeneratorTarget* gt = this->GetGeneratorTarget();
- std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config));
- std::string targetOutputReal = ConvertToNinjaPath(
+ std::string targetOutput = this->ConvertToNinjaPath(gt->GetFullPath(config));
+ std::string targetOutputReal = this->ConvertToNinjaPath(
gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
/*realname=*/true));
- std::string targetOutputImplib = ConvertToNinjaPath(
+ std::string targetOutputImplib = this->ConvertToNinjaPath(
gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
if (config != fileConfig) {
- if (targetOutput == ConvertToNinjaPath(gt->GetFullPath(fileConfig))) {
+ if (targetOutput ==
+ this->ConvertToNinjaPath(gt->GetFullPath(fileConfig))) {
return;
}
if (targetOutputReal ==
- ConvertToNinjaPath(gt->GetFullPath(fileConfig,
- cmStateEnums::RuntimeBinaryArtifact,
- /*realname=*/true))) {
+ this->ConvertToNinjaPath(
+ gt->GetFullPath(fileConfig, cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true))) {
return;
}
if (!gt->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
@@ -955,7 +956,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
!gt->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
.empty() &&
targetOutputImplib ==
- ConvertToNinjaPath(gt->GetFullPath(
+ this->ConvertToNinjaPath(gt->GetFullPath(
fileConfig, cmStateEnums::ImportLibraryArtifact))) {
return;
}
@@ -1095,7 +1096,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
std::vector<std::string> extraISPCObjects =
this->GetGeneratorTarget()->GetGeneratedISPCObjects(config);
std::transform(extraISPCObjects.begin(), extraISPCObjects.end(),
- std::back_inserter(linkBuild.ExplicitDeps), MapToNinjaPath());
+ std::back_inserter(linkBuild.ExplicitDeps),
+ this->MapToNinjaPath());
linkBuild.ImplicitDeps =
this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
@@ -1189,7 +1191,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
- EnsureParentDirectoryExists(impLibPath);
+ this->EnsureParentDirectoryExists(impLibPath);
if (gt->HasImportLibrary(config)) {
byproducts.push_back(targetOutputImplib);
if (firstForConfig) {
@@ -1218,7 +1220,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmStrCat(gt->GetSupportDirectory(), globalGen->ConfigDirectory(config));
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
- EnsureDirectoryExists(objPath);
+ this->EnsureDirectoryExists(objPath);
std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::string& link_path = vars["LINK_PATH"];
@@ -1247,11 +1249,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
- std::back_inserter(byproducts), MapToNinjaPath());
+ std::back_inserter(byproducts), this->MapToNinjaPath());
std::transform(
ccByproducts.begin(), ccByproducts.end(),
std::back_inserter(globalGen->GetByproductsForCleanTarget()),
- MapToNinjaPath());
+ this->MapToNinjaPath());
}
}
}
@@ -1272,7 +1274,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
obj_list_file, cmOutputConverter::SHELL);
- cmProp nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
+ cmProp nm_executable = this->GetMakefile()->GetDefinition("CMAKE_NM");
if (cmNonempty(nm_executable)) {
cmd += " --nm=";
cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
@@ -1325,7 +1327,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
- cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar);
+ cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
bool const lang_supports_response =
!(this->TargetLinkLanguage(config) == "RC" ||
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d41cbd2..672b579 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -12,7 +12,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
@@ -33,6 +35,7 @@
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
+#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -105,7 +108,7 @@ std::string cmNinjaTargetGenerator::LanguageCompilerRule(
'_', config);
}
-std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
+std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
std::string const& lang, const std::string& config) const
{
return cmStrCat(
@@ -114,7 +117,7 @@ std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
'_', config);
}
-std::string cmNinjaTargetGenerator::LanguageDependencyRule(
+std::string cmNinjaTargetGenerator::LanguageScanRule(
std::string const& lang, const std::string& config) const
{
return cmStrCat(
@@ -129,14 +132,7 @@ bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
return lang == "Fortran";
}
-bool cmNinjaTargetGenerator::UsePreprocessedSource(
- std::string const& lang) const
-{
- return lang == "Fortran";
-}
-
-bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
- std::string const& lang) const
+bool cmNinjaTargetGenerator::CompileWithDefines(std::string const& lang) const
{
return this->Makefile->IsOn(
cmStrCat("CMAKE_", lang, "_COMPILE_WITH_DEFINES"));
@@ -151,9 +147,26 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule(
'_', config);
}
-bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
+bool cmNinjaTargetGenerator::NeedCxxModuleSupport(
+ std::string const& lang, std::string const& config) const
{
- return lang == "Fortran";
+ if (lang != "CXX") {
+ return false;
+ }
+ if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) {
+ return false;
+ }
+ cmGeneratorTarget const* tgt = this->GetGeneratorTarget();
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ bool const uses_cxx20 =
+ standardResolver.HaveStandardAvailable(tgt, "CXX", config, "cxx_std_20");
+ return uses_cxx20 && 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(
@@ -190,7 +203,15 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
}
- std::string flags = this->GetFlags(language, config, filterArch);
+ std::string flags;
+ // Explicitly add the explicit language flag before any other flag
+ // so user flags can override it.
+ this->GeneratorTarget->AddExplicitLanguageFlags(flags, *source);
+
+ if (!flags.empty()) {
+ flags += " ";
+ }
+ flags += this->GetFlags(language, config, filterArch);
// Add Fortran format flags.
if (language == "Fortran") {
@@ -252,32 +273,6 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
}
-bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
-{
- std::string const& deptype = this->GetMakefile()->GetSafeDefinition(
- cmStrCat("CMAKE_NINJA_DEPTYPE_", lang));
- if (deptype == "msvc") {
- return true;
- }
- if (deptype == "intel") {
- // Ninja does not really define "intel", but we use it to switch based
- // on whether this environment supports "gcc" or "msvc" deptype.
- if (!this->GetGlobalGenerator()->SupportsMultilineDepfile()) {
- // This ninja version is too old to support the Intel depfile format.
- // Fall back to msvc deptype.
- return true;
- }
- if ((this->Makefile->GetHomeDirectory().find(' ') != std::string::npos) ||
- (this->Makefile->GetHomeOutputDirectory().find(' ') !=
- std::string::npos)) {
- // The Intel compiler does not properly escape spaces in a depfile.
- // Fall back to msvc deptype.
- return true;
- }
- }
- return false;
-}
-
// TODO: Refactor with
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
@@ -355,7 +350,8 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
const std::vector<std::string>& deps = cli->GetDepends();
cmNinjaDeps result(deps.size());
- std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
+ std::transform(deps.begin(), deps.end(), result.begin(),
+ this->MapToNinjaPath());
// Add a dependency on the link definitions file, if any.
if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
@@ -376,7 +372,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
std::vector<std::string> linkDeps;
this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage);
std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result),
- MapToNinjaPath());
+ this->MapToNinjaPath());
return result;
}
@@ -384,7 +380,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
std::string cmNinjaTargetGenerator::GetSourceFilePath(
cmSourceFile const* source) const
{
- return ConvertToNinjaPath(source->GetFullPath());
+ return this->ConvertToNinjaPath(source->GetFullPath());
}
std::string cmNinjaTargetGenerator::GetObjectFilePath(
@@ -465,7 +461,7 @@ std::string cmNinjaTargetGenerator::GetTargetOutputDir(
const std::string& config) const
{
std::string dir = this->GeneratorTarget->GetDirectory(config);
- return ConvertToNinjaPath(dir);
+ return this->ConvertToNinjaPath(dir);
}
std::string cmNinjaTargetGenerator::GetTargetFilePath(
@@ -502,13 +498,13 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
}
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(pdbPath), cmOutputConverter::SHELL);
+ this->ConvertToNinjaPath(pdbPath), cmOutputConverter::SHELL);
vars["TARGET_COMPILE_PDB"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(compilePdbPath), cmOutputConverter::SHELL);
+ this->ConvertToNinjaPath(compilePdbPath), cmOutputConverter::SHELL);
- EnsureParentDirectoryExists(pdbPath);
- EnsureParentDirectoryExists(compilePdbPath);
+ this->EnsureParentDirectoryExists(pdbPath);
+ this->EnsureParentDirectoryExists(compilePdbPath);
return true;
}
return false;
@@ -527,82 +523,62 @@ namespace {
// Create the command to run the dependency scanner
std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
const std::string& lang, const std::string& ppFile,
- bool needDyndep, const std::string& ddiFile)
+ const std::string& ddiFile)
{
- std::string ccmd =
- cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang,
- " --pp=", ppFile, " --dep=$DEP_FILE");
- if (needDyndep) {
- ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile);
- }
- return ccmd;
+ return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
+ " --lang=", lang, " --src=$in", " --pp=", ppFile,
+ " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile);
}
-// Helper function to create dependency scanning rule, with optional
-// explicit preprocessing step if preprocessCommand is non-empty
-cmNinjaRule GetPreprocessScanRule(
- const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars,
+// Helper function to create dependency scanning rule that may or may
+// not perform explicit preprocessing too.
+cmNinjaRule GetScanRule(
+ const std::string& ruleName,
+ cmRulePlaceholderExpander::RuleVariables const& vars,
const std::string& responseFlag, const std::string& flags,
- const std::string& launcher,
cmRulePlaceholderExpander* const rulePlaceholderExpander,
- std::string scanCommand, cmLocalNinjaGenerator* generator,
- const std::string& preprocessCommand = "")
+ cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds)
{
cmNinjaRule rule(ruleName);
- // Explicit preprocessing always uses a depfile.
+ // Scanning always uses a depfile for preprocessor dependencies.
rule.DepType = ""; // no deps= for multiple outputs
rule.DepFile = "$DEP_FILE";
- cmRulePlaceholderExpander::RuleVariables ppVars;
- ppVars.CMTargetName = vars.CMTargetName;
- ppVars.CMTargetType = vars.CMTargetType;
- ppVars.Language = vars.Language;
- ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
- ppVars.PreprocessedSource = "$out";
- ppVars.DependencyFile = rule.DepFile.c_str();
-
- // Preprocessing uses the original source, compilation uses
- // preprocessed output or original source
- ppVars.Source = vars.Source;
- vars.Source = "$in";
-
- // Copy preprocessor definitions to the preprocessor rule.
- ppVars.Defines = vars.Defines;
+ cmRulePlaceholderExpander::RuleVariables scanVars;
+ scanVars.CMTargetName = vars.CMTargetName;
+ scanVars.CMTargetType = vars.CMTargetType;
+ scanVars.Language = vars.Language;
+ scanVars.Object = "$OBJ_FILE";
+ scanVars.PreprocessedSource = "$out";
+ scanVars.DynDepFile = "$DYNDEP_INTERMEDIATE_FILE";
+ scanVars.DependencyFile = rule.DepFile.c_str();
+ scanVars.DependencyTarget = "$out";
- // Copy include directories to the preprocessor rule. The Fortran
- // compilation rule still needs them for the INCLUDE directive.
- ppVars.Includes = vars.Includes;
+ // Scanning needs the same preprocessor settings as direct compilation would.
+ scanVars.Source = vars.Source;
+ scanVars.Defines = vars.Defines;
+ scanVars.Includes = vars.Includes;
- // Preprocessing and compilation use the same flags.
- std::string ppFlags = flags;
+ // Scanning needs the compilation flags too.
+ std::string scanFlags = flags;
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
rule.RspContent =
- cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
- ppFlags = cmStrCat(responseFlag, rule.RspFile);
- ppVars.Defines = "";
- ppVars.Includes = "";
+ cmStrCat(' ', scanVars.Defines, ' ', scanVars.Includes, ' ', scanFlags);
+ scanFlags = cmStrCat(responseFlag, rule.RspFile);
+ scanVars.Defines = "";
+ scanVars.Includes = "";
}
- ppVars.Flags = ppFlags.c_str();
-
- // Rule for preprocessing source file.
- std::vector<std::string> ppCmds;
+ scanVars.Flags = scanFlags.c_str();
- if (!preprocessCommand.empty()) {
- // Lookup the explicit preprocessing rule.
- cmExpandList(preprocessCommand, ppCmds);
- for (std::string& i : ppCmds) {
- i = cmStrCat(launcher, i);
- rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars);
- }
+ // Rule for scanning a source file.
+ for (std::string& scanCmd : scanCmds) {
+ rulePlaceholderExpander->ExpandRuleVariables(generator, scanCmd, scanVars);
}
-
- // Run CMake dependency scanner on either preprocessed output or source file
- ppCmds.emplace_back(std::move(scanCommand));
- rule.Command = generator->BuildCommandLine(ppCmds);
+ rule.Command = generator->BuildCommandLine(scanCmds);
return rule;
}
@@ -628,11 +604,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmMakefile* mf = this->GetMakefile();
- // For some cases we do an explicit preprocessor invocation.
- bool const explicitPP = this->NeedExplicitPreprocessing(lang);
- bool const compilePPWithDefines = this->UsePreprocessedSource(lang) &&
- this->CompilePreprocessedSourceWithDefines(lang);
- bool const needDyndep = this->NeedDyndep(lang);
+ // 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";
@@ -646,65 +620,97 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
responseFlag = "@";
}
}
+ std::string const modmapFormatVar =
+ cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FORMAT");
+ std::string const modmapFormat =
+ this->Makefile->GetSafeDefinition(modmapFormatVar);
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
+ this->ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
cmLocalGenerator::SHELL);
std::string launcher;
- const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+ cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
if (cmNonempty(val)) {
- launcher = cmStrCat(val, ' ');
+ launcher = cmStrCat(*val, ' ');
}
std::string const cmakeCmd =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- if (explicitPP) {
- // Combined preprocessing and dependency scanning
- const auto ppScanCommand = GetScanCommand(
- cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE");
- const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
-
- auto ppRule = GetPreprocessScanRule(
- this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags,
- launcher, rulePlaceholderExpander.get(), ppScanCommand,
- this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar));
-
- // Write the rule for preprocessing file of the given language.
- ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
- ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
+ if (needDyndep) {
+ // Rule to scan dependencies of sources that need preprocessing.
+ {
+ std::vector<std::string> scanCommands;
+ std::string scanRuleName;
+ if (compilationPreprocesses) {
+ scanRuleName = this->LanguageScanRule(lang, config);
+ std::string const& scanCommand = mf->GetRequiredDefinition(
+ cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE"));
+ cmExpandList(scanCommand, scanCommands);
+ for (std::string& i : scanCommands) {
+ i = cmStrCat(launcher, i);
+ }
+ } else {
+ scanRuleName = this->LanguagePreprocessAndScanRule(lang, config);
+ std::string const& ppCommmand = mf->GetRequiredDefinition(
+ cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"));
+ cmExpandList(ppCommmand, scanCommands);
+ for (std::string& i : scanCommands) {
+ i = cmStrCat(launcher, i);
+ }
+ scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out",
+ "$DYNDEP_INTERMEDIATE_FILE"));
+ }
- this->GetGlobalGenerator()->AddRule(ppRule);
+ auto scanRule = GetScanRule(
+ scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(),
+ this->GetLocalGenerator(), std::move(scanCommands));
+
+ scanRule.Comment =
+ cmStrCat("Rule for generating ", lang, " dependencies.");
+ if (compilationPreprocesses) {
+ scanRule.Description =
+ cmStrCat("Scanning $in for ", lang, " dependencies");
+ } else {
+ scanRule.Description =
+ cmStrCat("Building ", lang, " preprocessed $out");
+ }
- if (!compilePPWithDefines) {
- // Remove preprocessor definitions from compilation step
- vars.Defines = "";
+ this->GetGlobalGenerator()->AddRule(scanRule);
}
- // Just dependency scanning for files that have preprocessing turned off
- const auto scanCommand =
- GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out");
+ if (!compilationPreprocesses) {
+ // Compilation will not preprocess, so it does not need the defines
+ // unless the compiler wants them for some other purpose.
+ if (!this->CompileWithDefines(lang)) {
+ vars.Defines = "";
+ }
- auto scanRule = GetPreprocessScanRule(
- this->LanguageDependencyRule(lang, config), vars, "", flags, launcher,
- rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator());
+ // Rule to scan dependencies of sources that do not need preprocessing.
+ std::string const& scanRuleName = this->LanguageScanRule(lang, config);
+ std::vector<std::string> scanCommands;
+ scanCommands.emplace_back(
+ GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
- // Write the rule for generating dependencies for the given language.
- scanRule.Comment = cmStrCat("Rule for generating ", lang,
- " dependencies on non-preprocessed files.");
- scanRule.Description =
- cmStrCat("Generating ", lang, " dependencies for $in");
+ auto scanRule = GetScanRule(
+ scanRuleName, vars, "", flags, rulePlaceholderExpander.get(),
+ this->GetLocalGenerator(), std::move(scanCommands));
- this->GetGlobalGenerator()->AddRule(scanRule);
- }
+ // Write the rule for generating dependencies for the given language.
+ scanRule.Comment = cmStrCat("Rule for generating ", lang,
+ " dependencies on non-preprocessed files.");
+ scanRule.Description =
+ cmStrCat("Generating ", lang, " dependencies for $in");
+
+ this->GetGlobalGenerator()->AddRule(scanRule);
+ }
- if (needDyndep) {
// Write the rule for ninja dyndep file generation.
cmNinjaRule rule(this->LanguageDyndepRule(lang, config));
// Command line length is almost always limited -> use response file for
@@ -714,12 +720,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// Run CMake dependency scanner on the source file (using the preprocessed
// source if that was performed).
+ std::string ddModmapArg;
+ if (!modmapFormat.empty()) {
+ ddModmapArg += cmStrCat(" --modmapfmt=", modmapFormat);
+ }
{
std::vector<std::string> ddCmds;
{
- std::string ccmd =
- cmStrCat(cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi,
- " --lang=", lang, " --dd=$out @", rule.RspFile);
+ std::string ccmd = cmStrCat(
+ cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi, " --lang=", lang,
+ ddModmapArg, " --dd=$out @", rule.RspFile);
ddCmds.emplace_back(std::move(ccmd));
}
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
@@ -743,12 +753,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// Tell ninja dependency format so all deps can be loaded into a database
std::string cldeps;
- if (explicitPP) {
- // The explicit preprocessing step will handle dependency scanning.
- } else if (this->NeedDepTypeMSVC(lang)) {
- rule.DepType = "msvc";
- rule.DepFile.clear();
- flags += " /showIncludes";
+ if (!compilationPreprocesses) {
+ // The compiler will not do preprocessing, so it has no such dependencies.
} else if (mf->IsOn(cmStrCat("CMAKE_NINJA_CMCLDEPS_", lang))) {
// For the MS resource compiler we need cmcldeps, but skip dependencies
// for source-file try_compile cases because they are always fresh.
@@ -764,20 +770,35 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
"\" \"", cl, "\" ");
}
} else {
- rule.DepType = "gcc";
- rule.DepFile = "$DEP_FILE";
+ const auto& depType = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_DEPFILE_FORMAT"));
+ if (depType == "msvc"_s) {
+ rule.DepType = "msvc";
+ rule.DepFile.clear();
+ } else {
+ rule.DepType = "gcc";
+ rule.DepFile = "$DEP_FILE";
+ }
+ vars.DependencyFile = rule.DepFile.c_str();
+ vars.DependencyTarget = "$out";
+
const std::string flagsName = cmStrCat("CMAKE_DEPFILE_FLAGS_", lang);
std::string depfileFlags = mf->GetSafeDefinition(flagsName);
if (!depfileFlags.empty()) {
- cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
- cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
- cmSystemTools::ReplaceString(
- depfileFlags, "<CMAKE_C_COMPILER>",
- cmToCStr(mf->GetDefinition("CMAKE_C_COMPILER")));
+ rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
+ depfileFlags, vars);
flags += cmStrCat(' ', depfileFlags);
}
}
+ if (needDyndep && !modmapFormat.empty()) {
+ std::string modmapFlags = mf->GetRequiredDefinition(
+ cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
+ cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
+ "$DYNDEP_MODULE_MAP_FILE");
+ flags += cmStrCat(' ', modmapFlags);
+ }
+
vars.Flags = flags.c_str();
vars.DependencyFile = rule.DepFile.c_str();
@@ -815,15 +836,21 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
// Maybe insert an include-what-you-use runner.
- if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
- std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
- cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ if (!compileCmds.empty() &&
+ (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
- std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
- cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
- std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
- cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ cmProp iwyu = nullptr;
+ cmProp cpplint = nullptr;
+ cmProp cppcheck = nullptr;
+ if (lang == "C" || lang == "CXX") {
+ std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
+ iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
+ cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
+ cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ }
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
cmNonempty(cppcheck)) {
std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
@@ -887,6 +914,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
compileCmds.front().insert(0, cldeps);
}
+ const auto& extraCommands = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
+ if (!extraCommands.empty()) {
+ auto commandList = cmExpandedList(extraCommands);
+ compileCmds.insert(compileCmds.end(), commandList.cbegin(),
+ commandList.cend());
+ }
+
for (std::string& i : compileCmds) {
i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
@@ -939,7 +974,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
config);
}
if (firstForConfig) {
- cmProp pchExtension = GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+ cmProp pchExtension =
+ this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
@@ -973,9 +1009,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
const std::vector<std::string>& ccbyproducts = ccg.GetByproducts();
std::transform(ccoutputs.begin(), ccoutputs.end(),
- std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ std::back_inserter(orderOnlyDeps),
+ this->MapToNinjaPath());
std::transform(ccbyproducts.begin(), ccbyproducts.end(),
- std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ std::back_inserter(orderOnlyDeps),
+ this->MapToNinjaPath());
}
std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end());
@@ -1062,78 +1100,91 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
namespace {
-cmNinjaBuild GetPreprocessOrScanBuild(
- const std::string& ruleName, const std::string& ppFileName, bool compilePP,
- bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
- const std::string& depFileName, bool needDyndep,
- const std::string& objectFileName)
+cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
+ const std::string& ppFileName,
+ bool compilePP, bool compilePPWithDefines,
+ cmNinjaBuild& objBuild, cmNinjaVars& vars,
+ std::string const& modmapFormat,
+ const std::string& objectFileName,
+ cmLocalGenerator* lg)
{
- // Explicit preprocessing and dependency
- cmNinjaBuild ppBuild(ruleName);
+ cmNinjaBuild scanBuild(ruleName);
if (!ppFileName.empty()) {
- ppBuild.Outputs.push_back(ppFileName);
- ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+ scanBuild.RspFile = cmStrCat(ppFileName, ".rsp");
} else {
- ppBuild.RspFile = "$out.rsp";
+ scanBuild.RspFile = "$out.rsp";
}
if (compilePP) {
- // Move compilation dependencies to the preprocessing build statement.
- std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
- std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
- std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
- std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
+ // Move compilation dependencies to the scan/preprocessing build statement.
+ std::swap(scanBuild.ExplicitDeps, objBuild.ExplicitDeps);
+ std::swap(scanBuild.ImplicitDeps, objBuild.ImplicitDeps);
+ std::swap(scanBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
+ std::swap(scanBuild.Variables["IN_ABS"], vars["IN_ABS"]);
// The actual compilation will now use the preprocessed source.
objBuild.ExplicitDeps.push_back(ppFileName);
} else {
- // Copy compilation dependencies to the preprocessing build statement.
- ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
- ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
- ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
- ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+ // Copy compilation dependencies to the scan/preprocessing build statement.
+ scanBuild.ExplicitDeps = objBuild.ExplicitDeps;
+ scanBuild.ImplicitDeps = objBuild.ImplicitDeps;
+ scanBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
+ scanBuild.Variables["IN_ABS"] = vars["IN_ABS"];
}
- // Preprocessing and compilation generally use the same flags.
- ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+ // Scanning and compilation generally use the same flags.
+ scanBuild.Variables["FLAGS"] = vars["FLAGS"];
if (compilePP && !compilePPWithDefines) {
- // Move preprocessor definitions to the preprocessor build statement.
- std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
+ // Move preprocessor definitions to the scan/preprocessor build statement.
+ std::swap(scanBuild.Variables["DEFINES"], vars["DEFINES"]);
} else {
- // Copy preprocessor definitions to the preprocessor build statement.
- ppBuild.Variables["DEFINES"] = vars["DEFINES"];
+ // Copy preprocessor definitions to the scan/preprocessor build statement.
+ scanBuild.Variables["DEFINES"] = vars["DEFINES"];
}
// Copy include directories to the preprocessor build statement. The
// Fortran compilation build statement still needs them for the INCLUDE
// directive.
- ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
+ scanBuild.Variables["INCLUDES"] = vars["INCLUDES"];
- // Explicit preprocessing always uses a depfile.
- ppBuild.Variables["DEP_FILE"] = depFileName;
+ // Tell dependency scanner the object file that will result from
+ // compiling the source.
+ scanBuild.Variables["OBJ_FILE"] = objectFileName;
+
+ // Tell dependency scanner where to store dyndep intermediate results.
+ std::string const& ddiFile = cmStrCat(objectFileName, ".ddi");
+ scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+
+ // Outputs of the scan/preprocessor build statement.
+ if (!ppFileName.empty()) {
+ scanBuild.Outputs.push_back(ppFileName);
+ scanBuild.ImplicitOuts.push_back(ddiFile);
+ } else {
+ scanBuild.Outputs.push_back(ddiFile);
+ }
+
+ // Scanning always uses a depfile for preprocessor dependencies.
+ std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
+ scanBuild.Variables["DEP_FILE"] =
+ lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);
if (compilePP) {
// The actual compilation does not need a depfile because it
// depends on the already-preprocessed source.
vars.erase("DEP_FILE");
}
- if (needDyndep) {
- // Tell dependency scanner the object file that will result from
- // compiling the source.
- ppBuild.Variables["OBJ_FILE"] = objectFileName;
-
- // Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
- if (ppFileName.empty()) {
- ppBuild.Outputs.push_back(ddiFile);
- } else {
- ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
- ppBuild.ImplicitOuts.push_back(ddiFile);
- }
+ if (!modmapFormat.empty()) {
+ // XXX(modmap): If changing this path construction, change
+ // `cmGlobalNinjaGenerator::WriteDyndep` to expect the corresponding
+ // file path.
+ std::string const ddModmapFile = cmStrCat(objectFileName, ".modmap");
+ scanBuild.Variables["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile;
+ scanBuild.ImplicitOuts.push_back(ddModmapFile);
}
- return ppBuild;
+
+ return scanBuild;
}
}
@@ -1157,7 +1208,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// build response file name
std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG");
- cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar);
+ cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
bool const lang_supports_response =
!(language == "RC" || (language == "CUDA" && !flag));
@@ -1170,7 +1221,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["DEFINES"] = this->ComputeDefines(source, language, config);
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
- if (!this->NeedDepTypeMSVC(language)) {
+ if (this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
bool replaceExt(false);
if (!language.empty()) {
std::string repVar =
@@ -1253,7 +1305,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
std::transform(depList.begin(), depList.end(),
std::back_inserter(objBuild.ImplicitDeps),
- MapToNinjaPath());
+ this->MapToNinjaPath());
}
objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
@@ -1270,13 +1322,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
sourceFileName, objBuild.OrderOnlyDeps);
}
- // For some cases we need to generate a ninja dyndep file.
- bool const needDyndep = this->NeedDyndep(language);
+ // For some cases we scan to dynamically discover dependencies.
+ bool const needDyndep = this->NeedDyndep(language, config);
+ bool const compilationPreprocesses =
+ !this->NeedExplicitPreprocessing(language);
- // For some cases we do an explicit preprocessor invocation.
- bool const explicitPP = this->NeedExplicitPreprocessing(language);
- if (explicitPP) {
+ std::string modmapFormat;
+ if (needDyndep) {
+ std::string const modmapFormatVar =
+ cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
+ modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar);
+ }
+ if (needDyndep) {
// If source/target has preprocessing turned off, we still need to
// generate an explicit dependency step
const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS");
@@ -1288,27 +1346,24 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
}
- bool const compilePP = this->UsePreprocessedSource(language) &&
+ bool const compilePP = !compilationPreprocesses &&
(preprocess != cmOutputConverter::FortranPreprocess::NotNeeded);
bool const compilePPWithDefines =
- compilePP && this->CompilePreprocessedSourceWithDefines(language);
-
- std::string const ppFileName = compilePP
- ? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config))
- : "";
+ compilePP && this->CompileWithDefines(language);
- std::string const buildName = compilePP
- ? this->LanguagePreprocessRule(language, config)
- : this->LanguageDependencyRule(language, config);
-
- const auto depExtension = compilePP ? ".pp.d" : ".d";
- const std::string depFileName =
- this->GetLocalGenerator()->ConvertToOutputFormat(
- cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
+ std::string scanRuleName;
+ std::string ppFileName;
+ if (compilePP) {
+ scanRuleName = this->LanguagePreprocessAndScanRule(language, config);
+ ppFileName = this->ConvertToNinjaPath(
+ this->GetPreprocessedFilePath(source, config));
+ } else {
+ scanRuleName = this->LanguageScanRule(language, config);
+ }
- cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
- buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
- depFileName, needDyndep, objectFileName);
+ cmNinjaBuild ppBuild = GetScanBuildStatement(
+ scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild,
+ vars, modmapFormat, objectFileName, this->LocalGenerator);
if (compilePP) {
// In case compilation requires flags that are incompatible with
@@ -1330,7 +1385,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
}
- if (firstForConfig && needDyndep) {
+ if (firstForConfig) {
std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
this->Configs[config].DDIFiles[language].push_back(ddiFile);
}
@@ -1340,14 +1395,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
ppBuild, commandLineLengthLimit);
- }
- if (needDyndep) {
+
std::string const dyndep = this->GetDyndepFilePath(language, config);
objBuild.OrderOnlyDeps.push_back(dyndep);
vars["dyndep"] = dyndep;
+
+ if (!modmapFormat.empty()) {
+ std::string const ddModmapFile = cmStrCat(objectFileName, ".modmap");
+ vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile;
+ objBuild.OrderOnlyDeps.push_back(ddModmapFile);
+ }
}
- EnsureParentDirectoryExists(objectFileName);
+ this->EnsureParentDirectoryExists(objectFileName);
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
objectDir, cmOutputConverter::SHELL);
@@ -1420,7 +1480,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
auto headers = this->GeneratorTarget->GetGeneratedISPCHeaders(config);
if (!headers.empty()) {
std::transform(headers.begin(), headers.end(), headers.begin(),
- MapToNinjaPath());
+ this->MapToNinjaPath());
objBuild.OrderOnlyDeps.insert(objBuild.OrderOnlyDeps.end(),
headers.begin(), headers.end());
}
@@ -1442,7 +1502,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
build.Comment = "Additional output files.";
build.Outputs = cmExpandedList(evaluatedObjectOutputs);
std::transform(build.Outputs.begin(), build.Outputs.end(),
- build.Outputs.begin(), MapToNinjaPath());
+ build.Outputs.begin(), this->MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
this->GetGlobalGenerator()->WriteBuild(
this->GetImplFileStream(fileConfig), build);
@@ -1458,17 +1518,26 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
tdi["compiler-id"] = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
+ std::string mod_dir;
if (lang == "Fortran") {
- std::string mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
+ mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
this->Makefile->GetHomeOutputDirectory());
- if (mod_dir.empty()) {
- mod_dir = this->Makefile->GetCurrentBinaryDirectory();
- }
- tdi["module-dir"] = mod_dir;
+ } else if (lang == "CXX") {
+ mod_dir =
+ cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory);
+ }
+ if (mod_dir.empty()) {
+ mod_dir = this->Makefile->GetCurrentBinaryDirectory();
+ }
+ tdi["module-dir"] = mod_dir;
+
+ if (lang == "Fortran") {
tdi["submodule-sep"] =
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
tdi["submodule-ext"] =
this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
+ } else if (lang == "CXX") {
+ // No extra information necessary.
}
tdi["dir-cur-bld"] = this->Makefile->GetCurrentBinaryDirectory();
@@ -1550,7 +1619,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string const& objectFileDir, std::string const& flags,
std::string const& defines, std::string const& includes)
{
- if (!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS")) {
+ if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) {
return;
}
@@ -1662,7 +1731,7 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists(
void cmNinjaTargetGenerator::EnsureParentDirectoryExists(
const std::string& path) const
{
- EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path));
+ this->EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path));
}
void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index a27c9b4..79dc622 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -42,8 +42,6 @@ public:
std::string GetTargetName() const;
- bool NeedDepTypeMSVC(const std::string& lang) const;
-
protected:
bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
@@ -67,16 +65,17 @@ protected:
std::string LanguageCompilerRule(const std::string& lang,
const std::string& config) const;
- std::string LanguagePreprocessRule(std::string const& lang,
- const std::string& config) const;
- std::string LanguageDependencyRule(std::string const& lang,
- const std::string& config) const;
- bool NeedExplicitPreprocessing(std::string const& lang) 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) const;
- bool UsePreprocessedSource(std::string const& lang) const;
- bool CompilePreprocessedSourceWithDefines(std::string const& lang) 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);
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index ad1d5f1..3995624 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include <algorithm>
#include <array>
#include <iterator>
+#include <set>
#include <string>
#include <utility>
#include <vector>
@@ -34,13 +35,30 @@ cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default;
void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
{
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ if (fileConfig != config &&
+ this->GetGeneratorTarget()->GetType() == cmStateEnums::GLOBAL_TARGET) {
+ continue;
+ }
+ this->WriteUtilBuildStatements(config, fileConfig);
+ }
+}
+
+void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements(
+ std::string const& config, std::string const& fileConfig)
+{
cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
std::string configDir;
if (genTarget->Target->IsPerConfig()) {
- configDir = gg->ConfigDirectory(config);
+ configDir = gg->ConfigDirectory(fileConfig);
}
std::string utilCommandName =
cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/",
@@ -60,12 +78,13 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
for (std::vector<cmCustomCommand> const* cmdList : cmdLists) {
for (cmCustomCommand const& ci : *cmdList) {
- cmCustomCommandGenerator ccg(ci, config, lg);
- lg->AppendCustomCommandDeps(ccg, deps, config);
+ cmCustomCommandGenerator ccg(ci, fileConfig, lg);
+ lg->AppendCustomCommandDeps(ccg, deps, fileConfig);
lg->AppendCustomCommandLines(ccg, commands);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
- std::back_inserter(util_outputs), MapToNinjaPath());
+ std::back_inserter(util_outputs),
+ this->MapToNinjaPath());
if (ci.GetUsesTerminal()) {
uses_terminal = true;
}
@@ -85,9 +104,9 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
const std::vector<std::string>& ccOutputs = ccg.GetOutputs();
const std::vector<std::string>& ccByproducts = ccg.GetByproducts();
std::transform(ccOutputs.begin(), ccOutputs.end(),
- std::back_inserter(deps), MapToNinjaPath());
+ std::back_inserter(deps), this->MapToNinjaPath());
std::transform(ccByproducts.begin(), ccByproducts.end(),
- std::back_inserter(deps), MapToNinjaPath());
+ std::back_inserter(deps), this->MapToNinjaPath());
}
}
}
@@ -103,13 +122,19 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
std::copy(util_outputs.begin(), util_outputs.end(),
std::back_inserter(gg->GetByproductsForCleanTarget()));
}
- lg->AppendTargetDepends(genTarget, deps, config, config,
+ // TODO: Does this need an output config?
+ // Does this need to go in impl-<config>.ninja?
+ lg->AppendTargetDepends(genTarget, deps, config, fileConfig,
DependOnTargetArtifact);
if (commands.empty()) {
phonyBuild.Comment = "Utility command for " + this->GetTargetName();
phonyBuild.ExplicitDeps = std::move(deps);
- gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
+ if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ gg->WriteBuild(this->GetImplFileStream(fileConfig), phonyBuild);
+ } else {
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
+ }
} else {
std::string command =
lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
@@ -145,15 +170,22 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
std::string ccConfig;
if (genTarget->Target->IsPerConfig() &&
genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
- ccConfig = config;
+ ccConfig = fileConfig;
+ }
+ if (config == fileConfig ||
+ gg->GetPerConfigUtilityTargets().count(genTarget->GetName())) {
+ gg->WriteCustomCommandBuild(
+ command, desc, "Utility command for " + this->GetTargetName(),
+ /*depfile*/ "", /*job_pool*/ "", uses_terminal,
+ /*restat*/ true, util_outputs, ccConfig, deps);
}
- gg->WriteCustomCommandBuild(command, desc,
- "Utility command for " + this->GetTargetName(),
- /*depfile*/ "", /*job_pool*/ "", uses_terminal,
- /*restat*/ true, util_outputs, ccConfig, deps);
phonyBuild.ExplicitDeps.push_back(utilCommandName);
- gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
+ if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ gg->WriteBuild(this->GetImplFileStream(fileConfig), phonyBuild);
+ } else {
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
+ }
}
// Find ADDITIONAL_CLEAN_FILES
diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
index 24b47f8..dbd3797 100644
--- a/Source/cmNinjaUtilityTargetGenerator.h
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -17,4 +17,8 @@ public:
~cmNinjaUtilityTargetGenerator() override;
void Generate(const std::string& config) override;
+
+private:
+ void WriteUtilBuildStatements(std::string const& config,
+ std::string const& fileConfig);
};
diff --git a/Source/cmPipeConnection.cxx b/Source/cmPipeConnection.cxx
deleted file mode 100644
index 1eede13..0000000
--- a/Source/cmPipeConnection.cxx
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmPipeConnection.h"
-
-#include <utility>
-
-#include "cmServer.h"
-
-cmPipeConnection::cmPipeConnection(std::string name,
- cmConnectionBufferStrategy* bufferStrategy)
- : cmEventBasedConnection(bufferStrategy)
- , PipeName(std::move(name))
-{
-}
-
-void cmPipeConnection::Connect(uv_stream_t* server)
-{
- if (this->WriteStream.get()) {
- // Accept and close all pipes but the first:
- cm::uv_pipe_ptr rejectPipe;
-
- rejectPipe.init(*this->Server->GetLoop(), 0);
- uv_accept(server, rejectPipe);
-
- return;
- }
-
- cm::uv_pipe_ptr ClientPipe;
- ClientPipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
-
- if (uv_accept(server, ClientPipe) != 0) {
- return;
- }
-
- uv_read_start(ClientPipe, on_alloc_buffer, on_read);
- WriteStream = std::move(ClientPipe);
- Server->OnConnected(this);
-}
-
-bool cmPipeConnection::OnServeStart(std::string* errorMessage)
-{
- this->ServerPipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
-
- int r;
- if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
- *errorMessage = std::string("Internal Error with ") + this->PipeName +
- ": " + uv_err_name(r);
- return false;
- }
-
- if ((r = uv_listen(this->ServerPipe, 1, on_new_connection)) != 0) {
- *errorMessage = std::string("Internal Error listening on ") +
- this->PipeName + ": " + uv_err_name(r);
- return false;
- }
-
- return cmConnection::OnServeStart(errorMessage);
-}
-
-bool cmPipeConnection::OnConnectionShuttingDown()
-{
- if (this->WriteStream.get()) {
- this->WriteStream->data = nullptr;
- }
-
- this->ServerPipe.reset();
-
- return cmEventBasedConnection::OnConnectionShuttingDown();
-}
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
deleted file mode 100644
index 1215716..0000000
--- a/Source/cmPipeConnection.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 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 <string>
-
-#include <cm3p/uv.h>
-
-#include "cmConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmPipeConnection : public cmEventBasedConnection
-{
-public:
- cmPipeConnection(std::string name,
- cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
- bool OnServeStart(std::string* pString) override;
-
- bool OnConnectionShuttingDown() override;
-
- void Connect(uv_stream_t* server) override;
-
-private:
- const std::string PipeName;
- cm::uv_pipe_ptr ServerPipe;
-};
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 18ce9c3..2194b0f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -340,6 +340,25 @@ class cmMakefile;
3, 19, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0114, \
"ExternalProject step targets fully adopt their steps.", 3, 19, 0, \
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0115, "Source file extensions must be explicit.", 3, 20, \
+ 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0116, \
+ "Ninja generators transform DEPFILEs from add_custom_command().", 3, \
+ 20, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0117, \
+ "MSVC RTTI flag /GR is not added to CMAKE_CXX_FLAGS by default.", 3, \
+ 20, 0, cmPolicies::WARN) \
+ SELECT( \
+ POLICY, CMP0118, \
+ "The GENERATED source file property is now visible in all directories.", \
+ 3, 20, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0119, \
+ "LANGUAGE source file property explicitly compiles as specified " \
+ "language.", \
+ 3, 20, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0120, \
+ "The WriteCompilerDetectionHeader module is removed.", 3, 20, 0, \
cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -375,7 +394,8 @@ class cmMakefile;
F(CMP0105) \
F(CMP0108) \
F(CMP0112) \
- F(CMP0113)
+ F(CMP0113) \
+ F(CMP0119)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
index 0fb4ff7..2d2676e 100644
--- a/Source/cmProcessOutput.cxx
+++ b/Source/cmProcessOutput.cxx
@@ -126,7 +126,7 @@ bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded,
bool cmProcessOutput::DecodeText(const char* data, size_t length,
std::string& decoded, size_t id)
{
- return DecodeText(std::string(data, length), decoded, id);
+ return this->DecodeText(std::string(data, length), decoded, id);
}
bool cmProcessOutput::DecodeText(std::vector<char> raw,
@@ -134,7 +134,7 @@ bool cmProcessOutput::DecodeText(std::vector<char> raw,
{
std::string str;
const bool success =
- DecodeText(std::string(raw.begin(), raw.end()), str, id);
+ this->DecodeText(std::string(raw.begin(), raw.end()), str, id);
decoded.assign(str.begin(), str.end());
return success;
}
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 0cfba63..ed32de9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -358,6 +358,17 @@ static bool IncludeByVariable(cmExecutionStatus& status,
return true;
}
+ std::string includeFile =
+ cmSystemTools::CollapseFullPath(*include, mf.GetCurrentSourceDirectory());
+ if (!cmSystemTools::FileExists(includeFile)) {
+ status.SetError(cmStrCat("could not find requested file:\n ", *include));
+ return false;
+ }
+ if (cmSystemTools::FileIsDirectory(includeFile)) {
+ status.SetError(cmStrCat("requested file is a directory:\n ", *include));
+ return false;
+ }
+
const bool readit = mf.ReadDependentFile(*include);
if (readit) {
return true;
@@ -367,7 +378,7 @@ static bool IncludeByVariable(cmExecutionStatus& status,
return true;
}
- status.SetError(cmStrCat("could not find file:\n ", *include));
+ status.SetError(cmStrCat("could not load requested file:\n ", *include));
return false;
}
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index f22f36d..06e151a 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -7,17 +7,17 @@
void cmPropertyMap::Clear()
{
- Map_.clear();
+ this->Map_.clear();
}
void cmPropertyMap::SetProperty(const std::string& name, const char* value)
{
if (!value) {
- Map_.erase(name);
+ this->Map_.erase(name);
return;
}
- Map_[name] = value;
+ this->Map_[name] = value;
}
void cmPropertyMap::AppendProperty(const std::string& name,
@@ -29,7 +29,7 @@ void cmPropertyMap::AppendProperty(const std::string& name,
}
{
- std::string& pVal = Map_[name];
+ std::string& pVal = this->Map_[name];
if (!pVal.empty() && !asString) {
pVal += ';';
}
@@ -39,13 +39,13 @@ void cmPropertyMap::AppendProperty(const std::string& name,
void cmPropertyMap::RemoveProperty(const std::string& name)
{
- Map_.erase(name);
+ this->Map_.erase(name);
}
cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
{
- auto it = Map_.find(name);
- if (it != Map_.end()) {
+ auto it = this->Map_.find(name);
+ if (it != this->Map_.end()) {
return &it->second;
}
return nullptr;
@@ -54,8 +54,8 @@ cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
std::vector<std::string> cmPropertyMap::GetKeys() const
{
std::vector<std::string> keyList;
- keyList.reserve(Map_.size());
- for (auto const& item : Map_) {
+ keyList.reserve(this->Map_.size());
+ for (auto const& item : this->Map_) {
keyList.push_back(item.first);
}
std::sort(keyList.begin(), keyList.end());
@@ -66,8 +66,8 @@ std::vector<std::pair<std::string, std::string>> cmPropertyMap::GetList() const
{
using StringPair = std::pair<std::string, std::string>;
std::vector<StringPair> kvList;
- kvList.reserve(Map_.size());
- for (auto const& item : Map_) {
+ kvList.reserve(this->Map_.size());
+ for (auto const& item : this->Map_) {
kvList.emplace_back(item.first, item.second);
}
std::sort(kvList.begin(), kvList.end(),
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index de462db..e058176 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -40,8 +40,7 @@ bool cmQTWrapCPPCommand(std::vector<std::string> const& args,
cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
if (curr) {
- cmProp p = curr->GetProperty("ABSTRACT");
- sf->SetProperty("ABSTRACT", cmToCStr(p));
+ sf->SetProperty("ABSTRACT", cmToCStr(curr->GetProperty("ABSTRACT")));
}
// Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index cf90417..e12a653 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -29,13 +29,13 @@ public:
{
}
- bool operator>(IntegerVersion const version)
+ bool operator>(IntegerVersion const version) const
{
return (this->Major > version.Major) ||
((this->Major == version.Major) && (this->Minor > version.Minor));
}
- bool operator>=(IntegerVersion const version)
+ bool operator>=(IntegerVersion const version) const
{
return (this->Major > version.Major) ||
((this->Major == version.Major) && (this->Minor >= version.Minor));
@@ -111,20 +111,20 @@ public:
RccLister(std::string rccExecutable, std::vector<std::string> listOptions);
//! The rcc executable
- std::string const& RccExcutable() const { return RccExcutable_; }
+ std::string const& RccExcutable() const { return this->RccExcutable_; }
void SetRccExecutable(std::string const& rccExecutable)
{
- RccExcutable_ = rccExecutable;
+ this->RccExcutable_ = rccExecutable;
}
//! The rcc executable list options
std::vector<std::string> const& ListOptions() const
{
- return ListOptions_;
+ return this->ListOptions_;
}
void SetListOptions(std::vector<std::string> const& listOptions)
{
- ListOptions_ = listOptions;
+ this->ListOptions_ = listOptions;
}
/**
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index fac2bbf..62b879f 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenGlobalInitializer.h"
+#include <set>
#include <utility>
#include <cm/memory>
@@ -56,7 +57,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autogen";
}
- GlobalAutoGenTargets_.emplace(localGen.get(), std::move(targetName));
+ this->GlobalAutoGenTargets_.emplace(localGen.get(),
+ std::move(targetName));
globalAutoGenTarget = true;
}
@@ -67,7 +69,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autorcc";
}
- GlobalAutoRccTargets_.emplace(localGen.get(), std::move(targetName));
+ this->GlobalAutoRccTargets_.emplace(localGen.get(),
+ std::move(targetName));
globalAutoRccTarget = true;
}
}
@@ -91,17 +94,23 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
// Don't process target
continue;
}
+ std::set<std::string> const& languages =
+ target->GetAllConfigCompileLanguages();
+ if (languages.count("CSharp")) {
+ // Don't process target if it's a CSharp target
+ continue;
+ }
- bool const moc = target->GetPropertyAsBool(kw().AUTOMOC);
- bool const uic = target->GetPropertyAsBool(kw().AUTOUIC);
- bool const rcc = target->GetPropertyAsBool(kw().AUTORCC);
+ bool const moc = target->GetPropertyAsBool(this->kw().AUTOMOC);
+ bool const uic = target->GetPropertyAsBool(this->kw().AUTOUIC);
+ bool const rcc = target->GetPropertyAsBool(this->kw().AUTORCC);
if (moc || uic || rcc) {
std::string const& mocExec =
- target->GetSafeProperty(kw().AUTOMOC_EXECUTABLE);
+ target->GetSafeProperty(this->kw().AUTOMOC_EXECUTABLE);
std::string const& uicExec =
- target->GetSafeProperty(kw().AUTOUIC_EXECUTABLE);
+ target->GetSafeProperty(this->kw().AUTOUIC_EXECUTABLE);
std::string const& rccExec =
- target->GetSafeProperty(kw().AUTORCC_EXECUTABLE);
+ target->GetSafeProperty(this->kw().AUTORCC_EXECUTABLE);
// We support Qt4, Qt5 and Qt6
auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get());
@@ -134,9 +143,10 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
}
if (mocIsValid || uicIsValid || rccIsValid) {
// Create autogen target initializer
- Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- this, target.get(), qtVersion.first, mocIsValid, uicIsValid,
- rccIsValid, globalAutoGenTarget, globalAutoRccTarget));
+ this->Initializers_.emplace_back(
+ cm::make_unique<cmQtAutoGenInitializer>(
+ this, target.get(), qtVersion.first, mocIsValid, uicIsValid,
+ rccIsValid, globalAutoGenTarget, globalAutoRccTarget));
}
}
}
@@ -177,8 +187,8 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
cmLocalGenerator* localGen, std::string const& targetName)
{
- auto it = GlobalAutoGenTargets_.find(localGen);
- if (it != GlobalAutoGenTargets_.end()) {
+ auto it = this->GlobalAutoGenTargets_.find(localGen);
+ if (it != this->GlobalAutoGenTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
target->Target->AddUtility(targetName, false, localGen->GetMakefile());
@@ -189,8 +199,8 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
cmLocalGenerator* localGen, std::string const& targetName)
{
- auto it = GlobalAutoRccTargets_.find(localGen);
- if (it != GlobalAutoRccTargets_.end()) {
+ auto it = this->GlobalAutoRccTargets_.find(localGen);
+ if (it != this->GlobalAutoRccTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
target->Target->AddUtility(targetName, false, localGen->GetMakefile());
@@ -251,7 +261,7 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
bool cmQtAutoGenGlobalInitializer::generate()
{
- return (InitializeCustomTargets() && SetupCustomTargets());
+ return (this->InitializeCustomTargets() && this->SetupCustomTargets());
}
bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
@@ -259,19 +269,19 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
// Initialize global autogen targets
{
std::string const comment = "Global AUTOGEN target";
- for (auto const& pair : GlobalAutoGenTargets_) {
- GetOrCreateGlobalTarget(pair.first, pair.second, comment);
+ for (auto const& pair : this->GlobalAutoGenTargets_) {
+ this->GetOrCreateGlobalTarget(pair.first, pair.second, comment);
}
}
// Initialize global autorcc targets
{
std::string const comment = "Global AUTORCC target";
- for (auto const& pair : GlobalAutoRccTargets_) {
- GetOrCreateGlobalTarget(pair.first, pair.second, comment);
+ for (auto const& pair : this->GlobalAutoRccTargets_) {
+ this->GetOrCreateGlobalTarget(pair.first, pair.second, comment);
}
}
// Initialize per target autogen targets
- for (auto& initializer : Initializers_) {
+ for (auto& initializer : this->Initializers_) {
if (!initializer->InitCustomTargets()) {
return false;
}
@@ -281,7 +291,7 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
bool cmQtAutoGenGlobalInitializer::SetupCustomTargets()
{
- for (auto& initializer : Initializers_) {
+ for (auto& initializer : this->Initializers_) {
if (!initializer->SetupCustomTargets()) {
return false;
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index cdae137..ea3821d 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -50,7 +50,7 @@ public:
std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators);
~cmQtAutoGenGlobalInitializer();
- Keywords const& kw() const { return Keywords_; };
+ Keywords const& kw() const { return this->Keywords_; };
bool generate();
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 3b62e9c..bfe174c 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -17,6 +17,7 @@
#include <cm/iterator>
#include <cm/memory>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
@@ -29,6 +30,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmGlobalNinjaGenerator.h"
#include "cmLinkItem.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
@@ -150,7 +152,8 @@ std::vector<std::string> SearchPathSanitizer::operator()(
res.reserve(paths.size());
for (std::string const& srcPath : paths) {
// Collapse relative paths
- std::string path = cmSystemTools::CollapseFullPath(srcPath, SourcePath_);
+ std::string path =
+ cmSystemTools::CollapseFullPath(srcPath, this->SourcePath_);
// Remove suffix slashes
while (cmHasSuffix(path, '/')) {
path.pop_back();
@@ -170,14 +173,17 @@ public:
// -- Single value
void Set(std::string const& key, std::string const& value)
{
- Value_[key] = value;
+ this->Value_[key] = value;
}
void SetConfig(std::string const& key,
cmQtAutoGenInitializer::ConfigString const& cfgStr);
- void SetBool(std::string const& key, bool value) { Value_[key] = value; }
+ void SetBool(std::string const& key, bool value)
+ {
+ this->Value_[key] = value;
+ }
void SetUInt(std::string const& key, unsigned int value)
{
- Value_[key] = value;
+ this->Value_[key] = value;
}
// -- Array utility
@@ -209,9 +215,9 @@ private:
void InfoWriter::SetConfig(std::string const& key,
cmQtAutoGenInitializer::ConfigString const& cfgStr)
{
- Set(key, cfgStr.Default);
+ this->Set(key, cfgStr.Default);
for (auto const& item : cfgStr.Config) {
- Set(cmStrCat(key, '_', item.first), item.second);
+ this->Set(cmStrCat(key, '_', item.first), item.second);
}
}
@@ -241,14 +247,14 @@ void InfoWriter::MakeStringArray(Json::Value& jval, CONT const& container)
template <typename CONT>
void InfoWriter::SetArray(std::string const& key, CONT const& container)
{
- MakeStringArray(Value_[key], container);
+ MakeStringArray(this->Value_[key], container);
}
template <typename CONT, typename FUNC>
void InfoWriter::SetArrayArray(std::string const& key, CONT const& container,
FUNC func)
{
- Json::Value& jval = Value_[key];
+ Json::Value& jval = this->Value_[key];
if (MakeArray(jval, container)) {
Json::ArrayIndex ii = 0;
for (auto const& citem : container) {
@@ -264,9 +270,9 @@ void InfoWriter::SetConfigArray(
std::string const& key,
cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr)
{
- SetArray(key, cfgStr.Default);
+ this->SetArray(key, cfgStr.Default);
for (auto const& item : cfgStr.Config) {
- SetArray(cmStrCat(key, '_', item.first), item.second);
+ this->SetArray(cmStrCat(key, '_', item.first), item.second);
}
}
@@ -281,7 +287,7 @@ bool InfoWriter::Save(std::string const& filename)
Json::StyledStreamWriter jsonWriter;
try {
- jsonWriter.write(fileStream, Value_);
+ jsonWriter.write(fileStream, this->Value_);
} catch (...) {
return false;
}
@@ -304,11 +310,11 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer(
, PathCheckSum(genTarget->Makefile)
, QtVersion(qtVersion)
{
- AutogenTarget.GlobalTarget = globalAutogenTarget;
- Moc.Enabled = mocEnabled;
- Uic.Enabled = uicEnabled;
- Rcc.Enabled = rccEnabled;
- Rcc.GlobalTarget = globalAutoRccTarget;
+ this->AutogenTarget.GlobalTarget = globalAutogenTarget;
+ this->Moc.Enabled = mocEnabled;
+ this->Uic.Enabled = uicEnabled;
+ this->Rcc.Enabled = rccEnabled;
+ this->Rcc.GlobalTarget = globalAutoRccTarget;
}
bool cmQtAutoGenInitializer::InitCustomTargets()
@@ -414,8 +420,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
cmSystemTools::ConvertToUnixSlashes(this->Dir.Work);
// Include directory
- ConfigFileNames(this->Dir.Include, cmStrCat(this->Dir.Build, "/include"),
- "");
+ this->ConfigFileNames(this->Dir.Include,
+ cmStrCat(this->Dir.Build, "/include"), "");
this->Dir.IncludeGenExp = this->Dir.Include.Default;
if (this->MultiConfig) {
this->Dir.IncludeGenExp += "_$<CONFIG>";
@@ -425,12 +431,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Moc, Uic and _autogen target settings
if (this->MocOrUicEnabled()) {
// Init moc specific settings
- if (this->Moc.Enabled && !InitMoc()) {
+ if (this->Moc.Enabled && !this->InitMoc()) {
return false;
}
// Init uic specific settings
- if (this->Uic.Enabled && !InitUic()) {
+ if (this->Uic.Enabled && !this->InitUic()) {
return false;
}
@@ -457,14 +463,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
cmStrCat(this->Dir.Info, "/AutogenInfo.json");
// Used settings file
- ConfigFileNames(this->AutogenTarget.SettingsFile,
- cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt");
- ConfigFileClean(this->AutogenTarget.SettingsFile);
+ this->ConfigFileNames(this->AutogenTarget.SettingsFile,
+ cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt");
+ this->ConfigFileClean(this->AutogenTarget.SettingsFile);
// Parse cache file
- ConfigFileNames(this->AutogenTarget.ParseCacheFile,
- cmStrCat(this->Dir.Info, "/ParseCache"), ".txt");
- ConfigFileClean(this->AutogenTarget.ParseCacheFile);
+ this->ConfigFileNames(this->AutogenTarget.ParseCacheFile,
+ cmStrCat(this->Dir.Info, "/ParseCache"), ".txt");
+ this->ConfigFileClean(this->AutogenTarget.ParseCacheFile);
}
// Autogen target: Compute user defined dependencies
@@ -533,7 +539,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
// Init rcc specific settings
- if (this->Rcc.Enabled && !InitRcc()) {
+ if (this->Rcc.Enabled && !this->InitRcc()) {
return false;
}
@@ -563,8 +569,23 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
bool cmQtAutoGenInitializer::InitMoc()
{
// Mocs compilation file
- this->Moc.CompilationFile =
- cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
+ if (this->GlobalGen->IsXcode()) {
+ // XXX(xcode-per-cfg-src): Drop this Xcode-specific code path
+ // when the Xcode generator supports per-config sources.
+ this->Moc.CompilationFile.Default =
+ cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
+ this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default;
+ } else {
+ this->ConfigFileNames(this->Moc.CompilationFile,
+ cmStrCat(this->Dir.Build, "/mocs_compilation"),
+ ".cpp");
+ if (this->MultiConfig) {
+ this->Moc.CompilationFileGenex =
+ cmStrCat(this->Dir.Build, "/mocs_compilation_$<CONFIG>.cpp"_s);
+ } else {
+ this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default;
+ }
+ }
// Moc predefs
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
@@ -574,8 +595,8 @@ bool cmQtAutoGenInitializer::InitMoc()
this->Moc.PredefsCmd);
// Header
if (!this->Moc.PredefsCmd.empty()) {
- ConfigFileNames(this->Moc.PredefsFile,
- cmStrCat(this->Dir.Build, "/moc_predefs"), ".h");
+ this->ConfigFileNames(this->Moc.PredefsFile,
+ cmStrCat(this->Dir.Build, "/moc_predefs"), ".h");
}
}
@@ -730,10 +751,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
auto const& kw = this->GlobalInitializer->kw();
auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath,
+ std::vector<size_t> const& configs,
bool muIt) -> MUFileHandle {
MUFileHandle muf = cm::make_unique<MUFile>();
muf->FullPath = fullPath;
muf->SF = sf;
+ if (!configs.empty() && configs.size() != this->ConfigsList.size()) {
+ muf->Configs = configs;
+ }
muf->Generated = sf->GetIsGenerated();
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
muf->SkipMoc = this->Moc.Enabled &&
@@ -772,42 +797,37 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Scan through target files
{
// Scan through target files
- std::vector<cmSourceFile*> srcFiles;
- this->GenTarget->GetConfigCommonSourceFiles(srcFiles);
- for (cmSourceFile* sf : srcFiles) {
- // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
- // Since we're iterating over source files that might be not in the
- // target we need to check for path errors (not existing files).
- std::string pathError;
- std::string const& fullPath = sf->ResolveFullPath(&pathError);
- if (!pathError.empty() || fullPath.empty()) {
- continue;
- }
+ for (cmGeneratorTarget::AllConfigSource const& acs :
+ this->GenTarget->GetAllConfigSources()) {
+ std::string const& fullPath = acs.Source->GetFullPath();
std::string const& extLower =
- cmSystemTools::LowerCase(sf->GetExtension());
+ cmSystemTools::LowerCase(acs.Source->GetExtension());
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
if (cm->IsAHeaderExtension(extLower)) {
- addMUHeader(makeMUFile(sf, fullPath, true), extLower);
+ addMUHeader(makeMUFile(acs.Source, fullPath, acs.Configs, true),
+ extLower);
} else if (cm->IsACLikeSourceExtension(extLower)) {
- addMUSource(makeMUFile(sf, fullPath, true));
+ addMUSource(makeMUFile(acs.Source, fullPath, acs.Configs, true));
}
}
// Register rcc enabled files
if (this->Rcc.Enabled) {
- if ((extLower == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
- !sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
+ if ((extLower == kw.qrc) &&
+ !acs.Source->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
+ !acs.Source->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
// Register qrc file
Qrc qrc;
qrc.QrcFile = fullPath;
qrc.QrcName =
cmSystemTools::GetFilenameWithoutLastExtension(qrc.QrcFile);
- qrc.Generated = sf->GetIsGenerated();
+ qrc.Generated = acs.Source->GetIsGenerated();
// RCC options
{
- std::string const opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS);
+ std::string const& opts =
+ acs.Source->GetSafeProperty(kw.AUTORCC_OPTIONS);
if (!opts.empty()) {
cmExpandList(opts, qrc.Options);
}
@@ -817,7 +837,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
}
}
- // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's
+ // cmGeneratorTarget::GetAllConfigSources computes the target's
// sources meta data cache. Clear it so that OBJECT library targets that
// are AUTOGEN initialized after this target get their added
// mocs_compilation.cpp source acknowledged by this target.
@@ -861,7 +881,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
if (sf != nullptr) {
- auto eMuf = makeMUFile(sf, fullPath, true);
+ auto eMuf = makeMUFile(sf, fullPath, muf.Configs, true);
// Only process moc/uic when the parent is processed as well
if (!muf.MocIt) {
eMuf->MocIt = false;
@@ -896,14 +916,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (cm->IsAHeaderExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
- auto muf = makeMUFile(sf.get(), fullPath, false);
+ auto muf = makeMUFile(sf.get(), fullPath, {}, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsACLikeSourceExtension(extLower)) {
if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
- auto muf = makeMUFile(sf.get(), fullPath, false);
+ auto muf = makeMUFile(sf.get(), fullPath, {}, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUSource(std::move(muf));
}
@@ -1020,7 +1040,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
qrc.QrcName, '_', qrc.QrcPathChecksum);
qrc.LockFile = cmStrCat(base, "_Lock.lock");
qrc.InfoFile = cmStrCat(base, "_Info.json");
- ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt");
+ this->ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt");
}
// rcc options
for (Qrc& qrc : this->Rcc.Qrcs) {
@@ -1066,10 +1086,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
// Files provided by the autogen target
- std::vector<std::string> autogenProvides;
+ std::vector<std::string> autogenByproducts;
if (this->Moc.Enabled) {
this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
- autogenProvides.push_back(this->Moc.CompilationFile);
+ autogenByproducts.push_back(this->Moc.CompilationFileGenex);
}
// Compose target comment
@@ -1090,8 +1110,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Compose command lines
- // TODO: Refactor autogen to output a per-config mocs_compilation.cpp instead
- // of fiddling with the include directories
+ // FIXME: Take advantage of our per-config mocs_compilation_$<CONFIG>.cpp
+ // instead of fiddling with the include directories
std::vector<std::string> configs;
this->GlobalGen->GetQtAutoGenConfigs(configs);
bool stdPipesUTF8 = true;
@@ -1118,7 +1138,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
usePRE_BUILD = false;
}
// Cannot use PRE_BUILD when a global autogen target is in place
- if (AutogenTarget.GlobalTarget) {
+ if (this->AutogenTarget.GlobalTarget) {
usePRE_BUILD = false;
}
}
@@ -1137,7 +1157,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// PRE_BUILD does not support file dependencies!
const std::vector<std::string> no_output;
const std::vector<std::string> no_deps;
- cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
+ cmCustomCommand cc(no_output, autogenByproducts, no_deps, commandLines,
this->Makefile->GetBacktrace(), autogenComment.c_str(),
this->Dir.Work.c_str(), stdPipesUTF8);
cc.SetEscapeOldStyle(false);
@@ -1237,11 +1257,23 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
const std::string outputFile =
cmStrCat(this->Dir.Build, "/", timestampFileName);
this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps");
- auto relativeBinaryDir = cmSystemTools::RelativePath(
- this->LocalGen->GetBinaryDirectory(),
- this->LocalGen->GetCurrentBinaryDirectory());
- if (!relativeBinaryDir.empty()) {
- relativeBinaryDir = cmStrCat(relativeBinaryDir, "/");
+ std::string relativeBinaryDir;
+ if (dynamic_cast<cmGlobalNinjaGenerator*>(this->GlobalGen)) {
+ switch (this->LocalGen->GetPolicyStatus(cmPolicies::CMP0116)) {
+ case cmPolicies::OLD:
+ case cmPolicies::WARN:
+ relativeBinaryDir = cmSystemTools::RelativePath(
+ this->LocalGen->GetBinaryDirectory(),
+ this->LocalGen->GetCurrentBinaryDirectory());
+ if (!relativeBinaryDir.empty()) {
+ relativeBinaryDir = cmStrCat(relativeBinaryDir, "/");
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ break;
+ }
}
this->AutogenTarget.DepFileRuleName =
cmStrCat(relativeBinaryDir, this->GenTarget->GetName(), "_autogen/",
@@ -1270,7 +1302,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Create autogen target
cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
this->AutogenTarget.Name, true, this->Dir.Work.c_str(),
- /*byproducts=*/autogenProvides,
+ /*byproducts=*/autogenByproducts,
/*depends=*/dependencies, commandLines, false, autogenComment.c_str());
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
@@ -1520,18 +1552,31 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetArray("CMAKE_LIST_FILES", this->Makefile->GetListFiles());
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
+ auto cfgArray = [this](std::vector<size_t> const& configs) -> Json::Value {
+ Json::Value value;
+ if (!configs.empty()) {
+ value = Json::arrayValue;
+ for (size_t ci : configs) {
+ value.append(this->ConfigsList[ci]);
+ }
+ }
+ return value;
+ };
+ info.SetArrayArray("HEADERS", headers,
+ [this, &cfgArray](Json::Value& jval, MUFile const* muf) {
+ jval.resize(4u);
+ jval[0u] = muf->FullPath;
+ jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm',
+ muf->UicIt ? 'U' : 'u');
+ jval[2u] = cfgArray(muf->Configs);
+ jval[3u] = this->GetMocBuildPath(*muf);
+ });
info.SetArrayArray(
- "HEADERS", headers, [this](Json::Value& jval, MUFile const* muf) {
+ "SOURCES", sources, [&cfgArray](Json::Value& jval, MUFile const* muf) {
jval.resize(3u);
jval[0u] = muf->FullPath;
jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
- jval[2u] = this->GetMocBuildPath(*muf);
- });
- info.SetArrayArray(
- "SOURCES", sources, [](Json::Value& jval, MUFile const* muf) {
- jval.resize(2u);
- jval[0u] = muf->FullPath;
- jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
+ jval[2u] = cfgArray(muf->Configs);
});
// Write moc settings
@@ -1550,7 +1595,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
jval[0u] = pair.first;
jval[1u] = pair.second;
});
- info.Set("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
+ info.SetConfig("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
info.SetArray("MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
info.SetConfig("MOC_PREDEFS_FILE", this->Moc.PredefsFile);
}
@@ -1624,7 +1669,7 @@ cmSourceFile* cmQtAutoGenInitializer::RegisterGeneratedSource(
std::string const& filename)
{
cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true);
- gFile->SetProperty("GENERATED", "1");
+ gFile->MarkAsGenerated();
gFile->SetProperty("SKIP_AUTOGEN", "1");
return gFile;
}
@@ -1643,6 +1688,28 @@ cmSourceFile* cmQtAutoGenInitializer::AddGeneratedSource(
return gFile;
}
+void cmQtAutoGenInitializer::AddGeneratedSource(ConfigString const& filename,
+ GenVarsT const& genVars,
+ bool prepend)
+{
+ // XXX(xcode-per-cfg-src): Drop the Xcode-specific part of the condition
+ // when the Xcode generator supports per-config sources.
+ if (!this->MultiConfig || this->GlobalGen->IsXcode()) {
+ this->AddGeneratedSource(filename.Default, genVars, prepend);
+ return;
+ }
+ for (auto const& cfg : this->ConfigsList) {
+ std::string const& filenameCfg = filename.Config.at(cfg);
+ // Register source at makefile
+ this->RegisterGeneratedSource(filenameCfg);
+ // Add source file to target for this configuration.
+ this->GenTarget->AddSource(
+ cmStrCat("$<$<CONFIG:"_s, cfg, ">:"_s, filenameCfg, ">"_s), prepend);
+ // Add source file to source group
+ this->AddToSourceGroup(filenameCfg, genVars.GenNameUpper);
+ }
+}
+
void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
cm::string_view genNameUpper)
{
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 3ab303a..e0e66f1 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <memory>
#include <set>
#include <string>
@@ -70,6 +71,7 @@ public:
{
std::string FullPath;
cmSourceFile* SF = nullptr;
+ std::vector<size_t> Configs;
bool Generated = false;
bool SkipMoc = false;
bool SkipUic = false;
@@ -132,6 +134,8 @@ private:
cmSourceFile* AddGeneratedSource(std::string const& filename,
GenVarsT const& genVars,
bool prepend = false);
+ void AddGeneratedSource(ConfigString const& filename,
+ GenVarsT const& genVars, bool prepend = false);
void AddToSourceGroup(std::string const& fileName,
cm::string_view genNameUpper);
void AddCleanFile(std::string const& fileName);
@@ -207,7 +211,8 @@ private:
bool RelaxedMode = false;
bool PathPrefix = false;
- std::string CompilationFile;
+ ConfigString CompilationFile;
+ std::string CompilationFileGenex;
// Compiler implicit pre defines
std::vector<std::string> PredefsCmd;
ConfigString PredefsFile;
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index ee2bc09..ebb6bd7 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -18,10 +18,10 @@ cmQtAutoGenerator::Logger::Logger()
if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) {
unsigned long iVerbose = 0;
if (cmStrToULong(verbose, &iVerbose)) {
- SetVerbosity(static_cast<unsigned int>(iVerbose));
+ this->SetVerbosity(static_cast<unsigned int>(iVerbose));
} else {
// Non numeric verbosity
- SetVerbose(cmIsOn(verbose));
+ this->SetVerbose(cmIsOn(verbose));
}
}
}
@@ -29,9 +29,9 @@ cmQtAutoGenerator::Logger::Logger()
std::string colorEnv;
cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
- SetColorOutput(cmIsOn(colorEnv));
+ this->SetColorOutput(cmIsOn(colorEnv));
} else {
- SetColorOutput(true);
+ this->SetColorOutput(true);
}
}
}
@@ -47,7 +47,7 @@ void cmQtAutoGenerator::Logger::RaiseVerbosity(unsigned int value)
void cmQtAutoGenerator::Logger::SetColorOutput(bool value)
{
- ColorOutput_ = value;
+ this->ColorOutput_ = value;
}
std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title)
@@ -61,7 +61,7 @@ void cmQtAutoGenerator::Logger::Info(GenT genType,
std::string msg = cmStrCat(GeneratorName(genType), ": ", message,
cmHasSuffix(message, '\n') ? "" : "\n");
{
- std::lock_guard<std::mutex> lock(Mutex_);
+ std::lock_guard<std::mutex> lock(this->Mutex_);
cmSystemTools::Stdout(msg);
}
}
@@ -80,7 +80,7 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType,
message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
}
{
- std::lock_guard<std::mutex> lock(Mutex_);
+ std::lock_guard<std::mutex> lock(this->Mutex_);
cmSystemTools::Stdout(msg);
}
}
@@ -92,7 +92,7 @@ void cmQtAutoGenerator::Logger::Error(GenT genType,
cmStrCat('\n', HeadLine(cmStrCat(GeneratorName(genType), " error")),
message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
{
- std::lock_guard<std::mutex> lock(Mutex_);
+ std::lock_guard<std::mutex> lock(this->Mutex_);
cmSystemTools::Stderr(msg);
}
}
@@ -108,7 +108,7 @@ void cmQtAutoGenerator::Logger::ErrorCommand(
msg += cmStrCat(HeadLine("Output"), output,
cmHasSuffix(output, '\n') ? "\n" : "\n\n");
{
- std::lock_guard<std::mutex> lock(Mutex_);
+ std::lock_guard<std::mutex> lock(this->Mutex_);
cmSystemTools::Stderr(msg);
}
}
@@ -215,7 +215,7 @@ cmQtAutoGenerator::~cmQtAutoGenerator() = default;
bool cmQtAutoGenerator::InfoT::Read(std::istream& istr)
{
try {
- istr >> Json_;
+ istr >> this->Json_;
} catch (...) {
return false;
}
@@ -264,22 +264,22 @@ bool cmQtAutoGenerator::InfoT::GetJsonArray(
std::string cmQtAutoGenerator::InfoT::ConfigKey(cm::string_view key) const
{
- return cmStrCat(key, '_', Gen_.InfoConfig());
+ return cmStrCat(key, '_', this->Gen_.InfoConfig());
}
bool cmQtAutoGenerator::InfoT::GetString(std::string const& key,
std::string& value,
bool required) const
{
- Json::Value const& jval = Json_[key];
+ Json::Value const& jval = this->Json_[key];
if (!jval.isString()) {
if (!jval.isNull() || required) {
- return LogError(cmStrCat(key, " is not a string."));
+ return this->LogError(cmStrCat(key, " is not a string."));
}
} else {
value = jval.asString();
if (value.empty() && required) {
- return LogError(cmStrCat(key, " is empty."));
+ return this->LogError(cmStrCat(key, " is empty."));
}
}
return true;
@@ -290,32 +290,32 @@ bool cmQtAutoGenerator::InfoT::GetStringConfig(std::string const& key,
bool required) const
{
{ // Try config
- std::string const configKey = ConfigKey(key);
- Json::Value const& jval = Json_[configKey];
+ std::string const configKey = this->ConfigKey(key);
+ Json::Value const& jval = this->Json_[configKey];
if (!jval.isNull()) {
if (!jval.isString()) {
- return LogError(cmStrCat(configKey, " is not a string."));
+ return this->LogError(cmStrCat(configKey, " is not a string."));
}
value = jval.asString();
if (required && value.empty()) {
- return LogError(cmStrCat(configKey, " is empty."));
+ return this->LogError(cmStrCat(configKey, " is empty."));
}
return true;
}
}
// Try plain
- return GetString(key, value, required);
+ return this->GetString(key, value, required);
}
bool cmQtAutoGenerator::InfoT::GetBool(std::string const& key, bool& value,
bool required) const
{
- Json::Value const& jval = Json_[key];
+ Json::Value const& jval = this->Json_[key];
if (jval.isBool()) {
value = jval.asBool();
} else {
if (!jval.isNull() || required) {
- return LogError(cmStrCat(key, " is not a boolean."));
+ return this->LogError(cmStrCat(key, " is not a boolean."));
}
}
return true;
@@ -325,12 +325,12 @@ bool cmQtAutoGenerator::InfoT::GetUInt(std::string const& key,
unsigned int& value,
bool required) const
{
- Json::Value const& jval = Json_[key];
+ Json::Value const& jval = this->Json_[key];
if (jval.isUInt()) {
value = jval.asUInt();
} else {
if (!jval.isNull() || required) {
- return LogError(cmStrCat(key, " is not an unsigned integer."));
+ return this->LogError(cmStrCat(key, " is not an unsigned integer."));
}
}
return true;
@@ -340,10 +340,10 @@ bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key,
std::vector<std::string>& list,
bool required) const
{
- Json::Value const& jval = Json_[key];
+ Json::Value const& jval = this->Json_[key];
if (!jval.isArray()) {
if (!jval.isNull() || required) {
- return LogError(cmStrCat(key, " is not an array."));
+ return this->LogError(cmStrCat(key, " is not an array."));
}
}
return GetJsonArray(list, jval) || !required;
@@ -353,10 +353,10 @@ bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key,
std::unordered_set<std::string>& list,
bool required) const
{
- Json::Value const& jval = Json_[key];
+ Json::Value const& jval = this->Json_[key];
if (!jval.isArray()) {
if (!jval.isNull() || required) {
- return LogError(cmStrCat(key, " is not an array."));
+ return this->LogError(cmStrCat(key, " is not an array."));
}
}
return GetJsonArray(list, jval) || !required;
@@ -367,34 +367,35 @@ bool cmQtAutoGenerator::InfoT::GetArrayConfig(std::string const& key,
bool required) const
{
{ // Try config
- std::string const configKey = ConfigKey(key);
- Json::Value const& jval = Json_[configKey];
+ std::string const configKey = this->ConfigKey(key);
+ Json::Value const& jval = this->Json_[configKey];
if (!jval.isNull()) {
if (!jval.isArray()) {
- return LogError(cmStrCat(configKey, " is not an array string."));
+ return this->LogError(cmStrCat(configKey, " is not an array string."));
}
if (!GetJsonArray(list, jval) && required) {
- return LogError(cmStrCat(configKey, " is empty."));
+ return this->LogError(cmStrCat(configKey, " is empty."));
}
return true;
}
}
// Try plain
- return GetArray(key, list, required);
+ return this->GetArray(key, list, required);
}
bool cmQtAutoGenerator::InfoT::LogError(GenT genType,
cm::string_view message) const
{
- Gen_.Log().Error(genType,
- cmStrCat("Info error in info file\n",
- Quoted(Gen_.InfoFile()), ":\n", message));
+ this->Gen_.Log().Error(genType,
+ cmStrCat("Info error in info file\n",
+ Quoted(this->Gen_.InfoFile()), ":\n",
+ message));
return false;
}
bool cmQtAutoGenerator::InfoT::LogError(cm::string_view message) const
{
- return LogError(Gen_.GenType_, message);
+ return this->LogError(this->Gen_.GenType_, message);
}
std::string cmQtAutoGenerator::SettingsFind(cm::string_view content,
@@ -418,10 +419,10 @@ std::string cmQtAutoGenerator::SettingsFind(cm::string_view content,
std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const
{
std::string res;
- if (cmHasPrefix(path, ProjectDirs().Source)) {
- res = cmStrCat("SRC:", path.substr(ProjectDirs().Source.size()));
- } else if (cmHasPrefix(path, ProjectDirs().Binary)) {
- res = cmStrCat("BIN:", path.substr(ProjectDirs().Binary.size()));
+ if (cmHasPrefix(path, this->ProjectDirs().Source)) {
+ res = cmStrCat("SRC:", path.substr(this->ProjectDirs().Source.size()));
+ } else if (cmHasPrefix(path, this->ProjectDirs().Binary)) {
+ res = cmStrCat("BIN:", path.substr(this->ProjectDirs().Binary.size()));
} else {
res = std::string(path);
}
@@ -431,17 +432,18 @@ std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const
bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config)
{
// Info config
- InfoConfig_ = std::string(config);
+ this->InfoConfig_ = std::string(config);
// Info file
- InfoFile_ = std::string(infoFile);
- cmSystemTools::CollapseFullPath(InfoFile_);
- InfoDir_ = cmSystemTools::GetFilenamePath(InfoFile_);
+ this->InfoFile_ = std::string(infoFile);
+ cmSystemTools::CollapseFullPath(this->InfoFile_);
+ this->InfoDir_ = cmSystemTools::GetFilenamePath(this->InfoFile_);
// Load info file time
- if (!InfoFileTime_.Load(InfoFile_)) {
+ if (!this->InfoFileTime_.Load(this->InfoFile_)) {
cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ",
- Quoted(InfoFile_), " is not readable\n"));
+ Quoted(this->InfoFile_),
+ " is not readable\n"));
return false;
}
@@ -450,17 +452,18 @@ bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config)
// Read info file
{
- cmsys::ifstream ifs(InfoFile_.c_str(),
+ cmsys::ifstream ifs(this->InfoFile_.c_str(),
(std::ios::in | std::ios::binary));
if (!ifs) {
- Log().Error(
- GenType_,
- cmStrCat("Could not to open info file ", Quoted(InfoFile_)));
+ this->Log().Error(
+ this->GenType_,
+ cmStrCat("Could not to open info file ", Quoted(this->InfoFile_)));
return false;
}
if (!info.Read(ifs)) {
- Log().Error(GenType_,
- cmStrCat("Could not read info file ", Quoted(InfoFile_)));
+ this->Log().Error(
+ this->GenType_,
+ cmStrCat("Could not read info file ", Quoted(this->InfoFile_)));
return false;
}
}
@@ -470,15 +473,17 @@ bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config)
unsigned int verbosity = 0;
// Info: setup project directories
if (!info.GetUInt("VERBOSITY", verbosity, false) ||
- !info.GetString("CMAKE_SOURCE_DIR", ProjectDirs_.Source, true) ||
- !info.GetString("CMAKE_BINARY_DIR", ProjectDirs_.Binary, true) ||
+ !info.GetString("CMAKE_SOURCE_DIR", this->ProjectDirs_.Source,
+ true) ||
+ !info.GetString("CMAKE_BINARY_DIR", this->ProjectDirs_.Binary,
+ true) ||
!info.GetString("CMAKE_CURRENT_SOURCE_DIR",
- ProjectDirs_.CurrentSource, true) ||
+ this->ProjectDirs_.CurrentSource, true) ||
!info.GetString("CMAKE_CURRENT_BINARY_DIR",
- ProjectDirs_.CurrentBinary, true)) {
+ this->ProjectDirs_.CurrentBinary, true)) {
return false;
}
- Logger_.RaiseVerbosity(verbosity);
+ this->Logger_.RaiseVerbosity(verbosity);
}
// -- Call virtual init from info method.
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index b4f057d..53fbd69 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -88,10 +88,10 @@ public:
cmQtAutoGenerator& operator=(cmQtAutoGenerator const&) = delete;
// -- Info options
- std::string const& InfoFile() const { return InfoFile_; }
- std::string const& InfoDir() const { return InfoDir_; }
- cmFileTime const& InfoFileTime() const { return InfoFileTime_; }
- std::string const& InfoConfig() const { return InfoConfig_; }
+ std::string const& InfoFile() const { return this->InfoFile_; }
+ std::string const& InfoDir() const { return this->InfoDir_; }
+ cmFileTime const& InfoFileTime() const { return this->InfoFileTime_; }
+ std::string const& InfoConfig() const { return this->InfoConfig_; }
// -- Info file parsing
/** Info file reader class. */
@@ -124,7 +124,7 @@ public:
Json::Value const& GetValue(std::string const& key) const
{
- return Json_[key];
+ return this->Json_[key];
}
/** Returns true if strings were appended to the list. */
@@ -150,7 +150,7 @@ public:
cm::string_view key);
// -- Directories
- ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; }
+ ProjectDirsT const& ProjectDirs() const { return this->ProjectDirs_; }
std::string MessagePath(cm::string_view path) const;
// -- Run
@@ -161,7 +161,7 @@ protected:
virtual bool InitFromInfo(InfoT const& info) = 0;
virtual bool Process() = 0;
// - Utility classes
- Logger const& Log() const { return Logger_; }
+ Logger const& Log() const { return this->Logger_; }
private:
// -- Generator type
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 9cb172b..3556051 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/memory>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
@@ -26,7 +27,6 @@
#include "cmCryptoHash.h"
#include "cmFileTime.h"
#include "cmGccDepfileReader.h"
-#include "cmGccDepfileReaderTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
@@ -313,22 +313,22 @@ public:
//! Get the generator. Only valid during Process() call!
cmQtAutoMocUicT* Gen() const
{
- return static_cast<cmQtAutoMocUicT*>(UserData());
+ return static_cast<cmQtAutoMocUicT*>(this->UserData());
};
// -- Accessors. Only valid during Process() call!
- Logger const& Log() const { return Gen()->Log(); }
- BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); }
- BaseEvalT& BaseEval() const { return Gen()->BaseEval(); }
- MocSettingsT const& MocConst() const { return Gen()->MocConst(); }
- MocEvalT& MocEval() const { return Gen()->MocEval(); }
- UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
- UicEvalT& UicEval() const { return Gen()->UicEval(); }
+ Logger const& Log() const { return this->Gen()->Log(); }
+ BaseSettingsT const& BaseConst() const { return this->Gen()->BaseConst(); }
+ BaseEvalT& BaseEval() const { return this->Gen()->BaseEval(); }
+ MocSettingsT const& MocConst() const { return this->Gen()->MocConst(); }
+ MocEvalT& MocEval() const { return this->Gen()->MocEval(); }
+ UicSettingsT const& UicConst() const { return this->Gen()->UicConst(); }
+ UicEvalT& UicEval() const { return this->Gen()->UicEval(); }
// -- Logging
std::string MessagePath(cm::string_view path) const
{
- return Gen()->MessagePath(path);
+ return this->Gen()->MessagePath(path);
}
// - Error logging with automatic abort
void LogError(GenT genType, cm::string_view message) const;
@@ -522,6 +522,7 @@ public:
class JobDepFilesMergeT : public JobFenceT
{
private:
+ std::vector<std::string> initialDependencies() const;
void Process() override;
};
@@ -541,9 +542,9 @@ public:
UicEvalT& UicEval() { return this->UicEval_; }
// -- Parallel job processing interface
- cmWorkerPool& WorkerPool() { return WorkerPool_; }
- void AbortError() { Abort(true); }
- void AbortSuccess() { Abort(false); }
+ cmWorkerPool& WorkerPool() { return this->WorkerPool_; }
+ void AbortError() { this->Abort(true); }
+ void AbortSuccess() { this->Abort(false); }
// -- Utility
std::string AbsoluteBuildPath(cm::string_view relativePath) const;
@@ -597,19 +598,19 @@ cmQtAutoMocUicT::IncludeKeyT::IncludeKeyT(std::string const& key,
, Base(cmSystemTools::GetFilenameWithoutLastExtension(key))
{
if (basePrefixLength != 0) {
- Base = Base.substr(basePrefixLength);
+ this->Base = this->Base.substr(basePrefixLength);
}
}
void cmQtAutoMocUicT::ParseCacheT::FileT::Clear()
{
- Moc.Macro.clear();
- Moc.Include.Underscore.clear();
- Moc.Include.Dot.clear();
- Moc.Depends.clear();
+ this->Moc.Macro.clear();
+ this->Moc.Include.Underscore.clear();
+ this->Moc.Include.Dot.clear();
+ this->Moc.Depends.clear();
- Uic.Include.clear();
- Uic.Depends.clear();
+ this->Uic.Include.clear();
+ this->Uic.Depends.clear();
}
cmQtAutoMocUicT::ParseCacheT::GetOrInsertT
@@ -617,15 +618,15 @@ cmQtAutoMocUicT::ParseCacheT::GetOrInsert(std::string const& fileName)
{
// Find existing entry
{
- auto it = Map_.find(fileName);
- if (it != Map_.end()) {
+ auto it = this->Map_.find(fileName);
+ if (it != this->Map_.end()) {
return GetOrInsertT{ it->second, false };
}
}
// Insert new entry
return GetOrInsertT{
- Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true
+ this->Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true
};
}
@@ -655,7 +656,7 @@ bool cmQtAutoMocUicT::ParseCacheT::ReadFromFile(std::string const& fileName)
}
// Check if this a file name line
if (line.front() != ' ') {
- fileHandle = GetOrInsert(line).first;
+ fileHandle = this->GetOrInsert(line).first;
continue;
}
@@ -702,7 +703,7 @@ bool cmQtAutoMocUicT::ParseCacheT::WriteToFile(std::string const& fileName)
return false;
}
ofs << "# Generated by CMake. Changes will be overwritten.\n";
- for (auto const& pair : Map_) {
+ for (auto const& pair : this->Map_) {
ofs << pair.first << '\n';
FileT const& file = *pair.second;
if (!file.Moc.Macro.empty()) {
@@ -732,7 +733,7 @@ cmQtAutoMocUicT::BaseSettingsT::~BaseSettingsT() = default;
cmQtAutoMocUicT::MocSettingsT::MocSettingsT()
{
- RegExpInclude.compile(
+ this->RegExpInclude.compile(
"(^|\n)[ \t]*#[ \t]*include[ \t]+"
"[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
}
@@ -741,14 +742,15 @@ cmQtAutoMocUicT::MocSettingsT::~MocSettingsT() = default;
bool cmQtAutoMocUicT::MocSettingsT::skipped(std::string const& fileName) const
{
- return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
+ return (!this->Enabled ||
+ (this->SkipList.find(fileName) != this->SkipList.end()));
}
std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const
{
std::string res;
- const auto itB = MacroFilters.cbegin();
- const auto itE = MacroFilters.cend();
+ const auto itB = this->MacroFilters.cbegin();
+ const auto itE = this->MacroFilters.cend();
const auto itL = itE - 1;
auto itC = itB;
for (; itC != itE; ++itC) {
@@ -768,30 +770,31 @@ std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const
cmQtAutoMocUicT::UicSettingsT::UicSettingsT()
{
- RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
+ this->RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
}
cmQtAutoMocUicT::UicSettingsT::~UicSettingsT() = default;
bool cmQtAutoMocUicT::UicSettingsT::skipped(std::string const& fileName) const
{
- return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
+ return (!this->Enabled ||
+ (this->SkipList.find(fileName) != this->SkipList.end()));
}
void cmQtAutoMocUicT::JobT::LogError(GenT genType,
cm::string_view message) const
{
- Gen()->AbortError();
- Gen()->Log().Error(genType, message);
+ this->Gen()->AbortError();
+ this->Gen()->Log().Error(genType, message);
}
void cmQtAutoMocUicT::JobT::LogCommandError(
GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
- Gen()->AbortError();
- Gen()->Log().ErrorCommand(genType, message, command, output);
+ this->Gen()->AbortError();
+ this->Gen()->Log().ErrorCommand(genType, message, command, output);
}
bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType,
@@ -800,48 +803,48 @@ bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType,
std::string* infoMessage)
{
// Log command
- if (Log().Verbose()) {
+ if (this->Log().Verbose()) {
cm::string_view info;
if (infoMessage != nullptr) {
info = *infoMessage;
}
- Log().Info(genType,
- cmStrCat(info,
- info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
- QuotedCommand(command), '\n'));
+ this->Log().Info(
+ genType,
+ cmStrCat(info, info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
+ QuotedCommand(command), '\n'));
}
// Run command
- return cmWorkerPool::JobT::RunProcess(result, command,
- BaseConst().AutogenBuildDir);
+ return this->cmWorkerPool::JobT::RunProcess(
+ result, command, this->BaseConst().AutogenBuildDir);
}
void cmQtAutoMocUicT::JobMocPredefsT::Process()
{
// (Re)generate moc_predefs.h on demand
std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
+ if (this->Log().Verbose()) {
reason = cm::make_unique<std::string>();
}
- if (!Update(reason.get())) {
+ if (!this->Update(reason.get())) {
return;
}
- std::string const& predefsFileAbs = MocConst().PredefsFileAbs;
+ std::string const& predefsFileAbs = this->MocConst().PredefsFileAbs;
{
cmWorkerPool::ProcessResultT result;
{
// Compose command
- std::vector<std::string> cmd = MocConst().PredefsCmd;
+ std::vector<std::string> cmd = this->MocConst().PredefsCmd;
// Add definitions
- cm::append(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, this->MocConst().OptionsDefinitions);
// Add includes
- cm::append(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, this->MocConst().OptionsIncludes);
// Execute command
- if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
- LogCommandError(GenT::MOC,
- cmStrCat("The content generation command for ",
- MessagePath(predefsFileAbs), " failed.\n",
- result.ErrorMessage),
- cmd, result.StdOut);
+ if (!this->RunProcess(GenT::MOC, result, cmd, reason.get())) {
+ this->LogCommandError(GenT::MOC,
+ cmStrCat("The content generation command for ",
+ this->MessagePath(predefsFileAbs),
+ " failed.\n", result.ErrorMessage),
+ cmd, result.StdOut);
return;
}
}
@@ -849,30 +852,31 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
// (Re)write predefs file only on demand
if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
- LogError(
+ this->LogError(
GenT::MOC,
- cmStrCat("Writing ", MessagePath(predefsFileAbs), " failed."));
+ cmStrCat("Writing ", this->MessagePath(predefsFileAbs), " failed."));
return;
}
} else {
// Touch to update the time stamp
- if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Touching " + MessagePath(predefsFileAbs));
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::MOC,
+ "Touching " + this->MessagePath(predefsFileAbs));
}
if (!cmSystemTools::Touch(predefsFileAbs, false)) {
- LogError(
- GenT::MOC,
- cmStrCat("Touching ", MessagePath(predefsFileAbs), " failed."));
+ this->LogError(GenT::MOC,
+ cmStrCat("Touching ", this->MessagePath(predefsFileAbs),
+ " failed."));
return;
}
}
}
// Read file time afterwards
- if (!MocEval().PredefsTime.Load(predefsFileAbs)) {
- LogError(GenT::MOC,
- cmStrCat("Reading the file time of ", MessagePath(predefsFileAbs),
- " failed."));
+ if (!this->MocEval().PredefsTime.Load(predefsFileAbs)) {
+ this->LogError(GenT::MOC,
+ cmStrCat("Reading the file time of ",
+ this->MessagePath(predefsFileAbs), " failed."));
return;
}
}
@@ -880,18 +884,20 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const
{
// Test if the file exists
- if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) {
+ if (!this->MocEval().PredefsTime.Load(this->MocConst().PredefsFileAbs)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
+ *reason = cmStrCat("Generating ",
+ this->MessagePath(this->MocConst().PredefsFileAbs),
", because it doesn't exist.");
}
return true;
}
// Test if the settings changed
- if (MocConst().SettingsChanged) {
+ if (this->MocConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
+ *reason = cmStrCat("Generating ",
+ this->MessagePath(this->MocConst().PredefsFileAbs),
", because the moc settings changed.");
}
return true;
@@ -899,14 +905,14 @@ bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const
// Test if the executable is newer
{
- std::string const& exec = MocConst().PredefsCmd.at(0);
+ std::string const& exec = this->MocConst().PredefsCmd.at(0);
cmFileTime execTime;
if (execTime.Load(exec)) {
- if (MocEval().PredefsTime.Older(execTime)) {
+ if (this->MocEval().PredefsTime.Older(execTime)) {
if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
- " because it is older than ", MessagePath(exec), '.');
+ *reason = cmStrCat(
+ "Generating ", this->MessagePath(this->MocConst().PredefsFileAbs),
+ " because it is older than ", this->MessagePath(exec), '.');
}
return true;
}
@@ -919,25 +925,27 @@ bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const
bool cmQtAutoMocUicT::JobParseT::ReadFile()
{
// Clear old parse information
- FileHandle->ParseData->Clear();
- std::string const& fileName = FileHandle->FileName;
+ this->FileHandle->ParseData->Clear();
+ std::string const& fileName = this->FileHandle->FileName;
// Write info
- if (Log().Verbose()) {
- Log().Info(GenT::GEN, cmStrCat("Parsing ", MessagePath(fileName)));
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::GEN,
+ cmStrCat("Parsing ", this->MessagePath(fileName)));
}
// Read file content
{
std::string error;
- if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) {
- LogError(
- GenT::GEN,
- cmStrCat("Could not read ", MessagePath(fileName), ".\n", error));
+ if (!cmQtAutoGenerator::FileRead(this->Content, fileName, &error)) {
+ this->LogError(GenT::GEN,
+ cmStrCat("Could not read ", this->MessagePath(fileName),
+ ".\n", error));
return false;
}
}
// Warn if empty
- if (Content.empty()) {
- Log().Warning(GenT::GEN, cmStrCat(MessagePath(fileName), " is empty."));
+ if (this->Content.empty()) {
+ this->Log().Warning(GenT::GEN,
+ cmStrCat(this->MessagePath(fileName), " is empty."));
return false;
}
return true;
@@ -958,16 +966,16 @@ void cmQtAutoMocUicT::JobParseT::CreateKeys(
void cmQtAutoMocUicT::JobParseT::MocMacro()
{
- for (KeyExpT const& filter : MocConst().MacroFilters) {
+ for (KeyExpT const& filter : this->MocConst().MacroFilters) {
// Run a simple find string check
- if (Content.find(filter.Key) == std::string::npos) {
+ if (this->Content.find(filter.Key) == std::string::npos) {
continue;
}
// Run the expensive regular expression check loop
cmsys::RegularExpressionMatch match;
- if (filter.Exp.find(Content.c_str(), match)) {
+ if (filter.Exp.find(this->Content.c_str(), match)) {
// Keep detected macro name
- FileHandle->ParseData->Moc.Macro = filter.Key;
+ this->FileHandle->ParseData->Moc.Macro = filter.Key;
return;
}
}
@@ -975,19 +983,20 @@ void cmQtAutoMocUicT::JobParseT::MocMacro()
void cmQtAutoMocUicT::JobParseT::MocDependecies()
{
- if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) {
+ if (this->MocConst().DependFilters.empty() ||
+ this->MocConst().CanOutputDependencies) {
return;
}
// Find dependency strings
std::set<std::string> parseDepends;
- for (KeyExpT const& filter : MocConst().DependFilters) {
+ for (KeyExpT const& filter : this->MocConst().DependFilters) {
// Run a simple find string check
- if (Content.find(filter.Key) == std::string::npos) {
+ if (this->Content.find(filter.Key) == std::string::npos) {
continue;
}
// Run the expensive regular expression check loop
- const char* contentChars = Content.c_str();
+ const char* contentChars = this->Content.c_str();
cmsys::RegularExpressionMatch match;
while (filter.Exp.find(contentChars, match)) {
{
@@ -1002,7 +1011,7 @@ void cmQtAutoMocUicT::JobParseT::MocDependecies()
// Store dependency strings
{
- auto& Depends = FileHandle->ParseData->Moc.Depends;
+ auto& Depends = this->FileHandle->ParseData->Moc.Depends;
Depends.reserve(parseDepends.size());
for (std::string const& item : parseDepends) {
Depends.emplace_back(item);
@@ -1016,15 +1025,15 @@ void cmQtAutoMocUicT::JobParseT::MocDependecies()
void cmQtAutoMocUicT::JobParseT::MocIncludes()
{
- if (Content.find("moc") == std::string::npos) {
+ if (this->Content.find("moc") == std::string::npos) {
return;
}
std::set<std::string> underscore;
std::set<std::string> dot;
{
- const char* contentChars = Content.c_str();
- cmsys::RegularExpression const& regExp = MocConst().RegExpInclude;
+ const char* contentChars = this->Content.c_str();
+ cmsys::RegularExpression const& regExp = this->MocConst().RegExpInclude;
cmsys::RegularExpressionMatch match;
while (regExp.find(contentChars, match)) {
std::string incString = match.match(2);
@@ -1042,21 +1051,21 @@ void cmQtAutoMocUicT::JobParseT::MocIncludes()
contentChars += match.end();
}
}
- auto& Include = FileHandle->ParseData->Moc.Include;
- CreateKeys(Include.Underscore, underscore, MocUnderscoreLength);
- CreateKeys(Include.Dot, dot, 0);
+ auto& Include = this->FileHandle->ParseData->Moc.Include;
+ this->CreateKeys(Include.Underscore, underscore, MocUnderscoreLength);
+ this->CreateKeys(Include.Dot, dot, 0);
}
void cmQtAutoMocUicT::JobParseT::UicIncludes()
{
- if (Content.find("ui_") == std::string::npos) {
+ if (this->Content.find("ui_") == std::string::npos) {
return;
}
std::set<std::string> includes;
{
- const char* contentChars = Content.c_str();
- cmsys::RegularExpression const& regExp = UicConst().RegExpInclude;
+ const char* contentChars = this->Content.c_str();
+ cmsys::RegularExpression const& regExp = this->UicConst().RegExpInclude;
cmsys::RegularExpressionMatch match;
while (regExp.find(contentChars, match)) {
includes.emplace(match.match(2));
@@ -1064,39 +1073,40 @@ void cmQtAutoMocUicT::JobParseT::UicIncludes()
contentChars += match.end();
}
}
- CreateKeys(FileHandle->ParseData->Uic.Include, includes, UiUnderscoreLength);
+ this->CreateKeys(this->FileHandle->ParseData->Uic.Include, includes,
+ UiUnderscoreLength);
}
void cmQtAutoMocUicT::JobParseHeaderT::Process()
{
- if (!ReadFile()) {
+ if (!this->ReadFile()) {
return;
}
// Moc parsing
- if (FileHandle->Moc) {
- MocMacro();
- MocDependecies();
+ if (this->FileHandle->Moc) {
+ this->MocMacro();
+ this->MocDependecies();
}
// Uic parsing
- if (FileHandle->Uic) {
- UicIncludes();
+ if (this->FileHandle->Uic) {
+ this->UicIncludes();
}
}
void cmQtAutoMocUicT::JobParseSourceT::Process()
{
- if (!ReadFile()) {
+ if (!this->ReadFile()) {
return;
}
// Moc parsing
- if (FileHandle->Moc) {
- MocMacro();
- MocDependecies();
- MocIncludes();
+ if (this->FileHandle->Moc) {
+ this->MocMacro();
+ this->MocDependecies();
+ this->MocIncludes();
}
// Uic parsing
- if (FileHandle->Uic) {
- UicIncludes();
+ if (this->FileHandle->Uic) {
+ this->UicIncludes();
}
}
@@ -1104,9 +1114,9 @@ std::string cmQtAutoMocUicT::JobEvalCacheT::MessageSearchLocations() const
{
std::string res;
res.reserve(512);
- for (std::string const& path : SearchLocations) {
+ for (std::string const& path : this->SearchLocations) {
res += " ";
- res += MessagePath(path);
+ res += this->MessagePath(path);
res += '\n';
}
return res;
@@ -1115,14 +1125,14 @@ std::string cmQtAutoMocUicT::JobEvalCacheT::MessageSearchLocations() const
void cmQtAutoMocUicT::JobEvalCacheMocT::Process()
{
// Evaluate headers
- for (auto const& pair : BaseEval().Headers) {
- if (!EvalHeader(pair.second)) {
+ for (auto const& pair : this->BaseEval().Headers) {
+ if (!this->EvalHeader(pair.second)) {
return;
}
}
// Evaluate sources
- for (auto const& pair : BaseEval().Sources) {
- if (!EvalSource(pair.second)) {
+ for (auto const& pair : this->BaseEval().Sources) {
+ if (!this->EvalSource(pair.second)) {
return;
}
}
@@ -1142,14 +1152,16 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalHeader(SourceFileHandleT source)
handle->SourceFile = std::move(source);
// Absolute build path
- if (BaseConst().MultiConfig) {
- handle->OutputFile = Gen()->AbsoluteIncludePath(sourceFile.BuildPath);
+ if (this->BaseConst().MultiConfig) {
+ handle->OutputFile =
+ this->Gen()->AbsoluteIncludePath(sourceFile.BuildPath);
} else {
- handle->OutputFile = Gen()->AbsoluteBuildPath(sourceFile.BuildPath);
+ handle->OutputFile =
+ this->Gen()->AbsoluteBuildPath(sourceFile.BuildPath);
}
// Register mapping in headers map
- RegisterMapping(handle);
+ this->RegisterMapping(handle);
}
return true;
@@ -1171,7 +1183,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName);
// For relaxed mode check if the own "moc_" or ".moc" file is included
- bool const relaxedMode = MocConst().RelaxedMode;
+ bool const relaxedMode = this->MocConst().RelaxedMode;
bool sourceIncludesMocUnderscore = false;
bool sourceIncludesDotMoc = false;
// Check if the sources own "moc_" or ".moc" file is included
@@ -1193,12 +1205,13 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
// Check if this source needs to be moc processed but doesn't.
if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
!(relaxedMode && sourceIncludesMocUnderscore)) {
- LogError(GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ",
- Quoted(parseData.Macro), " macro, but does not include ",
- MessagePath(sourceBase + ".moc"),
- "!\nConsider to\n - add #include \"", sourceBase,
- ".moc\"\n - enable SKIP_AUTOMOC for this file"));
+ this->LogError(GenT::MOC,
+ cmStrCat(this->MessagePath(sourceFile.FileName),
+ "\ncontains a ", Quoted(parseData.Macro),
+ " macro, but does not include ",
+ this->MessagePath(sourceBase + ".moc"),
+ "!\nConsider to\n - add #include \"", sourceBase,
+ ".moc\"\n - enable SKIP_AUTOMOC for this file"));
return false;
}
@@ -1207,14 +1220,16 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
SourceFileHandleT headerHandle;
{
std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base);
- if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) {
- LogError(GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the moc file ", MessagePath(incKey.Key),
- ",\nbut a header ", MessageHeader(headerBase),
- "\ncould not be found "
- "in the following directories\n",
- MessageSearchLocations()));
+ if (!this->FindIncludedHeader(headerHandle, sourceDirPrefix,
+ headerBase)) {
+ this->LogError(
+ GenT::MOC,
+ cmStrCat(this->MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", this->MessagePath(incKey.Key),
+ ",\nbut a header ", this->MessageHeader(headerBase),
+ "\ncould not be found "
+ "in the following directories\n",
+ this->MessageSearchLocations()));
return false;
}
}
@@ -1228,30 +1243,31 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
// used. This is for KDE4 compatibility.
// Issue a warning
- Log().Warning(
+ this->Log().Warning(
GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ",
+ cmStrCat(this->MessagePath(sourceFile.FileName), "\ncontains a ",
Quoted(parseData.Macro), " macro, but does not include ",
- MessagePath(sourceBase + ".moc"), ".\nInstead it includes ",
- MessagePath(incKey.Key), ".\nRunning moc on the source\n ",
- MessagePath(sourceFile.FileName), "!\nBetter include ",
- MessagePath(sourceBase + ".moc"),
+ this->MessagePath(sourceBase + ".moc"),
+ ".\nInstead it includes ", this->MessagePath(incKey.Key),
+ ".\nRunning moc on the source\n ",
+ this->MessagePath(sourceFile.FileName), "!\nBetter include ",
+ this->MessagePath(sourceBase + ".moc"),
" for compatibility with regular mode.\n",
"This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
// Create mapping
- if (!RegisterIncluded(incKey.Key, source, source)) {
+ if (!this->RegisterIncluded(incKey.Key, source, source)) {
return false;
}
continue;
}
// Check if header is skipped
- if (MocConst().skipped(headerHandle->FileName)) {
+ if (this->MocConst().skipped(headerHandle->FileName)) {
continue;
}
// Create mapping
- if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) {
+ if (!this->RegisterIncluded(incKey.Key, source, std::move(headerHandle))) {
return false;
}
}
@@ -1264,7 +1280,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (ownMoc && !parseData.Macro.empty()) {
// Create mapping for the regular use case
- if (!RegisterIncluded(incKey.Key, source, source)) {
+ if (!this->RegisterIncluded(incKey.Key, source, source)) {
return false;
}
continue;
@@ -1274,50 +1290,54 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
SourceFileHandleT headerHandle;
{
std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base);
- if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) {
- LogError(
+ if (!this->FindIncludedHeader(headerHandle, sourceDirPrefix,
+ headerBase)) {
+ this->LogError(
GenT::MOC,
cmStrCat(
- MessagePath(sourceFile.FileName), "\nincludes the moc file ",
- MessagePath(incKey.Key),
+ this->MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", this->MessagePath(incKey.Key),
",\nwhich seems to be the moc file from a different source "
"file.\nCMAKE_AUTOMOC_RELAXED_MODE:\nAlso a matching header ",
- MessageHeader(headerBase),
+ this->MessageHeader(headerBase),
"\ncould not be found in the following directories\n",
- MessageSearchLocations()));
+ this->MessageSearchLocations()));
return false;
}
}
// Check if header is skipped
- if (MocConst().skipped(headerHandle->FileName)) {
+ if (this->MocConst().skipped(headerHandle->FileName)) {
continue;
}
// Issue a warning
if (ownMoc && parseData.Macro.empty()) {
- Log().Warning(
+ this->Log().Warning(
GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the moc file ", MessagePath(incKey.Key),
- ", but does not contain a\n", MocConst().MacrosString(),
- " macro.\nRunning moc on the header\n ",
- MessagePath(headerHandle->FileName), "!\nBetter include ",
- MessagePath("moc_" + incKey.Base + ".cpp"),
- " for a compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
+ cmStrCat(
+ this->MessagePath(sourceFile.FileName), "\nincludes the moc file ",
+ this->MessagePath(incKey.Key), ", but does not contain a\n",
+ this->MocConst().MacrosString(),
+ " macro.\nRunning moc on the header\n ",
+ this->MessagePath(headerHandle->FileName), "!\nBetter include ",
+ this->MessagePath("moc_" + incKey.Base + ".cpp"),
+ " for a compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
} else {
- Log().Warning(
+ this->Log().Warning(
GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the moc file ", MessagePath(incKey.Key),
- " instead of ", MessagePath("moc_" + incKey.Base + ".cpp"),
- ".\nRunning moc on the header\n ",
- MessagePath(headerHandle->FileName), "!\nBetter include ",
- MessagePath("moc_" + incKey.Base + ".cpp"),
- " for compatibility with regular mode.\n",
- "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
+ cmStrCat(
+ this->MessagePath(sourceFile.FileName), "\nincludes the moc file ",
+ this->MessagePath(incKey.Key), " instead of ",
+ this->MessagePath("moc_" + incKey.Base + ".cpp"),
+ ".\nRunning moc on the header\n ",
+ this->MessagePath(headerHandle->FileName), "!\nBetter include ",
+ this->MessagePath("moc_" + incKey.Base + ".cpp"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
}
// Create mapping
- if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) {
+ if (!this->RegisterIncluded(incKey.Key, source,
+ std::move(headerHandle))) {
return false;
}
}
@@ -1328,26 +1348,27 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (!ownMoc) {
// Don't allow <BASE>.moc include other than own in regular mode
- LogError(GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the moc file ", MessagePath(incKey.Key),
- ",\nwhich seems to be the moc file from a different "
- "source file.\nThis is not supported. Include ",
- MessagePath(sourceBase + ".moc"),
- " to run moc on this source file."));
+ this->LogError(
+ GenT::MOC,
+ cmStrCat(this->MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", this->MessagePath(incKey.Key),
+ ",\nwhich seems to be the moc file from a different "
+ "source file.\nThis is not supported. Include ",
+ this->MessagePath(sourceBase + ".moc"),
+ " to run moc on this source file."));
return false;
}
// Accept but issue a warning if moc isn't required
if (parseData.Macro.empty()) {
- Log().Warning(GenT::MOC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the moc file ",
- MessagePath(incKey.Key),
- ", but does not contain a ",
- MocConst().MacrosString(), " macro."));
+ this->Log().Warning(
+ GenT::MOC,
+ cmStrCat(this->MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", this->MessagePath(incKey.Key),
+ ", but does not contain a ",
+ this->MocConst().MacrosString(), " macro."));
}
// Create mapping
- if (!RegisterIncluded(incKey.Key, source, source)) {
+ if (!this->RegisterIncluded(incKey.Key, source, source)) {
return false;
}
}
@@ -1361,7 +1382,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader(
cm::string_view includeBase)
{
// Clear search locations
- SearchLocations.clear();
+ this->SearchLocations.clear();
auto findHeader = [this,
&headerHandle](std::string const& basePath) -> bool {
@@ -1377,8 +1398,8 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader(
// Return a known file if it exists already
{
- auto it = BaseEval().Headers.find(testPath);
- if (it != BaseEval().Headers.end()) {
+ auto it = this->BaseEval().Headers.find(testPath);
+ if (it != this->BaseEval().Headers.end()) {
headerHandle = it->second;
found = true;
break;
@@ -1387,7 +1408,8 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader(
// Created and return discovered file entry
{
- SourceFileHandleT& handle = MocEval().HeadersDiscovered[testPath];
+ SourceFileHandleT& handle =
+ this->MocEval().HeadersDiscovered[testPath];
if (!handle) {
handle = std::make_shared<SourceFileT>(testPath);
handle->FileTime = fileTime;
@@ -1410,7 +1432,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader(
return true;
}
// Search in include directories
- for (std::string const& path : MocConst().IncludePaths) {
+ for (std::string const& path : this->MocConst().IncludePaths) {
if (findHeader(cmStrCat(path, '/', includeBase))) {
return true;
}
@@ -1424,24 +1446,24 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::RegisterIncluded(
SourceFileHandleT sourceFileHandle) const
{
// Check if this file is already included
- MappingHandleT& handle = MocEval().Includes[includeString];
+ MappingHandleT& handle = this->MocEval().Includes[includeString];
if (handle) {
// Check if the output file would be generated from different source files
if (handle->SourceFile != sourceFileHandle) {
std::string files =
- cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n');
+ cmStrCat(" ", this->MessagePath(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- files += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ files += cmStrCat(" ", this->MessagePath(item->FileName), '\n');
}
- LogError(
+ this->LogError(
GenT::MOC,
cmStrCat("The source files\n", files,
"contain the same include string ",
- MessagePath(includeString),
+ this->MessagePath(includeString),
", but\nthe moc file would be generated from different "
"source files\n ",
- MessagePath(sourceFileHandle->FileName), " and\n ",
- MessagePath(handle->SourceFile->FileName),
+ this->MessagePath(sourceFileHandle->FileName), " and\n ",
+ this->MessagePath(handle->SourceFile->FileName),
".\nConsider to\n"
" - not include the \"moc_<NAME>.cpp\" file\n"
" - add a directory prefix to a \"<NAME>.moc\" include "
@@ -1460,10 +1482,10 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::RegisterIncluded(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(sourceFileHandle);
- handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
+ handle->OutputFile = this->Gen()->AbsoluteIncludePath(includeString);
// Register mapping in sources/headers map
- RegisterMapping(handle);
+ this->RegisterMapping(handle);
return true;
}
@@ -1471,8 +1493,8 @@ void cmQtAutoMocUicT::JobEvalCacheMocT::RegisterMapping(
MappingHandleT mappingHandle) const
{
auto& regMap = mappingHandle->SourceFile->IsHeader
- ? MocEval().HeaderMappings
- : MocEval().SourceMappings;
+ ? this->MocEval().HeaderMappings
+ : this->MocEval().SourceMappings;
// Check if source file already gets mapped
auto& regHandle = regMap[mappingHandle->SourceFile->FileName];
if (!regHandle) {
@@ -1489,24 +1511,24 @@ void cmQtAutoMocUicT::JobEvalCacheMocT::RegisterMapping(
std::string cmQtAutoMocUicT::JobEvalCacheMocT::MessageHeader(
cm::string_view headerBase) const
{
- return MessagePath(cmStrCat(
+ return this->MessagePath(cmStrCat(
headerBase, ".{", cmJoin(this->BaseConst().HeaderExtensions, ","), '}'));
}
void cmQtAutoMocUicT::JobEvalCacheUicT::Process()
{
// Prepare buffers
- SearchLocations.reserve((UicConst().SearchPaths.size() + 1) * 2);
+ this->SearchLocations.reserve((this->UicConst().SearchPaths.size() + 1) * 2);
// Evaluate headers
- for (auto const& pair : BaseEval().Headers) {
- if (!EvalFile(pair.second)) {
+ for (auto const& pair : this->BaseEval().Headers) {
+ if (!this->EvalFile(pair.second)) {
return;
}
}
// Evaluate sources
- for (auto const& pair : BaseEval().Sources) {
- if (!EvalFile(pair.second)) {
+ for (auto const& pair : this->BaseEval().Sources) {
+ if (!this->EvalFile(pair.second)) {
return;
}
}
@@ -1524,22 +1546,24 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::EvalFile(
std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName);
for (IncludeKeyT const& incKey : Include) {
// Find .ui file
- UiName = cmStrCat(incKey.Base, ".ui");
- if (!FindIncludedUi(sourceDirPrefix, incKey.Dir)) {
- LogError(GenT::UIC,
- cmStrCat(MessagePath(sourceFile.FileName),
- "\nincludes the uic file ", MessagePath(incKey.Key),
- ",\nbut the user interface file ", MessagePath(UiName),
- "\ncould not be found in the following directories\n",
- MessageSearchLocations()));
+ this->UiName = cmStrCat(incKey.Base, ".ui");
+ if (!this->FindIncludedUi(sourceDirPrefix, incKey.Dir)) {
+ this->LogError(
+ GenT::UIC,
+ cmStrCat(this->MessagePath(sourceFile.FileName),
+ "\nincludes the uic file ", this->MessagePath(incKey.Key),
+ ",\nbut the user interface file ",
+ this->MessagePath(this->UiName),
+ "\ncould not be found in the following directories\n",
+ this->MessageSearchLocations()));
return false;
}
// Check if the file is skipped
- if (UicConst().skipped(UiFileHandle->FileName)) {
+ if (this->UicConst().skipped(this->UiFileHandle->FileName)) {
continue;
}
// Register mapping
- if (!RegisterMapping(incKey.Key, sourceFileHandle)) {
+ if (!this->RegisterMapping(incKey.Key, sourceFileHandle)) {
return false;
}
}
@@ -1551,7 +1575,7 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi(
cm::string_view sourceDirPrefix, cm::string_view includePrefix)
{
// Clear locations buffer
- SearchLocations.clear();
+ this->SearchLocations.clear();
auto findUi = [this](std::string const& testPath) -> bool {
std::string const fullPath = this->Gen()->CollapseFullPathTS(testPath);
@@ -1573,25 +1597,25 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi(
};
// Vicinity of the source
- if (findUi(cmStrCat(sourceDirPrefix, UiName))) {
+ if (findUi(cmStrCat(sourceDirPrefix, this->UiName))) {
return true;
}
if (!includePrefix.empty()) {
- if (findUi(cmStrCat(sourceDirPrefix, includePrefix, UiName))) {
+ if (findUi(cmStrCat(sourceDirPrefix, includePrefix, this->UiName))) {
return true;
}
}
// Additional AUTOUIC search paths
- auto const& searchPaths = UicConst().SearchPaths;
+ auto const& searchPaths = this->UicConst().SearchPaths;
if (!searchPaths.empty()) {
for (std::string const& sPath : searchPaths) {
- if (findUi(cmStrCat(sPath, '/', UiName))) {
+ if (findUi(cmStrCat(sPath, '/', this->UiName))) {
return true;
}
}
if (!includePrefix.empty()) {
for (std::string const& sPath : searchPaths) {
- if (findUi(cmStrCat(sPath, '/', includePrefix, UiName))) {
+ if (findUi(cmStrCat(sPath, '/', includePrefix, this->UiName))) {
return true;
}
}
@@ -1604,26 +1628,26 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi(
bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping(
std::string const& includeString, SourceFileHandleT includerFileHandle)
{
- auto& Includes = Gen()->UicEval().Includes;
+ auto& Includes = this->Gen()->UicEval().Includes;
auto it = Includes.find(includeString);
if (it != Includes.end()) {
MappingHandleT const& handle = it->second;
- if (handle->SourceFile != UiFileHandle) {
+ if (handle->SourceFile != this->UiFileHandle) {
// The output file already gets generated - from a different .ui file!
std::string files =
- cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n');
+ cmStrCat(" ", this->MessagePath(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- files += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ files += cmStrCat(" ", this->MessagePath(item->FileName), '\n');
}
- LogError(
+ this->LogError(
GenT::UIC,
cmStrCat(
"The source files\n", files, "contain the same include string ",
Quoted(includeString),
", but\nthe uic file would be generated from different "
"user interface files\n ",
- MessagePath(UiFileHandle->FileName), " and\n ",
- MessagePath(handle->SourceFile->FileName),
+ this->MessagePath(this->UiFileHandle->FileName), " and\n ",
+ this->MessagePath(handle->SourceFile->FileName),
".\nConsider to\n"
" - add a directory prefix to a \"ui_<NAME>.h\" include "
"(e.g \"sub/ui_<NAME>.h\")\n"
@@ -1638,8 +1662,8 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping(
MappingHandleT handle = std::make_shared<MappingT>();
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- handle->SourceFile = UiFileHandle;
- handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
+ handle->SourceFile = this->UiFileHandle;
+ handle->OutputFile = this->Gen()->AbsoluteIncludePath(includeString);
// Register mapping
Includes.emplace(includeString, std::move(handle));
}
@@ -1649,40 +1673,42 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping(
void cmQtAutoMocUicT::JobEvalCacheFinishT::Process()
{
// Add discovered header parse jobs
- Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered);
+ this->Gen()->CreateParseJobs<JobParseHeaderT>(
+ this->MocEval().HeadersDiscovered);
// Add dependency probing jobs
{
// Add fence job to ensure all parsing has finished
- Gen()->WorkerPool().EmplaceJob<JobFenceT>();
- if (MocConst().Enabled) {
- Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>();
+ this->Gen()->WorkerPool().EmplaceJob<JobFenceT>();
+ if (this->MocConst().Enabled) {
+ this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>();
}
- if (UicConst().Enabled) {
- Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>();
+ if (this->UicConst().Enabled) {
+ this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>();
}
// Add probe finish job
- Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>();
+ this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>();
}
}
void cmQtAutoMocUicT::JobProbeDepsMocT::Process()
{
// Create moc header jobs
- for (auto const& pair : MocEval().HeaderMappings) {
+ for (auto const& pair : this->MocEval().HeaderMappings) {
// Register if this mapping is a candidate for mocs_compilation.cpp
bool const compFile = pair.second->IncludeString.empty();
if (compFile) {
- MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath);
+ this->MocEval().CompFiles.emplace_back(
+ pair.second->SourceFile->BuildPath);
}
- if (!Generate(pair.second, compFile)) {
+ if (!this->Generate(pair.second, compFile)) {
return;
}
}
// Create moc source jobs
- for (auto const& pair : MocEval().SourceMappings) {
- if (!Generate(pair.second, false)) {
+ for (auto const& pair : this->MocEval().SourceMappings) {
+ if (!this->Generate(pair.second, false)) {
return;
}
}
@@ -1692,22 +1718,23 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
bool compFile) const
{
std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
+ if (this->Log().Verbose()) {
reason = cm::make_unique<std::string>();
}
- if (Probe(*mapping, reason.get())) {
+ if (this->Probe(*mapping, reason.get())) {
// Register the parent directory for creation
- MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
+ this->MocEval().OutputDirs.emplace(
+ cmQtAutoGen::ParentDir(mapping->OutputFile));
// Fetch the cache entry for the source file
std::string const& sourceFile = mapping->SourceFile->FileName;
ParseCacheT::GetOrInsertT cacheEntry =
- BaseEval().ParseCache.GetOrInsert(sourceFile);
+ this->BaseEval().ParseCache.GetOrInsert(sourceFile);
// Add moc job
- Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
+ this->Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
mapping, std::move(reason), std::move(cacheEntry.first));
// Check if a moc job for a mocs_compilation.cpp entry was generated
if (compFile) {
- MocEval().CompUpdated = true;
+ this->MocEval().CompUpdated = true;
}
}
return true;
@@ -1723,19 +1750,19 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping,
cmFileTime outputFileTime;
if (!outputFileTime.Load(outputFile)) {
if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", MessagePath(outputFile),
- ", because it doesn't exist, from ", MessagePath(sourceFile));
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
+ ", because it doesn't exist, from ",
+ this->MessagePath(sourceFile));
}
return true;
}
// Test if any setting changed
- if (MocConst().SettingsChanged) {
+ if (this->MocConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because the uic settings changed, from ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
@@ -1743,32 +1770,32 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping,
// Test if the source file is newer
if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because it's older than its source file, from ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
// Test if the moc_predefs file is newer
- if (!MocConst().PredefsFileAbs.empty()) {
- if (outputFileTime.Older(MocEval().PredefsTime)) {
+ if (!this->MocConst().PredefsFileAbs.empty()) {
+ if (outputFileTime.Older(this->MocEval().PredefsTime)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because it's older than ",
- MessagePath(MocConst().PredefsFileAbs), ", from ",
- MessagePath(sourceFile));
+ this->MessagePath(this->MocConst().PredefsFileAbs),
+ ", from ", this->MessagePath(sourceFile));
}
return true;
}
}
// Test if the moc executable is newer
- if (outputFileTime.Older(MocConst().ExecutableTime)) {
+ if (outputFileTime.Older(this->MocConst().ExecutableTime)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because it's older than the moc executable, from ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
@@ -1782,26 +1809,26 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping,
auto& dep = *it;
// Find dependency file
- auto const depMatch = FindDependency(sourceDir, dep);
+ auto const depMatch = this->FindDependency(sourceDir, dep);
if (depMatch.first.empty()) {
if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", MessagePath(outputFile), " from ",
- MessagePath(sourceFile), ", because its dependency ",
- MessagePath(dep), " vanished.");
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
+ " from ", this->MessagePath(sourceFile),
+ ", because its dependency ",
+ this->MessagePath(dep), " vanished.");
}
dependencies.erase(it);
- BaseEval().ParseCacheChanged = true;
+ this->BaseEval().ParseCacheChanged = true;
return true;
}
// Test if dependency file is older
if (outputFileTime.Older(depMatch.second)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because it's older than its dependency file ",
- MessagePath(depMatch.first), ", from ",
- MessagePath(sourceFile));
+ this->MessagePath(depMatch.first), ", from ",
+ this->MessagePath(sourceFile));
}
return true;
}
@@ -1817,7 +1844,7 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
{
using ResPair = std::pair<std::string, cmFileTime>;
// moc's dependency file contains absolute paths
- if (MocConst().CanOutputDependencies) {
+ if (this->MocConst().CanOutputDependencies) {
ResPair res{ includeString, {} };
if (res.second.Load(res.first)) {
return res;
@@ -1832,7 +1859,7 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
}
}
// Search in include directories
- for (std::string const& includePath : MocConst().IncludePaths) {
+ for (std::string const& includePath : this->MocConst().IncludePaths) {
ResPair res{ cmStrCat(includePath, '/', includeString), {} };
if (res.second.Load(res.first)) {
return res;
@@ -1844,20 +1871,22 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
void cmQtAutoMocUicT::JobProbeDepsUicT::Process()
{
- for (auto const& pair : Gen()->UicEval().Includes) {
+ for (auto const& pair : this->Gen()->UicEval().Includes) {
MappingHandleT const& mapping = pair.second;
std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
+ if (this->Log().Verbose()) {
reason = cm::make_unique<std::string>();
}
- if (!Probe(*mapping, reason.get())) {
+ if (!this->Probe(*mapping, reason.get())) {
continue;
}
// Register the parent directory for creation
- UicEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
+ this->UicEval().OutputDirs.emplace(
+ cmQtAutoGen::ParentDir(mapping->OutputFile));
// Add uic job
- Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping, std::move(reason));
+ this->Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping,
+ std::move(reason));
}
}
@@ -1871,19 +1900,19 @@ bool cmQtAutoMocUicT::JobProbeDepsUicT::Probe(MappingT const& mapping,
cmFileTime outputFileTime;
if (!outputFileTime.Load(outputFile)) {
if (reason != nullptr) {
- *reason =
- cmStrCat("Generating ", MessagePath(outputFile),
- ", because it doesn't exist, from ", MessagePath(sourceFile));
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
+ ", because it doesn't exist, from ",
+ this->MessagePath(sourceFile));
}
return true;
}
// Test if the uic settings changed
- if (UicConst().SettingsChanged) {
+ if (this->UicConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because the uic settings changed, from ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
@@ -1891,19 +1920,19 @@ bool cmQtAutoMocUicT::JobProbeDepsUicT::Probe(MappingT const& mapping,
// Test if the source file is newer
if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
" because it's older than the source file ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
// Test if the uic executable is newer
- if (outputFileTime.Older(UicConst().ExecutableTime)) {
+ if (outputFileTime.Older(this->UicConst().ExecutableTime)) {
if (reason != nullptr) {
- *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ *reason = cmStrCat("Generating ", this->MessagePath(outputFile),
", because it's older than the uic executable, from ",
- MessagePath(sourceFile));
+ this->MessagePath(sourceFile));
}
return true;
}
@@ -1919,64 +1948,64 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process()
auto createDirs = [this](GenT genType, StringSet const& dirSet) {
for (std::string const& dirName : dirSet) {
if (!cmSystemTools::MakeDirectory(dirName)) {
- this->LogError(
- genType,
- cmStrCat("Creating directory ", MessagePath(dirName), " failed."));
+ this->LogError(genType,
+ cmStrCat("Creating directory ",
+ this->MessagePath(dirName), " failed."));
return;
}
}
};
- if (MocConst().Enabled && UicConst().Enabled) {
- StringSet outputDirs = MocEval().OutputDirs;
- outputDirs.insert(UicEval().OutputDirs.begin(),
- UicEval().OutputDirs.end());
+ if (this->MocConst().Enabled && this->UicConst().Enabled) {
+ StringSet outputDirs = this->MocEval().OutputDirs;
+ outputDirs.insert(this->UicEval().OutputDirs.begin(),
+ this->UicEval().OutputDirs.end());
createDirs(GenT::GEN, outputDirs);
- } else if (MocConst().Enabled) {
- createDirs(GenT::MOC, MocEval().OutputDirs);
- } else if (UicConst().Enabled) {
- createDirs(GenT::UIC, UicEval().OutputDirs);
+ } else if (this->MocConst().Enabled) {
+ createDirs(GenT::MOC, this->MocEval().OutputDirs);
+ } else if (this->UicConst().Enabled) {
+ createDirs(GenT::UIC, this->UicEval().OutputDirs);
}
}
- if (MocConst().Enabled) {
+ if (this->MocConst().Enabled) {
// Add mocs compilations job
- Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
+ this->Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
}
- if (!BaseConst().DepFile.empty()) {
+ if (!this->BaseConst().DepFile.empty()) {
// Add job to merge dep files
- Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>();
+ this->Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>();
}
// Add finish job
- Gen()->WorkerPool().EmplaceJob<JobFinishT>();
+ this->Gen()->WorkerPool().EmplaceJob<JobFinishT>();
}
void cmQtAutoMocUicT::JobCompileMocT::Process()
{
- std::string const& sourceFile = Mapping->SourceFile->FileName;
- std::string const& outputFile = Mapping->OutputFile;
+ std::string const& sourceFile = this->Mapping->SourceFile->FileName;
+ std::string const& outputFile = this->Mapping->OutputFile;
// Compose moc command
std::vector<std::string> cmd;
{
// Reserve large enough
- cmd.reserve(MocConst().OptionsDefinitions.size() +
- MocConst().OptionsIncludes.size() +
- MocConst().OptionsExtra.size() + 16);
- cmd.push_back(MocConst().Executable);
+ cmd.reserve(this->MocConst().OptionsDefinitions.size() +
+ this->MocConst().OptionsIncludes.size() +
+ this->MocConst().OptionsExtra.size() + 16);
+ cmd.push_back(this->MocConst().Executable);
// Add definitions
- cm::append(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, this->MocConst().OptionsDefinitions);
// Add includes
- cm::append(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, this->MocConst().OptionsIncludes);
// Add predefs include
- if (!MocConst().PredefsFileAbs.empty()) {
+ if (!this->MocConst().PredefsFileAbs.empty()) {
cmd.emplace_back("--include");
- cmd.push_back(MocConst().PredefsFileAbs);
+ cmd.push_back(this->MocConst().PredefsFileAbs);
}
// Add path prefix on demand
- if (MocConst().PathPrefix && Mapping->SourceFile->IsHeader) {
- for (std::string const& dir : MocConst().IncludePaths) {
+ if (this->MocConst().PathPrefix && this->Mapping->SourceFile->IsHeader) {
+ for (std::string const& dir : this->MocConst().IncludePaths) {
cm::string_view prefix = sourceFile;
if (cmHasPrefix(prefix, dir)) {
prefix.remove_prefix(dir.size());
@@ -1996,8 +2025,8 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
}
// Add extra options
- cm::append(cmd, MocConst().OptionsExtra);
- if (MocConst().CanOutputDependencies) {
+ cm::append(cmd, this->MocConst().OptionsExtra);
+ if (this->MocConst().CanOutputDependencies) {
cmd.emplace_back("--output-dep-file");
}
// Add output file
@@ -2009,60 +2038,60 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
// Execute moc command
cmWorkerPool::ProcessResultT result;
- if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) {
+ if (!this->RunProcess(GenT::MOC, result, cmd, this->Reason.get())) {
// Moc command failed
std::string includers;
- if (!Mapping->IncluderFiles.empty()) {
+ if (!this->Mapping->IncluderFiles.empty()) {
includers = "included by\n";
- for (auto const& item : Mapping->IncluderFiles) {
- includers += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ for (auto const& item : this->Mapping->IncluderFiles) {
+ includers += cmStrCat(" ", this->MessagePath(item->FileName), '\n');
}
}
- LogCommandError(GenT::MOC,
- cmStrCat("The moc process failed to compile\n ",
- MessagePath(sourceFile), "\ninto\n ",
- MessagePath(outputFile), '\n', includers,
- result.ErrorMessage),
- cmd, result.StdOut);
+ this->LogCommandError(GenT::MOC,
+ cmStrCat("The moc process failed to compile\n ",
+ this->MessagePath(sourceFile), "\ninto\n ",
+ this->MessagePath(outputFile), '\n',
+ includers, result.ErrorMessage),
+ cmd, result.StdOut);
return;
}
// Moc command success. Print moc output.
if (!result.StdOut.empty()) {
- Log().Info(GenT::MOC, result.StdOut);
+ this->Log().Info(GenT::MOC, result.StdOut);
}
// Extract dependencies from the dep file moc generated for us
- if (MocConst().CanOutputDependencies) {
+ if (this->MocConst().CanOutputDependencies) {
const std::string depfile = outputFile + ".d";
- if (Log().Verbose()) {
- Log().Info(GenT::MOC,
- "Reading dependencies from " + MessagePath(depfile));
+ if (this->Log().Verbose()) {
+ this->Log().Info(
+ GenT::MOC, "Reading dependencies from " + this->MessagePath(depfile));
}
if (!cmSystemTools::FileExists(depfile)) {
- Log().Warning(GenT::MOC,
- "Dependency file " + MessagePath(depfile) +
- " does not exist.");
+ this->Log().Warning(GenT::MOC,
+ "Dependency file " + this->MessagePath(depfile) +
+ " does not exist.");
return;
}
- CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
+ this->CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
}
}
void cmQtAutoMocUicT::JobCompileUicT::Process()
{
- std::string const& sourceFile = Mapping->SourceFile->FileName;
- std::string const& outputFile = Mapping->OutputFile;
+ std::string const& sourceFile = this->Mapping->SourceFile->FileName;
+ std::string const& outputFile = this->Mapping->OutputFile;
// Compose uic command
std::vector<std::string> cmd;
- cmd.push_back(UicConst().Executable);
+ cmd.push_back(this->UicConst().Executable);
{
- std::vector<std::string> allOpts = UicConst().Options;
- auto optionIt = UicConst().UiFiles.find(sourceFile);
- if (optionIt != UicConst().UiFiles.end()) {
+ std::vector<std::string> allOpts = this->UicConst().Options;
+ auto optionIt = this->UicConst().UiFiles.find(sourceFile);
+ if (optionIt != this->UicConst().UiFiles.end()) {
UicMergeOptions(allOpts, optionIt->second.Options,
- (BaseConst().QtVersion.Major == 5));
+ (this->BaseConst().QtVersion.Major == 5));
}
cm::append(cmd, allOpts);
}
@@ -2071,24 +2100,25 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
cmd.emplace_back(sourceFile);
cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::UIC, result, cmd, Reason.get())) {
+ if (this->RunProcess(GenT::UIC, result, cmd, this->Reason.get())) {
// Uic command success
// Print uic output
if (!result.StdOut.empty()) {
- Log().Info(GenT::UIC, result.StdOut);
+ this->Log().Info(GenT::UIC, result.StdOut);
}
} else {
// Uic command failed
std::string includers;
- for (auto const& item : Mapping->IncluderFiles) {
- includers += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ for (auto const& item : this->Mapping->IncluderFiles) {
+ includers += cmStrCat(" ", this->MessagePath(item->FileName), '\n');
}
- LogCommandError(GenT::UIC,
- cmStrCat("The uic process failed to compile\n ",
- MessagePath(sourceFile), "\ninto\n ",
- MessagePath(outputFile), "\nincluded by\n",
- includers, result.ErrorMessage),
- cmd, result.StdOut);
+ this->LogCommandError(GenT::UIC,
+ cmStrCat("The uic process failed to compile\n ",
+ this->MessagePath(sourceFile), "\ninto\n ",
+ this->MessagePath(outputFile),
+ "\nincluded by\n", includers,
+ result.ErrorMessage),
+ cmd, result.StdOut);
}
}
@@ -2098,41 +2128,41 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process()
std::string content =
"// This file is autogenerated. Changes will be overwritten.\n";
- if (MocEval().CompFiles.empty()) {
+ if (this->MocEval().CompFiles.empty()) {
// Placeholder content
content += "// No files found that require moc or the moc files are "
"included\n"
"enum some_compilers { need_more_than_nothing };\n";
} else {
// Valid content
- const bool mc = BaseConst().MultiConfig;
+ const bool mc = this->BaseConst().MultiConfig;
cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
- content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
+ content += cmWrap(wrapFront, this->MocEval().CompFiles, wrapBack, "");
}
- std::string const& compAbs = MocConst().CompFileAbs;
+ std::string const& compAbs = this->MocConst().CompFileAbs;
if (cmQtAutoGenerator::FileDiffers(compAbs, content)) {
// Actually write mocs compilation file
- if (Log().Verbose()) {
- Log().Info(GenT::MOC,
- "Generating MOC compilation " + MessagePath(compAbs));
+ if (this->Log().Verbose()) {
+ this->Log().Info(
+ GenT::MOC, "Generating MOC compilation " + this->MessagePath(compAbs));
}
if (!FileWrite(compAbs, content)) {
- LogError(GenT::MOC,
- cmStrCat("Writing MOC compilation ", MessagePath(compAbs),
- " failed."));
+ this->LogError(GenT::MOC,
+ cmStrCat("Writing MOC compilation ",
+ this->MessagePath(compAbs), " failed."));
}
- } else if (MocEval().CompUpdated) {
+ } else if (this->MocEval().CompUpdated) {
// Only touch mocs compilation file
- if (Log().Verbose()) {
- Log().Info(GenT::MOC,
- "Touching MOC compilation " + MessagePath(compAbs));
+ if (this->Log().Verbose()) {
+ this->Log().Info(
+ GenT::MOC, "Touching MOC compilation " + this->MessagePath(compAbs));
}
if (!cmSystemTools::Touch(compAbs, false)) {
- LogError(GenT::MOC,
- cmStrCat("Touching MOC compilation ", MessagePath(compAbs),
- " failed."));
+ this->LogError(GenT::MOC,
+ cmStrCat("Touching MOC compilation ",
+ this->MessagePath(compAbs), " failed."));
}
}
}
@@ -2169,12 +2199,36 @@ std::string escapeDependencyPath(cm::string_view path)
return escapedPath;
}
+/*
+ * Return the initial dependencies of the merged depfile.
+ * Those are dependencies from the project files, not from moc runs.
+ */
+std::vector<std::string>
+cmQtAutoMocUicT::JobDepFilesMergeT::initialDependencies() const
+{
+ std::vector<std::string> dependencies;
+ dependencies.reserve(this->BaseConst().ListFiles.size() +
+ this->BaseEval().Headers.size() +
+ this->BaseEval().Sources.size());
+ cm::append(dependencies, this->BaseConst().ListFiles);
+ auto append_file_path =
+ [&dependencies](const SourceFileMapT::value_type& p) {
+ dependencies.push_back(p.first);
+ };
+ std::for_each(this->BaseEval().Headers.begin(),
+ this->BaseEval().Headers.end(), append_file_path);
+ std::for_each(this->BaseEval().Sources.begin(),
+ this->BaseEval().Sources.end(), append_file_path);
+ return dependencies;
+}
+
void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
{
- if (Log().Verbose()) {
- Log().Info(GenT::MOC,
- cmStrCat("Merging MOC dependencies into ",
- MessagePath(BaseConst().DepFile.c_str())));
+ if (this->Log().Verbose()) {
+ this->Log().Info(
+ GenT::MOC,
+ cmStrCat("Merging MOC dependencies into ",
+ this->MessagePath(this->BaseConst().DepFile.c_str())));
}
auto processDepFile =
[](const std::string& mocOutputFile) -> std::vector<std::string> {
@@ -2185,8 +2239,8 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
return dependenciesFromDepFile(f.c_str());
};
- std::vector<std::string> dependencies = BaseConst().ListFiles;
- ParseCacheT& parseCache = BaseEval().ParseCache;
+ std::vector<std::string> dependencies = this->initialDependencies();
+ ParseCacheT& parseCache = this->BaseEval().ParseCache;
auto processMappingEntry = [&](const MappingMapT::value_type& m) {
auto cacheEntry = parseCache.GetOrInsert(m.first);
if (cacheEntry.first->Moc.Depends.empty()) {
@@ -2197,10 +2251,10 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
cacheEntry.first->Moc.Depends.end());
};
- std::for_each(MocEval().HeaderMappings.begin(),
- MocEval().HeaderMappings.end(), processMappingEntry);
- std::for_each(MocEval().SourceMappings.begin(),
- MocEval().SourceMappings.end(), processMappingEntry);
+ std::for_each(this->MocEval().HeaderMappings.begin(),
+ this->MocEval().HeaderMappings.end(), processMappingEntry);
+ std::for_each(this->MocEval().SourceMappings.begin(),
+ this->MocEval().SourceMappings.end(), processMappingEntry);
// Remove duplicates to make the depfile smaller
std::sort(dependencies.begin(), dependencies.end());
@@ -2208,39 +2262,42 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
dependencies.end());
// Add form files
- for (const auto& uif : UicEval().UiFiles) {
+ for (const auto& uif : this->UicEval().UiFiles) {
dependencies.push_back(uif.first);
}
// Write the file
cmsys::ofstream ofs;
- ofs.open(BaseConst().DepFile.c_str(),
+ ofs.open(this->BaseConst().DepFile.c_str(),
(std::ios::out | std::ios::binary | std::ios::trunc));
if (!ofs) {
- LogError(GenT::GEN,
- cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile),
- " for writing."));
+ this->LogError(GenT::GEN,
+ cmStrCat("Cannot open ",
+ this->MessagePath(this->BaseConst().DepFile),
+ " for writing."));
return;
}
- ofs << BaseConst().DepFileRuleName << ": \\\n";
+ ofs << this->BaseConst().DepFileRuleName << ": \\\n";
for (const std::string& file : dependencies) {
ofs << '\t' << escapeDependencyPath(file) << " \\\n";
if (!ofs.good()) {
- LogError(GenT::GEN,
- cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
- " failed."));
+ this->LogError(GenT::GEN,
+ cmStrCat("Writing depfile",
+ this->MessagePath(this->BaseConst().DepFile),
+ " failed."));
return;
}
}
// Add the CMake executable to re-new cache data if necessary.
// Also, this is the last entry, so don't add a backslash.
- ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) << '\n';
+ ofs << '\t' << escapeDependencyPath(this->BaseConst().CMakeExecutable)
+ << '\n';
}
void cmQtAutoMocUicT::JobFinishT::Process()
{
- Gen()->AbortSuccess();
+ this->Gen()->AbortSuccess();
}
cmQtAutoMocUicT::cmQtAutoMocUicT()
@@ -2252,42 +2309,51 @@ cmQtAutoMocUicT::~cmQtAutoMocUicT() = default;
bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
// -- Required settings
- if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
- !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) ||
- !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) ||
- !info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
- !info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
- !info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
+ if (!info.GetBool("MULTI_CONFIG", this->BaseConst_.MultiConfig, true) ||
+ !info.GetUInt("QT_VERSION_MAJOR", this->BaseConst_.QtVersion.Major,
+ true) ||
+ !info.GetUInt("QT_VERSION_MINOR", this->BaseConst_.QtVersion.Minor,
+ true) ||
+ !info.GetUInt("PARALLEL", this->BaseConst_.ThreadCount, false) ||
+ !info.GetString("BUILD_DIR", this->BaseConst_.AutogenBuildDir, true) ||
+ !info.GetStringConfig("INCLUDE_DIR", this->BaseConst_.AutogenIncludeDir,
true) ||
- !info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
- !info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile,
- true) ||
- !info.GetString("DEP_FILE", BaseConst_.DepFile, false) ||
- !info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
+ !info.GetString("CMAKE_EXECUTABLE", this->BaseConst_.CMakeExecutable,
+ true) ||
+ !info.GetStringConfig("PARSE_CACHE_FILE",
+ this->BaseConst_.ParseCacheFile, true) ||
+ !info.GetString("DEP_FILE", this->BaseConst_.DepFile, false) ||
+ !info.GetString("DEP_FILE_RULE_NAME", this->BaseConst_.DepFileRuleName,
+ false) ||
+ !info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) ||
+ !info.GetArray("CMAKE_LIST_FILES", this->BaseConst_.ListFiles, true) ||
+ !info.GetArray("HEADER_EXTENSIONS", this->BaseConst_.HeaderExtensions,
+ true) ||
+ !info.GetString("QT_MOC_EXECUTABLE", this->MocConst_.Executable,
false) ||
- !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
- !info.GetArray("CMAKE_LIST_FILES", BaseConst_.ListFiles, true) ||
- !info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
- !info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
- !info.GetString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) {
+ !info.GetString("QT_UIC_EXECUTABLE", this->UicConst_.Executable,
+ false)) {
return false;
}
// -- Checks
- if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
- return info.LogError(cmStrCat("The CMake executable ",
- MessagePath(BaseConst_.CMakeExecutable),
- " does not exist."));
+ if (!this->BaseConst_.CMakeExecutableTime.Load(
+ this->BaseConst_.CMakeExecutable)) {
+ return info.LogError(
+ cmStrCat("The CMake executable ",
+ this->MessagePath(this->BaseConst_.CMakeExecutable),
+ " does not exist."));
}
// -- Evaluate values
- BaseConst_.ThreadCount = std::min(BaseConst_.ThreadCount, ParallelMax);
- WorkerPool_.SetThreadCount(BaseConst_.ThreadCount);
+ this->BaseConst_.ThreadCount =
+ std::min(this->BaseConst_.ThreadCount, ParallelMax);
+ this->WorkerPool_.SetThreadCount(this->BaseConst_.ThreadCount);
// -- Moc
- if (!MocConst_.Executable.empty()) {
+ if (!this->MocConst_.Executable.empty()) {
// -- Moc is enabled
- MocConst_.Enabled = true;
+ this->MocConst_.Enabled = true;
// -- Temporary buffers
struct
@@ -2297,18 +2363,21 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
} tmp;
// -- Required settings
- if (!info.GetBool("MOC_RELAXED_MODE", MocConst_.RelaxedMode, false) ||
- !info.GetBool("MOC_PATH_PREFIX", MocConst_.PathPrefix, true) ||
- !info.GetArray("MOC_SKIP", MocConst_.SkipList, false) ||
- !info.GetArrayConfig("MOC_DEFINITIONS", MocConst_.Definitions,
+ if (!info.GetBool("MOC_RELAXED_MODE", this->MocConst_.RelaxedMode,
+ false) ||
+ !info.GetBool("MOC_PATH_PREFIX", this->MocConst_.PathPrefix, true) ||
+ !info.GetArray("MOC_SKIP", this->MocConst_.SkipList, false) ||
+ !info.GetArrayConfig("MOC_DEFINITIONS", this->MocConst_.Definitions,
+ false) ||
+ !info.GetArrayConfig("MOC_INCLUDES", this->MocConst_.IncludePaths,
false) ||
- !info.GetArrayConfig("MOC_INCLUDES", MocConst_.IncludePaths, false) ||
- !info.GetArray("MOC_OPTIONS", MocConst_.OptionsExtra, false) ||
- !info.GetStringConfig("MOC_COMPILATION_FILE", MocConst_.CompFileAbs,
- true) ||
- !info.GetArray("MOC_PREDEFS_CMD", MocConst_.PredefsCmd, false) ||
- !info.GetStringConfig("MOC_PREDEFS_FILE", MocConst_.PredefsFileAbs,
- !MocConst_.PredefsCmd.empty()) ||
+ !info.GetArray("MOC_OPTIONS", this->MocConst_.OptionsExtra, false) ||
+ !info.GetStringConfig("MOC_COMPILATION_FILE",
+ this->MocConst_.CompFileAbs, true) ||
+ !info.GetArray("MOC_PREDEFS_CMD", this->MocConst_.PredefsCmd, false) ||
+ !info.GetStringConfig("MOC_PREDEFS_FILE",
+ this->MocConst_.PredefsFileAbs,
+ !this->MocConst_.PredefsCmd.empty()) ||
!info.GetArray("MOC_MACRO_NAMES", tmp.MacroNames, true) ||
!info.GetArray("MOC_DEPEND_FILTERS", tmp.DependFilters, false)) {
return false;
@@ -2316,12 +2385,12 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
// -- Evaluate settings
for (std::string const& item : tmp.MacroNames) {
- MocConst_.MacroFilters.emplace_back(
+ this->MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
// Can moc output dependencies or do we need to setup dependency filters?
- if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
- MocConst_.CanOutputDependencies = true;
+ if (this->BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
+ this->MocConst_.CanOutputDependencies = true;
} else {
Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
if (!val.isArray()) {
@@ -2371,22 +2440,23 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
}
}
// Check if moc executable exists (by reading the file time)
- if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
- return info.LogError(cmStrCat("The moc executable ",
- MessagePath(MocConst_.Executable),
- " does not exist."));
+ if (!this->MocConst_.ExecutableTime.Load(this->MocConst_.Executable)) {
+ return info.LogError(cmStrCat(
+ "The moc executable ", this->MessagePath(this->MocConst_.Executable),
+ " does not exist."));
}
}
// -- Uic
- if (!UicConst_.Executable.empty()) {
+ if (!this->UicConst_.Executable.empty()) {
// Uic is enabled
- UicConst_.Enabled = true;
+ this->UicConst_.Enabled = true;
// -- Required settings
- if (!info.GetArray("UIC_SKIP", UicConst_.SkipList, false) ||
- !info.GetArray("UIC_SEARCH_PATHS", UicConst_.SearchPaths, false) ||
- !info.GetArrayConfig("UIC_OPTIONS", UicConst_.Options, false)) {
+ if (!info.GetArray("UIC_SKIP", this->UicConst_.SkipList, false) ||
+ !info.GetArray("UIC_SEARCH_PATHS", this->UicConst_.SearchPaths,
+ false) ||
+ !info.GetArrayConfig("UIC_OPTIONS", this->UicConst_.Options, false)) {
return false;
}
// .ui files
@@ -2420,17 +2490,17 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
return false;
}
- auto& uiFile = UicConst_.UiFiles[entryName.asString()];
+ auto& uiFile = this->UicConst_.UiFiles[entryName.asString()];
InfoT::GetJsonArray(uiFile.Options, entryOptions);
}
}
// -- Evaluate settings
// Check if uic executable exists (by reading the file time)
- if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
- return info.LogError(cmStrCat("The uic executable ",
- MessagePath(UicConst_.Executable),
- " does not exist."));
+ if (!this->UicConst_.ExecutableTime.Load(this->UicConst_.Executable)) {
+ return info.LogError(cmStrCat(
+ "The uic executable ", this->MessagePath(this->UicConst_.Executable),
+ " does not exist."));
}
}
@@ -2452,17 +2522,20 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
Json::Value const& entry = val[ii];
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
- testEntry(entry.size() == 3, "JSON array size invalid.")) {
+ testEntry(entry.size() == 4, "JSON array size invalid.")) {
return false;
}
Json::Value const& entryName = entry[0u];
Json::Value const& entryFlags = entry[1u];
- Json::Value const& entryBuild = entry[2u];
+ Json::Value const& entryConfigs = entry[2u];
+ Json::Value const& entryBuild = entry[3u];
if (testEntry(entryName.isString(),
"JSON value for name is not a string.") ||
testEntry(entryFlags.isString(),
"JSON value for flags is not a string.") ||
+ testEntry(entryConfigs.isNull() || entryConfigs.isArray(),
+ "JSON value for configs is not null or array.") ||
testEntry(entryBuild.isString(),
"JSON value for build path is not a string.")) {
return false;
@@ -2475,6 +2548,22 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
return false;
}
+ if (entryConfigs.isArray()) {
+ bool configFound = false;
+ Json::ArrayIndex const configArraySize = entryConfigs.size();
+ for (Json::ArrayIndex ci = 0; ci != configArraySize; ++ci) {
+ Json::Value const& config = entryConfigs[ci];
+ if (testEntry(config.isString(),
+ "JSON value in config array is not a string.")) {
+ return false;
+ }
+ configFound = configFound || config.asString() == this->InfoConfig();
+ }
+ if (!configFound) {
+ continue;
+ }
+ }
+
cmFileTime fileTime;
if (!fileTime.Load(name)) {
return info.LogError(cmStrCat(
@@ -2486,14 +2575,15 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
sourceHandle->IsHeader = true;
sourceHandle->Moc = (flags[0] == 'M');
sourceHandle->Uic = (flags[1] == 'U');
- if (sourceHandle->Moc && MocConst().Enabled) {
+ if (sourceHandle->Moc && this->MocConst().Enabled) {
if (build.empty()) {
return info.LogError(
cmStrCat("Header file ", ii, " build path is empty"));
}
sourceHandle->BuildPath = std::move(build);
}
- BaseEval().Headers.emplace(std::move(name), std::move(sourceHandle));
+ this->BaseEval().Headers.emplace(std::move(name),
+ std::move(sourceHandle));
}
}
@@ -2515,16 +2605,19 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
Json::Value const& entry = val[ii];
if (testEntry(entry.isArray(), "JSON value is not an array.") ||
- testEntry(entry.size() == 2, "JSON array size invalid.")) {
+ testEntry(entry.size() == 3, "JSON array size invalid.")) {
return false;
}
Json::Value const& entryName = entry[0u];
Json::Value const& entryFlags = entry[1u];
+ Json::Value const& entryConfigs = entry[2u];
if (testEntry(entryName.isString(),
"JSON value for name is not a string.") ||
testEntry(entryFlags.isString(),
- "JSON value for flags is not a string.")) {
+ "JSON value for flags is not a string.") ||
+ testEntry(entryConfigs.isNull() || entryConfigs.isArray(),
+ "JSON value for configs is not null or array.")) {
return false;
}
@@ -2534,6 +2627,22 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
return false;
}
+ if (entryConfigs.isArray()) {
+ bool configFound = false;
+ Json::ArrayIndex const configArraySize = entryConfigs.size();
+ for (Json::ArrayIndex ci = 0; ci != configArraySize; ++ci) {
+ Json::Value const& config = entryConfigs[ci];
+ if (testEntry(config.isString(),
+ "JSON value in config array is not a string.")) {
+ return false;
+ }
+ configFound = configFound || config.asString() == this->InfoConfig();
+ }
+ if (!configFound) {
+ continue;
+ }
+ }
+
cmFileTime fileTime;
if (!fileTime.Load(name)) {
return info.LogError(cmStrCat(
@@ -2545,18 +2654,19 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
sourceHandle->IsHeader = false;
sourceHandle->Moc = (flags[0] == 'M');
sourceHandle->Uic = (flags[1] == 'U');
- BaseEval().Sources.emplace(std::move(name), std::move(sourceHandle));
+ this->BaseEval().Sources.emplace(std::move(name),
+ std::move(sourceHandle));
}
}
// -- Init derived information
// Moc variables
- if (MocConst().Enabled) {
+ if (this->MocConst().Enabled) {
// Compose moc includes list
{
// Compute framework paths
std::set<std::string> frameworkPaths;
- for (std::string const& path : MocConst().IncludePaths) {
+ for (std::string const& path : this->MocConst().IncludePaths) {
// Extract framework path
if (cmHasLiteralSuffix(path, ".framework/Headers")) {
// Go up twice to get to the framework root
@@ -2567,24 +2677,25 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
}
}
// Reserve options
- MocConst_.OptionsIncludes.reserve(MocConst().IncludePaths.size() +
- frameworkPaths.size() * 2);
+ this->MocConst_.OptionsIncludes.reserve(
+ this->MocConst().IncludePaths.size() + frameworkPaths.size() * 2);
// Append includes
- for (std::string const& path : MocConst().IncludePaths) {
- MocConst_.OptionsIncludes.emplace_back("-I" + path);
+ for (std::string const& path : this->MocConst().IncludePaths) {
+ this->MocConst_.OptionsIncludes.emplace_back("-I" + path);
}
// Append framework includes
for (std::string const& path : frameworkPaths) {
- MocConst_.OptionsIncludes.emplace_back("-F");
- MocConst_.OptionsIncludes.push_back(path);
+ this->MocConst_.OptionsIncludes.emplace_back("-F");
+ this->MocConst_.OptionsIncludes.push_back(path);
}
}
// Compose moc definitions list
{
- MocConst_.OptionsDefinitions.reserve(MocConst().Definitions.size());
- for (std::string const& def : MocConst().Definitions) {
- MocConst_.OptionsDefinitions.emplace_back("-D" + def);
+ this->MocConst_.OptionsDefinitions.reserve(
+ this->MocConst().Definitions.size());
+ for (std::string const& def : this->MocConst().Definitions) {
+ this->MocConst_.OptionsDefinitions.emplace_back("-D" + def);
}
}
}
@@ -2595,16 +2706,16 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
template <class JOBTYPE>
void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap)
{
- cmFileTime const parseCacheTime = BaseEval().ParseCacheTime;
- ParseCacheT& parseCache = BaseEval().ParseCache;
+ cmFileTime const parseCacheTime = this->BaseEval().ParseCacheTime;
+ ParseCacheT& parseCache = this->BaseEval().ParseCache;
for (auto& src : sourceMap) {
// Get or create the file parse data reference
ParseCacheT::GetOrInsertT cacheEntry = parseCache.GetOrInsert(src.first);
src.second->ParseData = std::move(cacheEntry.first);
// Create a parse job if the cache file was missing or is older
if (cacheEntry.second || src.second->FileTime.Newer(parseCacheTime)) {
- BaseEval().ParseCacheChanged = true;
- WorkerPool().EmplaceJob<JOBTYPE>(src.second);
+ this->BaseEval().ParseCacheChanged = true;
+ this->WorkerPool().EmplaceJob<JOBTYPE>(src.second);
}
}
}
@@ -2612,55 +2723,56 @@ void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap)
/** Concurrently callable implementation of cmSystemTools::CollapseFullPath */
std::string cmQtAutoMocUicT::CollapseFullPathTS(std::string const& path) const
{
- std::lock_guard<std::mutex> guard(CMakeLibMutex_);
- return cmSystemTools::CollapseFullPath(path, ProjectDirs().CurrentSource);
+ std::lock_guard<std::mutex> guard(this->CMakeLibMutex_);
+ return cmSystemTools::CollapseFullPath(path,
+ this->ProjectDirs().CurrentSource);
}
void cmQtAutoMocUicT::InitJobs()
{
// Add moc_predefs.h job
- if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) {
- WorkerPool().EmplaceJob<JobMocPredefsT>();
+ if (this->MocConst().Enabled && !this->MocConst().PredefsCmd.empty()) {
+ this->WorkerPool().EmplaceJob<JobMocPredefsT>();
}
// Add header parse jobs
- CreateParseJobs<JobParseHeaderT>(BaseEval().Headers);
+ this->CreateParseJobs<JobParseHeaderT>(this->BaseEval().Headers);
// Add source parse jobs
- CreateParseJobs<JobParseSourceT>(BaseEval().Sources);
+ this->CreateParseJobs<JobParseSourceT>(this->BaseEval().Sources);
// Add parse cache evaluations jobs
{
// Add a fence job to ensure all parsing has finished
- WorkerPool().EmplaceJob<JobFenceT>();
- if (MocConst().Enabled) {
- WorkerPool().EmplaceJob<JobEvalCacheMocT>();
+ this->WorkerPool().EmplaceJob<JobFenceT>();
+ if (this->MocConst().Enabled) {
+ this->WorkerPool().EmplaceJob<JobEvalCacheMocT>();
}
- if (UicConst().Enabled) {
- WorkerPool().EmplaceJob<JobEvalCacheUicT>();
+ if (this->UicConst().Enabled) {
+ this->WorkerPool().EmplaceJob<JobEvalCacheUicT>();
}
// Add evaluate job
- WorkerPool().EmplaceJob<JobEvalCacheFinishT>();
+ this->WorkerPool().EmplaceJob<JobEvalCacheFinishT>();
}
}
bool cmQtAutoMocUicT::Process()
{
- SettingsFileRead();
- ParseCacheRead();
- if (!CreateDirectories()) {
+ this->SettingsFileRead();
+ this->ParseCacheRead();
+ if (!this->CreateDirectories()) {
return false;
}
- InitJobs();
- if (!WorkerPool_.Process(this)) {
+ this->InitJobs();
+ if (!this->WorkerPool_.Process(this)) {
return false;
}
- if (JobError_) {
+ if (this->JobError_) {
return false;
}
- if (!ParseCacheWrite()) {
+ if (!this->ParseCacheWrite()) {
return false;
}
- if (!SettingsFileWrite()) {
+ if (!this->SettingsFileWrite()) {
return false;
}
return true;
@@ -2676,70 +2788,72 @@ void cmQtAutoMocUicT::SettingsFileRead()
cryptoHash.Append(";");
};
- if (MocConst_.Enabled) {
+ if (this->MocConst_.Enabled) {
cryptoHash.Initialize();
- cha(MocConst().Executable);
- for (auto const& item : MocConst().OptionsDefinitions) {
+ cha(this->MocConst().Executable);
+ for (auto const& item : this->MocConst().OptionsDefinitions) {
cha(item);
}
- for (auto const& item : MocConst().OptionsIncludes) {
+ for (auto const& item : this->MocConst().OptionsIncludes) {
cha(item);
}
- for (auto const& item : MocConst().OptionsExtra) {
+ for (auto const& item : this->MocConst().OptionsExtra) {
cha(item);
}
- for (auto const& item : MocConst().PredefsCmd) {
+ for (auto const& item : this->MocConst().PredefsCmd) {
cha(item);
}
- for (auto const& filter : MocConst().DependFilters) {
+ for (auto const& filter : this->MocConst().DependFilters) {
cha(filter.Key);
}
- for (auto const& filter : MocConst().MacroFilters) {
+ for (auto const& filter : this->MocConst().MacroFilters) {
cha(filter.Key);
}
- SettingsStringMoc_ = cryptoHash.FinalizeHex();
+ this->SettingsStringMoc_ = cryptoHash.FinalizeHex();
}
- if (UicConst().Enabled) {
+ if (this->UicConst().Enabled) {
cryptoHash.Initialize();
- cha(UicConst().Executable);
- std::for_each(UicConst().Options.begin(), UicConst().Options.end(), cha);
- for (const auto& item : UicConst().UiFiles) {
+ cha(this->UicConst().Executable);
+ std::for_each(this->UicConst().Options.begin(),
+ this->UicConst().Options.end(), cha);
+ for (const auto& item : this->UicConst().UiFiles) {
cha(item.first);
auto const& opts = item.second.Options;
std::for_each(opts.begin(), opts.end(), cha);
}
- SettingsStringUic_ = cryptoHash.FinalizeHex();
+ this->SettingsStringUic_ = cryptoHash.FinalizeHex();
}
}
// Read old settings and compare
{
std::string content;
- if (cmQtAutoGenerator::FileRead(content, SettingsFile_)) {
- if (MocConst().Enabled) {
- if (SettingsStringMoc_ != SettingsFind(content, "moc")) {
- MocConst_.SettingsChanged = true;
+ if (cmQtAutoGenerator::FileRead(content, this->SettingsFile_)) {
+ if (this->MocConst().Enabled) {
+ if (this->SettingsStringMoc_ != SettingsFind(content, "moc")) {
+ this->MocConst_.SettingsChanged = true;
}
}
- if (UicConst().Enabled) {
- if (SettingsStringUic_ != SettingsFind(content, "uic")) {
- UicConst_.SettingsChanged = true;
+ if (this->UicConst().Enabled) {
+ if (this->SettingsStringUic_ != SettingsFind(content, "uic")) {
+ this->UicConst_.SettingsChanged = true;
}
}
// In case any setting changed remove the old settings file.
// This triggers a full rebuild on the next run if the current
// build is aborted before writing the current settings in the end.
- if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
- cmSystemTools::RemoveFile(SettingsFile_);
+ if (this->MocConst().SettingsChanged ||
+ this->UicConst().SettingsChanged) {
+ cmSystemTools::RemoveFile(this->SettingsFile_);
}
} else {
// Settings file read failed
- if (MocConst().Enabled) {
- MocConst_.SettingsChanged = true;
+ if (this->MocConst().Enabled) {
+ this->MocConst_.SettingsChanged = true;
}
- if (UicConst().Enabled) {
- UicConst_.SettingsChanged = true;
+ if (this->UicConst().Enabled) {
+ this->UicConst_.SettingsChanged = true;
}
}
}
@@ -2748,11 +2862,11 @@ void cmQtAutoMocUicT::SettingsFileRead()
bool cmQtAutoMocUicT::SettingsFileWrite()
{
// Only write if any setting changed
- if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
- if (Log().Verbose()) {
- Log().Info(
- GenT::GEN,
- cmStrCat("Writing the settings file ", MessagePath(SettingsFile_)));
+ if (this->MocConst().SettingsChanged || this->UicConst().SettingsChanged) {
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::GEN,
+ cmStrCat("Writing the settings file ",
+ this->MessagePath(this->SettingsFile_)));
}
// Compose settings file content
std::string content;
@@ -2763,17 +2877,18 @@ bool cmQtAutoMocUicT::SettingsFileWrite()
content += cmStrCat(key, ':', value, '\n');
}
};
- SettingAppend("moc", SettingsStringMoc_);
- SettingAppend("uic", SettingsStringUic_);
+ SettingAppend("moc", this->SettingsStringMoc_);
+ SettingAppend("uic", this->SettingsStringUic_);
}
// Write settings file
std::string error;
- if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) {
- Log().Error(GenT::GEN,
- cmStrCat("Writing the settings file ",
- MessagePath(SettingsFile_), " failed.\n", error));
+ if (!cmQtAutoGenerator::FileWrite(this->SettingsFile_, content, &error)) {
+ this->Log().Error(GenT::GEN,
+ cmStrCat("Writing the settings file ",
+ this->MessagePath(this->SettingsFile_),
+ " failed.\n", error));
// Remove old settings file to trigger a full rebuild on the next run
- cmSystemTools::RemoveFile(SettingsFile_);
+ cmSystemTools::RemoveFile(this->SettingsFile_);
return false;
}
}
@@ -2784,41 +2899,46 @@ void cmQtAutoMocUicT::ParseCacheRead()
{
cm::string_view reason;
// Don't read the cache if it is invalid
- if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
+ if (!this->BaseEval().ParseCacheTime.Load(
+ this->BaseConst().ParseCacheFile)) {
reason = "Refreshing parse cache because it doesn't exist.";
- } else if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
+ } else if (this->MocConst().SettingsChanged ||
+ this->UicConst().SettingsChanged) {
reason = "Refreshing parse cache because the settings changed.";
- } else if (BaseEval().ParseCacheTime.Older(
- BaseConst().CMakeExecutableTime)) {
+ } else if (this->BaseEval().ParseCacheTime.Older(
+ this->BaseConst().CMakeExecutableTime)) {
reason =
"Refreshing parse cache because it is older than the CMake executable.";
}
if (!reason.empty()) {
// Don't read but refresh the complete parse cache
- if (Log().Verbose()) {
- Log().Info(GenT::GEN, reason);
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::GEN, reason);
}
- BaseEval().ParseCacheChanged = true;
+ this->BaseEval().ParseCacheChanged = true;
} else {
// Read parse cache
- BaseEval().ParseCache.ReadFromFile(BaseConst().ParseCacheFile);
+ this->BaseEval().ParseCache.ReadFromFile(this->BaseConst().ParseCacheFile);
}
}
bool cmQtAutoMocUicT::ParseCacheWrite()
{
- if (BaseEval().ParseCacheChanged) {
- if (Log().Verbose()) {
- Log().Info(GenT::GEN,
- cmStrCat("Writing the parse cache file ",
- MessagePath(BaseConst().ParseCacheFile)));
- }
- if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) {
- Log().Error(GenT::GEN,
- cmStrCat("Writing the parse cache file ",
- MessagePath(BaseConst().ParseCacheFile),
- " failed."));
+ if (this->BaseEval().ParseCacheChanged) {
+ if (this->Log().Verbose()) {
+ this->Log().Info(
+ GenT::GEN,
+ cmStrCat("Writing the parse cache file ",
+ this->MessagePath(this->BaseConst().ParseCacheFile)));
+ }
+ if (!this->BaseEval().ParseCache.WriteToFile(
+ this->BaseConst().ParseCacheFile)) {
+ this->Log().Error(
+ GenT::GEN,
+ cmStrCat("Writing the parse cache file ",
+ this->MessagePath(this->BaseConst().ParseCacheFile),
+ " failed."));
return false;
}
}
@@ -2828,11 +2948,12 @@ bool cmQtAutoMocUicT::ParseCacheWrite()
bool cmQtAutoMocUicT::CreateDirectories()
{
// Create AUTOGEN include directory
- if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) {
- Log().Error(GenT::GEN,
- cmStrCat("Creating the AUTOGEN include directory ",
- MessagePath(BaseConst().AutogenIncludeDir),
- " failed."));
+ if (!cmSystemTools::MakeDirectory(this->BaseConst().AutogenIncludeDir)) {
+ this->Log().Error(
+ GenT::GEN,
+ cmStrCat("Creating the AUTOGEN include directory ",
+ this->MessagePath(this->BaseConst().AutogenIncludeDir),
+ " failed."));
return false;
}
return true;
@@ -2841,34 +2962,34 @@ bool cmQtAutoMocUicT::CreateDirectories()
std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
const char* filePath)
{
- cmGccDepfileContent content = cmReadGccDepfile(filePath);
- if (content.empty()) {
+ auto const content = cmReadGccDepfile(filePath);
+ if (!content || content->empty()) {
return {};
}
// Moc outputs a depfile with exactly one rule.
// Discard the rule and return the dependencies.
- return content.front().paths;
+ return content->front().paths;
}
void cmQtAutoMocUicT::Abort(bool error)
{
if (error) {
- JobError_.store(true);
+ this->JobError_.store(true);
}
- WorkerPool_.Abort();
+ this->WorkerPool_.Abort();
}
std::string cmQtAutoMocUicT::AbsoluteBuildPath(
cm::string_view relativePath) const
{
- return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
+ return cmStrCat(this->BaseConst().AutogenBuildDir, '/', relativePath);
}
std::string cmQtAutoMocUicT::AbsoluteIncludePath(
cm::string_view relativePath) const
{
- return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
+ return cmStrCat(this->BaseConst().AutogenIncludeDir, '/', relativePath);
}
} // End of unnamed namespace
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 08eb4b5..943cc93 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -35,7 +35,7 @@ public:
private:
// -- Utility
- bool IsMultiConfig() const { return MultiConfig_; }
+ bool IsMultiConfig() const { return this->MultiConfig_; }
std::string MultiConfigOutput() const;
// -- Abstract processing interface
@@ -93,38 +93,41 @@ cmQtAutoRccT::~cmQtAutoRccT() = default;
bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
{
// -- Required settings
- if (!info.GetBool("MULTI_CONFIG", MultiConfig_, true) ||
- !info.GetString("BUILD_DIR", AutogenBuildDir_, true) ||
- !info.GetStringConfig("INCLUDE_DIR", IncludeDir_, true) ||
- !info.GetString("RCC_EXECUTABLE", RccExecutable_, true) ||
- !info.GetArray("RCC_LIST_OPTIONS", RccListOptions_, false) ||
- !info.GetString("LOCK_FILE", LockFile_, true) ||
- !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
- !info.GetString("SOURCE", QrcFile_, true) ||
- !info.GetString("OUTPUT_CHECKSUM", RccPathChecksum_, true) ||
- !info.GetString("OUTPUT_NAME", RccFileName_, true) ||
- !info.GetArray("OPTIONS", Options_, false) ||
- !info.GetArray("INPUTS", Inputs_, false)) {
+ if (!info.GetBool("MULTI_CONFIG", this->MultiConfig_, true) ||
+ !info.GetString("BUILD_DIR", this->AutogenBuildDir_, true) ||
+ !info.GetStringConfig("INCLUDE_DIR", this->IncludeDir_, true) ||
+ !info.GetString("RCC_EXECUTABLE", this->RccExecutable_, true) ||
+ !info.GetArray("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
+ !info.GetString("LOCK_FILE", this->LockFile_, true) ||
+ !info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) ||
+ !info.GetString("SOURCE", this->QrcFile_, true) ||
+ !info.GetString("OUTPUT_CHECKSUM", this->RccPathChecksum_, true) ||
+ !info.GetString("OUTPUT_NAME", this->RccFileName_, true) ||
+ !info.GetArray("OPTIONS", this->Options_, false) ||
+ !info.GetArray("INPUTS", this->Inputs_, false)) {
return false;
}
// -- Derive information
- QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_);
- QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_);
- RccFilePublic_ =
- cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_);
+ this->QrcFileName_ = cmSystemTools::GetFilenameName(this->QrcFile_);
+ this->QrcFileDir_ = cmSystemTools::GetFilenamePath(this->QrcFile_);
+ this->RccFilePublic_ =
+ cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '/',
+ this->RccFileName_);
// rcc output file name
- if (IsMultiConfig()) {
- RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput());
+ if (this->IsMultiConfig()) {
+ this->RccFileOutput_ =
+ cmStrCat(this->IncludeDir_, '/', this->MultiConfigOutput());
} else {
- RccFileOutput_ = RccFilePublic_;
+ this->RccFileOutput_ = this->RccFilePublic_;
}
// -- Checks
- if (!RccExecutableTime_.Load(RccExecutable_)) {
- return info.LogError(cmStrCat(
- "The rcc executable ", MessagePath(RccExecutable_), " does not exist."));
+ if (!this->RccExecutableTime_.Load(this->RccExecutable_)) {
+ return info.LogError(cmStrCat("The rcc executable ",
+ this->MessagePath(this->RccExecutable_),
+ " does not exist."));
}
return true;
@@ -132,41 +135,41 @@ bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
bool cmQtAutoRccT::Process()
{
- if (!SettingsFileRead()) {
+ if (!this->SettingsFileRead()) {
return false;
}
// Test if the rcc output needs to be regenerated
bool generate = false;
- if (!TestQrcRccFiles(generate)) {
+ if (!this->TestQrcRccFiles(generate)) {
return false;
}
- if (!generate && !TestResources(generate)) {
+ if (!generate && !this->TestResources(generate)) {
return false;
}
// Generate on demand
if (generate) {
- if (!GenerateRcc()) {
+ if (!this->GenerateRcc()) {
return false;
}
} else {
// Test if the info file is newer than the output file
- if (!TestInfoFile()) {
+ if (!this->TestInfoFile()) {
return false;
}
}
- if (!GenerateWrapper()) {
+ if (!this->GenerateWrapper()) {
return false;
}
- return SettingsFileWrite();
+ return this->SettingsFileWrite();
}
std::string cmQtAutoRccT::MultiConfigOutput() const
{
- return cmStrCat(RccPathChecksum_, '/',
- AppendFilenameSuffix(RccFileName_, "_CMAKE_"));
+ return cmStrCat(this->RccPathChecksum_, '/',
+ AppendFilenameSuffix(this->RccFileName_, "_CMAKE_"));
}
bool cmQtAutoRccT::SettingsFileRead()
@@ -178,23 +181,25 @@ bool cmQtAutoRccT::SettingsFileRead()
cryptoHash.Append(value);
cryptoHash.Append(";");
};
- cha(RccExecutable_);
- std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha);
- cha(QrcFile_);
- cha(RccPathChecksum_);
- cha(RccFileName_);
- std::for_each(Options_.begin(), Options_.end(), cha);
- std::for_each(Inputs_.begin(), Inputs_.end(), cha);
- SettingsString_ = cryptoHash.FinalizeHex();
+ cha(this->RccExecutable_);
+ std::for_each(this->RccListOptions_.begin(), this->RccListOptions_.end(),
+ cha);
+ cha(this->QrcFile_);
+ cha(this->RccPathChecksum_);
+ cha(this->RccFileName_);
+ std::for_each(this->Options_.begin(), this->Options_.end(), cha);
+ std::for_each(this->Inputs_.begin(), this->Inputs_.end(), cha);
+ this->SettingsString_ = cryptoHash.FinalizeHex();
}
// Make sure the settings file exists
- if (!cmSystemTools::FileExists(SettingsFile_, true)) {
+ if (!cmSystemTools::FileExists(this->SettingsFile_, true)) {
// Touch the settings file to make sure it exists
- if (!cmSystemTools::Touch(SettingsFile_, true)) {
- Log().Error(GenT::RCC,
- cmStrCat("Touching the settings file ",
- MessagePath(SettingsFile_), " failed."));
+ if (!cmSystemTools::Touch(this->SettingsFile_, true)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Touching the settings file ",
+ this->MessagePath(this->SettingsFile_),
+ " failed."));
return false;
}
}
@@ -202,21 +207,23 @@ bool cmQtAutoRccT::SettingsFileRead()
// Lock the lock file
{
// Make sure the lock file exists
- if (!cmSystemTools::FileExists(LockFile_, true)) {
- if (!cmSystemTools::Touch(LockFile_, true)) {
- Log().Error(GenT::RCC,
- cmStrCat("Touching the lock file ", MessagePath(LockFile_),
- " failed."));
+ if (!cmSystemTools::FileExists(this->LockFile_, true)) {
+ if (!cmSystemTools::Touch(this->LockFile_, true)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Touching the lock file ",
+ this->MessagePath(this->LockFile_),
+ " failed."));
return false;
}
}
// Lock the lock file
- cmFileLockResult lockResult =
- LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1));
+ cmFileLockResult lockResult = this->LockFileLock_.Lock(
+ this->LockFile_, static_cast<unsigned long>(-1));
if (!lockResult.IsOk()) {
- Log().Error(GenT::RCC,
- cmStrCat("Locking of the lock file ", MessagePath(LockFile_),
- " failed.\n", lockResult.GetOutputMessage()));
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Locking of the lock file ",
+ this->MessagePath(this->LockFile_),
+ " failed.\n", lockResult.GetOutputMessage()));
return false;
}
}
@@ -224,23 +231,24 @@ bool cmQtAutoRccT::SettingsFileRead()
// Read old settings
{
std::string content;
- if (FileRead(content, SettingsFile_)) {
- SettingsChanged_ = (SettingsString_ != SettingsFind(content, "rcc"));
+ if (FileRead(content, this->SettingsFile_)) {
+ this->SettingsChanged_ =
+ (this->SettingsString_ != SettingsFind(content, "rcc"));
// In case any setting changed clear the old settings file.
// This triggers a full rebuild on the next run if the current
// build is aborted before writing the current settings in the end.
- if (SettingsChanged_) {
+ if (this->SettingsChanged_) {
std::string error;
- if (!FileWrite(SettingsFile_, "", &error)) {
- Log().Error(GenT::RCC,
- cmStrCat("Clearing of the settings file ",
- MessagePath(SettingsFile_), " failed.\n",
- error));
+ if (!FileWrite(this->SettingsFile_, "", &error)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Clearing of the settings file ",
+ this->MessagePath(this->SettingsFile_),
+ " failed.\n", error));
return false;
}
}
} else {
- SettingsChanged_ = true;
+ this->SettingsChanged_ = true;
}
}
@@ -250,26 +258,28 @@ bool cmQtAutoRccT::SettingsFileRead()
bool cmQtAutoRccT::SettingsFileWrite()
{
// Only write if any setting changed
- if (SettingsChanged_) {
- if (Log().Verbose()) {
- Log().Info(GenT::RCC,
- "Writing settings file " + MessagePath(SettingsFile_));
+ if (this->SettingsChanged_) {
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::RCC,
+ "Writing settings file " +
+ this->MessagePath(this->SettingsFile_));
}
// Write settings file
- std::string content = cmStrCat("rcc:", SettingsString_, '\n');
+ std::string content = cmStrCat("rcc:", this->SettingsString_, '\n');
std::string error;
- if (!FileWrite(SettingsFile_, content, &error)) {
- Log().Error(GenT::RCC,
- cmStrCat("Writing of the settings file ",
- MessagePath(SettingsFile_), " failed.\n", error));
+ if (!FileWrite(this->SettingsFile_, content, &error)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Writing of the settings file ",
+ this->MessagePath(this->SettingsFile_),
+ " failed.\n", error));
// Remove old settings file to trigger a full rebuild on the next run
- cmSystemTools::RemoveFile(SettingsFile_);
+ cmSystemTools::RemoveFile(this->SettingsFile_);
return false;
}
}
// Unlock the lock file
- LockFileLock_.Release();
+ this->LockFileLock_.Release();
return true;
}
@@ -277,52 +287,57 @@ bool cmQtAutoRccT::SettingsFileWrite()
bool cmQtAutoRccT::TestQrcRccFiles(bool& generate)
{
// Test if the rcc input file exists
- if (!QrcFileTime_.Load(QrcFile_)) {
- Log().Error(GenT::RCC,
- cmStrCat("The resources file ", MessagePath(QrcFile_),
- " does not exist"));
+ if (!this->QrcFileTime_.Load(this->QrcFile_)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("The resources file ",
+ this->MessagePath(this->QrcFile_),
+ " does not exist"));
return false;
}
// Test if the rcc output file exists
- if (!RccFileTime_.Load(RccFileOutput_)) {
- if (Log().Verbose()) {
- Reason =
- cmStrCat("Generating ", MessagePath(RccFileOutput_),
- ", because it doesn't exist, from ", MessagePath(QrcFile_));
+ if (!this->RccFileTime_.Load(this->RccFileOutput_)) {
+ if (this->Log().Verbose()) {
+ this->Reason =
+ cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
+ ", because it doesn't exist, from ",
+ this->MessagePath(this->QrcFile_));
}
generate = true;
return true;
}
// Test if the settings changed
- if (SettingsChanged_) {
- if (Log().Verbose()) {
- Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
- ", because the rcc settings changed, from ",
- MessagePath(QrcFile_));
+ if (this->SettingsChanged_) {
+ if (this->Log().Verbose()) {
+ this->Reason =
+ cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
+ ", because the rcc settings changed, from ",
+ this->MessagePath(this->QrcFile_));
}
generate = true;
return true;
}
// Test if the rcc output file is older than the .qrc file
- if (RccFileTime_.Older(QrcFileTime_)) {
- if (Log().Verbose()) {
- Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
- ", because it is older than ", MessagePath(QrcFile_),
- ", from ", MessagePath(QrcFile_));
+ if (this->RccFileTime_.Older(this->QrcFileTime_)) {
+ if (this->Log().Verbose()) {
+ this->Reason = cmStrCat(
+ "Generating ", this->MessagePath(this->RccFileOutput_),
+ ", because it is older than ", this->MessagePath(this->QrcFile_),
+ ", from ", this->MessagePath(this->QrcFile_));
}
generate = true;
return true;
}
// Test if the rcc output file is older than the rcc executable
- if (RccFileTime_.Older(RccExecutableTime_)) {
- if (Log().Verbose()) {
- Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
- ", because it is older than the rcc executable, from ",
- MessagePath(QrcFile_));
+ if (this->RccFileTime_.Older(this->RccExecutableTime_)) {
+ if (this->Log().Verbose()) {
+ this->Reason =
+ cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
+ ", because it is older than the rcc executable, from ",
+ this->MessagePath(this->QrcFile_));
}
generate = true;
return true;
@@ -334,34 +349,38 @@ bool cmQtAutoRccT::TestQrcRccFiles(bool& generate)
bool cmQtAutoRccT::TestResources(bool& generate)
{
// Read resource files list
- if (Inputs_.empty()) {
+ if (this->Inputs_.empty()) {
std::string error;
- RccLister const lister(RccExecutable_, RccListOptions_);
- if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) {
- Log().Error(
- GenT::RCC,
- cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error));
+ RccLister const lister(this->RccExecutable_, this->RccListOptions_);
+ if (!lister.list(this->QrcFile_, this->Inputs_, error,
+ this->Log().Verbose())) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Listing of ",
+ this->MessagePath(this->QrcFile_),
+ " failed.\n", error));
return false;
}
}
// Check if any resource file is newer than the rcc output file
- for (std::string const& resFile : Inputs_) {
+ for (std::string const& resFile : this->Inputs_) {
// Check if the resource file exists
cmFileTime fileTime;
if (!fileTime.Load(resFile)) {
- Log().Error(GenT::RCC,
- cmStrCat("The resource file ", MessagePath(resFile),
- " listed in ", MessagePath(QrcFile_),
- " does not exist."));
+ this->Log().Error(GenT::RCC,
+ cmStrCat("The resource file ",
+ this->MessagePath(resFile), " listed in ",
+ this->MessagePath(this->QrcFile_),
+ " does not exist."));
return false;
}
// Check if the resource file is newer than the rcc output file
- if (RccFileTime_.Older(fileTime)) {
- if (Log().Verbose()) {
- Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
- ", because it is older than ", MessagePath(resFile),
- ", from ", MessagePath(QrcFile_));
+ if (this->RccFileTime_.Older(fileTime)) {
+ if (this->Log().Verbose()) {
+ this->Reason =
+ cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
+ ", because it is older than ", this->MessagePath(resFile),
+ ", from ", this->MessagePath(this->QrcFile_));
}
generate = true;
break;
@@ -373,21 +392,23 @@ bool cmQtAutoRccT::TestResources(bool& generate)
bool cmQtAutoRccT::TestInfoFile()
{
// Test if the rcc output file is older than the info file
- if (RccFileTime_.Older(InfoFileTime())) {
- if (Log().Verbose()) {
- Log().Info(GenT::RCC,
- cmStrCat("Touching ", MessagePath(RccFileOutput_),
- " because it is older than ",
- MessagePath(InfoFile())));
+ if (this->RccFileTime_.Older(this->InfoFileTime())) {
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::RCC,
+ cmStrCat("Touching ",
+ this->MessagePath(this->RccFileOutput_),
+ " because it is older than ",
+ this->MessagePath(this->InfoFile())));
}
// Touch build file
- if (!cmSystemTools::Touch(RccFileOutput_, false)) {
- Log().Error(
- GenT::RCC,
- cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed."));
+ if (!cmSystemTools::Touch(this->RccFileOutput_, false)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Touching ",
+ this->MessagePath(this->RccFileOutput_),
+ " failed."));
return false;
}
- BuildFileChanged_ = true;
+ this->BuildFileChanged_ = true;
}
return true;
@@ -396,51 +417,53 @@ bool cmQtAutoRccT::TestInfoFile()
bool cmQtAutoRccT::GenerateRcc()
{
// Make parent directory
- if (!MakeParentDirectory(RccFileOutput_)) {
- Log().Error(GenT::RCC,
- cmStrCat("Could not create parent directory of ",
- MessagePath(RccFileOutput_)));
+ if (!MakeParentDirectory(this->RccFileOutput_)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Could not create parent directory of ",
+ this->MessagePath(this->RccFileOutput_)));
return false;
}
// Compose rcc command
std::vector<std::string> cmd;
- cmd.push_back(RccExecutable_);
- cm::append(cmd, Options_);
+ cmd.push_back(this->RccExecutable_);
+ cm::append(cmd, this->Options_);
cmd.emplace_back("-o");
- cmd.push_back(RccFileOutput_);
- cmd.push_back(QrcFile_);
+ cmd.push_back(this->RccFileOutput_);
+ cmd.push_back(this->QrcFile_);
// Log reason and command
- if (Log().Verbose()) {
- Log().Info(GenT::RCC,
- cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n",
- QuotedCommand(cmd), '\n'));
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::RCC,
+ cmStrCat(this->Reason,
+ cmHasSuffix(this->Reason, '\n') ? "" : "\n",
+ QuotedCommand(cmd), '\n'));
}
std::string rccStdOut;
std::string rccStdErr;
int retVal = 0;
bool result = cmSystemTools::RunSingleCommand(
- cmd, &rccStdOut, &rccStdErr, &retVal, AutogenBuildDir_.c_str(),
+ cmd, &rccStdOut, &rccStdErr, &retVal, this->AutogenBuildDir_.c_str(),
cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
if (!result || (retVal != 0)) {
// rcc process failed
- Log().ErrorCommand(GenT::RCC,
- cmStrCat("The rcc process failed to compile\n ",
- MessagePath(QrcFile_), "\ninto\n ",
- MessagePath(RccFileOutput_)),
- cmd, rccStdOut + rccStdErr);
- cmSystemTools::RemoveFile(RccFileOutput_);
+ this->Log().ErrorCommand(GenT::RCC,
+ cmStrCat("The rcc process failed to compile\n ",
+ this->MessagePath(this->QrcFile_),
+ "\ninto\n ",
+ this->MessagePath(this->RccFileOutput_)),
+ cmd, rccStdOut + rccStdErr);
+ cmSystemTools::RemoveFile(this->RccFileOutput_);
return false;
}
// rcc process success
// Print rcc output
if (!rccStdOut.empty()) {
- Log().Info(GenT::RCC, rccStdOut);
+ this->Log().Info(GenT::RCC, rccStdOut);
}
- BuildFileChanged_ = true;
+ this->BuildFileChanged_ = true;
return true;
}
@@ -448,47 +471,48 @@ bool cmQtAutoRccT::GenerateRcc()
bool cmQtAutoRccT::GenerateWrapper()
{
// Generate a wrapper source file on demand
- if (IsMultiConfig()) {
+ if (this->IsMultiConfig()) {
// Wrapper file content
std::string content =
cmStrCat("// This is an autogenerated configuration wrapper file.\n",
"// Changes will be overwritten.\n", "#include <",
- MultiConfigOutput(), ">\n");
+ this->MultiConfigOutput(), ">\n");
// Compare with existing file content
bool fileDiffers = true;
{
std::string oldContents;
- if (FileRead(oldContents, RccFilePublic_)) {
+ if (FileRead(oldContents, this->RccFilePublic_)) {
fileDiffers = (oldContents != content);
}
}
if (fileDiffers) {
// Write new wrapper file
- if (Log().Verbose()) {
- Log().Info(GenT::RCC,
- cmStrCat("Generating RCC wrapper file ",
- MessagePath(RccFilePublic_)));
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::RCC,
+ cmStrCat("Generating RCC wrapper file ",
+ this->MessagePath(this->RccFilePublic_)));
}
std::string error;
- if (!FileWrite(RccFilePublic_, content, &error)) {
- Log().Error(GenT::RCC,
- cmStrCat("Generating RCC wrapper file ",
- MessagePath(RccFilePublic_), " failed.\n",
- error));
+ if (!FileWrite(this->RccFilePublic_, content, &error)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Generating RCC wrapper file ",
+ this->MessagePath(this->RccFilePublic_),
+ " failed.\n", error));
return false;
}
- } else if (BuildFileChanged_) {
+ } else if (this->BuildFileChanged_) {
// Just touch the wrapper file
- if (Log().Verbose()) {
- Log().Info(
- GenT::RCC,
- cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_)));
+ if (this->Log().Verbose()) {
+ this->Log().Info(GenT::RCC,
+ cmStrCat("Touching RCC wrapper file ",
+ this->MessagePath(this->RccFilePublic_)));
}
- if (!cmSystemTools::Touch(RccFilePublic_, false)) {
- Log().Error(GenT::RCC,
- cmStrCat("Touching RCC wrapper file ",
- MessagePath(RccFilePublic_), " failed."));
+ if (!cmSystemTools::Touch(this->RccFilePublic_, false)) {
+ this->Log().Error(GenT::RCC,
+ cmStrCat("Touching RCC wrapper file ",
+ this->MessagePath(this->RccFilePublic_),
+ " failed."));
return false;
}
}
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index f5f9c67..d00bbdf 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -3,7 +3,6 @@
#include "cmRulePlaceholderExpander.h"
#include <cctype>
-#include <cstring>
#include <utility>
#include "cmOutputConverter.h"
@@ -20,11 +19,6 @@ cmRulePlaceholderExpander::cmRulePlaceholderExpander(
{
}
-cmRulePlaceholderExpander::RuleVariables::RuleVariables()
-{
- memset(this, 0, sizeof(*this));
-}
-
std::string cmRulePlaceholderExpander::ExpandRuleVariable(
cmOutputConverter* outputConverter, std::string const& variable,
const RuleVariables& replaceValues)
@@ -50,6 +44,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.Source;
}
}
+ if (replaceValues.DynDepFile) {
+ if (variable == "DYNDEP_FILE") {
+ return replaceValues.DynDepFile;
+ }
+ }
if (replaceValues.PreprocessedSource) {
if (variable == "PREPROCESSED_SOURCE") {
return replaceValues.PreprocessedSource;
@@ -141,6 +140,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.DependencyFile;
}
}
+ if (replaceValues.DependencyTarget) {
+ if (variable == "DEP_TARGET") {
+ return replaceValues.DependencyTarget;
+ }
+ }
if (replaceValues.Fatbinary) {
if (variable == "FATBINARY") {
return replaceValues.Fatbinary;
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index c8d107d..f8dc368 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -27,45 +27,46 @@ public:
// ExpandRuleVariables
struct RuleVariables
{
- RuleVariables();
- const char* CMTargetName;
- const char* CMTargetType;
- const char* TargetPDB;
- const char* TargetCompilePDB;
- const char* TargetVersionMajor;
- const char* TargetVersionMinor;
- const char* Language;
- const char* AIXExports;
- const char* Objects;
- const char* Target;
- const char* LinkLibraries;
- const char* Source;
- const char* AssemblySource;
- const char* PreprocessedSource;
- const char* Output;
- const char* Object;
- const char* ObjectDir;
- const char* ObjectFileDir;
- const char* Flags;
- const char* ObjectsQuoted;
- const char* SONameFlag;
- const char* TargetSOName;
- const char* TargetInstallNameDir;
- const char* LinkFlags;
- const char* Manifests;
- const char* LanguageCompileFlags;
- const char* Defines;
- const char* Includes;
- const char* DependencyFile;
- const char* FilterPrefix;
- const char* SwiftLibraryName;
- const char* SwiftModule;
- const char* SwiftModuleName;
- const char* SwiftOutputFileMap;
- const char* SwiftSources;
- const char* ISPCHeader;
- const char* Fatbinary;
- const char* RegisterFile;
+ const char* CMTargetName = nullptr;
+ const char* CMTargetType = nullptr;
+ const char* TargetPDB = nullptr;
+ const char* TargetCompilePDB = nullptr;
+ const char* TargetVersionMajor = nullptr;
+ const char* TargetVersionMinor = nullptr;
+ const char* Language = nullptr;
+ const char* AIXExports = nullptr;
+ const char* Objects = nullptr;
+ const char* Target = nullptr;
+ const char* LinkLibraries = nullptr;
+ const char* Source = nullptr;
+ const char* AssemblySource = nullptr;
+ const char* PreprocessedSource = nullptr;
+ const char* DynDepFile = nullptr;
+ const char* Output = nullptr;
+ const char* Object = nullptr;
+ const char* ObjectDir = nullptr;
+ const char* ObjectFileDir = nullptr;
+ const char* Flags = nullptr;
+ const char* ObjectsQuoted = nullptr;
+ const char* SONameFlag = nullptr;
+ const char* TargetSOName = nullptr;
+ const char* TargetInstallNameDir = nullptr;
+ const char* LinkFlags = nullptr;
+ const char* Manifests = nullptr;
+ const char* LanguageCompileFlags = nullptr;
+ const char* Defines = nullptr;
+ const char* Includes = nullptr;
+ const char* DependencyFile = nullptr;
+ const char* DependencyTarget = nullptr;
+ const char* FilterPrefix = nullptr;
+ const char* SwiftLibraryName = nullptr;
+ const char* SwiftModule = nullptr;
+ const char* SwiftModuleName = nullptr;
+ const char* SwiftOutputFileMap = nullptr;
+ const char* SwiftSources = nullptr;
+ const char* ISPCHeader = nullptr;
+ const char* Fatbinary = nullptr;
+ const char* RegisterFile = nullptr;
};
// Expand rule variables in CMake of the type found in language rules
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx
new file mode 100644
index 0000000..e046069
--- /dev/null
+++ b/Source/cmScanDepFormat.cxx
@@ -0,0 +1,265 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmScanDepFormat.h"
+
+#include <cctype>
+#include <cstdio>
+
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+static bool ParseFilename(Json::Value const& val, std::string& result)
+{
+ if (val.isString()) {
+ result = val.asString();
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static Json::Value EncodeFilename(std::string const& path)
+{
+ std::string data;
+ data.reserve(path.size());
+
+ for (auto const& byte : path) {
+ if (std::iscntrl(byte)) {
+ // Control characters.
+ data.append("\\u");
+ char buf[5];
+ std::snprintf(buf, sizeof(buf), "%04x", byte);
+ data.append(buf);
+ } else if (byte == '"' || byte == '\\') {
+ // Special JSON characters.
+ data.push_back('\\');
+ data.push_back(byte);
+ } else {
+ // Other data.
+ data.push_back(byte);
+ }
+ }
+
+ return data;
+}
+
+#define PARSE_BLOB(val, res) \
+ do { \
+ if (!ParseFilename(val, res)) { \
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \
+ arg_pp, ": invalid blob")); \
+ return false; \
+ } \
+ } while (0)
+
+#define PARSE_FILENAME(val, res) \
+ do { \
+ if (!ParseFilename(val, res)) { \
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \
+ arg_pp, ": invalid filename")); \
+ return false; \
+ } \
+ \
+ if (!cmSystemTools::FileIsFullPath(res)) { \
+ res = cmStrCat(work_directory, '/', res); \
+ } \
+ } while (0)
+
+bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info)
+{
+ Json::Value ppio;
+ Json::Value const& ppi = ppio;
+ cmsys::ifstream ppf(arg_pp.c_str(), std::ios::in | std::ios::binary);
+ {
+ Json::Reader reader;
+ if (!reader.parse(ppf, ppio, false)) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_pp,
+ reader.getFormattedErrorMessages()));
+ return false;
+ }
+ }
+
+ Json::Value const& version = ppi["version"];
+ if (version.asUInt() != 0) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_pp, ": version ", version.asString()));
+ return false;
+ }
+
+ Json::Value const& rules = ppi["rules"];
+ if (rules.isArray()) {
+ if (rules.size() != 1) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_pp, ": expected 1 source entry"));
+ return false;
+ }
+
+ for (auto const& rule : rules) {
+ Json::Value const& workdir = rule["work-directory"];
+ if (!workdir.isString()) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_pp,
+ ": work-directory is not a string"));
+ return false;
+ }
+ std::string work_directory;
+ PARSE_BLOB(workdir, work_directory);
+
+ Json::Value const& depends = rule["depends"];
+ if (depends.isArray()) {
+ std::string depend_filename;
+ for (auto const& depend : depends) {
+ PARSE_FILENAME(depend, depend_filename);
+ info->Includes.push_back(depend_filename);
+ }
+ }
+
+ if (rule.isMember("future-compile")) {
+ Json::Value const& future_compile = rule["future-compile"];
+
+ if (future_compile.isMember("outputs")) {
+ Json::Value const& outputs = future_compile["outputs"];
+ if (outputs.isArray()) {
+ if (outputs.empty()) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
+ ": expected at least one 1 output"));
+ return false;
+ }
+
+ PARSE_FILENAME(outputs[0], info->PrimaryOutput);
+ }
+ }
+
+ if (future_compile.isMember("provides")) {
+ Json::Value const& provides = future_compile["provides"];
+ if (provides.isArray()) {
+ for (auto const& provide : provides) {
+ cmSourceReqInfo provide_info;
+
+ Json::Value const& logical_name = provide["logical-name"];
+ PARSE_BLOB(logical_name, provide_info.LogicalName);
+
+ if (provide.isMember("compiled-module-path")) {
+ Json::Value const& compiled_module_path =
+ provide["compiled-module-path"];
+ PARSE_FILENAME(compiled_module_path,
+ provide_info.CompiledModulePath);
+ } else {
+ provide_info.CompiledModulePath =
+ cmStrCat(provide_info.LogicalName, ".mod");
+ }
+
+ info->Provides.push_back(provide_info);
+ }
+ }
+ }
+
+ if (future_compile.isMember("requires")) {
+ Json::Value const& reqs = future_compile["requires"];
+ if (reqs.isArray()) {
+ for (auto const& require : reqs) {
+ cmSourceReqInfo require_info;
+
+ Json::Value const& logical_name = require["logical-name"];
+ PARSE_BLOB(logical_name, require_info.LogicalName);
+
+ if (require.isMember("compiled-module-path")) {
+ Json::Value const& compiled_module_path =
+ require["compiled-module-path"];
+ PARSE_FILENAME(compiled_module_path,
+ require_info.CompiledModulePath);
+ }
+
+ info->Requires.push_back(require_info);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool cmScanDepFormat_P1689_Write(std::string const& path,
+ std::string const& input,
+ cmSourceInfo const& info)
+{
+ Json::Value ddi(Json::objectValue);
+ ddi["version"] = 0;
+ ddi["revision"] = 0;
+
+ Json::Value& rules = ddi["rules"] = Json::arrayValue;
+
+ Json::Value rule(Json::objectValue);
+ rule["work-directory"] =
+ EncodeFilename(cmSystemTools::GetCurrentWorkingDirectory());
+ Json::Value& inputs = rule["inputs"] = Json::arrayValue;
+ inputs.append(EncodeFilename(input));
+
+ Json::Value& rule_outputs = rule["outputs"] = Json::arrayValue;
+ rule_outputs.append(EncodeFilename(path));
+
+ Json::Value& depends = rule["depends"] = Json::arrayValue;
+ for (auto const& include : info.Includes) {
+ depends.append(EncodeFilename(include));
+ }
+
+ Json::Value& future_compile = rule["future-compile"] = Json::objectValue;
+
+ Json::Value& outputs = future_compile["outputs"] = Json::arrayValue;
+ outputs.append(info.PrimaryOutput);
+
+ Json::Value& provides = future_compile["provides"] = Json::arrayValue;
+ for (auto const& provide : info.Provides) {
+ Json::Value provide_obj(Json::objectValue);
+ auto const encoded = EncodeFilename(provide.LogicalName);
+ provide_obj["logical-name"] = encoded;
+ if (provide.CompiledModulePath.empty()) {
+ provide_obj["compiled-module-path"] = encoded;
+ } else {
+ provide_obj["compiled-module-path"] =
+ EncodeFilename(provide.CompiledModulePath);
+ }
+
+ // TODO: Source file tracking. See below.
+
+ provides.append(provide_obj);
+ }
+
+ Json::Value& reqs = future_compile["requires"] = Json::arrayValue;
+ for (auto const& require : info.Requires) {
+ Json::Value require_obj(Json::objectValue);
+ auto const encoded = EncodeFilename(require.LogicalName);
+ require_obj["logical-name"] = encoded;
+ if (require.CompiledModulePath.empty()) {
+ require_obj["compiled-module-path"] = encoded;
+ } else {
+ require_obj["compiled-module-path"] =
+ EncodeFilename(require.CompiledModulePath);
+ }
+
+ // TODO: Source filename inclusion. Requires collating with the provides
+ // filenames (as a sanity check if available on both sides).
+
+ reqs.append(require_obj);
+ }
+
+ rules.append(rule);
+
+ cmGeneratedFileStream ddif(path);
+ ddif << ddi;
+
+ return !!ddif;
+}
diff --git a/Source/cmScanDepFormat.h b/Source/cmScanDepFormat.h
new file mode 100644
index 0000000..1ad0ecf
--- /dev/null
+++ b/Source/cmScanDepFormat.h
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+#include <vector>
+
+struct cmSourceReqInfo
+{
+ std::string LogicalName;
+ std::string CompiledModulePath;
+};
+
+struct cmSourceInfo
+{
+ std::string PrimaryOutput;
+
+ // Set of provided and required modules.
+ std::vector<cmSourceReqInfo> Provides;
+ std::vector<cmSourceReqInfo> Requires;
+
+ // Set of files included in the translation unit.
+ std::vector<std::string> Includes;
+};
+
+bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
+ cmSourceInfo* info);
+bool cmScanDepFormat_P1689_Write(std::string const& path,
+ std::string const& input,
+ cmSourceInfo const& info);
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
deleted file mode 100644
index 7f97406..0000000
--- a/Source/cmServer.cxx
+++ /dev/null
@@ -1,570 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmServer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <csignal>
-#include <cstdint>
-#include <iostream>
-#include <mutex>
-#include <utility>
-
-#include <cm/memory>
-#include <cm/shared_mutex>
-
-#include <cm3p/json/reader.h>
-#include <cm3p/json/writer.h>
-
-#include "cmsys/FStream.hxx"
-
-#include "cmConnection.h"
-#include "cmFileMonitor.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmServerDictionary.h"
-#include "cmServerProtocol.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-void on_signal(uv_signal_t* signal, int signum)
-{
- auto conn = static_cast<cmServerBase*>(signal->data);
- conn->OnSignal(signum);
-}
-
-static void on_walk_to_shutdown(uv_handle_t* handle, void* arg)
-{
- (void)arg;
- assert(uv_is_closing(handle));
- if (!uv_is_closing(handle)) {
- uv_close(handle, &cmEventBasedConnection::on_close);
- }
-}
-
-class cmServer::DebugInfo
-{
-public:
- DebugInfo()
- : StartTime(uv_hrtime())
- {
- }
-
- bool PrintStatistics = false;
-
- std::string OutputFile;
- uint64_t StartTime;
-};
-
-cmServer::cmServer(cmConnection* conn, bool supportExperimental)
- : cmServerBase(conn)
- , SupportExperimental(supportExperimental)
-{
- // Register supported protocols:
- this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
-}
-
-cmServer::~cmServer()
-{
- Close();
-}
-
-void cmServer::ProcessRequest(cmConnection* connection,
- const std::string& input)
-{
- Json::Reader reader;
- Json::Value value;
- if (!reader.parse(input, value)) {
- this->WriteParseError(connection, "Failed to parse JSON input.");
- return;
- }
-
- std::unique_ptr<DebugInfo> debug;
- Json::Value debugValue = value["debug"];
- if (!debugValue.isNull()) {
- debug = cm::make_unique<DebugInfo>();
- debug->OutputFile = debugValue["dumpToFile"].asString();
- debug->PrintStatistics = debugValue["showStats"].asBool();
- }
-
- const cmServerRequest request(this, connection, value[kTYPE_KEY].asString(),
- value[kCOOKIE_KEY].asString(), value);
-
- if (request.Type.empty()) {
- cmServerResponse response(request);
- response.SetError("No type given in request.");
- this->WriteResponse(connection, response, nullptr);
- return;
- }
-
- cmSystemTools::SetMessageCallback(
- [&request](const std::string& msg, const char* title) {
- reportMessage(msg, title, request);
- });
-
- if (this->Protocol) {
- this->Protocol->CMakeInstance()->SetProgressCallback(
- [&request](const std::string& msg, float prog) {
- reportProgress(msg, prog, request);
- });
- this->WriteResponse(connection, this->Protocol->Process(request),
- debug.get());
- } else {
- this->WriteResponse(connection, this->SetProtocolVersion(request),
- debug.get());
- }
-}
-
-void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
-{
- if (protocol->IsExperimental() && !this->SupportExperimental) {
- protocol.reset();
- return;
- }
- auto version = protocol->ProtocolVersion();
- assert(version.first >= 0);
- assert(version.second >= 0);
- auto it = std::find_if(
- this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
- [version](const std::unique_ptr<cmServerProtocol>& p) {
- return p->ProtocolVersion() == version;
- });
- if (it == this->SupportedProtocols.end()) {
- this->SupportedProtocols.push_back(std::move(protocol));
- }
-}
-
-void cmServer::PrintHello(cmConnection* connection) const
-{
- Json::Value hello = Json::objectValue;
- hello[kTYPE_KEY] = "hello";
-
- Json::Value& protocolVersions = hello[kSUPPORTED_PROTOCOL_VERSIONS] =
- Json::arrayValue;
-
- for (auto const& proto : this->SupportedProtocols) {
- auto version = proto->ProtocolVersion();
- Json::Value tmp = Json::objectValue;
- tmp[kMAJOR_KEY] = version.first;
- tmp[kMINOR_KEY] = version.second;
- if (proto->IsExperimental()) {
- tmp[kIS_EXPERIMENTAL_KEY] = true;
- }
- protocolVersions.append(tmp);
- }
-
- this->WriteJsonObject(connection, hello, nullptr);
-}
-
-void cmServer::reportProgress(const std::string& msg, float progress,
- const cmServerRequest& request)
-{
- if (progress < 0.0f || progress > 1.0f) {
- request.ReportMessage(msg, "");
- } else {
- request.ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg);
- }
-}
-
-void cmServer::reportMessage(const std::string& msg, const char* title,
- const cmServerRequest& request)
-{
- std::string titleString;
- if (title) {
- titleString = title;
- }
- request.ReportMessage(msg, titleString);
-}
-
-cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
-{
- if (request.Type != kHANDSHAKE_TYPE) {
- return request.ReportError("Waiting for type \"" + kHANDSHAKE_TYPE +
- "\".");
- }
-
- Json::Value requestedProtocolVersion = request.Data[kPROTOCOL_VERSION_KEY];
- if (requestedProtocolVersion.isNull()) {
- return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
- "\" is required for \"" + kHANDSHAKE_TYPE +
- "\".");
- }
-
- if (!requestedProtocolVersion.isObject()) {
- return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
- "\" must be a JSON object.");
- }
-
- Json::Value majorValue = requestedProtocolVersion[kMAJOR_KEY];
- if (!majorValue.isInt()) {
- return request.ReportError("\"" + kMAJOR_KEY +
- "\" must be set and an integer.");
- }
-
- Json::Value minorValue = requestedProtocolVersion[kMINOR_KEY];
- if (!minorValue.isNull() && !minorValue.isInt()) {
- return request.ReportError("\"" + kMINOR_KEY +
- "\" must be unset or an integer.");
- }
-
- const int major = majorValue.asInt();
- const int minor = minorValue.isNull() ? -1 : minorValue.asInt();
- if (major < 0) {
- return request.ReportError("\"" + kMAJOR_KEY + "\" must be >= 0.");
- }
- if (!minorValue.isNull() && minor < 0) {
- return request.ReportError("\"" + kMINOR_KEY +
- "\" must be >= 0 when set.");
- }
-
- this->Protocol =
- cmServer::FindMatchingProtocol(this->SupportedProtocols, major, minor);
- if (!this->Protocol) {
- return request.ReportError("Protocol version not supported.");
- }
-
- std::string errorMessage;
- if (!this->Protocol->Activate(this, request, &errorMessage)) {
- this->Protocol = nullptr;
- return request.ReportError("Failed to activate protocol version: " +
- errorMessage);
- }
- return request.Reply(Json::objectValue);
-}
-
-bool cmServer::Serve(std::string* errorMessage)
-{
- if (this->SupportedProtocols.empty()) {
- *errorMessage =
- "No protocol versions defined. Maybe you need --experimental?";
- return false;
- }
- assert(!this->Protocol);
-
- return cmServerBase::Serve(errorMessage);
-}
-
-cmFileMonitor* cmServer::FileMonitor() const
-{
- return fileMonitor.get();
-}
-
-void cmServer::WriteJsonObject(const Json::Value& jsonValue,
- const DebugInfo* debug) const
-{
- cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : this->Connections) {
- WriteJsonObject(connection.get(), jsonValue, debug);
- }
-}
-
-void cmServer::WriteJsonObject(cmConnection* connection,
- const Json::Value& jsonValue,
- const DebugInfo* debug) const
-{
- Json::FastWriter writer;
-
- auto beforeJson = uv_hrtime();
- std::string result = writer.write(jsonValue);
-
- if (debug) {
- Json::Value copy = jsonValue;
- if (debug->PrintStatistics) {
- Json::Value stats = Json::objectValue;
- auto endTime = uv_hrtime();
-
- stats["jsonSerialization"] = double(endTime - beforeJson) / 1000000.0;
- stats["totalTime"] = double(endTime - debug->StartTime) / 1000000.0;
- stats["size"] = static_cast<int>(result.size());
- if (!debug->OutputFile.empty()) {
- stats["dumpFile"] = debug->OutputFile;
- }
-
- copy["zzzDebug"] = stats;
-
- result = writer.write(copy); // Update result to include debug info
- }
-
- if (!debug->OutputFile.empty()) {
- cmsys::ofstream myfile(debug->OutputFile.c_str());
- myfile << result;
- }
- }
-
- connection->WriteData(result);
-}
-
-cmServerProtocol* cmServer::FindMatchingProtocol(
- const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
- int minor)
-{
- cmServerProtocol* bestMatch = nullptr;
- for (const auto& protocol : protocols) {
- auto version = protocol->ProtocolVersion();
- if (major != version.first) {
- continue;
- }
- if (minor == version.second) {
- return protocol.get();
- }
- if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
- bestMatch = protocol.get();
- }
- }
- return minor < 0 ? bestMatch : nullptr;
-}
-
-void cmServer::WriteProgress(const cmServerRequest& request, int min,
- int current, int max,
- const std::string& message) const
-{
- assert(min <= current && current <= max);
- assert(message.length() != 0);
-
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kPROGRESS_TYPE;
- obj[kREPLY_TO_KEY] = request.Type;
- obj[kCOOKIE_KEY] = request.Cookie;
- obj[kPROGRESS_MESSAGE_KEY] = message;
- obj[kPROGRESS_MINIMUM_KEY] = min;
- obj[kPROGRESS_MAXIMUM_KEY] = max;
- obj[kPROGRESS_CURRENT_KEY] = current;
-
- this->WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteMessage(const cmServerRequest& request,
- const std::string& message,
- const std::string& title) const
-{
- if (message.empty()) {
- return;
- }
-
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kMESSAGE_TYPE;
- obj[kREPLY_TO_KEY] = request.Type;
- obj[kCOOKIE_KEY] = request.Cookie;
- obj[kMESSAGE_KEY] = message;
- if (!title.empty()) {
- obj[kTITLE_KEY] = title;
- }
-
- WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteParseError(cmConnection* connection,
- const std::string& message) const
-{
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = kERROR_TYPE;
- obj[kERROR_MESSAGE_KEY] = message;
- obj[kREPLY_TO_KEY] = "";
- obj[kCOOKIE_KEY] = "";
-
- this->WriteJsonObject(connection, obj, nullptr);
-}
-
-void cmServer::WriteSignal(const std::string& name,
- const Json::Value& data) const
-{
- assert(data.isObject());
- Json::Value obj = data;
- obj[kTYPE_KEY] = kSIGNAL_TYPE;
- obj[kREPLY_TO_KEY] = "";
- obj[kCOOKIE_KEY] = "";
- obj[kNAME_KEY] = name;
-
- WriteJsonObject(obj, nullptr);
-}
-
-void cmServer::WriteResponse(cmConnection* connection,
- const cmServerResponse& response,
- const DebugInfo* debug) const
-{
- assert(response.IsComplete());
-
- Json::Value obj = response.Data();
- obj[kCOOKIE_KEY] = response.Cookie;
- obj[kTYPE_KEY] = response.IsError() ? kERROR_TYPE : kREPLY_TYPE;
- obj[kREPLY_TO_KEY] = response.Type;
- if (response.IsError()) {
- obj[kERROR_MESSAGE_KEY] = response.ErrorMessage();
- }
-
- this->WriteJsonObject(connection, obj, debug);
-}
-
-void cmServer::OnConnected(cmConnection* connection)
-{
- PrintHello(connection);
-}
-
-void cmServer::OnServeStart()
-{
- cmServerBase::OnServeStart();
- fileMonitor = std::make_shared<cmFileMonitor>(GetLoop());
-}
-
-void cmServer::StartShutDown()
-{
- if (fileMonitor) {
- fileMonitor->StopMonitoring();
- fileMonitor.reset();
- }
- cmServerBase::StartShutDown();
-}
-
-static void __start_thread(void* arg)
-{
- auto server = static_cast<cmServerBase*>(arg);
- std::string error;
- bool success = server->Serve(&error);
- if (!success || !error.empty()) {
- std::cerr << "Error during serve: " << error << std::endl;
- }
-}
-
-bool cmServerBase::StartServeThread()
-{
- ServeThreadRunning = true;
- uv_thread_create(&ServeThread, __start_thread, this);
- return true;
-}
-
-static void __shutdownThread(uv_async_t* arg)
-{
- auto server = static_cast<cmServerBase*>(arg->data);
- server->StartShutDown();
-}
-
-bool cmServerBase::Serve(std::string* errorMessage)
-{
-#ifndef NDEBUG
- uv_thread_t blank_thread_t = {};
- assert(uv_thread_equal(&blank_thread_t, &ServeThreadId));
- ServeThreadId = uv_thread_self();
-#endif
-
- errorMessage->clear();
-
- ShutdownSignal.init(Loop, __shutdownThread, this);
-
- SIGINTHandler.init(Loop, this);
- SIGHUPHandler.init(Loop, this);
-
- SIGINTHandler.start(&on_signal, SIGINT);
- SIGHUPHandler.start(&on_signal, SIGHUP);
-
- OnServeStart();
-
- {
- cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : Connections) {
- if (!connection->OnServeStart(errorMessage)) {
- return false;
- }
- }
- }
-
- if (uv_run(&Loop, UV_RUN_DEFAULT) != 0) {
- // It is important we don't ever let the event loop exit with open handles
- // at best this is a memory leak, but it can also introduce race conditions
- // which can hang the program.
- assert(false && "Event loop stopped in unclean state.");
-
- *errorMessage = "Internal Error: Event loop stopped in unclean state.";
- return false;
- }
-
- return true;
-}
-
-void cmServerBase::OnConnected(cmConnection*)
-{
-}
-
-void cmServerBase::OnServeStart()
-{
-}
-
-void cmServerBase::StartShutDown()
-{
- ShutdownSignal.reset();
- SIGINTHandler.reset();
- SIGHUPHandler.reset();
-
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- for (auto& connection : Connections) {
- connection->OnConnectionShuttingDown();
- }
- Connections.clear();
- }
-
- uv_walk(&Loop, on_walk_to_shutdown, nullptr);
-}
-
-bool cmServerBase::OnSignal(int signum)
-{
- (void)signum;
- StartShutDown();
- return true;
-}
-
-cmServerBase::cmServerBase(cmConnection* connection)
-{
- auto err = uv_loop_init(&Loop);
- (void)err;
- Loop.data = this;
- assert(err == 0);
-
- AddNewConnection(connection);
-}
-
-void cmServerBase::Close()
-{
- if (Loop.data) {
- if (ServeThreadRunning) {
- this->ShutdownSignal.send();
- uv_thread_join(&ServeThread);
- }
-
- uv_loop_close(&Loop);
- Loop.data = nullptr;
- }
-}
-cmServerBase::~cmServerBase()
-{
- Close();
-}
-
-void cmServerBase::AddNewConnection(cmConnection* ownedConnection)
-{
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- Connections.emplace_back(ownedConnection);
- }
- ownedConnection->SetServer(this);
-}
-
-uv_loop_t* cmServerBase::GetLoop()
-{
- return &Loop;
-}
-
-void cmServerBase::OnDisconnect(cmConnection* pConnection)
-{
- auto pred = [pConnection](const std::unique_ptr<cmConnection>& m) {
- return m.get() == pConnection;
- };
- {
- std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
- Connections.erase(
- std::remove_if(Connections.begin(), Connections.end(), pred),
- Connections.end());
- }
-
- if (Connections.empty()) {
- this->ShutdownSignal.send();
- }
-}
diff --git a/Source/cmServer.h b/Source/cmServer.h
deleted file mode 100644
index 9543329..0000000
--- a/Source/cmServer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* 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 <memory>
-#include <string>
-#include <vector>
-
-#include <cm/shared_mutex>
-
-#include <cm3p/json/value.h>
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServerProtocol;
-class cmServerRequest;
-class cmServerResponse;
-
-/***
- * This essentially hold and manages a libuv event queue and responds to
- * messages
- * on any of its connections.
- */
-class cmServerBase
-{
-public:
- cmServerBase(cmConnection* connection);
- virtual ~cmServerBase();
-
- virtual void AddNewConnection(cmConnection* ownedConnection);
-
- /***
- * The main override responsible for tailoring behavior towards
- * whatever the given server is supposed to do
- *
- * This should almost always be called by the given connections
- * directly.
- *
- * @param connection The connection the request was received on
- * @param request The actual request
- */
- virtual void ProcessRequest(cmConnection* connection,
- const std::string& request) = 0;
- virtual void OnConnected(cmConnection* connection);
-
- /***
- * Start a dedicated thread. If this is used to start the server, it will
- * join on the
- * servers dtor.
- */
- virtual bool StartServeThread();
- virtual bool Serve(std::string* errorMessage);
-
- virtual void OnServeStart();
- virtual void StartShutDown();
-
- virtual bool OnSignal(int signum);
- uv_loop_t* GetLoop();
- void Close();
- void OnDisconnect(cmConnection* pConnection);
-
-protected:
- mutable cm::shared_mutex ConnectionsMutex;
- std::vector<std::unique_ptr<cmConnection>> Connections;
-
- bool ServeThreadRunning = false;
- uv_thread_t ServeThread;
- cm::uv_async_ptr ShutdownSignal;
-#ifndef NDEBUG
-public:
- // When the server starts it will mark down it's current thread ID,
- // which is useful in other contexts to just assert that operations
- // are performed on that same thread.
- uv_thread_t ServeThreadId = {};
-
-protected:
-#endif
-
- uv_loop_t Loop;
-
- cm::uv_signal_ptr SIGINTHandler;
- cm::uv_signal_ptr SIGHUPHandler;
-};
-
-class cmServer : public cmServerBase
-{
-public:
- class DebugInfo;
-
- cmServer(cmConnection* conn, bool supportExperimental);
- ~cmServer() override;
-
- cmServer(cmServer const&) = delete;
- cmServer& operator=(cmServer const&) = delete;
-
- bool Serve(std::string* errorMessage) override;
-
- cmFileMonitor* FileMonitor() const;
-
-private:
- void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
-
- // Callbacks from cmServerConnection:
-
- void ProcessRequest(cmConnection* connection,
- const std::string& request) override;
- std::shared_ptr<cmFileMonitor> fileMonitor;
-
-public:
- void OnServeStart() override;
-
- void StartShutDown() override;
-
-public:
- void OnConnected(cmConnection* connection) override;
-
-private:
- static void reportProgress(const std::string& msg, float progress,
- const cmServerRequest& request);
- static void reportMessage(const std::string& msg, const char* title,
- const cmServerRequest& request);
-
- // Handle requests:
- cmServerResponse SetProtocolVersion(const cmServerRequest& request);
-
- void PrintHello(cmConnection* connection) const;
-
- // Write responses:
- void WriteProgress(const cmServerRequest& request, int min, int current,
- int max, const std::string& message) const;
- void WriteMessage(const cmServerRequest& request, const std::string& message,
- const std::string& title) const;
- void WriteResponse(cmConnection* connection,
- const cmServerResponse& response,
- const DebugInfo* debug) const;
- void WriteParseError(cmConnection* connection,
- const std::string& message) const;
- void WriteSignal(const std::string& name, const Json::Value& obj) const;
-
- void WriteJsonObject(Json::Value const& jsonValue,
- const DebugInfo* debug) const;
-
- void WriteJsonObject(cmConnection* connection, Json::Value const& jsonValue,
- const DebugInfo* debug) const;
-
- static cmServerProtocol* FindMatchingProtocol(
- const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
- int minor);
-
- const bool SupportExperimental;
-
- cmServerProtocol* Protocol = nullptr;
- std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
-
- friend class cmServerProtocol;
- friend class cmServerRequest;
-};
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
deleted file mode 100644
index b4f41a0..0000000
--- a/Source/cmServerConnection.cxx
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmConfigure.h"
-
-#include "cmServerConnection.h"
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-
-#ifdef _WIN32
-# include "io.h"
-#else
-# include <unistd.h>
-#endif
-#include <cassert>
-#include <utility>
-
-cmStdIoConnection::cmStdIoConnection(
- cmConnectionBufferStrategy* bufferStrategy)
- : cmEventBasedConnection(bufferStrategy)
-{
-}
-
-cm::uv_stream_ptr cmStdIoConnection::SetupStream(int file_id)
-{
- switch (uv_guess_handle(file_id)) {
- case UV_TTY: {
- cm::uv_tty_ptr tty;
- tty.init(*this->Server->GetLoop(), file_id, file_id == 0,
- static_cast<cmEventBasedConnection*>(this));
- uv_tty_set_mode(tty, UV_TTY_MODE_NORMAL);
- return { std::move(tty) };
- }
- case UV_FILE:
- if (file_id == 0) {
- return nullptr;
- }
- // Intentional fallthrough; stdin can _not_ be treated as a named
- // pipe, however stdout can be.
- CM_FALLTHROUGH;
- case UV_NAMED_PIPE: {
- cm::uv_pipe_ptr pipe;
- pipe.init(*this->Server->GetLoop(), 0,
- static_cast<cmEventBasedConnection*>(this));
- uv_pipe_open(pipe, file_id);
- return { std::move(pipe) };
- }
- default:
- assert(false && "Unable to determine stream type");
- return nullptr;
- }
-}
-
-void cmStdIoConnection::SetServer(cmServerBase* s)
-{
- cmConnection::SetServer(s);
- if (!s) {
- return;
- }
-
- this->ReadStream = SetupStream(0);
- this->WriteStream = SetupStream(1);
-}
-
-void shutdown_connection(uv_prepare_t* prepare)
-{
- cmStdIoConnection* connection =
- static_cast<cmStdIoConnection*>(prepare->data);
-
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(prepare))) {
- uv_close(reinterpret_cast<uv_handle_t*>(prepare),
- &cmEventBasedConnection::on_close_delete<uv_prepare_t>);
- }
- connection->OnDisconnect(0);
-}
-
-bool cmStdIoConnection::OnServeStart(std::string* pString)
-{
- Server->OnConnected(this);
- if (this->ReadStream.get()) {
- uv_read_start(this->ReadStream, on_alloc_buffer, on_read);
- } else if (uv_guess_handle(0) == UV_FILE) {
- char buffer[1024];
- while (auto len = read(0, buffer, sizeof(buffer))) {
- ReadData(std::string(buffer, buffer + len));
- }
-
- // We can't start the disconnect from here, add a prepare hook to do that
- // for us
- auto prepare = new uv_prepare_t();
- prepare->data = this;
- uv_prepare_init(Server->GetLoop(), prepare);
- uv_prepare_start(prepare, shutdown_connection);
- }
- return cmConnection::OnServeStart(pString);
-}
-
-bool cmStdIoConnection::OnConnectionShuttingDown()
-{
- if (ReadStream.get()) {
- uv_read_stop(ReadStream);
- ReadStream->data = nullptr;
- }
-
- this->ReadStream.reset();
-
- cmEventBasedConnection::OnConnectionShuttingDown();
-
- return true;
-}
-
-cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
- : cmPipeConnection(name, new cmServerBufferStrategy)
-{
-}
-
-cmServerStdIoConnection::cmServerStdIoConnection()
- : cmStdIoConnection(new cmServerBufferStrategy)
-{
-}
-
-cmConnectionBufferStrategy::~cmConnectionBufferStrategy() = default;
-
-void cmConnectionBufferStrategy::clear()
-{
-}
-
-std::string cmServerBufferStrategy::BufferOutMessage(
- const std::string& rawBuffer) const
-{
- return std::string("\n") + kSTART_MAGIC + std::string("\n") + rawBuffer +
- kEND_MAGIC + std::string("\n");
-}
-
-std::string cmServerBufferStrategy::BufferMessage(std::string& RawReadBuffer)
-{
- for (;;) {
- auto needle = RawReadBuffer.find('\n');
-
- if (needle == std::string::npos) {
- return "";
- }
- std::string line = RawReadBuffer.substr(0, needle);
- const auto ls = line.size();
- if (ls > 1 && line.at(ls - 1) == '\r') {
- line.erase(ls - 1, 1);
- }
- RawReadBuffer.erase(RawReadBuffer.begin(),
- RawReadBuffer.begin() + static_cast<long>(needle) + 1);
- if (line == kSTART_MAGIC) {
- RequestBuffer.clear();
- continue;
- }
- if (line == kEND_MAGIC) {
- std::string rtn;
- rtn.swap(this->RequestBuffer);
- return rtn;
- }
-
- this->RequestBuffer += line;
- this->RequestBuffer += "\n";
- }
-}
diff --git a/Source/cmServerConnection.h b/Source/cmServerConnection.h
deleted file mode 100644
index a70edb4..0000000
--- a/Source/cmServerConnection.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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 <string>
-
-#include "cmConnection.h"
-#include "cmPipeConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * This connection buffer strategy accepts messages in the form of
- * [== "CMake Server" ==[
-{
- ... some JSON message ...
-}
-]== "CMake Server" ==]
- * and only passes on the core json; it discards the envelope.
- */
-class cmServerBufferStrategy : public cmConnectionBufferStrategy
-{
-public:
- std::string BufferMessage(std::string& rawBuffer) override;
- std::string BufferOutMessage(const std::string& rawBuffer) const override;
-
-private:
- std::string RequestBuffer;
-};
-
-/***
- * Generic connection over std io interfaces -- tty
- */
-class cmStdIoConnection : public cmEventBasedConnection
-{
-public:
- cmStdIoConnection(cmConnectionBufferStrategy* bufferStrategy);
-
- void SetServer(cmServerBase* s) override;
-
- bool OnConnectionShuttingDown() override;
-
- bool OnServeStart(std::string* pString) override;
-
-private:
- cm::uv_stream_ptr SetupStream(int file_id);
- cm::uv_stream_ptr ReadStream;
-};
-
-/***
- * These specific connections use the cmake server
- * buffering strategy.
- */
-class cmServerStdIoConnection : public cmStdIoConnection
-{
-public:
- cmServerStdIoConnection();
-};
-
-class cmServerPipeConnection : public cmPipeConnection
-{
-public:
- cmServerPipeConnection(const std::string& name);
-};
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
deleted file mode 100644
index 961e4b7..0000000
--- a/Source/cmServerDictionary.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kDIRTY_SIGNAL = "dirty";
-static const std::string kFILE_CHANGE_SIGNAL = "fileChange";
-
-static const std::string kCACHE_TYPE = "cache";
-static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs";
-static const std::string kCODE_MODEL_TYPE = "codemodel";
-static const std::string kCOMPUTE_TYPE = "compute";
-static const std::string kCONFIGURE_TYPE = "configure";
-static const std::string kERROR_TYPE = "error";
-static const std::string kFILESYSTEM_WATCHERS_TYPE = "fileSystemWatchers";
-static const std::string kGLOBAL_SETTINGS_TYPE = "globalSettings";
-static const std::string kHANDSHAKE_TYPE = "handshake";
-static const std::string kMESSAGE_TYPE = "message";
-static const std::string kPROGRESS_TYPE = "progress";
-static const std::string kREPLY_TYPE = "reply";
-static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
-static const std::string kSIGNAL_TYPE = "signal";
-static const std::string kCTEST_INFO_TYPE = "ctestInfo";
-
-static const std::string kBUILD_FILES_KEY = "buildFiles";
-static const std::string kCACHE_ARGUMENTS_KEY = "cacheArguments";
-static const std::string kCACHE_KEY = "cache";
-static const std::string kCAPABILITIES_KEY = "capabilities";
-static const std::string kCHECK_SYSTEM_VARS_KEY = "checkSystemVars";
-static const std::string kCMAKE_ROOT_DIRECTORY_KEY = "cmakeRootDirectory";
-static const std::string kCOOKIE_KEY = "cookie";
-static const std::string kDEBUG_OUTPUT_KEY = "debugOutput";
-static const std::string kERROR_MESSAGE_KEY = "errorMessage";
-static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
-static const std::string kGENERATOR_KEY = "generator";
-static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
-static const std::string kKEYS_KEY = "keys";
-static const std::string kMAJOR_KEY = "major";
-static const std::string kMESSAGE_KEY = "message";
-static const std::string kMINOR_KEY = "minor";
-static const std::string kPLATFORM_KEY = "platform";
-static const std::string kPROGRESS_CURRENT_KEY = "progressCurrent";
-static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum";
-static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage";
-static const std::string kPROGRESS_MINIMUM_KEY = "progressMinimum";
-static const std::string kPROTOCOL_VERSION_KEY = "protocolVersion";
-static const std::string kREPLY_TO_KEY = "inReplyTo";
-static const std::string kSUPPORTED_PROTOCOL_VERSIONS =
- "supportedProtocolVersions";
-static const std::string kTITLE_KEY = "title";
-static const std::string kTOOLSET_KEY = "toolset";
-static const std::string kTRACE_EXPAND_KEY = "traceExpand";
-static const std::string kTRACE_KEY = "trace";
-static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized";
-static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli";
-static const std::string kWARN_UNUSED_KEY = "warnUnused";
-static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories";
-static const std::string kWATCHED_FILES_KEY = "watchedFiles";
-
-static const std::string kSTART_MAGIC = "[== \"CMake Server\" ==[";
-static const std::string kEND_MAGIC = "]== \"CMake Server\" ==]";
-
-static const std::string kRENAME_PROPERTY_VALUE = "rename";
-static const std::string kCHANGE_PROPERTY_VALUE = "change";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
deleted file mode 100644
index e586fd9..0000000
--- a/Source/cmServerProtocol.cxx
+++ /dev/null
@@ -1,760 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmServerProtocol.h"
-
-#include <algorithm>
-#include <cassert>
-#include <functional>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <cm/memory>
-#include <cmext/algorithm>
-
-#include <cm3p/uv.h>
-
-#include "cmExternalMakefileProjectGenerator.h"
-#include "cmFileMonitor.h"
-#include "cmGlobalGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmMessageType.h"
-#include "cmProperty.h"
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-#include "cmState.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-// Get rid of some windows macros:
-#undef max
-
-namespace {
-
-std::vector<std::string> toStringList(const Json::Value& in)
-{
- std::vector<std::string> result;
- for (auto const& it : in) {
- result.push_back(it.asString());
- }
- return result;
-}
-
-} // namespace
-
-cmServerRequest::cmServerRequest(cmServer* server, cmConnection* connection,
- std::string t, std::string c, Json::Value d)
- : Type(std::move(t))
- , Cookie(std::move(c))
- , Data(std::move(d))
- , Connection(connection)
- , m_Server(server)
-{
-}
-
-void cmServerRequest::ReportProgress(int min, int current, int max,
- const std::string& message) const
-{
- this->m_Server->WriteProgress(*this, min, current, max, message);
-}
-
-void cmServerRequest::ReportMessage(const std::string& message,
- const std::string& title) const
-{
- m_Server->WriteMessage(*this, message, title);
-}
-
-cmServerResponse cmServerRequest::Reply(const Json::Value& data) const
-{
- cmServerResponse response(*this);
- response.SetData(data);
- return response;
-}
-
-cmServerResponse cmServerRequest::ReportError(const std::string& message) const
-{
- cmServerResponse response(*this);
- response.SetError(message);
- return response;
-}
-
-cmServerResponse::cmServerResponse(const cmServerRequest& request)
- : Type(request.Type)
- , Cookie(request.Cookie)
-{
-}
-
-void cmServerResponse::SetData(const Json::Value& data)
-{
- assert(this->m_Payload == PAYLOAD_UNKNOWN);
- if (!data[kCOOKIE_KEY].isNull() || !data[kTYPE_KEY].isNull()) {
- this->SetError("Response contains cookie or type field.");
- return;
- }
- this->m_Payload = PAYLOAD_DATA;
- this->m_Data = data;
-}
-
-void cmServerResponse::SetError(const std::string& message)
-{
- assert(this->m_Payload == PAYLOAD_UNKNOWN);
- this->m_Payload = PAYLOAD_ERROR;
- this->m_ErrorMessage = message;
-}
-
-bool cmServerResponse::IsComplete() const
-{
- return this->m_Payload != PAYLOAD_UNKNOWN;
-}
-
-bool cmServerResponse::IsError() const
-{
- assert(this->m_Payload != PAYLOAD_UNKNOWN);
- return this->m_Payload == PAYLOAD_ERROR;
-}
-
-std::string cmServerResponse::ErrorMessage() const
-{
- if (this->m_Payload == PAYLOAD_ERROR) {
- return this->m_ErrorMessage;
- }
- return std::string();
-}
-
-Json::Value cmServerResponse::Data() const
-{
- assert(this->m_Payload != PAYLOAD_UNKNOWN);
- return this->m_Data;
-}
-
-bool cmServerProtocol::Activate(cmServer* server,
- const cmServerRequest& request,
- std::string* errorMessage)
-{
- assert(server);
- this->m_Server = server;
- this->m_CMakeInstance =
- cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
- this->m_WarnUnused = false;
- const bool result = this->DoActivate(request, errorMessage);
- if (!result) {
- this->m_CMakeInstance = nullptr;
- }
- return result;
-}
-
-cmFileMonitor* cmServerProtocol::FileMonitor() const
-{
- return this->m_Server ? this->m_Server->FileMonitor() : nullptr;
-}
-
-void cmServerProtocol::SendSignal(const std::string& name,
- const Json::Value& data) const
-{
- if (this->m_Server) {
- this->m_Server->WriteSignal(name, data);
- }
-}
-
-cmake* cmServerProtocol::CMakeInstance() const
-{
- return this->m_CMakeInstance.get();
-}
-
-bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
- std::string* /*errorMessage*/)
-{
- return true;
-}
-
-std::pair<int, int> cmServerProtocol1::ProtocolVersion() const
-{
- return { 1, 2 };
-}
-
-static void setErrorMessage(std::string* errorMessage, const std::string& text)
-{
- if (errorMessage) {
- *errorMessage = text;
- }
-}
-
-static bool getOrTestHomeDirectory(cmState* state, std::string& value,
- std::string* errorMessage)
-{
- const std::string cachedValue =
- *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
- if (value.empty()) {
- value = cachedValue;
- return true;
- }
- const std::string suffix = "/CMakeLists.txt";
- const std::string cachedValueCML = cachedValue + suffix;
- const std::string valueCML = value + suffix;
- if (!cmSystemTools::SameFile(valueCML, cachedValueCML)) {
- setErrorMessage(errorMessage,
- std::string("\"CMAKE_HOME_DIRECTORY\" is set but "
- "incompatible with configured "
- "source directory value."));
- return false;
- }
- return true;
-}
-
-static bool getOrTestValue(cmState* state, const std::string& key,
- std::string& value,
- const std::string& keyDescription,
- std::string* errorMessage)
-{
- const std::string cachedValue = state->GetSafeCacheEntryValue(key);
- if (value.empty()) {
- value = cachedValue;
- }
- if (!cachedValue.empty() && cachedValue != value) {
- setErrorMessage(errorMessage,
- std::string("\"") + key +
- "\" is set but incompatible with configured " +
- keyDescription + " value.");
- return false;
- }
- return true;
-}
-
-bool cmServerProtocol1::DoActivate(const cmServerRequest& request,
- std::string* errorMessage)
-{
- std::string sourceDirectory = request.Data[kSOURCE_DIRECTORY_KEY].asString();
- std::string buildDirectory = request.Data[kBUILD_DIRECTORY_KEY].asString();
- std::string generator = request.Data[kGENERATOR_KEY].asString();
- std::string extraGenerator = request.Data[kEXTRA_GENERATOR_KEY].asString();
- std::string toolset = request.Data[kTOOLSET_KEY].asString();
- std::string platform = request.Data[kPLATFORM_KEY].asString();
-
- // normalize source and build directory
- if (!sourceDirectory.empty()) {
- sourceDirectory = cmSystemTools::CollapseFullPath(sourceDirectory);
- cmSystemTools::ConvertToUnixSlashes(sourceDirectory);
- }
- if (!buildDirectory.empty()) {
- buildDirectory = cmSystemTools::CollapseFullPath(buildDirectory);
- cmSystemTools::ConvertToUnixSlashes(buildDirectory);
- }
-
- if (buildDirectory.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kBUILD_DIRECTORY_KEY +
- "\" is missing.");
- return false;
- }
-
- cmake* cm = CMakeInstance();
- if (cmSystemTools::PathExists(buildDirectory)) {
- if (!cmSystemTools::FileIsDirectory(buildDirectory)) {
- setErrorMessage(errorMessage,
- std::string("\"") + kBUILD_DIRECTORY_KEY +
- "\" exists but is not a directory.");
- return false;
- }
-
- const std::string cachePath = cmake::FindCacheFile(buildDirectory);
- if (cm->LoadCache(cachePath)) {
- cmState* state = cm->GetState();
-
- // Check generator:
- if (!getOrTestValue(state, "CMAKE_GENERATOR", generator, "generator",
- errorMessage)) {
- return false;
- }
-
- // check extra generator:
- if (!getOrTestValue(state, "CMAKE_EXTRA_GENERATOR", extraGenerator,
- "extra generator", errorMessage)) {
- return false;
- }
-
- // check sourcedir:
- if (!getOrTestHomeDirectory(state, sourceDirectory, errorMessage)) {
- return false;
- }
-
- // check toolset:
- if (!getOrTestValue(state, "CMAKE_GENERATOR_TOOLSET", toolset, "toolset",
- errorMessage)) {
- return false;
- }
-
- // check platform:
- if (!getOrTestValue(state, "CMAKE_GENERATOR_PLATFORM", platform,
- "platform", errorMessage)) {
- return false;
- }
- }
- }
-
- if (sourceDirectory.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kSOURCE_DIRECTORY_KEY +
- "\" is unset but required.");
- return false;
- }
- if (!cmSystemTools::FileIsDirectory(sourceDirectory)) {
- setErrorMessage(errorMessage,
- std::string("\"") + kSOURCE_DIRECTORY_KEY +
- "\" is not a directory.");
- return false;
- }
- if (generator.empty()) {
- setErrorMessage(errorMessage,
- std::string("\"") + kGENERATOR_KEY +
- "\" is unset but required.");
- return false;
- }
-
- std::vector<cmake::GeneratorInfo> generators;
- cm->GetRegisteredGenerators(generators);
- auto baseIt = std::find_if(generators.begin(), generators.end(),
- [&generator](const cmake::GeneratorInfo& info) {
- return info.name == generator;
- });
- if (baseIt == generators.end()) {
- setErrorMessage(errorMessage,
- std::string("Generator \"") + generator +
- "\" not supported.");
- return false;
- }
- auto extraIt = std::find_if(
- generators.begin(), generators.end(),
- [&generator, &extraGenerator](const cmake::GeneratorInfo& info) {
- return info.baseName == generator && info.extraName == extraGenerator;
- });
- if (extraIt == generators.end()) {
- setErrorMessage(errorMessage,
- std::string("The combination of generator \"" + generator +
- "\" and extra generator \"" + extraGenerator +
- "\" is not supported."));
- return false;
- }
- if (!extraIt->supportsToolset && !toolset.empty()) {
- setErrorMessage(errorMessage,
- std::string("Toolset was provided but is not supported by "
- "the requested generator."));
- return false;
- }
- if (!extraIt->supportsPlatform && !platform.empty()) {
- setErrorMessage(errorMessage,
- std::string("Platform was provided but is not supported "
- "by the requested generator."));
- return false;
- }
-
- this->GeneratorInfo =
- GeneratorInformation(generator, extraGenerator, toolset, platform,
- sourceDirectory, buildDirectory);
-
- this->m_State = STATE_ACTIVE;
- return true;
-}
-
-void cmServerProtocol1::HandleCMakeFileChanges(const std::string& path,
- int event, int status)
-{
- assert(status == 0);
- static_cast<void>(status);
-
- if (!m_isDirty) {
- m_isDirty = true;
- SendSignal(kDIRTY_SIGNAL, Json::objectValue);
- }
- Json::Value obj = Json::objectValue;
- obj[kPATH_KEY] = path;
- Json::Value properties = Json::arrayValue;
- if (event & UV_RENAME) {
- properties.append(kRENAME_PROPERTY_VALUE);
- }
- if (event & UV_CHANGE) {
- properties.append(kCHANGE_PROPERTY_VALUE);
- }
-
- obj[kPROPERTIES_KEY] = properties;
- SendSignal(kFILE_CHANGE_SIGNAL, obj);
-}
-
-cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request)
-{
- assert(this->m_State >= STATE_ACTIVE);
-
- if (request.Type == kCACHE_TYPE) {
- return this->ProcessCache(request);
- }
- if (request.Type == kCMAKE_INPUTS_TYPE) {
- return this->ProcessCMakeInputs(request);
- }
- if (request.Type == kCODE_MODEL_TYPE) {
- return this->ProcessCodeModel(request);
- }
- if (request.Type == kCOMPUTE_TYPE) {
- return this->ProcessCompute(request);
- }
- if (request.Type == kCONFIGURE_TYPE) {
- return this->ProcessConfigure(request);
- }
- if (request.Type == kFILESYSTEM_WATCHERS_TYPE) {
- return this->ProcessFileSystemWatchers(request);
- }
- if (request.Type == kGLOBAL_SETTINGS_TYPE) {
- return this->ProcessGlobalSettings(request);
- }
- if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
- return this->ProcessSetGlobalSettings(request);
- }
- if (request.Type == kCTEST_INFO_TYPE) {
- return this->ProcessCTests(request);
- }
-
- return request.ReportError("Unknown command!");
-}
-
-bool cmServerProtocol1::IsExperimental() const
-{
- return true;
-}
-
-cmServerResponse cmServerProtocol1::ProcessCache(
- const cmServerRequest& request)
-{
- cmState* state = this->CMakeInstance()->GetState();
-
- Json::Value result = Json::objectValue;
-
- std::vector<std::string> allKeys = state->GetCacheEntryKeys();
-
- Json::Value list = Json::arrayValue;
- std::vector<std::string> keys = toStringList(request.Data[kKEYS_KEY]);
- if (keys.empty()) {
- keys = allKeys;
- } else {
- for (auto const& i : keys) {
- if (!cm::contains(allKeys, i)) {
- return request.ReportError("Key \"" + i + "\" not found in cache.");
- }
- }
- }
- std::sort(keys.begin(), keys.end());
- for (auto const& key : keys) {
- Json::Value entry = Json::objectValue;
- entry[kKEY_KEY] = key;
- entry[kTYPE_KEY] =
- cmState::CacheEntryTypeToString(state->GetCacheEntryType(key));
- entry[kVALUE_KEY] = *state->GetCacheEntryValue(key);
-
- Json::Value props = Json::objectValue;
- bool haveProperties = false;
- for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
- haveProperties = true;
- props[prop] = *state->GetCacheEntryProperty(key, prop);
- }
- if (haveProperties) {
- entry[kPROPERTIES_KEY] = props;
- }
-
- list.append(entry);
- }
-
- result[kCACHE_KEY] = list;
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCMakeInputs(
- const cmServerRequest& request)
-{
- if (this->m_State < STATE_CONFIGURED) {
- return request.ReportError("This instance was not yet configured.");
- }
-
- const cmake* cm = this->CMakeInstance();
- const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot();
- const std::string& sourceDir = cm->GetHomeDirectory();
-
- Json::Value result = Json::objectValue;
- result[kSOURCE_DIRECTORY_KEY] = sourceDir;
- result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir;
- result[kBUILD_FILES_KEY] = cmDumpCMakeInputs(cm);
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCodeModel(
- const cmServerRequest& request)
-{
- if (this->m_State != STATE_COMPUTED) {
- return request.ReportError("No build system was generated yet.");
- }
-
- return request.Reply(cmDumpCodeModel(this->CMakeInstance()));
-}
-
-cmServerResponse cmServerProtocol1::ProcessCompute(
- const cmServerRequest& request)
-{
- if (this->m_State > STATE_CONFIGURED) {
- return request.ReportError("This build system was already generated.");
- }
- if (this->m_State < STATE_CONFIGURED) {
- return request.ReportError("This project was not configured yet.");
- }
-
- cmake* cm = this->CMakeInstance();
- int ret = cm->Generate();
-
- if (ret < 0) {
- return request.ReportError("Failed to compute build system.");
- }
- m_State = STATE_COMPUTED;
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessConfigure(
- const cmServerRequest& request)
-{
- if (this->m_State == STATE_INACTIVE) {
- return request.ReportError("This instance is inactive.");
- }
-
- FileMonitor()->StopMonitoring();
-
- std::string errorMessage;
- cmake* cm = this->CMakeInstance();
- this->GeneratorInfo.SetupGenerator(cm, &errorMessage);
- if (!errorMessage.empty()) {
- return request.ReportError(errorMessage);
- }
-
- // Make sure the types of cacheArguments matches (if given):
- std::vector<std::string> cacheArgs = { "unused" };
- bool cacheArgumentsError = false;
- const Json::Value passedArgs = request.Data[kCACHE_ARGUMENTS_KEY];
- if (!passedArgs.isNull()) {
- if (passedArgs.isString()) {
- cacheArgs.push_back(passedArgs.asString());
- } else if (passedArgs.isArray()) {
- for (auto const& arg : passedArgs) {
- if (!arg.isString()) {
- cacheArgumentsError = true;
- break;
- }
- cacheArgs.push_back(arg.asString());
- }
- } else {
- cacheArgumentsError = true;
- }
- }
- if (cacheArgumentsError) {
- request.ReportError(
- "cacheArguments must be unset, a string or an array of strings.");
- }
-
- std::string sourceDir = cm->GetHomeDirectory();
- const std::string buildDir = cm->GetHomeOutputDirectory();
-
- cmGlobalGenerator* gg = cm->GetGlobalGenerator();
-
- if (buildDir.empty()) {
- return request.ReportError("No build directory set via Handshake.");
- }
-
- if (cm->LoadCache(buildDir)) {
- // build directory has been set up before
- cmProp cachedSourceDir =
- cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
- if (!cachedSourceDir) {
- return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
- }
- if (sourceDir.empty()) {
- sourceDir = *cachedSourceDir;
- cm->SetHomeDirectory(sourceDir);
- }
-
- cmProp cachedGenerator =
- cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
- if (cachedGenerator) {
- if (gg && gg->GetName() != *cachedGenerator) {
- return request.ReportError("Configured generator does not match with "
- "CMAKE_GENERATOR found in cache.");
- }
- }
- } else {
- // build directory has not been set up before
- if (sourceDir.empty()) {
- return request.ReportError("No sourceDirectory set via "
- "setGlobalSettings and no cache found in "
- "buildDirectory.");
- }
- }
-
- cmSystemTools::ResetErrorOccuredFlag(); // Reset error state
-
- if (cm->AddCMakePaths() != 1) {
- return request.ReportError("Failed to set CMake paths.");
- }
-
- if (!cm->SetCacheArgs(cacheArgs)) {
- return request.ReportError("cacheArguments could not be set.");
- }
-
- int ret = cm->Configure();
- cm->IssueMessage(
- MessageType::DEPRECATION_WARNING,
- "The 'cmake-server(7)' is deprecated. "
- "Please port clients to use the 'cmake-file-api(7)' instead.");
- if (ret < 0) {
- return request.ReportError("Configuration failed.");
- }
-
- std::vector<std::string> toWatchList;
- cmGetCMakeInputs(gg, std::string(), buildDir, nullptr, &toWatchList,
- nullptr);
-
- FileMonitor()->MonitorPaths(toWatchList,
- [this](const std::string& p, int e, int s) {
- this->HandleCMakeFileChanges(p, e, s);
- });
-
- m_State = STATE_CONFIGURED;
- m_isDirty = false;
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessGlobalSettings(
- const cmServerRequest& request)
-{
- cmake* cm = this->CMakeInstance();
- Json::Value obj = Json::objectValue;
-
- // Capabilities information:
- obj[kCAPABILITIES_KEY] = cm->ReportCapabilitiesJson();
-
- obj[kDEBUG_OUTPUT_KEY] = cm->GetDebugOutput();
- obj[kTRACE_KEY] = cm->GetTrace();
- obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
- obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
- obj[kWARN_UNUSED_KEY] = m_WarnUnused;
- obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
- obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
-
- obj[kSOURCE_DIRECTORY_KEY] = this->GeneratorInfo.SourceDirectory;
- obj[kBUILD_DIRECTORY_KEY] = this->GeneratorInfo.BuildDirectory;
-
- // Currently used generator:
- obj[kGENERATOR_KEY] = this->GeneratorInfo.GeneratorName;
- obj[kEXTRA_GENERATOR_KEY] = this->GeneratorInfo.ExtraGeneratorName;
-
- return request.Reply(obj);
-}
-
-static void setBool(const cmServerRequest& request, const std::string& key,
- std::function<void(bool)> const& setter)
-{
- if (request.Data[key].isNull()) {
- return;
- }
- setter(request.Data[key].asBool());
-}
-
-cmServerResponse cmServerProtocol1::ProcessSetGlobalSettings(
- const cmServerRequest& request)
-{
- const std::vector<std::string> boolValues = {
- kDEBUG_OUTPUT_KEY, kTRACE_KEY, kTRACE_EXPAND_KEY,
- kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY,
- kCHECK_SYSTEM_VARS_KEY
- };
- for (std::string const& i : boolValues) {
- if (!request.Data[i].isNull() && !request.Data[i].isBool()) {
- return request.ReportError("\"" + i +
- "\" must be unset or a bool value.");
- }
- }
-
- cmake* cm = this->CMakeInstance();
-
- setBool(request, kDEBUG_OUTPUT_KEY,
- [cm](bool e) { cm->SetDebugOutputOn(e); });
- setBool(request, kTRACE_KEY, [cm](bool e) { cm->SetTrace(e); });
- setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
- setBool(request, kWARN_UNINITIALIZED_KEY,
- [cm](bool e) { cm->SetWarnUninitialized(e); });
- setBool(request, kWARN_UNUSED_KEY, [this](bool e) { m_WarnUnused = e; });
- setBool(request, kWARN_UNUSED_CLI_KEY,
- [cm](bool e) { cm->SetWarnUnusedCli(e); });
- setBool(request, kCHECK_SYSTEM_VARS_KEY,
- [cm](bool e) { cm->SetCheckSystemVars(e); });
-
- return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessFileSystemWatchers(
- const cmServerRequest& request)
-{
- const cmFileMonitor* const fm = FileMonitor();
- Json::Value result = Json::objectValue;
- Json::Value files = Json::arrayValue;
- for (auto const& f : fm->WatchedFiles()) {
- files.append(f);
- }
- Json::Value directories = Json::arrayValue;
- for (auto const& d : fm->WatchedDirectories()) {
- directories.append(d);
- }
- result[kWATCHED_FILES_KEY] = files;
- result[kWATCHED_DIRECTORIES_KEY] = directories;
-
- return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCTests(
- const cmServerRequest& request)
-{
- if (this->m_State < STATE_COMPUTED) {
- return request.ReportError("This instance was not yet computed.");
- }
-
- return request.Reply(cmDumpCTestInfo(this->CMakeInstance()));
-}
-
-cmServerProtocol1::GeneratorInformation::GeneratorInformation(
- std::string generatorName, std::string extraGeneratorName,
- std::string toolset, std::string platform, std::string sourceDirectory,
- std::string buildDirectory)
- : GeneratorName(std::move(generatorName))
- , ExtraGeneratorName(std::move(extraGeneratorName))
- , Toolset(std::move(toolset))
- , Platform(std::move(platform))
- , SourceDirectory(std::move(sourceDirectory))
- , BuildDirectory(std::move(buildDirectory))
-{
-}
-
-void cmServerProtocol1::GeneratorInformation::SetupGenerator(
- cmake* cm, std::string* errorMessage)
-{
- const std::string fullGeneratorName =
- cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- GeneratorName, ExtraGeneratorName);
-
- cm->SetHomeDirectory(SourceDirectory);
- cm->SetHomeOutputDirectory(BuildDirectory);
-
- auto gg = cm->CreateGlobalGenerator(fullGeneratorName);
- if (!gg) {
- setErrorMessage(
- errorMessage,
- std::string("Could not set up the requested combination of \"") +
- kGENERATOR_KEY + "\" and \"" + kEXTRA_GENERATOR_KEY + "\"");
- return;
- }
-
- cm->SetGlobalGenerator(std::move(gg));
-
- cm->SetGeneratorToolset(Toolset);
- cm->SetGeneratorPlatform(Platform);
-}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
deleted file mode 100644
index 6009e23..0000000
--- a/Source/cmServerProtocol.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* 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 <memory>
-#include <string>
-#include <utility>
-
-#include <cm3p/json/value.h>
-
-#include "cmake.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServer;
-class cmServerRequest;
-
-class cmServerResponse
-{
-public:
- explicit cmServerResponse(const cmServerRequest& request);
-
- void SetData(const Json::Value& data);
- void SetError(const std::string& message);
-
- bool IsComplete() const;
- bool IsError() const;
- std::string ErrorMessage() const;
- Json::Value Data() const;
-
- const std::string Type;
- const std::string Cookie;
-
-private:
- enum PayLoad
- {
- PAYLOAD_UNKNOWN,
- PAYLOAD_ERROR,
- PAYLOAD_DATA
- };
- PayLoad m_Payload = PAYLOAD_UNKNOWN;
- std::string m_ErrorMessage;
- Json::Value m_Data;
-};
-
-class cmServerRequest
-{
-public:
- cmServerResponse Reply(const Json::Value& data) const;
- cmServerResponse ReportError(const std::string& message) const;
-
- const std::string Type;
- const std::string Cookie;
- const Json::Value Data;
- cmConnection* Connection;
-
-private:
- cmServerRequest(cmServer* server, cmConnection* connection, std::string t,
- std::string c, Json::Value d);
-
- void ReportProgress(int min, int current, int max,
- const std::string& message) const;
- void ReportMessage(const std::string& message,
- const std::string& title) const;
-
- cmServer* m_Server;
-
- friend class cmServer;
-};
-
-class cmServerProtocol
-{
-public:
- cmServerProtocol() = default;
- virtual ~cmServerProtocol() = default;
-
- cmServerProtocol(cmServerProtocol const&) = delete;
- cmServerProtocol& operator=(cmServerProtocol const&) = delete;
-
- virtual std::pair<int, int> ProtocolVersion() const = 0;
- virtual bool IsExperimental() const = 0;
- virtual cmServerResponse Process(const cmServerRequest& request) = 0;
-
- bool Activate(cmServer* server, const cmServerRequest& request,
- std::string* errorMessage);
-
- cmFileMonitor* FileMonitor() const;
- void SendSignal(const std::string& name, const Json::Value& data) const;
-
-protected:
- cmake* CMakeInstance() const;
- // Implement protocol specific activation tasks here. Called from Activate().
- virtual bool DoActivate(const cmServerRequest& request,
- std::string* errorMessage);
- bool m_WarnUnused = false; // storage for legacy option
-
-private:
- std::unique_ptr<cmake> m_CMakeInstance;
- cmServer* m_Server = nullptr; // not owned!
-
- friend class cmServer;
-};
-
-class cmServerProtocol1 : public cmServerProtocol
-{
-public:
- std::pair<int, int> ProtocolVersion() const override;
- bool IsExperimental() const override;
- cmServerResponse Process(const cmServerRequest& request) override;
-
-private:
- bool DoActivate(const cmServerRequest& request,
- std::string* errorMessage) override;
-
- void HandleCMakeFileChanges(const std::string& path, int event, int status);
-
- // Handle requests:
- cmServerResponse ProcessCache(const cmServerRequest& request);
- cmServerResponse ProcessCMakeInputs(const cmServerRequest& request);
- cmServerResponse ProcessCodeModel(const cmServerRequest& request);
- cmServerResponse ProcessCompute(const cmServerRequest& request);
- cmServerResponse ProcessConfigure(const cmServerRequest& request);
- cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
- cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
- cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request);
- cmServerResponse ProcessCTests(const cmServerRequest& request);
-
- enum State
- {
- STATE_INACTIVE,
- STATE_ACTIVE,
- STATE_CONFIGURED,
- STATE_COMPUTED
- };
- State m_State = STATE_INACTIVE;
-
- bool m_isDirty = false;
-
- struct GeneratorInformation
- {
- public:
- GeneratorInformation() = default;
- GeneratorInformation(std::string generatorName,
- std::string extraGeneratorName, std::string toolset,
- std::string platform, std::string sourceDirectory,
- std::string buildDirectory);
-
- void SetupGenerator(cmake* cm, std::string* errorMessage);
-
- std::string GeneratorName;
- std::string ExtraGeneratorName;
- std::string Toolset;
- std::string Platform;
-
- std::string SourceDirectory;
- std::string BuildDirectory;
- };
-
- GeneratorInformation GeneratorInfo;
-};
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index df6a38a..970564d 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -10,9 +10,12 @@
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmSourceFileLocation.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -157,7 +160,7 @@ bool HandleSourceFileDirectoryScopeValidation(
return true;
}
-bool HandleAndValidateSourceFileDirectortoryScopes(
+bool HandleAndValidateSourceFileDirectoryScopes(
cmExecutionStatus& status, bool source_file_directory_option_enabled,
bool source_file_target_option_enabled,
std::vector<std::string>& source_file_directories,
@@ -216,8 +219,92 @@ void MakeSourceFilePathsAbsoluteIfNeeded(
source_files_absolute_paths.push_back(absolute_file_path);
}
}
+
+bool HandleAndValidateSourceFilePropertyGENERATED(
+ cmSourceFile* sf, std::string const& propertyValue, PropertyOp op)
+{
+ auto& mf = *sf->GetLocation().GetMakefile();
+ auto policyStatus = mf.GetPolicyStatus(cmPolicies::CMP0118);
+
+ const bool policyWARN = policyStatus == cmPolicies::WARN;
+ const bool policyNEW = policyStatus != cmPolicies::OLD && !policyWARN;
+
+ if (policyWARN) {
+ if (!cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0118),
+ "\nAttempt to set property 'GENERATED' with the following "
+ "non-boolean value (which will be interpreted as \"0\"):\n",
+ propertyValue,
+ "\nThat exact value will not be retrievable. A value of "
+ "\"0\" will be returned instead.\n"
+ "This will be an error under policy CMP0118.\n"));
+ }
+ if (cmIsOff(propertyValue)) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0118),
+ "\nUnsetting property 'GENERATED' will not be allowed under "
+ "policy CMP0118!\n"));
+ }
+ if (op == PropertyOp::Append || op == PropertyOp::AppendAsString) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0118),
+ "\nAppending to property 'GENERATED' will not be allowed "
+ "under policy CMP0118!\n"));
+ }
+ } else if (policyNEW) {
+ if (!cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_ERROR,
+ cmStrCat(
+ "Policy CMP0118 is set to NEW and the following non-boolean value "
+ "given for property 'GENERATED' is therefore not allowed:\n",
+ propertyValue, "\nReplace it with a boolean value!\n"));
+ return true;
+ }
+ if (cmIsOff(propertyValue)) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_ERROR,
+ "Unsetting the 'GENERATED' property is not allowed under CMP0118!\n");
+ return true;
+ }
+ if (op == PropertyOp::Append || op == PropertyOp::AppendAsString) {
+ mf.IssueMessage(MessageType::AUTHOR_ERROR,
+ "Policy CMP0118 is set to NEW and appending to the "
+ "'GENERATED' property is therefore not allowed. Only "
+ "setting it to \"1\" is allowed!\n");
+ return true;
+ }
+ }
+
+ // Set property.
+ if (!policyNEW) {
+ // Do it the traditional way.
+ switch (op) {
+ case PropertyOp::Append:
+ sf->AppendProperty("GENERATED", propertyValue, false);
+ break;
+ case PropertyOp::AppendAsString:
+ sf->AppendProperty("GENERATED", propertyValue, true);
+ break;
+ case PropertyOp::Remove:
+ sf->SetProperty("GENERATED", nullptr);
+ break;
+ case PropertyOp::Set:
+ sf->SetProperty("GENERATED", propertyValue.c_str());
+ break;
+ }
+ } else {
+ sf->MarkAsGenerated();
+ }
+ return true;
}
+} // END: namespace SetPropertyCommand
+
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -324,7 +411,7 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
std::vector<cmMakefile*> source_file_directory_makefiles;
bool file_scopes_handled =
- SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
@@ -367,7 +454,7 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
return true;
}
-namespace {
+namespace /* anonymous */ {
bool HandleGlobalMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
@@ -525,6 +612,18 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove)
{
+ // Special validation and handling of GENERATED flag?
+ if (propertyName == "GENERATED") {
+ SetPropertyCommand::PropertyOp op = (remove)
+ ? SetPropertyCommand::PropertyOp::Remove
+ : (appendAsString)
+ ? SetPropertyCommand::PropertyOp::AppendAsString
+ : (appendMode) ? SetPropertyCommand::PropertyOp::Append
+ : SetPropertyCommand::PropertyOp::Set;
+ return SetPropertyCommand::HandleAndValidateSourceFilePropertyGENERATED(
+ sf, propertyValue, op);
+ }
+
// Set or append the property.
if (appendMode) {
sf->AppendProperty(propertyName, propertyValue, appendAsString);
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 89fdd9a..05c4873 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -9,6 +9,7 @@
class cmMakefile;
class cmExecutionStatus;
+class cmSourceFile;
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status);
@@ -25,7 +26,7 @@ bool HandleSourceFileDirectoryScopeValidation(
std::vector<std::string>& source_file_directories,
std::vector<std::string>& source_file_target_directories);
-bool HandleAndValidateSourceFileDirectortoryScopes(
+bool HandleAndValidateSourceFileDirectoryScopes(
cmExecutionStatus& status, bool source_directories_option_encountered,
bool source_target_directories_option_encountered,
std::vector<std::string>& source_directories,
@@ -39,4 +40,16 @@ void MakeSourceFilePathsAbsoluteIfNeeded(
std::vector<std::string>& source_files_absolute_paths,
std::vector<std::string>::const_iterator files_it_begin,
std::vector<std::string>::const_iterator files_it_end, bool needed);
+
+enum class PropertyOp
+{
+ Remove,
+ Set,
+ Append,
+ AppendAsString
+};
+
+bool HandleAndValidateSourceFilePropertyGENERATED(
+ cmSourceFile* sf, std::string const& propertyValue,
+ PropertyOp op = PropertyOp::Set);
}
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index c1b0c28..742aa96 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -7,6 +7,7 @@
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -82,7 +83,7 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
const auto props_begin = options_it;
bool file_scopes_handled =
- SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
@@ -167,7 +168,13 @@ static bool RunCommandForScope(
if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) {
// loop through the props and set them
for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) {
- sf->SetProperty(*k, (k + 1)->c_str());
+ // Special handling for GENERATED property?
+ if (*k == "GENERATED"_s) {
+ SetPropertyCommand::HandleAndValidateSourceFilePropertyGENERATED(
+ sf, *(k + 1));
+ } else {
+ sf->SetProperty(*k, (k + 1)->c_str());
+ }
}
}
}
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index ef44a57..9d9a7c3 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -8,6 +8,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -15,9 +16,12 @@
#include "cmake.h"
cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name,
- cmSourceFileLocationKind kind)
- : Location(mf, name, kind)
+ bool generated, cmSourceFileLocationKind kind)
+ : Location(mf, name, (!generated) ? kind : cmSourceFileLocationKind::Known)
{
+ if (generated) {
+ this->MarkAsGenerated();
+ }
}
std::string const& cmSourceFile::GetExtension() const
@@ -25,6 +29,8 @@ std::string const& cmSourceFile::GetExtension() const
return this->Extension;
}
+const std::string propTRUE = "1";
+const std::string propFALSE = "0";
const std::string cmSourceFile::propLANGUAGE = "LANGUAGE";
const std::string cmSourceFile::propLOCATION = "LOCATION";
const std::string cmSourceFile::propGENERATED = "GENERATED";
@@ -54,16 +60,14 @@ std::string const& cmSourceFile::GetOrDetermineLanguage()
}
// Perform computation needed to get the language if necessary.
- if (this->FullPath.empty() && this->Language.empty()) {
- // If a known extension is given or a known full path is given
- // then trust that the current extension is sufficient to
- // determine the language. This will fail only if the user
- // specifies a full path to the source but leaves off the
- // extension, which is kind of weird.
- if (this->Location.ExtensionIsAmbiguous() &&
+ if (this->Language.empty()) {
+ // If a known extension is given or a known full path is given then trust
+ // that the current extension is sufficient to determine the language. This
+ // will fail only if the user specifies a full path to the source but
+ // leaves off the extension, which is kind of weird.
+ if (this->FullPath.empty() && this->Location.ExtensionIsAmbiguous() &&
this->Location.DirectoryIsAmbiguous()) {
- // Finalize the file location to get the extension and set the
- // language.
+ // Finalize the file location to get the extension and set the language.
this->ResolveFullPath();
} else {
// Use the known extension to get the language if possible.
@@ -93,10 +97,11 @@ cmSourceFileLocation const& cmSourceFile::GetLocation() const
return this->Location;
}
-std::string const& cmSourceFile::ResolveFullPath(std::string* error)
+std::string const& cmSourceFile::ResolveFullPath(std::string* error,
+ std::string* cmp0115Warning)
{
if (this->FullPath.empty()) {
- if (this->FindFullPath(error)) {
+ if (this->FindFullPath(error, cmp0115Warning)) {
this->CheckExtension();
}
}
@@ -108,14 +113,18 @@ std::string const& cmSourceFile::GetFullPath() const
return this->FullPath;
}
-bool cmSourceFile::FindFullPath(std::string* error)
+bool cmSourceFile::FindFullPath(std::string* error,
+ std::string* cmp0115Warning)
{
// If the file is generated compute the location without checking on disk.
- if (this->GetIsGenerated()) {
+ // Note: We also check for a locally set GENERATED property, because
+ // it might have been set before policy CMP0118 was set to NEW.
+ if (this->GetIsGenerated(CheckScope::GlobalAndLocal)) {
// The file is either already a full path or is relative to the
// build directory for the target.
this->Location.DirectoryUseBinary();
this->FullPath = this->Location.GetFullPath();
+ this->FindFullPathFailed = false;
return true;
}
@@ -131,9 +140,11 @@ bool cmSourceFile::FindFullPath(std::string* error)
// List of extension lists
std::vector<std::string> exts =
makefile->GetCMakeInstance()->GetAllExtensions();
+ auto cmp0115 = makefile->GetPolicyStatus(cmPolicies::CMP0115);
// Tries to find the file in a given directory
- auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
+ auto findInDir = [this, &exts, &lPath, cmp0115, cmp0115Warning,
+ makefile](std::string const& dir) -> bool {
// Compute full path
std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
// Try full path
@@ -141,13 +152,29 @@ bool cmSourceFile::FindFullPath(std::string* error)
this->FullPath = fullPath;
return true;
}
- // Try full path with extension
- for (std::string const& ext : exts) {
- if (!ext.empty()) {
- std::string extPath = cmStrCat(fullPath, '.', ext);
- if (cmSystemTools::FileExists(extPath)) {
- this->FullPath = extPath;
- return true;
+ // This has to be an if statement due to a bug in Oracle Developer Studio.
+ // See https://community.oracle.com/tech/developers/discussion/4476246/
+ // for details.
+ if (cmp0115 == cmPolicies::OLD || cmp0115 == cmPolicies::WARN) {
+ // Try full path with extension
+ for (std::string const& ext : exts) {
+ if (!ext.empty()) {
+ std::string extPath = cmStrCat(fullPath, '.', ext);
+ if (cmSystemTools::FileExists(extPath)) {
+ this->FullPath = extPath;
+ if (cmp0115 == cmPolicies::WARN) {
+ std::string warning =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0115),
+ "\nFile:\n ", extPath);
+ if (cmp0115Warning) {
+ *cmp0115Warning = std::move(warning);
+ } else {
+ makefile->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING, warning);
+ }
+ }
+ return true;
+ }
}
}
}
@@ -168,11 +195,19 @@ bool cmSourceFile::FindFullPath(std::string* error)
}
// Compose error
- std::string err =
- cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions");
- for (std::string const& ext : exts) {
- err += " .";
- err += ext;
+ std::string err = cmStrCat("Cannot find source file:\n ", lPath);
+ switch (cmp0115) {
+ case cmPolicies::OLD:
+ case cmPolicies::WARN:
+ err = cmStrCat(err, "\nTried extensions");
+ for (auto const& ext : exts) {
+ err = cmStrCat(err, " .", ext);
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ break;
}
if (error != nullptr) {
*error = std::move(err);
@@ -246,11 +281,6 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
} else {
this->Properties.SetProperty(prop, value);
}
-
- // Update IsGenerated flag
- if (prop == propGENERATED) {
- this->IsGenerated = cmIsOn(value);
- }
}
void cmSourceFile::AppendProperty(const std::string& prop,
@@ -274,14 +304,9 @@ void cmSourceFile::AppendProperty(const std::string& prop,
} else {
this->Properties.AppendProperty(prop, value, asString);
}
-
- // Update IsGenerated flag
- if (prop == propGENERATED) {
- this->IsGenerated = this->GetPropertyAsBool(propGENERATED);
- }
}
-const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
+cmProp cmSourceFile::GetPropertyForUser(const std::string& prop)
{
// This method is a consequence of design history and backwards
// compatibility. GetProperty is (and should be) a const method.
@@ -305,13 +330,27 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
// Similarly, LANGUAGE can be determined by the file extension
// if it is requested by the user.
if (prop == propLANGUAGE) {
- // The c_str pointer is valid until `this->Language` is modified.
- return this->GetOrDetermineLanguage().c_str();
+ // The pointer is valid until `this->Language` is modified.
+ return &this->GetOrDetermineLanguage();
+ }
+
+ // Special handling for GENERATED property.
+ if (prop == propGENERATED) {
+ // We need to check policy CMP0118 in order to determine if we need to
+ // possibly consider the value of a locally set GENERATED property, too.
+ auto policyStatus =
+ this->Location.GetMakefile()->GetPolicyStatus(cmPolicies::CMP0118);
+ if (this->GetIsGenerated(
+ (policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD)
+ ? CheckScope::GlobalAndLocal
+ : CheckScope::Global)) {
+ return &propTRUE;
+ }
+ return &propFALSE;
}
// Perform the normal property lookup.
- cmProp p = this->GetProperty(prop);
- return p ? p->c_str() : nullptr;
+ return this->GetProperty(prop);
}
cmProp cmSourceFile::GetProperty(const std::string& prop) const
@@ -369,13 +408,15 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const
return retVal;
}
-const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
+const std::string& cmSourceFile::GetSafeProperty(const std::string& prop) const
{
cmProp ret = this->GetProperty(prop);
- if (!ret) {
- return "";
+ if (ret) {
+ return *ret;
}
- return ret->c_str();
+
+ static std::string const s_empty;
+ return s_empty;
}
bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
@@ -383,11 +424,29 @@ bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
return cmIsOn(this->GetProperty(prop));
}
+void cmSourceFile::MarkAsGenerated()
+{
+ this->IsGenerated = true;
+ auto& mf = *this->Location.GetMakefile();
+ mf.GetGlobalGenerator()->MarkAsGeneratedFile(this->ResolveFullPath());
+}
+
+bool cmSourceFile::GetIsGenerated(CheckScope checkScope) const
+{
+ if (this->IsGenerated) {
+ // Globally marked as generated!
+ return true;
+ }
+ if (checkScope == CheckScope::GlobalAndLocal) {
+ // Check locally stored properties.
+ return this->GetPropertyAsBool(propGENERATED);
+ }
+ return false;
+}
+
void cmSourceFile::SetProperties(cmPropertyMap properties)
{
this->Properties = std::move(properties);
-
- this->IsGenerated = this->GetPropertyAsBool(propGENERATED);
}
cmCustomCommand* cmSourceFile::GetCustomCommand() const
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 39ea8e3..76a5ded 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -20,18 +20,18 @@ class cmMakefile;
/** \class cmSourceFile
* \brief Represent a class loaded from a makefile.
*
- * cmSourceFile is represents a class loaded from
- * a makefile.
+ * cmSourceFile represents a class loaded from a makefile.
*/
class cmSourceFile
{
public:
/**
- * Construct with the makefile storing the source and the initial
- * name referencing it.
+ * Construct with the makefile storing the source and the initial name
+ * referencing it. If it shall be marked as generated, this source file's
+ * kind is assumed to be known, regardless of the given value.
*/
cmSourceFile(
- cmMakefile* mf, const std::string& name,
+ cmMakefile* mf, const std::string& name, bool generated,
cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
/**
@@ -47,16 +47,36 @@ public:
//! Might return a nullptr if the property is not set or invalid
cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
- const char* GetSafeProperty(const std::string& prop) const;
+ const std::string& GetSafeProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
/** Implement getting a property when called from a CMake language
command like get_property or get_source_file_property. */
- const char* GetPropertyForUser(const std::string& prop);
+ cmProp GetPropertyForUser(const std::string& prop);
- //! Checks is the GENERATED property is set and true
- /// @return Equivalent to GetPropertyAsBool("GENERATED")
- bool GetIsGenerated() const { return this->IsGenerated; }
+ /// Marks this file as generated
+ /**
+ * This stores this file's path in the global table for all generated source
+ * files.
+ */
+ void MarkAsGenerated();
+ enum class CheckScope
+ {
+ Global,
+ GlobalAndLocal
+ };
+ /// Determines if this source file is marked as generated.
+ /**
+ * This will check if this file's path is stored in the global table of all
+ * generated source files. If that is not the case and checkScope is set to
+ * GlobalAndLocal the value of the possibly existing local GENERATED property
+ * is returned instead.
+ * @param checkScope Determines if alternatively for backwards-compatibility
+ * a local GENERATED property should be considered, too.
+ * @return true if this source file is marked as generated, otherwise false.
+ */
+ bool GetIsGenerated(
+ CheckScope checkScope = CheckScope::GlobalAndLocal) const;
const std::vector<BT<std::string>>& GetCompileOptions() const
{
@@ -77,7 +97,8 @@ public:
* Resolves the full path to the file. Attempts to locate the file on disk
* and finalizes its location.
*/
- std::string const& ResolveFullPath(std::string* error = nullptr);
+ std::string const& ResolveFullPath(std::string* error = nullptr,
+ std::string* cmp0115Warning = nullptr);
/**
* The resolved full path to the file. The returned file name might be empty
@@ -138,7 +159,7 @@ private:
bool FindFullPathFailed = false;
bool IsGenerated = false;
- bool FindFullPath(std::string* error);
+ bool FindFullPath(std::string* error, std::string* cmp0115Warning);
void CheckExtension();
void CheckLanguage(std::string const& ext);
@@ -154,7 +175,7 @@ private:
#define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"
#define CM_SOURCE_REGEX \
- "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
+ "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
"rc|def|r|odl|idl|hpj|bat)$"
#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$"
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 222bafa..921eb0e 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -33,8 +33,7 @@ cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
this->AmbiguousExtension = true;
this->Directory = cmSystemTools::GetFilenamePath(name);
if (cmSystemTools::FileIsFullPath(this->Directory)) {
- this->Directory = cmSystemTools::CollapseFullPath(
- this->Directory, mf->GetHomeOutputDirectory());
+ this->Directory = cmSystemTools::CollapseFullPath(this->Directory);
}
this->Name = cmSystemTools::GetFilenameName(name);
if (kind == cmSourceFileLocationKind::Known) {
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index 8672f61..bf6925e 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -44,6 +44,16 @@ struct StandardNeeded
int value;
};
+int ParseStd(std::string const& level)
+{
+ try {
+ return std::stoi(level);
+ } catch (std::invalid_argument&) {
+ // Fall through to use an invalid value.
+ }
+ return -1;
+}
+
struct StanardLevelComputer
{
explicit StanardLevelComputer(std::string lang, std::vector<int> levels,
@@ -113,17 +123,8 @@ struct StanardLevelComputer
standardStr = "03";
}
- int standardValue = -1;
- int defaultValue = -1;
- try {
- standardValue = std::stoi(standardStr);
- defaultValue = std::stoi(*defaultStd);
- } catch (std::invalid_argument&) {
- // fall through as we want an error
- // when we can't find the bad value in the `stds` vector
- }
-
- auto stdIt = std::find(cm::cbegin(stds), cm::cend(stds), standardValue);
+ auto stdIt =
+ std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(standardStr));
if (stdIt == cm::cend(stds)) {
std::string e =
cmStrCat(this->Language, "_STANDARD is set to invalid value '",
@@ -134,7 +135,7 @@ struct StanardLevelComputer
}
auto defaultStdIt =
- std::find(cm::cbegin(stds), cm::cend(stds), defaultValue);
+ std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(*defaultStd));
if (defaultStdIt == cm::cend(stds)) {
std::string e = cmStrCat("CMAKE_", this->Language,
"_STANDARD_DEFAULT is set to invalid value '",
@@ -195,7 +196,7 @@ struct StanardLevelComputer
if (existingStandard) {
existingLevelIter =
std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
- std::stoi(*existingStandard));
+ ParseStd(*existingStandard));
if (existingLevelIter == cm::cend(this->Levels)) {
const std::string e =
cmStrCat("The ", this->Language, "_STANDARD property on target \"",
@@ -240,7 +241,7 @@ struct StanardLevelComputer
}
// convert defaultStandard to an integer
if (std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
- std::stoi(*defaultStandard)) == cm::cend(this->Levels)) {
+ ParseStd(*defaultStandard)) == cm::cend(this->Levels)) {
const std::string e = cmStrCat("The CMAKE_", this->Language,
"_STANDARD_DEFAULT variable contains an "
"invalid value: \"",
@@ -257,7 +258,7 @@ struct StanardLevelComputer
auto existingLevelIter =
std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
- std::stoi(*existingStandard));
+ ParseStd(*existingStandard));
if (existingLevelIter == cm::cend(this->Levels)) {
const std::string e =
cmStrCat("The ", this->Language, "_STANDARD property on target \"",
@@ -311,19 +312,19 @@ std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping =
std::vector<std::string>{ "90", "99", "11" } } },
{ "CXX",
StanardLevelComputer{
- "CXX", std::vector<int>{ 98, 11, 14, 17, 20 },
- std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+ "CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
+ std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
{ "CUDA",
StanardLevelComputer{
- "CUDA", std::vector<int>{ 03, 11, 14, 17, 20 },
- std::vector<std::string>{ "03", "11", "14", "17", "20" } } },
+ "CUDA", std::vector<int>{ 03, 11, 14, 17, 20, 23 },
+ std::vector<std::string>{ "03", "11", "14", "17", "20", "23" } } },
{ "OBJC",
StanardLevelComputer{ "OBJC", std::vector<int>{ 90, 99, 11 },
std::vector<std::string>{ "90", "99", "11" } } },
{ "OBJCXX",
StanardLevelComputer{
- "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20 },
- std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+ "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
+ std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
};
}
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index d268e62..0fd7901 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -441,6 +441,19 @@ void cmState::AddBuiltinCommand(std::string const& name,
});
}
+void cmState::AddFlowControlCommand(std::string const& name, Command command)
+{
+ this->FlowControlCommands.insert(name);
+ this->AddBuiltinCommand(name, std::move(command));
+}
+
+void cmState::AddFlowControlCommand(std::string const& name,
+ BuiltinCommand command)
+{
+ this->FlowControlCommands.insert(name);
+ this->AddBuiltinCommand(name, command);
+}
+
void cmState::AddDisallowedCommand(std::string const& name,
BuiltinCommand command,
cmPolicies::PolicyID policy,
@@ -470,7 +483,7 @@ void cmState::AddDisallowedCommand(std::string const& name,
void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
- this->AddBuiltinCommand(
+ this->AddFlowControlCommand(
name,
[name, error](std::vector<cmListFileArgument> const&,
cmExecutionStatus& status) -> bool {
@@ -485,21 +498,33 @@ void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
});
}
-void cmState::AddScriptedCommand(std::string const& name, Command command)
+bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command,
+ cmMakefile& mf)
{
std::string sName = cmSystemTools::LowerCase(name);
+ if (this->FlowControlCommands.count(sName)) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Built-in flow control command \"", sName,
+ "\" cannot be overridden."),
+ command.Backtrace);
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
// if the command already exists, give a new name to the old command.
if (Command oldCmd = this->GetCommandByExactName(sName)) {
this->ScriptedCommands["_" + sName] = oldCmd;
}
- this->ScriptedCommands[sName] = std::move(command);
+ this->ScriptedCommands[sName] = std::move(command.Value);
+ return true;
}
cmState::Command cmState::GetCommand(std::string const& name) const
{
- return GetCommandByExactName(cmSystemTools::LowerCase(name));
+ return this->GetCommandByExactName(cmSystemTools::LowerCase(name));
}
cmState::Command cmState::GetCommandByExactName(std::string const& name) const
diff --git a/Source/cmState.h b/Source/cmState.h
index e4c9eb5..4e41156 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -9,6 +9,7 @@
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "cmDefinitions.h"
@@ -24,6 +25,7 @@
class cmCacheManager;
class cmCommand;
class cmGlobVerificationManager;
+class cmMakefile;
class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
@@ -159,10 +161,13 @@ public:
std::unique_ptr<cmCommand> command);
void AddBuiltinCommand(std::string const& name, Command command);
void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
+ void AddFlowControlCommand(std::string const& name, Command command);
+ void AddFlowControlCommand(std::string const& name, BuiltinCommand command);
void AddDisallowedCommand(std::string const& name, BuiltinCommand command,
cmPolicies::PolicyID policy, const char* message);
void AddUnexpectedCommand(std::string const& name, const char* error);
- void AddScriptedCommand(std::string const& name, Command command);
+ bool AddScriptedCommand(std::string const& name, BT<Command> command,
+ cmMakefile& mf);
void RemoveBuiltinCommand(std::string const& name);
void RemoveUserDefinedCommands();
std::vector<std::string> GetCommandNames() const;
@@ -225,6 +230,7 @@ private:
std::vector<std::string> EnabledLanguages;
std::unordered_map<std::string, Command> BuiltinCommands;
std::unordered_map<std::string, Command> ScriptedCommands;
+ std::unordered_set<std::string> FlowControlCommands;
cmPropertyMap GlobalProperties;
std::unique_ptr<cmCacheManager> CacheManager;
std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 796bb1f..7ce362a 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -148,11 +148,13 @@ bool cmStateDirectory::ContainsBoth(std::string const& local_path,
cmSystemTools::IsSubDirectory(a, b));
};
- bool bothInBinary = PathEqOrSubDir(local_path, GetRelativePathTopBinary()) &&
- PathEqOrSubDir(remote_path, GetRelativePathTopBinary());
+ bool bothInBinary =
+ PathEqOrSubDir(local_path, this->GetRelativePathTopBinary()) &&
+ PathEqOrSubDir(remote_path, this->GetRelativePathTopBinary());
- bool bothInSource = PathEqOrSubDir(local_path, GetRelativePathTopSource()) &&
- PathEqOrSubDir(remote_path, GetRelativePathTopSource());
+ bool bothInSource =
+ PathEqOrSubDir(local_path, this->GetRelativePathTopSource()) &&
+ PathEqOrSubDir(remote_path, this->GetRelativePathTopSource());
return bothInBinary || bothInSource;
}
diff --git a/Source/cmString.cxx b/Source/cmString.cxx
index 898b828..8721242 100644
--- a/Source/cmString.cxx
+++ b/Source/cmString.cxx
@@ -19,17 +19,17 @@ void String::internally_mutate_to_stable_string()
// We assume that only one thread mutates this instance at
// a time even if we point to a shared string buffer referenced
// by other threads.
- *this = String(data(), size());
+ *this = String(this->data(), this->size());
}
bool String::is_stable() const
{
- return str_if_stable() != nullptr;
+ return this->str_if_stable() != nullptr;
}
void String::stabilize()
{
- if (is_stable()) {
+ if (this->is_stable()) {
return;
}
this->internally_mutate_to_stable_string();
@@ -37,16 +37,17 @@ void String::stabilize()
std::string const* String::str_if_stable() const
{
- if (!data()) {
+ if (!this->data()) {
// We view no string.
// This is stable for the lifetime of our current value.
return &empty_string_;
}
- if (string_ && data() == string_->data() && size() == string_->size()) {
+ if (this->string_ && this->data() == this->string_->data() &&
+ this->size() == this->string_->size()) {
// We view an entire string.
// This is stable for the lifetime of our current value.
- return string_.get();
+ return this->string_.get();
}
return nullptr;
@@ -54,18 +55,18 @@ std::string const* String::str_if_stable() const
std::string const& String::str()
{
- if (std::string const* s = str_if_stable()) {
+ if (std::string const* s = this->str_if_stable()) {
return *s;
}
// Mutate to hold a std::string that is stable for the lifetime
// of our current value.
this->internally_mutate_to_stable_string();
- return *string_;
+ return *this->string_;
}
const char* String::c_str()
{
- const char* c = data();
+ const char* c = this->data();
if (c == nullptr) {
return c;
}
@@ -73,42 +74,42 @@ const char* String::c_str()
// We always point into a null-terminated string so it is safe to
// access one past the end. If it is a null byte then we can use
// the pointer directly.
- if (c[size()] == '\0') {
+ if (c[this->size()] == '\0') {
return c;
}
// Mutate to hold a std::string so we can get a null terminator.
this->internally_mutate_to_stable_string();
- c = string_->c_str();
+ c = this->string_->c_str();
return c;
}
String& String::insert(size_type index, size_type count, char ch)
{
std::string s;
- s.reserve(size() + count);
- s.assign(data(), size());
+ s.reserve(this->size() + count);
+ s.assign(this->data(), this->size());
s.insert(index, count, ch);
return *this = std::move(s);
}
String& String::erase(size_type index, size_type count)
{
- if (index > size()) {
+ if (index > this->size()) {
throw std::out_of_range("Index out of range in String::erase");
}
- size_type const rcount = std::min(count, size() - index);
+ size_type const rcount = std::min(count, this->size() - index);
size_type const rindex = index + rcount;
std::string s;
- s.reserve(size() - rcount);
- s.assign(data(), index);
- s.append(data() + rindex, size() - rindex);
+ s.reserve(this->size() - rcount);
+ s.assign(this->data(), index);
+ s.append(this->data() + rindex, this->size() - rindex);
return *this = std::move(s);
}
String String::substr(size_type pos, size_type count) const
{
- if (pos > size()) {
+ if (pos > this->size()) {
throw std::out_of_range("Index out of range in String::substr");
}
return String(*this, pos, count);
@@ -116,14 +117,14 @@ String String::substr(size_type pos, size_type count) const
String::String(std::string&& s, Private)
: string_(std::make_shared<std::string>(std::move(s)))
- , view_(string_->data(), string_->size())
+ , view_(this->string_->data(), this->string_->size())
{
}
String::size_type String::copy(char* dest, size_type count,
size_type pos) const
{
- return view_.copy(dest, count, pos);
+ return this->view_.copy(dest, count, pos);
}
std::ostream& operator<<(std::ostream& os, String const& s)
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index b41b960..f1e462b 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -301,8 +301,8 @@ public:
The other instance is left as a null string. */
String& operator=(String&& s) noexcept
{
- string_ = std::move(s.string_);
- view_ = s.view_;
+ this->string_ = std::move(s.string_);
+ this->view_ = s.view_;
s.view_ = string_view();
return *this;
}
@@ -340,33 +340,33 @@ public:
}
/** Return true if the instance is not a null string. */
- explicit operator bool() const noexcept { return data() != nullptr; }
+ explicit operator bool() const noexcept { return this->data() != nullptr; }
/** Return a view of the string. */
- string_view view() const noexcept { return view_; }
+ string_view view() const noexcept { return this->view_; }
operator string_view() const noexcept { return this->view(); }
/** Return true if the instance is an empty stringn or null string. */
- bool empty() const noexcept { return view_.empty(); }
+ bool empty() const noexcept { return this->view_.empty(); }
/** Return a pointer to the start of the string. */
- const char* data() const noexcept { return view_.data(); }
+ const char* data() const noexcept { return this->view_.data(); }
/** Return the length of the string in bytes. */
- size_type size() const noexcept { return view_.size(); }
- size_type length() const noexcept { return view_.length(); }
+ size_type size() const noexcept { return this->view_.size(); }
+ size_type length() const noexcept { return this->view_.length(); }
/** Return the character at the given position.
No bounds checking is performed. */
- char operator[](size_type pos) const noexcept { return view_[pos]; }
+ char operator[](size_type pos) const noexcept { return this->view_[pos]; }
/** Return the character at the given position.
If the position is out of bounds, throws std::out_of_range. */
- char at(size_type pos) const { return view_.at(pos); }
+ char at(size_type pos) const { return this->view_.at(pos); }
- char front() const noexcept { return view_.front(); }
+ char front() const noexcept { return this->view_.front(); }
- char back() const noexcept { return view_.back(); }
+ char back() const noexcept { return this->view_.back(); }
/** Return true if this instance is stable and otherwise false.
An instance is stable if it is in the 'null' state or if it is
@@ -392,15 +392,18 @@ public:
or str() is called. */
const char* c_str();
- const_iterator begin() const noexcept { return view_.begin(); }
- const_iterator end() const noexcept { return view_.end(); }
- const_iterator cbegin() const noexcept { return begin(); }
- const_iterator cend() const noexcept { return end(); }
+ const_iterator begin() const noexcept { return this->view_.begin(); }
+ const_iterator end() const noexcept { return this->view_.end(); }
+ const_iterator cbegin() const noexcept { return this->begin(); }
+ const_iterator cend() const noexcept { return this->end(); }
- const_reverse_iterator rbegin() const noexcept { return view_.rbegin(); }
- const_reverse_iterator rend() const noexcept { return view_.rend(); }
- const_reverse_iterator crbegin() const noexcept { return rbegin(); }
- const_reverse_iterator crend() const noexcept { return rend(); }
+ const_reverse_iterator rbegin() const noexcept
+ {
+ return this->view_.rbegin();
+ }
+ const_reverse_iterator rend() const noexcept { return this->view_.rend(); }
+ const_reverse_iterator crbegin() const noexcept { return this->rbegin(); }
+ const_reverse_iterator crend() const noexcept { return this->rend(); }
/** Append to the string using any type that implements the
AsStringView trait. */
@@ -410,8 +413,8 @@ public:
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
std::string r;
- r.reserve(size() + v.size());
- r.assign(data(), size());
+ r.reserve(this->size() + v.size());
+ r.assign(this->data(), this->size());
r.append(v.data(), v.size());
return *this = std::move(r);
}
@@ -428,21 +431,21 @@ public:
void push_back(char ch)
{
std::string s;
- s.reserve(size() + 1);
- s.assign(data(), size());
+ s.reserve(this->size() + 1);
+ s.assign(this->data(), this->size());
s.push_back(ch);
*this = std::move(s);
}
- void pop_back() { *this = String(*this, 0, size() - 1); }
+ void pop_back() { *this = String(*this, 0, this->size() - 1); }
template <typename T>
typename std::enable_if<AsStringView<T>::value, String&>::type replace(
size_type pos, size_type count, T&& s)
{
- const_iterator first = begin() + pos;
+ const_iterator first = this->begin() + pos;
const_iterator last = first + count;
- return replace(first, last, std::forward<T>(s));
+ return this->replace(first, last, std::forward<T>(s));
}
template <typename InputIterator>
@@ -450,9 +453,9 @@ public:
InputIterator first2, InputIterator last2)
{
std::string out;
- out.append(view_.begin(), first);
+ out.append(this->view_.begin(), first);
out.append(first2, last2);
- out.append(last, view_.end());
+ out.append(last, this->view_.end());
return *this = std::move(out);
}
@@ -462,10 +465,11 @@ public:
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
std::string out;
- out.reserve((first - view_.begin()) + v.size() + (view_.end() - last));
- out.append(view_.begin(), first);
+ out.reserve((first - this->view_.begin()) + v.size() +
+ (this->view_.end() - last));
+ out.append(this->view_.begin(), first);
out.append(v.data(), v.size());
- out.append(last, view_.end());
+ out.append(last, this->view_.end());
return *this = std::move(out);
}
@@ -476,39 +480,40 @@ public:
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
v = v.substr(pos2, count2);
- return replace(pos, count, v);
+ return this->replace(pos, count, v);
}
String& replace(size_type pos, size_type count, size_type count2, char ch)
{
- const_iterator first = begin() + pos;
+ const_iterator first = this->begin() + pos;
const_iterator last = first + count;
- return replace(first, last, count2, ch);
+ return this->replace(first, last, count2, ch);
}
String& replace(const_iterator first, const_iterator last, size_type count2,
char ch)
{
std::string out;
- out.reserve((first - view_.begin()) + count2 + (view_.end() - last));
- out.append(view_.begin(), first);
+ out.reserve((first - this->view_.begin()) + count2 +
+ (this->view_.end() - last));
+ out.append(this->view_.begin(), first);
out.append(count2, ch);
- out.append(last, view_.end());
+ out.append(last, this->view_.end());
return *this = std::move(out);
}
size_type copy(char* dest, size_type count, size_type pos = 0) const;
- void resize(size_type count) { resize(count, char()); }
+ void resize(size_type count) { this->resize(count, char()); }
void resize(size_type count, char ch)
{
std::string s;
s.reserve(count);
- if (count <= size()) {
- s.assign(data(), count);
+ if (count <= this->size()) {
+ s.assign(this->data(), count);
} else {
- s.assign(data(), size());
+ s.assign(this->data(), this->size());
s.resize(count, ch);
}
*this = std::move(s);
@@ -516,8 +521,8 @@ public:
void swap(String& other)
{
- std::swap(string_, other.string_);
- std::swap(view_, other.view_);
+ std::swap(this->string_, other.string_);
+ std::swap(this->view_, other.view_);
}
/** Return a substring starting at position 'pos' and
@@ -528,29 +533,29 @@ public:
typename std::enable_if<AsStringView<T>::value, int>::type compare(
T&& s) const
{
- return view_.compare(AsStringView<T>::view(std::forward<T>(s)));
+ return this->view_.compare(AsStringView<T>::view(std::forward<T>(s)));
}
int compare(size_type pos1, size_type count1, string_view v) const
{
- return view_.compare(pos1, count1, v);
+ return this->view_.compare(pos1, count1, v);
}
int compare(size_type pos1, size_type count1, string_view v, size_type pos2,
size_type count2) const
{
- return view_.compare(pos1, count1, v, pos2, count2);
+ return this->view_.compare(pos1, count1, v, pos2, count2);
}
int compare(size_type pos1, size_type count1, const char* s) const
{
- return view_.compare(pos1, count1, s);
+ return this->view_.compare(pos1, count1, s);
}
int compare(size_type pos1, size_type count1, const char* s,
size_type count2) const
{
- return view_.compare(pos1, count1, s, count2);
+ return this->view_.compare(pos1, count1, s, count2);
}
template <typename T>
@@ -558,12 +563,12 @@ public:
T&& s, size_type pos = 0) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.find(v, pos);
+ return this->view_.find(v, pos);
}
size_type find(const char* s, size_type pos, size_type count) const
{
- return view_.find(s, pos, count);
+ return this->view_.find(s, pos, count);
}
template <typename T>
@@ -571,12 +576,12 @@ public:
T&& s, size_type pos = npos) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.rfind(v, pos);
+ return this->view_.rfind(v, pos);
}
size_type rfind(const char* s, size_type pos, size_type count) const
{
- return view_.rfind(s, pos, count);
+ return this->view_.rfind(s, pos, count);
}
template <typename T>
@@ -584,12 +589,12 @@ public:
find_first_of(T&& s, size_type pos = 0) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.find_first_of(v, pos);
+ return this->view_.find_first_of(v, pos);
}
size_type find_first_of(const char* s, size_type pos, size_type count) const
{
- return view_.find_first_of(s, pos, count);
+ return this->view_.find_first_of(s, pos, count);
}
template <typename T>
@@ -597,13 +602,13 @@ public:
find_first_not_of(T&& s, size_type pos = 0) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.find_first_not_of(v, pos);
+ return this->view_.find_first_not_of(v, pos);
}
size_type find_first_not_of(const char* s, size_type pos,
size_type count) const
{
- return view_.find_first_not_of(s, pos, count);
+ return this->view_.find_first_not_of(s, pos, count);
}
template <typename T>
@@ -611,12 +616,12 @@ public:
find_last_of(T&& s, size_type pos = npos) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.find_last_of(v, pos);
+ return this->view_.find_last_of(v, pos);
}
size_type find_last_of(const char* s, size_type pos, size_type count) const
{
- return view_.find_last_of(s, pos, count);
+ return this->view_.find_last_of(s, pos, count);
}
template <typename T>
@@ -624,13 +629,13 @@ public:
find_last_not_of(T&& s, size_type pos = npos) const
{
string_view v = AsStringView<T>::view(std::forward<T>(s));
- return view_.find_last_not_of(v, pos);
+ return this->view_.find_last_not_of(v, pos);
}
size_type find_last_not_of(const char* s, size_type pos,
size_type count) const
{
- return view_.find_last_not_of(s, pos, count);
+ return this->view_.find_last_not_of(s, pos, count);
}
private:
@@ -822,7 +827,10 @@ struct StringOpPlus
}
#endif
operator std::string() const;
- std::string::size_type size() const { return l.size() + r.size(); }
+ std::string::size_type size() const
+ {
+ return this->l.size() + this->r.size();
+ }
};
template <typename T>
@@ -848,7 +856,7 @@ template <typename L, typename R>
StringOpPlus<L, R>::operator std::string() const
{
std::string s;
- s.reserve(size());
+ s.reserve(this->size());
s += *this;
return s;
}
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index e0af281..fb0b705 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -161,42 +161,42 @@ inline void MakeDigits(cm::string_view& view, char (&digits)[N],
cmAlphaNum::cmAlphaNum(int val)
{
- MakeDigits(View_, Digits_, "%i", val);
+ MakeDigits(this->View_, this->Digits_, "%i", val);
}
cmAlphaNum::cmAlphaNum(unsigned int val)
{
- MakeDigits(View_, Digits_, "%u", val);
+ MakeDigits(this->View_, this->Digits_, "%u", val);
}
cmAlphaNum::cmAlphaNum(long int val)
{
- MakeDigits(View_, Digits_, "%li", val);
+ MakeDigits(this->View_, this->Digits_, "%li", val);
}
cmAlphaNum::cmAlphaNum(unsigned long int val)
{
- MakeDigits(View_, Digits_, "%lu", val);
+ MakeDigits(this->View_, this->Digits_, "%lu", val);
}
cmAlphaNum::cmAlphaNum(long long int val)
{
- MakeDigits(View_, Digits_, "%lli", val);
+ MakeDigits(this->View_, this->Digits_, "%lli", val);
}
cmAlphaNum::cmAlphaNum(unsigned long long int val)
{
- MakeDigits(View_, Digits_, "%llu", val);
+ MakeDigits(this->View_, this->Digits_, "%llu", val);
}
cmAlphaNum::cmAlphaNum(float val)
{
- MakeDigits(View_, Digits_, "%g", static_cast<double>(val));
+ MakeDigits(this->View_, this->Digits_, "%g", static_cast<double>(val));
}
cmAlphaNum::cmAlphaNum(double val)
{
- MakeDigits(View_, Digits_, "%g", val);
+ MakeDigits(this->View_, this->Digits_, "%g", val);
}
std::string cmCatViews(std::initializer_list<cm::string_view> views)
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 01e3d94..6b458ec 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -48,7 +48,7 @@ struct cmStrCmp
{
}
- bool operator()(cm::string_view sv) const { return Test_ == sv; }
+ bool operator()(cm::string_view sv) const { return this->Test_ == sv; }
private:
std::string const Test_;
@@ -163,9 +163,9 @@ public:
{
}
cmAlphaNum(char ch)
- : View_(Digits_, 1)
+ : View_(this->Digits_, 1)
{
- Digits_[0] = ch;
+ this->Digits_[0] = ch;
}
cmAlphaNum(int val);
cmAlphaNum(unsigned int val);
@@ -176,7 +176,7 @@ public:
cmAlphaNum(float val);
cmAlphaNum(double val);
- cm::string_view View() const { return View_; }
+ cm::string_view View() const { return this->View_; }
private:
cm::string_view View_;
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index b28fca9..0c8adc7 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -966,21 +966,21 @@ public:
const std::string& Args::PopFront(cm::string_view error)
{
- if (empty()) {
+ if (this->empty()) {
throw json_error({ error });
}
- const std::string& res = *begin();
- advance(1);
+ const std::string& res = *this->begin();
+ this->advance(1);
return res;
}
const std::string& Args::PopBack(cm::string_view error)
{
- if (empty()) {
+ if (this->empty()) {
throw json_error({ error });
}
- const std::string& res = *(end() - 1);
- retreat(1);
+ const std::string& res = *(this->end() - 1);
+ this->retreat(1);
return res;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 6a705f4..024356f 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1255,6 +1255,30 @@ void cmSystemTools::ConvertToOutputSlashes(std::string& path)
#endif
}
+void cmSystemTools::ConvertToLongPath(std::string& path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Try to convert path to a long path only if the path contains character '~'
+ if (path.find('~') == std::string::npos) {
+ return;
+ }
+
+ std::wstring wPath = cmsys::Encoding::ToWide(path);
+ DWORD ret = GetLongPathNameW(wPath.c_str(), nullptr, 0);
+ std::vector<wchar_t> buffer(ret);
+ if (ret != 0) {
+ ret = GetLongPathNameW(wPath.c_str(), buffer.data(),
+ static_cast<DWORD>(buffer.size()));
+ }
+
+ if (ret != 0) {
+ path = cmsys::Encoding::ToNarrow(buffer.data());
+ }
+#else
+ static_cast<void>(path);
+#endif
+}
+
std::string cmSystemTools::ConvertToRunCommandPath(const std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 1100f05..5bbbb0c 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -287,6 +287,12 @@ public:
// running cmake needs paths to be in its format
static std::string ConvertToRunCommandPath(const std::string& path);
+ /**
+ * For windows computes the long path for the given path,
+ * For Unix, it is a noop
+ */
+ static void ConvertToLongPath(std::string& path);
+
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.
Both remote and local must be full paths. Basically, if
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bda2b30..1fd2355 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -213,7 +213,7 @@ public:
bool CheckImportedLibName(std::string const& prop,
std::string const& value) const;
- std::string ProcessSourceItemCMP0049(const std::string& s);
+ std::string ProcessSourceItemCMP0049(const std::string& s) const;
};
namespace {
@@ -230,34 +230,35 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
: impl(cm::make_unique<cmTargetInternals>())
{
assert(mf);
- impl->TargetType = type;
- impl->Makefile = mf;
- impl->Name = name;
- impl->IsGeneratorProvided = false;
- impl->HaveInstallRule = false;
- impl->IsDLLPlatform = false;
- impl->IsAIX = false;
- impl->IsAndroid = false;
- impl->IsImportedTarget =
+ this->impl->TargetType = type;
+ this->impl->Makefile = mf;
+ this->impl->Name = name;
+ this->impl->IsGeneratorProvided = false;
+ this->impl->HaveInstallRule = false;
+ this->impl->IsDLLPlatform = false;
+ this->impl->IsAIX = false;
+ this->impl->IsAndroid = false;
+ this->impl->IsImportedTarget =
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
- impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
- impl->BuildInterfaceIncludesAppended = false;
- impl->PerConfig = (perConfig == PerConfig::Yes);
+ this->impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
+ this->impl->BuildInterfaceIncludesAppended = false;
+ this->impl->PerConfig = (perConfig == PerConfig::Yes);
// Check whether this is a DLL platform.
- impl->IsDLLPlatform =
- !impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
+ this->impl->IsDLLPlatform =
+ !this->impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")
+ .empty();
// Check whether we are targeting AIX.
{
std::string const& systemName =
- impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- impl->IsAIX = (systemName == "AIX" || systemName == "OS400");
+ this->impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ this->impl->IsAIX = (systemName == "AIX" || systemName == "OS400");
}
// Check whether we are targeting an Android platform.
- impl->IsAndroid =
- (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
+ this->impl->IsAndroid = (this->impl->Makefile->GetSafeDefinition(
+ "CMAKE_SYSTEM_NAME") == "Android");
std::string defKey;
defKey.reserve(128);
@@ -373,12 +374,16 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("ISPC_INSTRUCTION_SETS");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
+ initProp("OBJC_CLANG_TIDY");
+ initProp("OBJCXX_CLANG_TIDY");
initProp("Swift_LANGUAGE_VERSION");
initProp("Swift_MODULE_DIRECTORY");
initProp("VS_JUST_MY_CODE_DEBUGGING");
initProp("DISABLE_PRECOMPILE_HEADERS");
initProp("UNITY_BUILD");
+ initProp("UNITY_BUILD_UNIQUE_ID");
initProp("OPTIMIZE_DEPENDENCIES");
+ initProp("EXPORT_COMPILE_COMMANDS");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
initPropValue("UNITY_BUILD_MODE", "BATCH");
initPropValue("PCH_WARN_INVALID", "ON");
@@ -433,7 +438,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
for (auto const& prop : configProps) {
// Interface libraries have no output locations, so honor only
// the configuration map.
- if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY &&
+ if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY &&
strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) {
continue;
}
@@ -446,15 +451,15 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
// compatibility with previous CMake versions in which executables
// did not support this variable. Projects may still specify the
// property directly.
- if (impl->TargetType != cmStateEnums::EXECUTABLE &&
- impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) {
+ if (this->impl->TargetType != cmStateEnums::EXECUTABLE &&
+ this->impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) {
std::string property =
cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
initProp(property);
}
- if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
- impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
+ if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ this->impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
cmSystemTools::UpperCase(configName));
initProp(property);
@@ -463,66 +468,67 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
// Save the backtrace of target construction.
- impl->Backtrace = impl->Makefile->GetBacktrace();
+ this->impl->Backtrace = this->impl->Makefile->GetBacktrace();
if (!this->IsImported()) {
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- cm::append(impl->IncludeDirectoriesEntries,
- impl->Makefile->GetIncludeDirectoriesEntries());
- cm::append(impl->IncludeDirectoriesBacktraces,
- impl->Makefile->GetIncludeDirectoriesBacktraces());
+ cm::append(this->impl->IncludeDirectoriesEntries,
+ this->impl->Makefile->GetIncludeDirectoriesEntries());
+ cm::append(this->impl->IncludeDirectoriesBacktraces,
+ this->impl->Makefile->GetIncludeDirectoriesBacktraces());
{
- auto const& sysInc = impl->Makefile->GetSystemIncludeDirectories();
- impl->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end());
+ auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories();
+ this->impl->SystemIncludeDirectories.insert(sysInc.begin(),
+ sysInc.end());
}
- cm::append(impl->CompileOptionsEntries,
- impl->Makefile->GetCompileOptionsEntries());
- cm::append(impl->CompileOptionsBacktraces,
- impl->Makefile->GetCompileOptionsBacktraces());
+ cm::append(this->impl->CompileOptionsEntries,
+ this->impl->Makefile->GetCompileOptionsEntries());
+ cm::append(this->impl->CompileOptionsBacktraces,
+ this->impl->Makefile->GetCompileOptionsBacktraces());
- cm::append(impl->LinkOptionsEntries,
- impl->Makefile->GetLinkOptionsEntries());
- cm::append(impl->LinkOptionsBacktraces,
- impl->Makefile->GetLinkOptionsBacktraces());
+ cm::append(this->impl->LinkOptionsEntries,
+ this->impl->Makefile->GetLinkOptionsEntries());
+ cm::append(this->impl->LinkOptionsBacktraces,
+ this->impl->Makefile->GetLinkOptionsBacktraces());
- cm::append(impl->LinkDirectoriesEntries,
- impl->Makefile->GetLinkDirectoriesEntries());
- cm::append(impl->LinkDirectoriesBacktraces,
- impl->Makefile->GetLinkDirectoriesBacktraces());
+ cm::append(this->impl->LinkDirectoriesEntries,
+ this->impl->Makefile->GetLinkDirectoriesEntries());
+ cm::append(this->impl->LinkDirectoriesBacktraces,
+ this->impl->Makefile->GetLinkDirectoriesBacktraces());
}
- if (impl->TargetType == cmStateEnums::EXECUTABLE) {
+ if (this->impl->TargetType == cmStateEnums::EXECUTABLE) {
initProp("ANDROID_GUI");
initProp("CROSSCOMPILING_EMULATOR");
initProp("ENABLE_EXPORTS");
}
- if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
- impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
+ if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ this->impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
} else if (this->CanCompileSources()) {
initProp("POSITION_INDEPENDENT_CODE");
}
- if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
- impl->TargetType == cmStateEnums::EXECUTABLE) {
+ if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ this->impl->TargetType == cmStateEnums::EXECUTABLE) {
initProp("AIX_EXPORT_ALL_SYMBOLS");
initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
}
// Record current policies for later use.
- impl->Makefile->RecordPolicies(impl->PolicyMap);
+ this->impl->Makefile->RecordPolicies(this->impl->PolicyMap);
- if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) {
+ if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) {
// This policy is checked in a few conditions. The properties relevant
// to the policy are always ignored for cmStateEnums::INTERFACE_LIBRARY
// targets,
// so ensure that the conditions don't lead to nonsense.
- impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
+ this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
}
- if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
+ if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
@@ -555,40 +561,40 @@ cmTarget& cmTarget::operator=(cmTarget&&) noexcept = default;
cmStateEnums::TargetType cmTarget::GetType() const
{
- return impl->TargetType;
+ return this->impl->TargetType;
}
cmMakefile* cmTarget::GetMakefile() const
{
- return impl->Makefile;
+ return this->impl->Makefile;
}
cmPolicies::PolicyMap const& cmTarget::GetPolicyMap() const
{
- return impl->PolicyMap;
+ return this->impl->PolicyMap;
}
const std::string& cmTarget::GetName() const
{
- return impl->Name;
+ return this->impl->Name;
}
cmPolicies::PolicyStatus cmTarget::GetPolicyStatus(
cmPolicies::PolicyID policy) const
{
- return impl->PolicyMap.Get(policy);
+ return this->impl->PolicyMap.Get(policy);
}
cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
{
- return impl->Makefile->GetGlobalGenerator();
+ return this->impl->Makefile->GetGlobalGenerator();
}
BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
const std::string& propertyName) const
{
- auto entry = impl->LanguageStandardProperties.find(propertyName);
- if (entry != impl->LanguageStandardProperties.end()) {
+ auto entry = this->impl->LanguageStandardProperties.find(propertyName);
+ if (entry != this->impl->LanguageStandardProperties.end()) {
return &entry->second;
}
@@ -600,17 +606,17 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang,
const std::string& feature)
{
cmListFileBacktrace featureBacktrace;
- for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) {
- if (impl->CompileFeaturesEntries[i] == feature) {
- if (i < impl->CompileFeaturesBacktraces.size()) {
- featureBacktrace = impl->CompileFeaturesBacktraces[i];
+ for (size_t i = 0; i < this->impl->CompileFeaturesEntries.size(); i++) {
+ if (this->impl->CompileFeaturesEntries[i] == feature) {
+ if (i < this->impl->CompileFeaturesBacktraces.size()) {
+ featureBacktrace = this->impl->CompileFeaturesBacktraces[i];
}
break;
}
}
BTs<std::string>& languageStandardProperty =
- impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
+ this->impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
if (languageStandardProperty.Value != value) {
languageStandardProperty.Value = value;
languageStandardProperty.Backtraces.clear();
@@ -620,19 +626,24 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang,
void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
{
- impl->Utilities.insert(BT<std::pair<std::string, bool>>(
+ this->impl->Utilities.insert(BT<std::pair<std::string, bool>>(
{ name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
}
+void cmTarget::AddUtility(BT<std::pair<std::string, bool>> util)
+{
+ this->impl->Utilities.emplace(std::move(util));
+}
+
std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
const
{
- return impl->Utilities;
+ return this->impl->Utilities;
}
cmListFileBacktrace const& cmTarget::GetBacktrace() const
{
- return impl->Backtrace;
+ return this->impl->Backtrace;
}
bool cmTarget::IsExecutableWithExports() const
@@ -645,74 +656,74 @@ bool cmTarget::IsFrameworkOnApple() const
{
return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
- impl->Makefile->IsOn("APPLE") &&
+ this->impl->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("FRAMEWORK"));
}
bool cmTarget::IsAppBundleOnApple() const
{
return (this->GetType() == cmStateEnums::EXECUTABLE &&
- impl->Makefile->IsOn("APPLE") &&
+ this->impl->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
bool cmTarget::IsAndroidGuiExecutable() const
{
- return (this->GetType() == cmStateEnums::EXECUTABLE && impl->IsAndroid &&
- this->GetPropertyAsBool("ANDROID_GUI"));
+ return (this->GetType() == cmStateEnums::EXECUTABLE &&
+ this->impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI"));
}
std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
{
- return impl->PreBuildCommands;
+ return this->impl->PreBuildCommands;
}
void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd)
{
- impl->PreBuildCommands.push_back(cmd);
+ this->impl->PreBuildCommands.push_back(cmd);
}
void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd)
{
- impl->PreBuildCommands.push_back(std::move(cmd));
+ this->impl->PreBuildCommands.push_back(std::move(cmd));
}
std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const
{
- return impl->PreLinkCommands;
+ return this->impl->PreLinkCommands;
}
void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd)
{
- impl->PreLinkCommands.push_back(cmd);
+ this->impl->PreLinkCommands.push_back(cmd);
}
void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd)
{
- impl->PreLinkCommands.push_back(std::move(cmd));
+ this->impl->PreLinkCommands.push_back(std::move(cmd));
}
std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const
{
- return impl->PostBuildCommands;
+ return this->impl->PostBuildCommands;
}
void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd)
{
- impl->PostBuildCommands.push_back(cmd);
+ this->impl->PostBuildCommands.push_back(cmd);
}
void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd)
{
- impl->PostBuildCommands.push_back(std::move(cmd));
+ this->impl->PostBuildCommands.push_back(std::move(cmd));
}
void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
{
if (!srcs.empty()) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->SourceEntries.push_back(cmJoin(srcs, ";"));
- impl->SourceBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->SourceEntries.push_back(cmJoin(srcs, ";"));
+ this->impl->SourceBacktraces.push_back(lfbt);
}
}
@@ -723,25 +734,26 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
for (auto filename : srcs) {
if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) {
if (!filename.empty()) {
- filename = impl->ProcessSourceItemCMP0049(filename);
+ filename = this->impl->ProcessSourceItemCMP0049(filename);
if (filename.empty()) {
return;
}
}
- impl->Makefile->GetOrCreateSource(filename);
+ this->impl->Makefile->GetOrCreateSource(filename);
}
srcFiles += sep;
srcFiles += filename;
sep = ";";
}
if (!srcFiles.empty()) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->SourceEntries.push_back(std::move(srcFiles));
- impl->SourceBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->SourceEntries.push_back(std::move(srcFiles));
+ this->impl->SourceBacktraces.push_back(lfbt);
}
}
-std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s)
+std::string cmTargetInternals::ProcessSourceItemCMP0049(
+ const std::string& s) const
{
std::string src = s;
@@ -780,7 +792,7 @@ std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s)
std::string cmTarget::GetSourceCMP0049(const std::string& s)
{
- return impl->ProcessSourceItemCMP0049(s);
+ return this->impl->ProcessSourceItemCMP0049(s);
}
struct CreateLocation
@@ -792,7 +804,7 @@ struct CreateLocation
{
}
- cmSourceFileLocation operator()(const std::string& filename)
+ cmSourceFileLocation operator()(const std::string& filename) const
{
return cmSourceFileLocation(this->Makefile, filename);
}
@@ -839,26 +851,28 @@ public:
cmSourceFile* cmTarget::AddSource(const std::string& src, bool before)
{
- cmSourceFileLocation sfl(impl->Makefile, src,
+ cmSourceFileLocation sfl(this->impl->Makefile, src,
cmSourceFileLocationKind::Known);
- if (std::find_if(impl->SourceEntries.begin(), impl->SourceEntries.end(),
- TargetPropertyEntryFinder(sfl)) ==
- impl->SourceEntries.end()) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->SourceEntries.insert(
- before ? impl->SourceEntries.begin() : impl->SourceEntries.end(), src);
- impl->SourceBacktraces.insert(before ? impl->SourceBacktraces.begin()
- : impl->SourceBacktraces.end(),
- lfbt);
+ if (std::find_if(
+ this->impl->SourceEntries.begin(), this->impl->SourceEntries.end(),
+ TargetPropertyEntryFinder(sfl)) == this->impl->SourceEntries.end()) {
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->SourceEntries.insert(before ? this->impl->SourceEntries.begin()
+ : this->impl->SourceEntries.end(),
+ src);
+ this->impl->SourceBacktraces.insert(
+ before ? this->impl->SourceBacktraces.begin()
+ : this->impl->SourceBacktraces.end(),
+ lfbt);
}
if (cmGeneratorExpression::Find(src) != std::string::npos) {
return nullptr;
}
- return impl->Makefile->GetOrCreateSource(src, false,
- cmSourceFileLocationKind::Known);
+ return this->impl->Makefile->GetOrCreateSource(
+ src, false, cmSourceFileLocationKind::Known);
}
-void cmTarget::ClearDependencyInformation(cmMakefile& mf)
+void cmTarget::ClearDependencyInformation(cmMakefile& mf) const
{
std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS");
mf.RemoveCacheDefinition(depname);
@@ -873,7 +887,7 @@ std::string cmTarget::GetDebugGeneratorExpressions(
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> debugConfigs =
- impl->Makefile->GetCMakeInstance()->GetDebugConfigs();
+ this->impl->Makefile->GetCMakeInstance()->GetDebugConfigs();
std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
@@ -899,13 +913,14 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
cmListFileContext const& lfc)
{
bool ret = true;
- if (!impl->TLLCommands.empty()) {
- if (impl->TLLCommands.back().first != signature) {
+ if (!this->impl->TLLCommands.empty()) {
+ if (this->impl->TLLCommands.back().first != signature) {
ret = false;
}
}
- if (impl->TLLCommands.empty() || impl->TLLCommands.back().second != lfc) {
- impl->TLLCommands.emplace_back(signature, lfc);
+ if (this->impl->TLLCommands.empty() ||
+ this->impl->TLLCommands.back().second != lfc) {
+ this->impl->TLLCommands.emplace_back(signature, lfc);
}
return ret;
}
@@ -915,12 +930,13 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
const char* sigString =
(sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain");
s << "The uses of the " << sigString << " signature are here:\n";
- cmStateDirectory cmDir = impl->Makefile->GetStateSnapshot().GetDirectory();
- for (auto const& cmd : impl->TLLCommands) {
+ cmStateDirectory cmDir =
+ this->impl->Makefile->GetStateSnapshot().GetDirectory();
+ for (auto const& cmd : this->impl->TLLCommands) {
if (cmd.first == sig) {
cmListFileContext lfc = cmd.second;
lfc.FilePath = cmDir.ConvertToRelPathIfNotContained(
- impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
+ this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
s << " * " << lfc << '\n';
}
}
@@ -928,59 +944,59 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
std::string const& cmTarget::GetInstallPath() const
{
- return impl->InstallPath;
+ return this->impl->InstallPath;
}
void cmTarget::SetInstallPath(std::string const& name)
{
- impl->InstallPath = name;
+ this->impl->InstallPath = name;
}
std::string const& cmTarget::GetRuntimeInstallPath() const
{
- return impl->RuntimeInstallPath;
+ return this->impl->RuntimeInstallPath;
}
void cmTarget::SetRuntimeInstallPath(std::string const& name)
{
- impl->RuntimeInstallPath = name;
+ this->impl->RuntimeInstallPath = name;
}
bool cmTarget::GetHaveInstallRule() const
{
- return impl->HaveInstallRule;
+ return this->impl->HaveInstallRule;
}
void cmTarget::SetHaveInstallRule(bool hir)
{
- impl->HaveInstallRule = hir;
+ this->impl->HaveInstallRule = hir;
}
void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
{
- impl->InstallGenerators.emplace_back(g);
+ this->impl->InstallGenerators.emplace_back(g);
}
std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
const
{
- return impl->InstallGenerators;
+ return this->impl->InstallGenerators;
}
bool cmTarget::GetIsGeneratorProvided() const
{
- return impl->IsGeneratorProvided;
+ return this->impl->IsGeneratorProvided;
}
void cmTarget::SetIsGeneratorProvided(bool igp)
{
- impl->IsGeneratorProvided = igp;
+ this->impl->IsGeneratorProvided = igp;
}
cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries()
const
{
- return impl->OriginalLinkLibraries;
+ return this->impl->OriginalLinkLibraries;
}
void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
@@ -1002,11 +1018,11 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
(tgt &&
(tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
- (impl->Name == lib)) {
+ (this->impl->Name == lib)) {
return;
}
- impl->OriginalLinkLibraries.emplace_back(lib, llt);
+ this->impl->OriginalLinkLibraries.emplace_back(lib, llt);
// Add the explicit dependency information for libraries. This is
// simply a set of libraries separated by ";". There should always
@@ -1016,11 +1032,11 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
// may be purposefully duplicated to handle recursive dependencies,
// and we removing one instance will break the link line. Duplicates
// will be appropriately eliminated at emit time.
- if (impl->TargetType >= cmStateEnums::STATIC_LIBRARY &&
- impl->TargetType <= cmStateEnums::MODULE_LIBRARY &&
+ if (this->impl->TargetType >= cmStateEnums::STATIC_LIBRARY &&
+ this->impl->TargetType <= cmStateEnums::MODULE_LIBRARY &&
(this->GetPolicyStatusCMP0073() == cmPolicies::OLD ||
this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) {
- std::string targetEntry = cmStrCat(impl->Name, "_LIB_DEPENDS");
+ std::string targetEntry = cmStrCat(this->impl->Name, "_LIB_DEPENDS");
std::string dependencies;
cmProp old_val = mf.GetDefinition(targetEntry);
if (old_val) {
@@ -1047,102 +1063,102 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
void cmTarget::AddSystemIncludeDirectories(const std::set<std::string>& incs)
{
- impl->SystemIncludeDirectories.insert(incs.begin(), incs.end());
+ this->impl->SystemIncludeDirectories.insert(incs.begin(), incs.end());
}
std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const
{
- return impl->SystemIncludeDirectories;
+ return this->impl->SystemIncludeDirectories;
}
cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
- return cmMakeRange(impl->IncludeDirectoriesEntries);
+ return cmMakeRange(this->impl->IncludeDirectoriesEntries);
}
cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
{
- return cmMakeRange(impl->IncludeDirectoriesBacktraces);
+ return cmMakeRange(this->impl->IncludeDirectoriesBacktraces);
}
cmStringRange cmTarget::GetCompileOptionsEntries() const
{
- return cmMakeRange(impl->CompileOptionsEntries);
+ return cmMakeRange(this->impl->CompileOptionsEntries);
}
cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
{
- return cmMakeRange(impl->CompileOptionsBacktraces);
+ return cmMakeRange(this->impl->CompileOptionsBacktraces);
}
cmStringRange cmTarget::GetCompileFeaturesEntries() const
{
- return cmMakeRange(impl->CompileFeaturesEntries);
+ return cmMakeRange(this->impl->CompileFeaturesEntries);
}
cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
{
- return cmMakeRange(impl->CompileFeaturesBacktraces);
+ return cmMakeRange(this->impl->CompileFeaturesBacktraces);
}
cmStringRange cmTarget::GetCompileDefinitionsEntries() const
{
- return cmMakeRange(impl->CompileDefinitionsEntries);
+ return cmMakeRange(this->impl->CompileDefinitionsEntries);
}
cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
{
- return cmMakeRange(impl->CompileDefinitionsBacktraces);
+ return cmMakeRange(this->impl->CompileDefinitionsBacktraces);
}
cmStringRange cmTarget::GetPrecompileHeadersEntries() const
{
- return cmMakeRange(impl->PrecompileHeadersEntries);
+ return cmMakeRange(this->impl->PrecompileHeadersEntries);
}
cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const
{
- return cmMakeRange(impl->PrecompileHeadersBacktraces);
+ return cmMakeRange(this->impl->PrecompileHeadersBacktraces);
}
cmStringRange cmTarget::GetSourceEntries() const
{
- return cmMakeRange(impl->SourceEntries);
+ return cmMakeRange(this->impl->SourceEntries);
}
cmBacktraceRange cmTarget::GetSourceBacktraces() const
{
- return cmMakeRange(impl->SourceBacktraces);
+ return cmMakeRange(this->impl->SourceBacktraces);
}
cmStringRange cmTarget::GetLinkOptionsEntries() const
{
- return cmMakeRange(impl->LinkOptionsEntries);
+ return cmMakeRange(this->impl->LinkOptionsEntries);
}
cmBacktraceRange cmTarget::GetLinkOptionsBacktraces() const
{
- return cmMakeRange(impl->LinkOptionsBacktraces);
+ return cmMakeRange(this->impl->LinkOptionsBacktraces);
}
cmStringRange cmTarget::GetLinkDirectoriesEntries() const
{
- return cmMakeRange(impl->LinkDirectoriesEntries);
+ return cmMakeRange(this->impl->LinkDirectoriesEntries);
}
cmBacktraceRange cmTarget::GetLinkDirectoriesBacktraces() const
{
- return cmMakeRange(impl->LinkDirectoriesBacktraces);
+ return cmMakeRange(this->impl->LinkDirectoriesBacktraces);
}
cmStringRange cmTarget::GetLinkImplementationEntries() const
{
- return cmMakeRange(impl->LinkImplementationPropertyEntries);
+ return cmMakeRange(this->impl->LinkImplementationPropertyEntries);
}
cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
{
- return cmMakeRange(impl->LinkImplementationPropertyBacktraces);
+ return cmMakeRange(this->impl->LinkImplementationPropertyBacktraces);
}
void cmTarget::SetProperty(const std::string& prop, const char* value)
@@ -1171,154 +1187,154 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(TYPE);
#undef MAKE_STATIC_PROP
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
- impl->Makefile->IssueMessage(
+ this->impl->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"MANUALLY_ADDED_DEPENDENCIES property is read-only\n");
return;
}
if (prop == propNAME) {
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "NAME property is read-only\n");
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == propTYPE) {
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "TYPE property is read-only\n");
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "TYPE property is read-only\n");
return;
}
if (prop == propEXPORT_NAME && this->IsImported()) {
std::ostringstream e;
e << "EXPORT_NAME property can't be set on imported targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == propSOURCES && this->IsImported()) {
std::ostringstream e;
- e << "SOURCES property can't be set on imported targets (\"" << impl->Name
- << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ e << "SOURCES property can't be set on imported targets (\""
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == propIMPORTED_GLOBAL && !this->IsImported()) {
std::ostringstream e;
e << "IMPORTED_GLOBAL property can't be set on non-imported targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == propINCLUDE_DIRECTORIES) {
- impl->IncludeDirectoriesEntries.clear();
- impl->IncludeDirectoriesBacktraces.clear();
+ this->impl->IncludeDirectoriesEntries.clear();
+ this->impl->IncludeDirectoriesBacktraces.clear();
if (value) {
- impl->IncludeDirectoriesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->IncludeDirectoriesBacktraces.push_back(lfbt);
+ this->impl->IncludeDirectoriesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->IncludeDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == propCOMPILE_OPTIONS) {
- impl->CompileOptionsEntries.clear();
- impl->CompileOptionsBacktraces.clear();
+ this->impl->CompileOptionsEntries.clear();
+ this->impl->CompileOptionsBacktraces.clear();
if (value) {
- impl->CompileOptionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileOptionsBacktraces.push_back(lfbt);
+ this->impl->CompileOptionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileOptionsBacktraces.push_back(lfbt);
}
} else if (prop == propCOMPILE_FEATURES) {
- impl->CompileFeaturesEntries.clear();
- impl->CompileFeaturesBacktraces.clear();
+ this->impl->CompileFeaturesEntries.clear();
+ this->impl->CompileFeaturesBacktraces.clear();
if (value) {
- impl->CompileFeaturesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileFeaturesBacktraces.push_back(lfbt);
+ this->impl->CompileFeaturesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileFeaturesBacktraces.push_back(lfbt);
}
} else if (prop == propCOMPILE_DEFINITIONS) {
- impl->CompileDefinitionsEntries.clear();
- impl->CompileDefinitionsBacktraces.clear();
+ this->impl->CompileDefinitionsEntries.clear();
+ this->impl->CompileDefinitionsBacktraces.clear();
if (value) {
- impl->CompileDefinitionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileDefinitionsBacktraces.push_back(lfbt);
+ this->impl->CompileDefinitionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileDefinitionsBacktraces.push_back(lfbt);
}
} else if (prop == propLINK_OPTIONS) {
- impl->LinkOptionsEntries.clear();
- impl->LinkOptionsBacktraces.clear();
+ this->impl->LinkOptionsEntries.clear();
+ this->impl->LinkOptionsBacktraces.clear();
if (value) {
- impl->LinkOptionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkOptionsBacktraces.push_back(lfbt);
+ this->impl->LinkOptionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkOptionsBacktraces.push_back(lfbt);
}
} else if (prop == propLINK_DIRECTORIES) {
- impl->LinkDirectoriesEntries.clear();
- impl->LinkDirectoriesBacktraces.clear();
+ this->impl->LinkDirectoriesEntries.clear();
+ this->impl->LinkDirectoriesBacktraces.clear();
if (value) {
- impl->LinkDirectoriesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkDirectoriesBacktraces.push_back(lfbt);
+ this->impl->LinkDirectoriesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == propPRECOMPILE_HEADERS) {
- impl->PrecompileHeadersEntries.clear();
- impl->PrecompileHeadersBacktraces.clear();
+ this->impl->PrecompileHeadersEntries.clear();
+ this->impl->PrecompileHeadersBacktraces.clear();
if (value) {
- impl->PrecompileHeadersEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ this->impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->PrecompileHeadersBacktraces.push_back(lfbt);
}
} else if (prop == propLINK_LIBRARIES) {
- impl->LinkImplementationPropertyEntries.clear();
- impl->LinkImplementationPropertyBacktraces.clear();
+ this->impl->LinkImplementationPropertyEntries.clear();
+ this->impl->LinkImplementationPropertyBacktraces.clear();
if (value) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkImplementationPropertyEntries.emplace_back(value);
- impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkImplementationPropertyEntries.emplace_back(value);
+ this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == propSOURCES) {
- impl->SourceEntries.clear();
- impl->SourceBacktraces.clear();
+ this->impl->SourceEntries.clear();
+ this->impl->SourceBacktraces.clear();
if (value) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->SourceEntries.emplace_back(value);
- impl->SourceBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->SourceEntries.emplace_back(value);
+ this->impl->SourceBacktraces.push_back(lfbt);
}
} else if (prop == propIMPORTED_GLOBAL) {
if (!cmIsOn(value)) {
std::ostringstream e;
e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
/* no need to change anything if value does not change */
- if (!impl->ImportedGloballyVisible) {
- impl->ImportedGloballyVisible = true;
+ if (!this->impl->ImportedGloballyVisible) {
+ this->impl->ImportedGloballyVisible = true;
this->GetGlobalGenerator()->IndexTarget(this);
}
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
- !impl->CheckImportedLibName(prop, value ? value : "")) {
+ !this->impl->CheckImportedLibName(prop, value ? value : "")) {
/* error was reported by check method */
} else if (prop == propCUDA_PTX_COMPILATION &&
this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
std::ostringstream e;
e << "CUDA_PTX_COMPILATION property can only be applied to OBJECT "
"targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
} else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) {
if (this->GetProperty("PRECOMPILE_HEADERS")) {
std::ostringstream e;
e << "PRECOMPILE_HEADERS property is already set on target (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
- auto reusedTarget =
- impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
- value);
+ auto reusedTarget = this->impl->Makefile->GetCMakeInstance()
+ ->GetGlobalGenerator()
+ ->FindTarget(value);
if (!reusedTarget) {
const std::string e(
"PRECOMPILE_HEADERS_REUSE_FROM set with non existing target");
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
return;
}
@@ -1327,7 +1343,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
reusedFrom = value;
}
- impl->Properties.SetProperty(prop, reusedFrom.c_str());
+ this->impl->Properties.SetProperty(prop, reusedFrom.c_str());
reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
@@ -1335,18 +1351,18 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
this->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp));
- this->AddUtility(reusedFrom, false, impl->Makefile);
+ this->AddUtility(reusedFrom, false, this->impl->Makefile);
} else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
prop == propOBJCXX_STANDARD) {
if (value) {
- impl->LanguageStandardProperties[prop] =
- BTs<std::string>(value, impl->Makefile->GetBacktrace());
+ this->impl->LanguageStandardProperties[prop] =
+ BTs<std::string>(value, this->impl->Makefile->GetBacktrace());
} else {
- impl->LanguageStandardProperties.erase(prop);
+ this->impl->LanguageStandardProperties.erase(prop);
}
} else {
- impl->Properties.SetProperty(prop, value);
+ this->impl->Properties.SetProperty(prop, value);
}
}
@@ -1354,102 +1370,102 @@ void cmTarget::AppendProperty(const std::string& prop,
const std::string& value, bool asString)
{
if (prop == "NAME") {
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "NAME property is read-only\n");
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == "EXPORT_NAME" && this->IsImported()) {
std::ostringstream e;
e << "EXPORT_NAME property can't be set on imported targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == "SOURCES" && this->IsImported()) {
std::ostringstream e;
- e << "SOURCES property can't be set on imported targets (\"" << impl->Name
- << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ e << "SOURCES property can't be set on imported targets (\""
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == "IMPORTED_GLOBAL") {
std::ostringstream e;
e << "IMPORTED_GLOBAL property can't be appended, only set on imported "
"targets (\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (prop == "INCLUDE_DIRECTORIES") {
if (!value.empty()) {
- impl->IncludeDirectoriesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->IncludeDirectoriesBacktraces.push_back(lfbt);
+ this->impl->IncludeDirectoriesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->IncludeDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_OPTIONS") {
if (!value.empty()) {
- impl->CompileOptionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileOptionsBacktraces.push_back(lfbt);
+ this->impl->CompileOptionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_FEATURES") {
if (!value.empty()) {
- impl->CompileFeaturesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileFeaturesBacktraces.push_back(lfbt);
+ this->impl->CompileFeaturesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileFeaturesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_DEFINITIONS") {
if (!value.empty()) {
- impl->CompileDefinitionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->CompileDefinitionsBacktraces.push_back(lfbt);
+ this->impl->CompileDefinitionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->CompileDefinitionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_OPTIONS") {
if (!value.empty()) {
- impl->LinkOptionsEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkOptionsBacktraces.push_back(lfbt);
+ this->impl->LinkOptionsEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_DIRECTORIES") {
if (!value.empty()) {
- impl->LinkDirectoriesEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkDirectoriesBacktraces.push_back(lfbt);
+ this->impl->LinkDirectoriesEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "PRECOMPILE_HEADERS") {
if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
std::ostringstream e;
e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target "
"(\""
- << impl->Name << "\")\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ << this->impl->Name << "\")\n";
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
if (!value.empty()) {
- impl->PrecompileHeadersEntries.emplace_back(value);
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ this->impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->PrecompileHeadersBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_LIBRARIES") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->LinkImplementationPropertyEntries.emplace_back(value);
- impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkImplementationPropertyEntries.emplace_back(value);
+ this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == "SOURCES") {
- cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
- impl->SourceEntries.emplace_back(value);
- impl->SourceBacktraces.push_back(lfbt);
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->SourceEntries.emplace_back(value);
+ this->impl->SourceBacktraces.push_back(lfbt);
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- prop + " property may not be APPENDed.");
+ this->impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR, prop + " property may not be APPENDed.");
} else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" ||
prop == "OBJCXX_STANDARD") {
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- prop + " property may not be appended.");
+ this->impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR, prop + " property may not be appended.");
} else {
- impl->Properties.AppendProperty(prop, value, asString);
+ this->impl->Properties.AppendProperty(prop, value, asString);
}
}
@@ -1462,17 +1478,17 @@ void cmTarget::AppendBuildInterfaceIncludes()
!this->IsExecutableWithExports()) {
return;
}
- if (impl->BuildInterfaceIncludesAppended) {
+ if (this->impl->BuildInterfaceIncludesAppended) {
return;
}
- impl->BuildInterfaceIncludesAppended = true;
+ this->impl->BuildInterfaceIncludesAppended = true;
- if (impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) {
- std::string dirs = impl->Makefile->GetCurrentBinaryDirectory();
+ if (this->impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) {
+ std::string dirs = this->impl->Makefile->GetCurrentBinaryDirectory();
if (!dirs.empty()) {
dirs += ';';
}
- dirs += impl->Makefile->GetCurrentSourceDirectory();
+ dirs += this->impl->Makefile->GetCurrentSourceDirectory();
if (!dirs.empty()) {
this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
("$<BUILD_INTERFACE:" + dirs + ">"));
@@ -1483,67 +1499,67 @@ void cmTarget::AppendBuildInterfaceIncludes()
void cmTarget::InsertInclude(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- auto position = before ? impl->IncludeDirectoriesEntries.begin()
- : impl->IncludeDirectoriesEntries.end();
+ auto position = before ? this->impl->IncludeDirectoriesEntries.begin()
+ : this->impl->IncludeDirectoriesEntries.end();
- auto btPosition = before ? impl->IncludeDirectoriesBacktraces.begin()
- : impl->IncludeDirectoriesBacktraces.end();
+ auto btPosition = before ? this->impl->IncludeDirectoriesBacktraces.begin()
+ : this->impl->IncludeDirectoriesBacktraces.end();
- impl->IncludeDirectoriesEntries.insert(position, entry);
- impl->IncludeDirectoriesBacktraces.insert(btPosition, bt);
+ this->impl->IncludeDirectoriesEntries.insert(position, entry);
+ this->impl->IncludeDirectoriesBacktraces.insert(btPosition, bt);
}
void cmTarget::InsertCompileOption(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- auto position = before ? impl->CompileOptionsEntries.begin()
- : impl->CompileOptionsEntries.end();
+ auto position = before ? this->impl->CompileOptionsEntries.begin()
+ : this->impl->CompileOptionsEntries.end();
- auto btPosition = before ? impl->CompileOptionsBacktraces.begin()
- : impl->CompileOptionsBacktraces.end();
+ auto btPosition = before ? this->impl->CompileOptionsBacktraces.begin()
+ : this->impl->CompileOptionsBacktraces.end();
- impl->CompileOptionsEntries.insert(position, entry);
- impl->CompileOptionsBacktraces.insert(btPosition, bt);
+ this->impl->CompileOptionsEntries.insert(position, entry);
+ this->impl->CompileOptionsBacktraces.insert(btPosition, bt);
}
void cmTarget::InsertCompileDefinition(std::string const& entry,
cmListFileBacktrace const& bt)
{
- impl->CompileDefinitionsEntries.push_back(entry);
- impl->CompileDefinitionsBacktraces.push_back(bt);
+ this->impl->CompileDefinitionsEntries.push_back(entry);
+ this->impl->CompileDefinitionsBacktraces.push_back(bt);
}
void cmTarget::InsertLinkOption(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- auto position =
- before ? impl->LinkOptionsEntries.begin() : impl->LinkOptionsEntries.end();
+ auto position = before ? this->impl->LinkOptionsEntries.begin()
+ : this->impl->LinkOptionsEntries.end();
- auto btPosition = before ? impl->LinkOptionsBacktraces.begin()
- : impl->LinkOptionsBacktraces.end();
+ auto btPosition = before ? this->impl->LinkOptionsBacktraces.begin()
+ : this->impl->LinkOptionsBacktraces.end();
- impl->LinkOptionsEntries.insert(position, entry);
- impl->LinkOptionsBacktraces.insert(btPosition, bt);
+ this->impl->LinkOptionsEntries.insert(position, entry);
+ this->impl->LinkOptionsBacktraces.insert(btPosition, bt);
}
void cmTarget::InsertLinkDirectory(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- auto position = before ? impl->LinkDirectoriesEntries.begin()
- : impl->LinkDirectoriesEntries.end();
+ auto position = before ? this->impl->LinkDirectoriesEntries.begin()
+ : this->impl->LinkDirectoriesEntries.end();
- auto btPosition = before ? impl->LinkDirectoriesBacktraces.begin()
- : impl->LinkDirectoriesBacktraces.end();
+ auto btPosition = before ? this->impl->LinkDirectoriesBacktraces.begin()
+ : this->impl->LinkDirectoriesBacktraces.end();
- impl->LinkDirectoriesEntries.insert(position, entry);
- impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
+ this->impl->LinkDirectoriesEntries.insert(position, entry);
+ this->impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
}
void cmTarget::InsertPrecompileHeader(std::string const& entry,
cmListFileBacktrace const& bt)
{
- impl->PrecompileHeadersEntries.push_back(entry);
- impl->PrecompileHeadersBacktraces.push_back(bt);
+ this->impl->PrecompileHeadersEntries.push_back(entry);
+ this->impl->PrecompileHeadersBacktraces.push_back(bt);
}
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
@@ -1712,19 +1728,19 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
prop == propOBJCXX_STANDARD) {
- auto propertyIter = impl->LanguageStandardProperties.find(prop);
- if (propertyIter == impl->LanguageStandardProperties.end()) {
+ auto propertyIter = this->impl->LanguageStandardProperties.find(prop);
+ if (propertyIter == this->impl->LanguageStandardProperties.end()) {
return nullptr;
}
return &(propertyIter->second.Value);
}
if (prop == propLINK_LIBRARIES) {
- if (impl->LinkImplementationPropertyEntries.empty()) {
+ if (this->impl->LinkImplementationPropertyEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->LinkImplementationPropertyEntries, ";");
+ output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";");
return &output;
}
// the type property returns what type the target is
@@ -1732,70 +1748,71 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
return &cmState::GetTargetTypeName(this->GetType());
}
if (prop == propINCLUDE_DIRECTORIES) {
- if (impl->IncludeDirectoriesEntries.empty()) {
+ if (this->impl->IncludeDirectoriesEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->IncludeDirectoriesEntries, ";");
+ output = cmJoin(this->impl->IncludeDirectoriesEntries, ";");
return &output;
}
if (prop == propCOMPILE_FEATURES) {
- if (impl->CompileFeaturesEntries.empty()) {
+ if (this->impl->CompileFeaturesEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->CompileFeaturesEntries, ";");
+ output = cmJoin(this->impl->CompileFeaturesEntries, ";");
return &output;
}
if (prop == propCOMPILE_OPTIONS) {
- if (impl->CompileOptionsEntries.empty()) {
+ if (this->impl->CompileOptionsEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->CompileOptionsEntries, ";");
+ output = cmJoin(this->impl->CompileOptionsEntries, ";");
return &output;
}
if (prop == propCOMPILE_DEFINITIONS) {
- if (impl->CompileDefinitionsEntries.empty()) {
+ if (this->impl->CompileDefinitionsEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->CompileDefinitionsEntries, ";");
+ output = cmJoin(this->impl->CompileDefinitionsEntries, ";");
return &output;
}
if (prop == propLINK_OPTIONS) {
- if (impl->LinkOptionsEntries.empty()) {
+ if (this->impl->LinkOptionsEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->LinkOptionsEntries, ";");
+ output = cmJoin(this->impl->LinkOptionsEntries, ";");
return &output;
}
if (prop == propLINK_DIRECTORIES) {
- if (impl->LinkDirectoriesEntries.empty()) {
+ if (this->impl->LinkDirectoriesEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->LinkDirectoriesEntries, ";");
+ output = cmJoin(this->impl->LinkDirectoriesEntries, ";");
return &output;
}
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
- if (impl->Utilities.empty()) {
+ if (this->impl->Utilities.empty()) {
return nullptr;
}
static std::string output;
static std::vector<std::string> utilities;
- utilities.resize(impl->Utilities.size());
+ utilities.resize(this->impl->Utilities.size());
std::transform(
- impl->Utilities.cbegin(), impl->Utilities.cend(), utilities.begin(),
+ this->impl->Utilities.cbegin(), this->impl->Utilities.cend(),
+ utilities.begin(),
[](const BT<std::pair<std::string, bool>>& item) -> std::string {
return item.Value.first;
});
@@ -1803,12 +1820,12 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
return &output;
}
if (prop == propPRECOMPILE_HEADERS) {
- if (impl->PrecompileHeadersEntries.empty()) {
+ if (this->impl->PrecompileHeadersEntries.empty()) {
return nullptr;
}
static std::string output;
- output = cmJoin(impl->PrecompileHeadersEntries, ";");
+ output = cmJoin(this->impl->PrecompileHeadersEntries, ";");
return &output;
}
if (prop == propIMPORTED) {
@@ -1821,24 +1838,25 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
return &this->GetName();
}
if (prop == propBINARY_DIR) {
- return &impl->Makefile->GetStateSnapshot()
+ return &this->impl->Makefile->GetStateSnapshot()
.GetDirectory()
.GetCurrentBinary();
}
if (prop == propSOURCE_DIR) {
- return &impl->Makefile->GetStateSnapshot()
+ return &this->impl->Makefile->GetStateSnapshot()
.GetDirectory()
.GetCurrentSource();
}
}
- cmProp retVal = impl->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->impl->Properties.GetPropertyValue(prop);
if (!retVal) {
- const bool chain =
- impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET);
+ const bool chain = this->impl->Makefile->GetState()->IsPropertyChained(
+ prop, cmProperty::TARGET);
if (chain) {
- return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
- prop, chain);
+ return this->impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetProperty(prop, chain);
}
return nullptr;
}
@@ -1863,32 +1881,32 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const
cmPropertyMap const& cmTarget::GetProperties() const
{
- return impl->Properties;
+ return this->impl->Properties;
}
bool cmTarget::IsDLLPlatform() const
{
- return impl->IsDLLPlatform;
+ return this->impl->IsDLLPlatform;
}
bool cmTarget::IsAIX() const
{
- return impl->IsAIX;
+ return this->impl->IsAIX;
}
bool cmTarget::IsImported() const
{
- return impl->IsImportedTarget;
+ return this->impl->IsImportedTarget;
}
bool cmTarget::IsImportedGloballyVisible() const
{
- return impl->ImportedGloballyVisible;
+ return this->impl->ImportedGloballyVisible;
}
bool cmTarget::IsPerConfig() const
{
- return impl->PerConfig;
+ return this->impl->PerConfig;
}
bool cmTarget::CanCompileSources() const
@@ -1943,8 +1961,8 @@ const char* cmTarget::GetSuffixVariableInternal(
? "CMAKE_SHARED_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
case cmStateEnums::ImportLibraryArtifact:
- return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
- : "CMAKE_IMPORT_LIBRARY_SUFFIX");
+ return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
+ : "CMAKE_IMPORT_LIBRARY_SUFFIX");
}
break;
default:
@@ -1984,8 +2002,8 @@ const char* cmTarget::GetPrefixVariableInternal(
? "CMAKE_SHARED_LIBRARY_PREFIX"
: "");
case cmStateEnums::ImportLibraryArtifact:
- return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
- : "CMAKE_IMPORT_LIBRARY_PREFIX");
+ return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
+ : "CMAKE_IMPORT_LIBRARY_PREFIX");
}
break;
default:
@@ -2067,7 +2085,7 @@ std::string cmTarget::ImportedGetFullPath(
switch (this->GetPolicyStatus(cmPolicies::CMP0111)) {
case cmPolicies::WARN:
- impl->Makefile->IssueMessage(
+ this->impl->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0111) + "\n" +
message());
@@ -2075,7 +2093,8 @@ std::string cmTarget::ImportedGetFullPath(
case cmPolicies::OLD:
break;
default:
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, message());
+ this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ message());
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d8f66bc..3066eb2 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -114,7 +114,7 @@ public:
LinkLibraryVectorType const& GetOriginalLinkLibraries() const;
//! Clear the dependency information recorded for this target, if any.
- void ClearDependencyInformation(cmMakefile& mf);
+ void ClearDependencyInformation(cmMakefile& mf) const;
void AddLinkLibrary(cmMakefile& mf, std::string const& lib,
cmTargetLinkLibraryType llt);
@@ -164,6 +164,7 @@ public:
*/
void AddUtility(std::string const& name, bool cross,
cmMakefile* mf = nullptr);
+ void AddUtility(BT<std::pair<std::string, bool>> util);
//! Get the utilities used by this target
std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
@@ -171,7 +172,7 @@ public:
void SetProperty(const std::string& prop, const char* value);
void SetProperty(const std::string& prop, const std::string& value)
{
- SetProperty(prop, value.c_str());
+ this->SetProperty(prop, value.c_str());
}
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 35635b9..3897499 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -84,8 +84,8 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
bool system)
{
- cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend,
- system);
+ this->cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend,
+ system);
if (system) {
std::string joined = this->Join(content);
tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined);
@@ -101,5 +101,6 @@ bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
args, "INCLUDE_DIRECTORIES",
TargetIncludeDirectoriesImpl::ArgumentFlags(
TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
+ TargetIncludeDirectoriesImpl::PROCESS_AFTER |
TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
}
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index 0670bd9..a5066cc 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -57,7 +57,7 @@ private:
bool prepend, bool system) override
{
std::string const& base = this->Makefile->GetCurrentSourceDirectory();
- cmTargetPropCommandBase::HandleInterfaceContent(
+ this->cmTargetPropCommandBase::HandleInterfaceContent(
tgt, ConvertToAbsoluteContent(content, base), prepend, system);
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 9e30136..e41714a 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -45,15 +45,26 @@ bool cmTargetPropCommandBase::HandleArguments(
this->HandleMissingTarget(args[0]);
return false;
}
- if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) &&
- (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) {
- this->SetError("called with non-compilable target type");
- return false;
+ const bool isRegularTarget =
+ (this->Target->GetType() == cmStateEnums::EXECUTABLE) ||
+ (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
+ (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
+ (this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) ||
+ (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
+ (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
+ (this->Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY);
+ const bool isCustomTarget = this->Target->GetType() == cmStateEnums::UTILITY;
+
+ if (prop == "SOURCES") {
+ if (!isRegularTarget && !isCustomTarget) {
+ this->SetError("called with non-compilable target type");
+ return false;
+ }
+ } else {
+ if (!isRegularTarget) {
+ this->SetError("called with non-compilable target type");
+ return false;
+ }
}
bool system = false;
@@ -76,6 +87,13 @@ bool cmTargetPropCommandBase::HandleArguments(
}
prepend = true;
++argIndex;
+ } else if ((flags & PROCESS_AFTER) && args[argIndex] == "AFTER") {
+ if (args.size() < 3) {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ prepend = false;
+ ++argIndex;
}
if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") {
@@ -131,6 +149,11 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
this->SetError("may only set INTERFACE properties on IMPORTED targets");
return false;
}
+ if (this->Target->GetType() == cmStateEnums::UTILITY &&
+ scope != "PRIVATE") {
+ this->SetError("may only set PRIVATE properties on custom targets");
+ return false;
+ }
}
return this->PopulateTargetProperies(scope, content, prepend, system);
}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 50ac1aa..fc24fe8 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -23,8 +23,9 @@ public:
{
NO_FLAGS = 0x0,
PROCESS_BEFORE = 0x1,
- PROCESS_SYSTEM = 0x2,
- PROCESS_REUSE_FROM = 0x3
+ PROCESS_AFTER = 0x2,
+ PROCESS_SYSTEM = 0x3,
+ PROCESS_REUSE_FROM = 0x4
};
bool HandleArguments(std::vector<std::string> const& args,
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index a1fbc9b..26282ef 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -25,8 +25,9 @@ protected:
const std::vector<std::string>& content,
bool prepend, bool system) override
{
- cmTargetPropCommandBase::HandleInterfaceContent(
- tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system);
+ this->cmTargetPropCommandBase::HandleInterfaceContent(
+ tgt, this->ConvertToAbsoluteContent(tgt, content, true), prepend,
+ system);
}
private:
@@ -43,7 +44,8 @@ private:
bool /*prepend*/, bool /*system*/) override
{
tgt->AppendProperty(
- "SOURCES", this->Join(ConvertToAbsoluteContent(tgt, content, false)));
+ "SOURCES",
+ this->Join(this->ConvertToAbsoluteContent(tgt, content, false)));
return true; // Successfully handled.
}
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index da4593f..7022c4e 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -147,7 +147,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Evaluate command line arguments
std::vector<std::string> argv =
- EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);
+ this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);
// Expand arguments if COMMAND_EXPAND_LISTS is set
if (this->Test->GetCommandExpandLists()) {
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 67f7e11..7fb69bf 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -38,7 +38,7 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString,
return std::string();
}
- return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag);
+ return this->CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag);
}
std::string cmTimestamp::FileModificationTime(const char* path,
@@ -53,7 +53,7 @@ std::string cmTimestamp::FileModificationTime(const char* path,
}
time_t mtime = cmsys::SystemTools::ModifiedTime(real_path);
- return CreateTimestampFromTimeT(mtime, formatString, utcFlag);
+ return this->CreateTimestampFromTimeT(mtime, formatString, utcFlag);
}
std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
@@ -90,7 +90,7 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
: static_cast<char>(0);
if (c1 == '%' && c2 != 0) {
- result += AddTimestampComponent(c2, timeStruct, timeT);
+ result += this->AddTimestampComponent(c2, timeStruct, timeT);
++i;
} else {
result += c1;
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
new file mode 100644
index 0000000..b91e1ce
--- /dev/null
+++ b/Source/cmTransformDepfile.cxx
@@ -0,0 +1,101 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmTransformDepfile.h"
+
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <cm/optional>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
+#include "cmSystemTools.h"
+
+namespace {
+void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename)
+{
+ for (auto c : filename) {
+ switch (c) {
+ case ' ':
+ fout << "\\ ";
+ break;
+ case '\\':
+ fout << "\\\\";
+ break;
+ default:
+ fout << c;
+ break;
+ }
+ }
+}
+
+void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content)
+{
+ for (auto const& dep : content) {
+ bool first = true;
+ for (auto const& rule : dep.rules) {
+ if (!first) {
+ fout << " \\\n ";
+ }
+ first = false;
+ WriteFilenameGcc(fout, rule);
+ }
+ fout << ':';
+ for (auto const& path : dep.paths) {
+ fout << " \\\n ";
+ WriteFilenameGcc(fout, path);
+ }
+ fout << '\n';
+ }
+}
+
+void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content)
+{
+ for (auto const& dep : content) {
+ fout << '^';
+ bool first = true;
+ for (auto const& rule : dep.rules) {
+ if (!first) {
+ fout << '|';
+ }
+ first = false;
+ fout << cmSystemTools::ConvertToOutputPath(rule);
+ }
+ fout << "\r\n";
+ for (auto const& path : dep.paths) {
+ fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n";
+ }
+ }
+}
+}
+
+bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
+ const std::string& infile, const std::string& outfile)
+{
+ cmGccDepfileContent content;
+ if (cmSystemTools::FileExists(infile)) {
+ auto result = cmReadGccDepfile(infile.c_str(), prefix);
+ if (!result) {
+ return false;
+ }
+ content = *std::move(result);
+ }
+
+ cmsys::ofstream fout(outfile.c_str());
+ if (!fout) {
+ return false;
+ }
+ switch (format) {
+ case cmDepfileFormat::GccDepfile:
+ WriteGccDepfile(fout, content);
+ break;
+ case cmDepfileFormat::VsTlog:
+ WriteVsTlog(fout, content);
+ break;
+ }
+ return true;
+}
diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h
new file mode 100644
index 0000000..792c1aa
--- /dev/null
+++ b/Source/cmTransformDepfile.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+
+enum class cmDepfileFormat
+{
+ GccDepfile,
+ VsTlog,
+};
+
+bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
+ const std::string& infile, const std::string& outfile);
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index df2f64e..e556a11 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -80,7 +80,7 @@ struct uv_handle_deleter
template <typename T>
void uv_handle_ptr_base_<T>::allocate(void* data)
{
- reset();
+ this->reset();
/*
We use calloc since we know all these types are c structs
@@ -88,32 +88,33 @@ void uv_handle_ptr_base_<T>::allocate(void* data)
but casting from uv_handle_t to certain other types -- namely
uv_timer_t -- triggers a cast_align warning on certain systems.
*/
- handle.reset(static_cast<T*>(calloc(1, sizeof(T))), uv_handle_deleter<T>());
- handle->data = data;
+ this->handle.reset(static_cast<T*>(calloc(1, sizeof(T))),
+ uv_handle_deleter<T>());
+ this->handle->data = data;
}
template <typename T>
void uv_handle_ptr_base_<T>::reset()
{
- handle.reset();
+ this->handle.reset();
}
template <typename T>
uv_handle_ptr_base_<T>::operator uv_handle_t*()
{
- return reinterpret_cast<uv_handle_t*>(handle.get());
+ return reinterpret_cast<uv_handle_t*>(this->handle.get());
}
template <typename T>
T* uv_handle_ptr_base_<T>::operator->() const noexcept
{
- return handle.get();
+ return this->handle.get();
}
template <typename T>
T* uv_handle_ptr_base_<T>::get() const
{
- return handle.get();
+ return this->handle.get();
}
template <typename T>
@@ -146,7 +147,7 @@ struct uv_handle_deleter<uv_async_t>
void operator()(uv_async_t* handle)
{
- std::lock_guard<std::mutex> lock(*handleMutex);
+ std::lock_guard<std::mutex> lock(*this->handleMutex);
handle_default_delete(handle);
}
};
@@ -164,8 +165,8 @@ void uv_async_ptr::send()
int uv_async_ptr::init(uv_loop_t& loop, uv_async_cb async_cb, void* data)
{
- allocate(data);
- return uv_async_init(&loop, handle.get(), async_cb);
+ this->allocate(data);
+ return uv_async_init(&loop, this->handle.get(), async_cb);
}
#endif
@@ -183,62 +184,62 @@ struct uv_handle_deleter<uv_signal_t>
int uv_signal_ptr::init(uv_loop_t& loop, void* data)
{
- allocate(data);
- return uv_signal_init(&loop, handle.get());
+ this->allocate(data);
+ return uv_signal_init(&loop, this->handle.get());
}
int uv_signal_ptr::start(uv_signal_cb cb, int signum)
{
- assert(handle);
+ assert(this->handle);
return uv_signal_start(*this, cb, signum);
}
void uv_signal_ptr::stop()
{
- if (handle) {
+ if (this->handle) {
uv_signal_stop(*this);
}
}
int uv_pipe_ptr::init(uv_loop_t& loop, int ipc, void* data)
{
- allocate(data);
+ this->allocate(data);
return uv_pipe_init(&loop, *this, ipc);
}
uv_pipe_ptr::operator uv_stream_t*() const
{
- return reinterpret_cast<uv_stream_t*>(handle.get());
+ return reinterpret_cast<uv_stream_t*>(this->handle.get());
}
int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options,
void* data)
{
- allocate(data);
+ this->allocate(data);
return uv_spawn(&loop, *this, &options);
}
int uv_timer_ptr::init(uv_loop_t& loop, void* data)
{
- allocate(data);
+ this->allocate(data);
return uv_timer_init(&loop, *this);
}
int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
{
- assert(handle);
+ assert(this->handle);
return uv_timer_start(*this, cb, timeout, repeat);
}
#ifndef CMAKE_BOOTSTRAP
uv_tty_ptr::operator uv_stream_t*() const
{
- return reinterpret_cast<uv_stream_t*>(handle.get());
+ return reinterpret_cast<uv_stream_t*>(this->handle.get());
}
int uv_tty_ptr::init(uv_loop_t& loop, int fd, int readable, void* data)
{
- allocate(data);
+ this->allocate(data);
return uv_tty_init(&loop, *this, fd, readable);
}
#endif
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index d9de7f3..356e227 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -128,7 +128,7 @@ public:
// dtors to work. Some compilers do not like '= default' here.
uv_handle_ptr_base_() {} // NOLINT(modernize-use-equals-default)
uv_handle_ptr_base_(std::nullptr_t) {}
- ~uv_handle_ptr_base_() { reset(); }
+ ~uv_handle_ptr_base_() { this->reset(); }
/**
* Properly close the handle if needed and sets the inner handle to nullptr
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index cd52b3f..2513303 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -82,7 +82,7 @@ bool cmUuid::StringToBinary(std::string const& input,
return false;
}
size_t digits = kUuidGroups[i] * 2;
- if (!StringToBinaryImpl(input.substr(index, digits), output)) {
+ if (!this->StringToBinaryImpl(input.substr(index, digits), output)) {
return false;
}
@@ -134,12 +134,12 @@ bool cmUuid::StringToBinaryImpl(std::string const& input,
for (size_t i = 0; i < input.size(); i += 2) {
char c1 = 0;
- if (!IntFromHexDigit(input[i], c1)) {
+ if (!this->IntFromHexDigit(input[i], c1)) {
return false;
}
char c2 = 0;
- if (!IntFromHexDigit(input[i + 1], c2)) {
+ if (!this->IntFromHexDigit(input[i + 1], c2)) {
return false;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4eb3b7f..a93a78a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -676,7 +676,7 @@ void cmVisualStudio10TargetGenerator::Generate()
cmStrCat(this->DefaultArtifactDir, "\\nasm.props");
ConvertToWindowsSlash(propsLocal);
this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
- true, true);
+ true);
Elem(e1, "Import").Attribute("Project", propsLocal);
}
}
@@ -1020,9 +1020,9 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
cm::string_view tagName =
cm::string_view(p).substr(propNamePrefix.length());
if (!tagName.empty()) {
- const std::string& value = *props.GetPropertyValue(p);
- if (!value.empty()) {
- e2.Element(tagName, value);
+ cmProp value = props.GetPropertyValue(p);
+ if (cmNonempty(value)) {
+ e2.Element(tagName, *value);
}
}
}
@@ -1897,8 +1897,15 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
// Figure out if there's any additional flags to use
if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf);
+
for (const std::string& config : this->Configurations) {
- toolSettings[config]["AdditionalOptions"] = *saf;
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["AdditionalOptions"] = evaluated;
+ }
}
}
// Figure out if debug information should be generated
@@ -2402,27 +2409,28 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
configDefines += *ccdefs;
}
- // Add precompile headers compile options.
- std::string customAndPchOptions = options;
+ // We have pch state in the following situation:
+ // 1. We have SKIP_PRECOMPILE_HEADERS == true
+ // 2. We are creating the pre-compiled header
+ // 3. We are a different language than the linker language AND pch is
+ // enabled
const std::string pchSource =
this->GeneratorTarget->GetPchSource(config, lang);
- if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- std::string pchOptions;
- if (sf.GetFullPath() == pchSource) {
- pchOptions =
- this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
- } else {
- pchOptions =
- this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
- }
- customAndPchOptions = cmStrCat(customAndPchOptions, ';', pchOptions);
- }
+ const bool skipPCH =
+ pchSource.empty() || sf.GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS");
+ const bool makePCH = (sf.GetFullPath() == pchSource);
+ const bool useSharedPCH =
+ !skipPCH && (lang == this->GeneratorTarget->GetLinkerLanguage(config));
+ const bool useDifferentLangPCH =
+ !skipPCH && (lang != this->GeneratorTarget->GetLinkerLanguage(config));
+ const bool needsPCHFlags =
+ (makePCH || useSharedPCH || useDifferentLangPCH);
// if we have flags or defines for this config then
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
- !includes.empty() || compileAs || noWinRT ||
- !customAndPchOptions.empty()) {
+ !includes.empty() || compileAs || noWinRT || !options.empty() ||
+ needsPCHFlags) {
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
@@ -2455,15 +2463,35 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} else {
clOptions.Parse(flags);
}
- if (!customAndPchOptions.empty()) {
+
+ if (needsPCHFlags) {
+ // Add precompile headers compile options.
+ std::string expandedOptions;
+ std::string pchOptions;
+ if (makePCH) {
+ pchOptions =
+ this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+ } else if (useSharedPCH) {
+ std::string pchHeader =
+ this->GeneratorTarget->GetPchHeader(config, lang);
+ clOptions.AddFlag("ForcedIncludeFiles", pchHeader);
+ } else if (useDifferentLangPCH) {
+ pchOptions =
+ this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
+ }
+ this->LocalGenerator->AppendCompileOptions(expandedOptions,
+ pchOptions);
+ clOptions.Parse(expandedOptions);
+ }
+
+ if (!options.empty()) {
std::string expandedOptions;
if (configDependentOptions) {
this->LocalGenerator->AppendCompileOptions(
expandedOptions,
- genexInterpreter.Evaluate(customAndPchOptions, "COMPILE_OPTIONS"));
+ genexInterpreter.Evaluate(options, "COMPILE_OPTIONS"));
} else {
- this->LocalGenerator->AppendCompileOptions(expandedOptions,
- customAndPchOptions);
+ this->LocalGenerator->AppendCompileOptions(expandedOptions, options);
}
clOptions.Parse(expandedOptions);
}
@@ -2786,6 +2814,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) {
clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ } else if (this->MSTools && vcxproj == this->ProjectType &&
+ !pchHeader.empty()) {
+ clOptions.AddFlag("PrecompiledHeader", "Use");
+ clOptions.AddFlag("PrecompiledHeaderFile", pchHeader);
+ std::string pchFile =
+ this->GeneratorTarget->GetPchFile(configName, linkLanguage);
+ clOptions.AddFlag("PrecompiledHeaderOutputFile", pchFile);
}
// Get preprocessor definitions for this directory.
@@ -4183,8 +4218,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
cmLocalGenerator* lg = dt->GetLocalGenerator();
std::string name = dt->GetName();
std::string path;
- cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
- if (p) {
+ if (cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT")) {
path = *p;
} else {
path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
@@ -4972,9 +5006,9 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties(
if (cmHasPrefix(p, propNamePrefix)) {
std::string tagName = p.substr(propNamePrefix.length());
if (!tagName.empty()) {
- const std::string& val = *props.GetPropertyValue(p);
- if (!val.empty()) {
- tags[tagName] = val;
+ cmProp val = props.GetPropertyValue(p);
+ if (cmNonempty(val)) {
+ tags[tagName] = *val;
} else {
tags.erase(tagName);
}
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index 12aba4f..f2c091f 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -50,11 +50,14 @@ public:
bool startRead(DataFunction dataFunction, EndFunction endFunction);
//! libuv pipe
- uv_pipe_t* uv_pipe() const { return UVPipe_.get(); }
+ uv_pipe_t* uv_pipe() const { return this->UVPipe_.get(); }
//! uv_pipe() casted to libuv stream
- uv_stream_t* uv_stream() const { return static_cast<uv_stream_t*>(UVPipe_); }
+ uv_stream_t* uv_stream() const
+ {
+ return static_cast<uv_stream_t*>(this->UVPipe_);
+ }
//! uv_pipe() casted to libuv handle
- uv_handle_t* uv_handle() { return static_cast<uv_handle_t*>(UVPipe_); }
+ uv_handle_t* uv_handle() { return static_cast<uv_handle_t*>(this->UVPipe_); }
private:
// -- Libuv callbacks
@@ -71,37 +74,37 @@ private:
void cmUVPipeBuffer::reset()
{
- if (UVPipe_.get() != nullptr) {
- EndFunction_ = nullptr;
- DataFunction_ = nullptr;
- Buffer_.clear();
- Buffer_.shrink_to_fit();
- UVPipe_.reset();
+ if (this->UVPipe_.get() != nullptr) {
+ this->EndFunction_ = nullptr;
+ this->DataFunction_ = nullptr;
+ this->Buffer_.clear();
+ this->Buffer_.shrink_to_fit();
+ this->UVPipe_.reset();
}
}
bool cmUVPipeBuffer::init(uv_loop_t* uv_loop)
{
- reset();
+ this->reset();
if (uv_loop == nullptr) {
return false;
}
- int ret = UVPipe_.init(*uv_loop, 0, this);
+ int ret = this->UVPipe_.init(*uv_loop, 0, this);
return (ret == 0);
}
bool cmUVPipeBuffer::startRead(DataFunction dataFunction,
EndFunction endFunction)
{
- if (UVPipe_.get() == nullptr) {
+ if (this->UVPipe_.get() == nullptr) {
return false;
}
if (!dataFunction || !endFunction) {
return false;
}
- DataFunction_ = std::move(dataFunction);
- EndFunction_ = std::move(endFunction);
- int ret = uv_read_start(uv_stream(), &cmUVPipeBuffer::UVAlloc,
+ this->DataFunction_ = std::move(dataFunction);
+ this->EndFunction_ = std::move(endFunction);
+ int ret = uv_read_start(this->uv_stream(), &cmUVPipeBuffer::UVAlloc,
&cmUVPipeBuffer::UVData);
return (ret == 0);
}
@@ -153,10 +156,10 @@ public:
public:
// -- Const accessors
- SetupT const& Setup() const { return Setup_; }
- cmWorkerPool::ProcessResultT* Result() const { return Setup_.Result; }
- bool IsStarted() const { return IsStarted_; }
- bool IsFinished() const { return IsFinished_; }
+ SetupT const& Setup() const { return this->Setup_; }
+ cmWorkerPool::ProcessResultT* Result() const { return this->Setup_.Result; }
+ bool IsStarted() const { return this->IsStarted_; }
+ bool IsFinished() const { return this->IsFinished_; }
// -- Runtime
void setup(cmWorkerPool::ProcessResultT* result, bool mergedOutput,
@@ -193,109 +196,113 @@ void cmUVReadOnlyProcess::setup(cmWorkerPool::ProcessResultT* result,
std::vector<std::string> const& command,
std::string const& workingDirectory)
{
- Setup_.WorkingDirectory = workingDirectory;
- Setup_.Command = command;
- Setup_.Result = result;
- Setup_.MergedOutput = mergedOutput;
+ this->Setup_.WorkingDirectory = workingDirectory;
+ this->Setup_.Command = command;
+ this->Setup_.Result = result;
+ this->Setup_.MergedOutput = mergedOutput;
}
bool cmUVReadOnlyProcess::start(uv_loop_t* uv_loop,
std::function<void()> finishedCallback)
{
- if (IsStarted() || (Result() == nullptr)) {
+ if (this->IsStarted() || (this->Result() == nullptr)) {
return false;
}
// Reset result before the start
- Result()->reset();
+ this->Result()->reset();
// Fill command string pointers
- if (!Setup().Command.empty()) {
- CommandPtr_.reserve(Setup().Command.size() + 1);
- for (std::string const& arg : Setup().Command) {
- CommandPtr_.push_back(arg.c_str());
+ if (!this->Setup().Command.empty()) {
+ this->CommandPtr_.reserve(this->Setup().Command.size() + 1);
+ for (std::string const& arg : this->Setup().Command) {
+ this->CommandPtr_.push_back(arg.c_str());
}
- CommandPtr_.push_back(nullptr);
+ this->CommandPtr_.push_back(nullptr);
} else {
- Result()->ErrorMessage = "Empty command";
+ this->Result()->ErrorMessage = "Empty command";
}
- if (!Result()->error()) {
- if (!UVPipeOut_.init(uv_loop)) {
- Result()->ErrorMessage = "libuv stdout pipe initialization failed";
+ if (!this->Result()->error()) {
+ if (!this->UVPipeOut_.init(uv_loop)) {
+ this->Result()->ErrorMessage = "libuv stdout pipe initialization failed";
}
}
- if (!Result()->error()) {
- if (!UVPipeErr_.init(uv_loop)) {
- Result()->ErrorMessage = "libuv stderr pipe initialization failed";
+ if (!this->Result()->error()) {
+ if (!this->UVPipeErr_.init(uv_loop)) {
+ this->Result()->ErrorMessage = "libuv stderr pipe initialization failed";
}
}
- if (!Result()->error()) {
+ if (!this->Result()->error()) {
// -- Setup process stdio options
// stdin
- UVOptionsStdIO_[0].flags = UV_IGNORE;
- UVOptionsStdIO_[0].data.stream = nullptr;
+ this->UVOptionsStdIO_[0].flags = UV_IGNORE;
+ this->UVOptionsStdIO_[0].data.stream = nullptr;
// stdout
- UVOptionsStdIO_[1].flags =
+ this->UVOptionsStdIO_[1].flags =
static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
- UVOptionsStdIO_[1].data.stream = UVPipeOut_.uv_stream();
+ this->UVOptionsStdIO_[1].data.stream = this->UVPipeOut_.uv_stream();
// stderr
- UVOptionsStdIO_[2].flags =
+ this->UVOptionsStdIO_[2].flags =
static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE);
- UVOptionsStdIO_[2].data.stream = UVPipeErr_.uv_stream();
+ this->UVOptionsStdIO_[2].data.stream = this->UVPipeErr_.uv_stream();
// -- Setup process options
- std::fill_n(reinterpret_cast<char*>(&UVOptions_), sizeof(UVOptions_), 0);
- UVOptions_.exit_cb = &cmUVReadOnlyProcess::UVExit;
- UVOptions_.file = CommandPtr_[0];
- UVOptions_.args = const_cast<char**>(CommandPtr_.data());
- UVOptions_.cwd = Setup_.WorkingDirectory.c_str();
- UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE;
- UVOptions_.stdio_count = static_cast<int>(UVOptionsStdIO_.size());
- UVOptions_.stdio = UVOptionsStdIO_.data();
+ std::fill_n(reinterpret_cast<char*>(&this->UVOptions_),
+ sizeof(this->UVOptions_), 0);
+ this->UVOptions_.exit_cb = &cmUVReadOnlyProcess::UVExit;
+ this->UVOptions_.file = this->CommandPtr_[0];
+ this->UVOptions_.args = const_cast<char**>(this->CommandPtr_.data());
+ this->UVOptions_.cwd = this->Setup_.WorkingDirectory.c_str();
+ this->UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE;
+ this->UVOptions_.stdio_count =
+ static_cast<int>(this->UVOptionsStdIO_.size());
+ this->UVOptions_.stdio = this->UVOptionsStdIO_.data();
// -- Spawn process
- int uvErrorCode = UVProcess_.spawn(*uv_loop, UVOptions_, this);
+ int uvErrorCode = this->UVProcess_.spawn(*uv_loop, this->UVOptions_, this);
if (uvErrorCode != 0) {
- Result()->ErrorMessage = "libuv process spawn failed";
+ this->Result()->ErrorMessage = "libuv process spawn failed";
if (const char* uvErr = uv_strerror(uvErrorCode)) {
- Result()->ErrorMessage += ": ";
- Result()->ErrorMessage += uvErr;
+ this->Result()->ErrorMessage += ": ";
+ this->Result()->ErrorMessage += uvErr;
}
}
}
// -- Start reading from stdio streams
- if (!Result()->error()) {
- if (!UVPipeOut_.startRead(
+ if (!this->Result()->error()) {
+ if (!this->UVPipeOut_.startRead(
[this](cmUVPipeBuffer::DataRange range) {
this->UVPipeOutData(range);
},
[this](ssize_t error) { this->UVPipeOutEnd(error); })) {
- Result()->ErrorMessage = "libuv start reading from stdout pipe failed";
+ this->Result()->ErrorMessage =
+ "libuv start reading from stdout pipe failed";
}
}
- if (!Result()->error()) {
- if (!UVPipeErr_.startRead(
+ if (!this->Result()->error()) {
+ if (!this->UVPipeErr_.startRead(
[this](cmUVPipeBuffer::DataRange range) {
this->UVPipeErrData(range);
},
[this](ssize_t error) { this->UVPipeErrEnd(error); })) {
- Result()->ErrorMessage = "libuv start reading from stderr pipe failed";
+ this->Result()->ErrorMessage =
+ "libuv start reading from stderr pipe failed";
}
}
- if (!Result()->error()) {
- IsStarted_ = true;
- FinishedCallback_ = std::move(finishedCallback);
+ if (!this->Result()->error()) {
+ this->IsStarted_ = true;
+ this->FinishedCallback_ = std::move(finishedCallback);
} else {
// Clear libuv handles and finish
- UVProcess_.reset();
- UVPipeOut_.reset();
- UVPipeErr_.reset();
- CommandPtr_.clear();
+ this->UVProcess_.reset();
+ this->UVPipeOut_.reset();
+ this->UVPipeErr_.reset();
+ this->CommandPtr_.clear();
}
- return IsStarted();
+ return this->IsStarted();
}
void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus,
@@ -325,36 +332,36 @@ void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus,
void cmUVReadOnlyProcess::UVPipeOutData(cmUVPipeBuffer::DataRange data)
{
- Result()->StdOut.append(data.begin(), data.end());
+ this->Result()->StdOut.append(data.begin(), data.end());
}
void cmUVReadOnlyProcess::UVPipeOutEnd(ssize_t error)
{
// Process pipe error
- if ((error != 0) && !Result()->error()) {
- Result()->ErrorMessage = cmStrCat(
+ if ((error != 0) && !this->Result()->error()) {
+ this->Result()->ErrorMessage = cmStrCat(
"Reading from stdout pipe failed with libuv error code ", error);
}
// Try finish
- UVTryFinish();
+ this->UVTryFinish();
}
void cmUVReadOnlyProcess::UVPipeErrData(cmUVPipeBuffer::DataRange data)
{
- std::string* str =
- Setup_.MergedOutput ? &Result()->StdOut : &Result()->StdErr;
+ std::string* str = this->Setup_.MergedOutput ? &this->Result()->StdOut
+ : &this->Result()->StdErr;
str->append(data.begin(), data.end());
}
void cmUVReadOnlyProcess::UVPipeErrEnd(ssize_t error)
{
// Process pipe error
- if ((error != 0) && !Result()->error()) {
- Result()->ErrorMessage = cmStrCat(
+ if ((error != 0) && !this->Result()->error()) {
+ this->Result()->ErrorMessage = cmStrCat(
"Reading from stderr pipe failed with libuv error code ", error);
}
// Try finish
- UVTryFinish();
+ this->UVTryFinish();
}
void cmUVReadOnlyProcess::UVTryFinish()
@@ -362,12 +369,13 @@ void cmUVReadOnlyProcess::UVTryFinish()
// There still might be data in the pipes after the process has finished.
// Therefore check if the process is finished AND all pipes are closed
// before signaling the worker thread to continue.
- if ((UVProcess_.get() != nullptr) || (UVPipeOut_.uv_pipe() != nullptr) ||
- (UVPipeErr_.uv_pipe() != nullptr)) {
+ if ((this->UVProcess_.get() != nullptr) ||
+ (this->UVPipeOut_.uv_pipe() != nullptr) ||
+ (this->UVPipeErr_.uv_pipe() != nullptr)) {
return;
}
- IsFinished_ = true;
- FinishedCallback_();
+ this->IsFinished_ = true;
+ this->FinishedCallback_();
}
/**
@@ -385,7 +393,7 @@ public:
/**
* Set the internal thread
*/
- void SetThread(std::thread&& aThread) { Thread_ = std::move(aThread); }
+ void SetThread(std::thread&& aThread) { this->Thread_ = std::move(aThread); }
/**
* Run an external process
@@ -414,13 +422,13 @@ private:
cmWorkerPoolWorker::cmWorkerPoolWorker(uv_loop_t& uvLoop)
{
- Proc_.Request.init(uvLoop, &cmWorkerPoolWorker::UVProcessStart, this);
+ this->Proc_.Request.init(uvLoop, &cmWorkerPoolWorker::UVProcessStart, this);
}
cmWorkerPoolWorker::~cmWorkerPoolWorker()
{
- if (Thread_.joinable()) {
- Thread_.join();
+ if (this->Thread_.joinable()) {
+ this->Thread_.join();
}
}
@@ -433,17 +441,17 @@ bool cmWorkerPoolWorker::RunProcess(cmWorkerPool::ProcessResultT& result,
}
// Create process instance
{
- std::lock_guard<std::mutex> lock(Proc_.Mutex);
- Proc_.ROP = cm::make_unique<cmUVReadOnlyProcess>();
- Proc_.ROP->setup(&result, true, command, workingDirectory);
+ std::lock_guard<std::mutex> lock(this->Proc_.Mutex);
+ this->Proc_.ROP = cm::make_unique<cmUVReadOnlyProcess>();
+ this->Proc_.ROP->setup(&result, true, command, workingDirectory);
}
// Send asynchronous process start request to libuv loop
- Proc_.Request.send();
+ this->Proc_.Request.send();
// Wait until the process has been finished and destroyed
{
- std::unique_lock<std::mutex> ulock(Proc_.Mutex);
- while (Proc_.ROP) {
- Proc_.Condition.wait(ulock);
+ std::unique_lock<std::mutex> ulock(this->Proc_.Mutex);
+ while (this->Proc_.ROP) {
+ this->Proc_.Condition.wait(ulock);
}
}
return !result.error();
@@ -469,12 +477,13 @@ void cmWorkerPoolWorker::UVProcessStart(uv_async_t* handle)
void cmWorkerPoolWorker::UVProcessFinished()
{
- std::lock_guard<std::mutex> lock(Proc_.Mutex);
- if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) {
- Proc_.ROP.reset();
+ std::lock_guard<std::mutex> lock(this->Proc_.Mutex);
+ if (this->Proc_.ROP &&
+ (this->Proc_.ROP->IsFinished() || !this->Proc_.ROP->IsStarted())) {
+ this->Proc_.ROP.reset();
}
// Notify idling thread
- Proc_.Condition.notify_one();
+ this->Proc_.Condition.notify_one();
}
/**
@@ -539,19 +548,19 @@ public:
void cmWorkerPool::ProcessResultT::reset()
{
- ExitStatus = 0;
- TermSignal = 0;
- if (!StdOut.empty()) {
- StdOut.clear();
- StdOut.shrink_to_fit();
+ this->ExitStatus = 0;
+ this->TermSignal = 0;
+ if (!this->StdOut.empty()) {
+ this->StdOut.clear();
+ this->StdOut.shrink_to_fit();
}
- if (!StdErr.empty()) {
- StdErr.clear();
- StdErr.shrink_to_fit();
+ if (!this->StdErr.empty()) {
+ this->StdErr.clear();
+ this->StdErr.shrink_to_fit();
}
- if (!ErrorMessage.empty()) {
- ErrorMessage.clear();
- ErrorMessage.shrink_to_fit();
+ if (!this->ErrorMessage.empty()) {
+ this->ErrorMessage.clear();
+ this->ErrorMessage.shrink_to_fit();
}
}
@@ -563,56 +572,58 @@ cmWorkerPoolInternal::cmWorkerPoolInternal(cmWorkerPool* pool)
#ifdef CMAKE_UV_SIGNAL_HACK
UVHackRAII = cm::make_unique<cmUVSignalHackRAII>();
#endif
- UVLoop = cm::make_unique<uv_loop_t>();
- uv_loop_init(UVLoop.get());
+ this->UVLoop = cm::make_unique<uv_loop_t>();
+ uv_loop_init(this->UVLoop.get());
}
cmWorkerPoolInternal::~cmWorkerPoolInternal()
{
- uv_loop_close(UVLoop.get());
+ uv_loop_close(this->UVLoop.get());
}
bool cmWorkerPoolInternal::Process()
{
// Reset state flags
- Processing = true;
- Aborting = false;
+ this->Processing = true;
+ this->Aborting = false;
// Initialize libuv asynchronous request
- UVRequestBegin.init(*UVLoop, &cmWorkerPoolInternal::UVSlotBegin, this);
- UVRequestEnd.init(*UVLoop, &cmWorkerPoolInternal::UVSlotEnd, this);
+ this->UVRequestBegin.init(*this->UVLoop, &cmWorkerPoolInternal::UVSlotBegin,
+ this);
+ this->UVRequestEnd.init(*this->UVLoop, &cmWorkerPoolInternal::UVSlotEnd,
+ this);
// Send begin request
- UVRequestBegin.send();
+ this->UVRequestBegin.send();
// Run libuv loop
- bool success = (uv_run(UVLoop.get(), UV_RUN_DEFAULT) == 0);
+ bool success = (uv_run(this->UVLoop.get(), UV_RUN_DEFAULT) == 0);
// Update state flags
- Processing = false;
- Aborting = false;
+ this->Processing = false;
+ this->Aborting = false;
return success;
}
void cmWorkerPoolInternal::Abort()
{
// Clear all jobs and set abort flag
- std::lock_guard<std::mutex> guard(Mutex);
- if (!Aborting) {
+ std::lock_guard<std::mutex> guard(this->Mutex);
+ if (!this->Aborting) {
// Register abort and clear queue
- Aborting = true;
- Queue.clear();
- Condition.notify_all();
+ this->Aborting = true;
+ this->Queue.clear();
+ this->Condition.notify_all();
}
}
inline bool cmWorkerPoolInternal::PushJob(cmWorkerPool::JobHandleT&& jobHandle)
{
- std::lock_guard<std::mutex> guard(Mutex);
- if (Aborting) {
+ std::lock_guard<std::mutex> guard(this->Mutex);
+ if (this->Aborting) {
return false;
}
// Append the job to the queue
- Queue.emplace_back(std::move(jobHandle));
+ this->Queue.emplace_back(std::move(jobHandle));
// Notify an idle worker if there's one
- if (WorkersIdle != 0) {
- Condition.notify_one();
+ if (this->WorkersIdle != 0) {
+ this->Condition.notify_one();
}
// Return success
return true;
@@ -652,79 +663,79 @@ void cmWorkerPoolInternal::UVSlotEnd(uv_async_t* handle)
void cmWorkerPoolInternal::Work(unsigned int workerIndex)
{
cmWorkerPool::JobHandleT jobHandle;
- std::unique_lock<std::mutex> uLock(Mutex);
+ std::unique_lock<std::mutex> uLock(this->Mutex);
// Increment running workers count
- ++WorkersRunning;
+ ++this->WorkersRunning;
// Enter worker main loop
while (true) {
// Abort on request
- if (Aborting) {
+ if (this->Aborting) {
break;
}
// Wait for new jobs on the main CV
- if (Queue.empty()) {
- ++WorkersIdle;
- Condition.wait(uLock);
- --WorkersIdle;
+ if (this->Queue.empty()) {
+ ++this->WorkersIdle;
+ this->Condition.wait(uLock);
+ --this->WorkersIdle;
continue;
}
// If there is a fence currently active or waiting,
// sleep on the main CV and try again.
- if (FenceProcessing) {
- Condition.wait(uLock);
+ if (this->FenceProcessing) {
+ this->Condition.wait(uLock);
continue;
}
// Pop next job from queue
- jobHandle = std::move(Queue.front());
- Queue.pop_front();
+ jobHandle = std::move(this->Queue.front());
+ this->Queue.pop_front();
// Check for fence jobs
bool raisedFence = false;
if (jobHandle->IsFence()) {
- FenceProcessing = true;
+ this->FenceProcessing = true;
raisedFence = true;
// Wait on the Fence CV until all pending jobs are done.
- while (JobsProcessing != 0 && !Aborting) {
- ConditionFence.wait(uLock);
+ while (this->JobsProcessing != 0 && !this->Aborting) {
+ this->ConditionFence.wait(uLock);
}
// When aborting, explicitly kick all threads alive once more.
- if (Aborting) {
- FenceProcessing = false;
- Condition.notify_all();
+ if (this->Aborting) {
+ this->FenceProcessing = false;
+ this->Condition.notify_all();
break;
}
}
// Unlocked scope for job processing
- ++JobsProcessing;
+ ++this->JobsProcessing;
{
uLock.unlock();
- jobHandle->Work(Pool, workerIndex); // Process job
- jobHandle.reset(); // Destroy job
+ jobHandle->Work(this->Pool, workerIndex); // Process job
+ jobHandle.reset(); // Destroy job
uLock.lock();
}
- --JobsProcessing;
+ --this->JobsProcessing;
// If this was the thread that entered fence processing
// originally, notify all idling workers that the fence
// is done.
if (raisedFence) {
- FenceProcessing = false;
- Condition.notify_all();
+ this->FenceProcessing = false;
+ this->Condition.notify_all();
}
// If fence processing is still not done, notify the
// the fencing worker when all active jobs are done.
- if (FenceProcessing && JobsProcessing == 0) {
- ConditionFence.notify_all();
+ if (this->FenceProcessing && this->JobsProcessing == 0) {
+ this->ConditionFence.notify_all();
}
}
// Decrement running workers count
- if (--WorkersRunning == 0) {
+ if (--this->WorkersRunning == 0) {
// Last worker thread about to finish. Send libuv event.
- UVRequestEnd.send();
+ this->UVRequestEnd.send();
}
}
@@ -735,7 +746,7 @@ bool cmWorkerPool::JobT::RunProcess(ProcessResultT& result,
std::string const& workingDirectory)
{
// Get worker by index
- auto* wrk = Pool_->Int_->Workers.at(WorkerIndex_).get();
+ auto* wrk = this->Pool_->Int_->Workers.at(this->WorkerIndex_).get();
return wrk->RunProcess(result, command, workingDirectory);
}
@@ -748,29 +759,29 @@ cmWorkerPool::~cmWorkerPool() = default;
void cmWorkerPool::SetThreadCount(unsigned int threadCount)
{
- if (!Int_->Processing) {
- ThreadCount_ = (threadCount > 0) ? threadCount : 1u;
+ if (!this->Int_->Processing) {
+ this->ThreadCount_ = (threadCount > 0) ? threadCount : 1u;
}
}
bool cmWorkerPool::Process(void* userData)
{
// Setup user data
- UserData_ = userData;
+ this->UserData_ = userData;
// Run libuv loop
- bool success = Int_->Process();
+ bool success = this->Int_->Process();
// Clear user data
- UserData_ = nullptr;
+ this->UserData_ = nullptr;
// Return
return success;
}
bool cmWorkerPool::PushJob(JobHandleT&& jobHandle)
{
- return Int_->PushJob(std::move(jobHandle));
+ return this->Int_->PushJob(std::move(jobHandle));
}
void cmWorkerPool::Abort()
{
- Int_->Abort();
+ this->Int_->Abort();
}
diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h
index 0fb6707..9082d7f 100644
--- a/Source/cmWorkerPool.h
+++ b/Source/cmWorkerPool.h
@@ -28,7 +28,8 @@ public:
void reset();
bool error() const
{
- return (ExitStatus != 0) || (TermSignal != 0) || !ErrorMessage.empty();
+ return (this->ExitStatus != 0) || (this->TermSignal != 0) ||
+ !this->ErrorMessage.empty();
}
std::int64_t ExitStatus = 0;
@@ -60,7 +61,7 @@ public:
* - no jobs later in the queue will be processed before this job was
* processed
*/
- bool IsFence() const { return Fence_; }
+ bool IsFence() const { return this->Fence_; }
protected:
/**
@@ -80,13 +81,13 @@ public:
* Get the worker pool.
* Only valid during the JobT::Process() call!
*/
- cmWorkerPool* Pool() const { return Pool_; }
+ cmWorkerPool* Pool() const { return this->Pool_; }
/**
* Get the user data.
* Only valid during the JobT::Process() call!
*/
- void* UserData() const { return Pool_->UserData(); };
+ void* UserData() const { return this->Pool_->UserData(); };
/**
* Get the worker index.
@@ -95,7 +96,7 @@ public:
* Concurrently processing jobs will never have the same WorkerIndex().
* Only valid during the JobT::Process() call!
*/
- unsigned int WorkerIndex() const { return WorkerIndex_; }
+ unsigned int WorkerIndex() const { return this->WorkerIndex_; }
/**
* Run an external read only process.
@@ -111,8 +112,8 @@ public:
//! Worker thread entry method.
void Work(cmWorkerPool* pool, unsigned int workerIndex)
{
- Pool_ = pool;
- WorkerIndex_ = workerIndex;
+ this->Pool_ = pool;
+ this->WorkerIndex_ = workerIndex;
this->Process();
}
@@ -150,7 +151,7 @@ public:
{
public:
//! Does nothing
- void Process() override { Pool()->Abort(); }
+ void Process() override { this->Pool()->Abort(); }
};
public:
@@ -161,7 +162,7 @@ public:
/**
* Number of worker threads.
*/
- unsigned int ThreadCount() const { return ThreadCount_; }
+ unsigned int ThreadCount() const { return this->ThreadCount_; }
/**
* Set the number of worker threads.
@@ -184,7 +185,7 @@ public:
*
* Only valid during Process().
*/
- void* UserData() const { return UserData_; }
+ void* UserData() const { return this->UserData_; }
// -- Job processing interface
@@ -212,7 +213,7 @@ public:
template <class T, typename... Args>
bool EmplaceJob(Args&&... args)
{
- return PushJob(cm::make_unique<T>(std::forward<Args>(args)...));
+ return this->PushJob(cm::make_unique<T>(std::forward<Args>(args)...));
}
private:
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index c8adea9..e593621 100644
--- a/Source/cmWorkingDirectory.h
+++ b/Source/cmWorkingDirectory.h
@@ -26,7 +26,7 @@ public:
bool SetDirectory(std::string const& newdir);
void Pop();
- bool Failed() const { return ResultCode != 0; }
+ bool Failed() const { return this->ResultCode != 0; }
/** \return 0 if the last attempt to set the working directory was
* successful. If it failed, the value returned will be the
@@ -34,7 +34,7 @@ public:
* of the error code can be obtained by passing the result
* to \c std::strerror().
*/
- int GetLastResult() const { return ResultCode; }
+ int GetLastResult() const { return this->ResultCode; }
std::string const& GetOldDirectory() const { return this->OldDir; }
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index ac5be3f..dd5e86e 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -81,6 +81,13 @@ public:
void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
+ size_t GetObjectCount() { return this->List.size(); }
+ void InsertObject(size_t position, cmXCodeObject* value)
+ {
+ if (position < GetObjectCount()) {
+ this->List.insert(this->List.begin() + position, value);
+ }
+ }
void PrependObject(cmXCodeObject* value)
{
this->List.insert(this->List.begin(), value);
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index a16c4c8..8a32377 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -140,9 +140,9 @@ public:
cmXMLDocument(cmXMLWriter& xml)
: xmlwr(xml)
{
- xmlwr.StartDocument();
+ this->xmlwr.StartDocument();
}
- ~cmXMLDocument() { xmlwr.EndDocument(); }
+ ~cmXMLDocument() { this->xmlwr.EndDocument(); }
cmXMLDocument(const cmXMLDocument&) = delete;
cmXMLDocument& operator=(const cmXMLDocument&) = delete;
@@ -157,19 +157,19 @@ public:
cmXMLElement(cmXMLWriter& xml, const char* tag)
: xmlwr(xml)
{
- xmlwr.StartElement(tag);
+ this->xmlwr.StartElement(tag);
}
cmXMLElement(cmXMLElement& par, const char* tag)
: xmlwr(par.xmlwr)
{
- xmlwr.StartElement(tag);
+ this->xmlwr.StartElement(tag);
}
cmXMLElement(cmXMLDocument& doc, const char* tag)
: xmlwr(doc.xmlwr)
{
- xmlwr.StartElement(tag);
+ this->xmlwr.StartElement(tag);
}
- ~cmXMLElement() { xmlwr.EndElement(); }
+ ~cmXMLElement() { this->xmlwr.EndElement(); }
cmXMLElement(const cmXMLElement&) = delete;
cmXMLElement& operator=(const cmXMLElement&) = delete;
@@ -177,20 +177,20 @@ public:
template <typename T>
cmXMLElement& Attribute(const char* name, T const& value)
{
- xmlwr.Attribute(name, value);
+ this->xmlwr.Attribute(name, value);
return *this;
}
template <typename T>
void Content(T const& content)
{
- xmlwr.Content(content);
+ this->xmlwr.Content(content);
}
template <typename T>
void Element(std::string const& name, T const& value)
{
- xmlwr.Element(name, value);
+ this->xmlwr.Element(name, value);
}
- void Comment(const char* comment) { xmlwr.Comment(comment); }
+ void Comment(const char* comment) { this->xmlwr.Comment(comment); }
private:
cmXMLWriter& xmlwr;
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
index 122e022..15f83e0 100644
--- a/Source/cm_codecvt.cxx
+++ b/Source/cm_codecvt.cxx
@@ -35,7 +35,7 @@ codecvt::codecvt(Encoding e)
case codecvt::None:
// No encoding
default:
- m_noconv = true;
+ this->m_noconv = true;
}
}
@@ -43,7 +43,7 @@ codecvt::~codecvt() = default;
bool codecvt::do_always_noconv() const throw()
{
- return m_noconv;
+ return this->m_noconv;
}
std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from,
@@ -53,7 +53,7 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from,
{
from_next = from;
to_next = to;
- if (m_noconv) {
+ if (this->m_noconv) {
return std::codecvt_base::noconv;
}
#if defined(_WIN32)
@@ -130,7 +130,7 @@ std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to,
char*& to_next) const
{
to_next = to;
- if (m_noconv) {
+ if (this->m_noconv) {
return std::codecvt_base::noconv;
}
#if defined(_WIN32)
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index e655634..48848a7 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -29,6 +29,7 @@
#include "cm_sys_stat.h"
#include "cmCMakePresetsFile.h"
+#include "cmCommandLineArgument.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -132,6 +133,13 @@ namespace {
using JsonValueMapType = std::unordered_map<std::string, Json::Value>;
#endif
+auto IgnoreAndTrueLambda = [](std::string const&, cmake*) -> bool {
+ return true;
+};
+
+using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value, cmake* state)>;
+
} // namespace
static bool cmakeCheckStampFile(const std::string& stampName);
@@ -200,8 +208,9 @@ cmake::cmake(Role role, cmState::Mode mode)
};
// The "c" extension MUST precede the "C" extension.
- setupExts(this->CLikeSourceFileExtensions,
- { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
+ setupExts(
+ this->CLikeSourceFileExtensions,
+ { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", "mm" });
setupExts(this->HeaderFileExtensions,
{ "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
setupExts(this->CudaFileExtensions, { "cu" });
@@ -263,7 +272,7 @@ Json::Value cmake::ReportCapabilitiesJson() const
}
obj["generators"] = generators;
obj["fileApi"] = cmFileAPI::ReportCapabilities();
- obj["serverMode"] = true;
+ obj["serverMode"] = false;
return obj;
}
@@ -386,152 +395,145 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
{
auto findPackageMode = false;
auto seenScriptOption = false;
- for (unsigned int i = 1; i < args.size(); ++i) {
- std::string const& arg = args[i];
- if (cmHasLiteralPrefix(arg, "-D")) {
- std::string entry = arg.substr(2);
- if (entry.empty()) {
- ++i;
- if (i < args.size()) {
- entry = args[i];
- } else {
- cmSystemTools::Error("-D must be followed with VAR=VALUE.");
- return false;
- }
- }
- std::string var;
- std::string value;
- cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
- if (cmState::ParseCacheEntry(entry, var, value, type)) {
+
+ auto DefineLambda = [](std::string const& entry, cmake* state) -> bool {
+ std::string var;
+ std::string value;
+ cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
+ if (cmState::ParseCacheEntry(entry, var, value, type)) {
#ifndef CMAKE_BOOTSTRAP
- this->UnprocessedPresetVariables.erase(var);
+ state->UnprocessedPresetVariables.erase(var);
#endif
- this->ProcessCacheArg(var, value, type);
- } else {
- cmSystemTools::Error("Parse error in command line argument: " + arg +
- "\n" + "Should be: VAR:type=value\n");
- return false;
- }
- } else if (cmHasLiteralPrefix(arg, "-W")) {
- std::string entry = arg.substr(2);
- if (entry.empty()) {
- ++i;
- if (i < args.size()) {
- entry = args[i];
- } else {
- cmSystemTools::Error("-W must be followed with [no-]<name>.");
- return false;
- }
- }
+ state->ProcessCacheArg(var, value, type);
+ } else {
+ cmSystemTools::Error(cmStrCat("Parse error in command line argument: ",
+ entry, "\n Should be: VAR:type=value\n"));
+ return false;
+ }
+ return true;
+ };
- std::string name;
- bool foundNo = false;
- bool foundError = false;
- unsigned int nameStartPosition = 0;
+ auto WarningLambda = [](cm::string_view entry, cmake* state) -> bool {
+ bool foundNo = false;
+ bool foundError = false;
- if (entry.find("no-", nameStartPosition) == 0) {
- foundNo = true;
- nameStartPosition += 3;
- }
+ if (cmHasLiteralPrefix(entry, "no-")) {
+ foundNo = true;
+ entry.remove_prefix(3);
+ }
- if (entry.find("error=", nameStartPosition) == 0) {
- foundError = true;
- nameStartPosition += 6;
- }
+ if (cmHasLiteralPrefix(entry, "error=")) {
+ foundError = true;
+ entry.remove_prefix(6);
+ }
- name = entry.substr(nameStartPosition);
- if (name.empty()) {
- cmSystemTools::Error("No warning name provided.");
- return false;
- }
+ if (entry.empty()) {
+ cmSystemTools::Error("No warning name provided.");
+ return false;
+ }
- if (!foundNo && !foundError) {
- // -W<name>
- this->DiagLevels[name] = std::max(this->DiagLevels[name], DIAG_WARN);
- } else if (foundNo && !foundError) {
- // -Wno<name>
- this->DiagLevels[name] = DIAG_IGNORE;
- } else if (!foundNo && foundError) {
- // -Werror=<name>
- this->DiagLevels[name] = DIAG_ERROR;
- } else {
- // -Wno-error=<name>
- this->DiagLevels[name] = std::min(this->DiagLevels[name], DIAG_WARN);
- }
- } else if (cmHasLiteralPrefix(arg, "-U")) {
- std::string entryPattern = arg.substr(2);
- if (entryPattern.empty()) {
- ++i;
- if (i < args.size()) {
- entryPattern = args[i];
- } else {
- cmSystemTools::Error("-U must be followed with VAR.");
- return false;
- }
+ std::string const name = std::string(entry);
+ if (!foundNo && !foundError) {
+ // -W<name>
+ state->DiagLevels[name] = std::max(state->DiagLevels[name], DIAG_WARN);
+ } else if (foundNo && !foundError) {
+ // -Wno<name>
+ state->DiagLevels[name] = DIAG_IGNORE;
+ } else if (!foundNo && foundError) {
+ // -Werror=<name>
+ state->DiagLevels[name] = DIAG_ERROR;
+ } else {
+ // -Wno-error=<name>
+ // This can downgrade an error to a warning, but should not enable
+ // or disable a warning in the first place.
+ auto dli = state->DiagLevels.find(name);
+ if (dli != state->DiagLevels.end()) {
+ dli->second = std::min(dli->second, DIAG_WARN);
}
- cmsys::RegularExpression regex(
- cmsys::Glob::PatternToRegex(entryPattern, true, true));
- // go through all cache entries and collect the vars which will be
- // removed
- std::vector<std::string> entriesToDelete;
- std::vector<std::string> cacheKeys = this->State->GetCacheEntryKeys();
- for (std::string const& ck : cacheKeys) {
- cmStateEnums::CacheEntryType t = this->State->GetCacheEntryType(ck);
- if (t != cmStateEnums::STATIC) {
- if (regex.find(ck)) {
- entriesToDelete.push_back(ck);
- }
+ }
+ return true;
+ };
+
+ auto UnSetLambda = [](std::string const& entryPattern,
+ cmake* state) -> bool {
+ cmsys::RegularExpression regex(
+ cmsys::Glob::PatternToRegex(entryPattern, true, true));
+ // go through all cache entries and collect the vars which will be
+ // removed
+ std::vector<std::string> entriesToDelete;
+ std::vector<std::string> cacheKeys = state->State->GetCacheEntryKeys();
+ for (std::string const& ck : cacheKeys) {
+ cmStateEnums::CacheEntryType t = state->State->GetCacheEntryType(ck);
+ if (t != cmStateEnums::STATIC) {
+ if (regex.find(ck)) {
+ entriesToDelete.push_back(ck);
}
}
+ }
- // now remove them from the cache
- for (std::string const& currentEntry : entriesToDelete) {
+ // now remove them from the cache
+ for (std::string const& currentEntry : entriesToDelete) {
#ifndef CMAKE_BOOTSTRAP
- this->UnprocessedPresetVariables.erase(currentEntry);
+ state->UnprocessedPresetVariables.erase(currentEntry);
#endif
- this->State->RemoveCacheEntry(currentEntry);
- }
- } else if (cmHasLiteralPrefix(arg, "-C")) {
- std::string path = arg.substr(2);
- if (path.empty()) {
- ++i;
- if (i < args.size()) {
- path = args[i];
- } else {
- cmSystemTools::Error("-C must be followed by a file name.");
- return false;
- }
- }
- cmSystemTools::Stdout("loading initial cache file " + path + "\n");
- // Resolve script path specified on command line relative to $PWD.
- path = cmSystemTools::CollapseFullPath(path);
- this->ReadListFile(args, path);
- } else if (cmHasLiteralPrefix(arg, "-P")) {
- i++;
- if (i >= args.size()) {
- cmSystemTools::Error("-P must be followed by a file name.");
- return false;
- }
- std::string path = args[i];
- if (path.empty()) {
- cmSystemTools::Error("No cmake script provided.");
- return false;
- }
- // Register fake project commands that hint misuse in script mode.
- GetProjectCommandsInScriptMode(this->GetState());
- // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
- // set to $PWD for -P mode.
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(
- cmSystemTools::GetCurrentWorkingDirectory());
- this->ReadListFile(args, path);
- seenScriptOption = true;
- } else if (arg == "--" && seenScriptOption) {
+ state->State->RemoveCacheEntry(currentEntry);
+ }
+ return true;
+ };
+
+ auto ScriptLambda = [&](std::string const& path, cmake* state) -> bool {
+ // Register fake project commands that hint misuse in script mode.
+ GetProjectCommandsInScriptMode(state->GetState());
+ // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
+ // set to $PWD for -P mode.
+ state->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ state->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ state->ReadListFile(args, path);
+ seenScriptOption = true;
+ return true;
+ };
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "-D", "-D must be followed with VAR=VALUE.",
+ CommandArgument::Values::One, DefineLambda },
+ CommandArgument{ "-W", "-W must be followed with [no-]<name>.",
+ CommandArgument::Values::One, WarningLambda },
+ CommandArgument{ "-U", "-U must be followed with VAR.",
+ CommandArgument::Values::One, UnSetLambda },
+ CommandArgument{ "-C", "-C must be followed by a file name.",
+ CommandArgument::Values::One,
+ [&](std::string const& value, cmake* state) -> bool {
+ cmSystemTools::Stdout("loading initial cache file " +
+ value + "\n");
+ // Resolve script path specified on command line
+ // relative to $PWD.
+ auto path = cmSystemTools::CollapseFullPath(value);
+ state->ReadListFile(args, path);
+ return true;
+ } },
+ CommandArgument{ "-P", "-P must be followed by a file name.",
+ CommandArgument::Values::One, ScriptLambda },
+ CommandArgument{ "--find-package", CommandArgument::Values::Zero,
+ [&](std::string const&, cmake*) -> bool {
+ findPackageMode = true;
+ return true;
+ } },
+ };
+ for (decltype(args.size()) i = 1; i < args.size(); ++i) {
+ std::string const& arg = args[i];
+
+ if (arg == "--" && seenScriptOption) {
// Stop processing CMake args and avoid possible errors
// when arbitrary args are given to CMake script.
break;
- } else if (cmHasLiteralPrefix(arg, "--find-package")) {
- findPackageMode = true;
+ }
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ const bool parsedCorrectly = m.parse(arg, i, args, this);
+ if (!parsedCorrectly) {
+ return false;
+ }
+ }
}
}
@@ -730,255 +732,341 @@ void cmake::SetArgs(const std::vector<std::string>& args)
bool haveToolset = false;
bool havePlatform = false;
bool haveBArg = false;
+ bool scriptMode = false;
+ std::string possibleUnknownArg;
#if !defined(CMAKE_BOOTSTRAP)
std::string profilingFormat;
std::string profilingOutput;
std::string presetName;
bool listPresets = false;
#endif
- for (unsigned int i = 1; i < args.size(); ++i) {
- std::string const& arg = args[i];
- if (cmHasLiteralPrefix(arg, "-H") || cmHasLiteralPrefix(arg, "-S")) {
- std::string path = arg.substr(2);
- if (path.empty()) {
- ++i;
- if (i >= args.size()) {
- cmSystemTools::Error("No source directory specified for -S");
- return;
- }
- path = args[i];
- if (path[0] == '-') {
- cmSystemTools::Error("No source directory specified for -S");
- return;
- }
- }
- path = cmSystemTools::CollapseFullPath(path);
- cmSystemTools::ConvertToUnixSlashes(path);
- this->SetHomeDirectory(path);
- // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
- // NOLINTNEXTLINE(bugprone-branch-clone)
- } else if (cmHasLiteralPrefix(arg, "-O")) {
- // There is no local generate anymore. Ignore -O option.
- } else if (cmHasLiteralPrefix(arg, "-B")) {
- std::string path = arg.substr(2);
- if (path.empty()) {
- ++i;
- if (i >= args.size()) {
- cmSystemTools::Error("No build directory specified for -B");
- return;
- }
- path = args[i];
- if (path[0] == '-') {
- cmSystemTools::Error("No build directory specified for -B");
- return;
- }
- }
+ auto SourceArgLambda = [](std::string const& value, cmake* state) -> bool {
+ std::string path = cmSystemTools::CollapseFullPath(value);
+ cmSystemTools::ConvertToUnixSlashes(path);
+ state->SetHomeDirectory(path);
+ return true;
+ };
+
+ auto BuildArgLambda = [&](std::string const& value, cmake* state) -> bool {
+ std::string path = cmSystemTools::CollapseFullPath(value);
+ cmSystemTools::ConvertToUnixSlashes(path);
+ state->SetHomeOutputDirectory(path);
+ haveBArg = true;
+ return true;
+ };
- path = cmSystemTools::CollapseFullPath(path);
- cmSystemTools::ConvertToUnixSlashes(path);
- this->SetHomeOutputDirectory(path);
- haveBArg = true;
- } else if ((i < args.size() - 2) &&
- cmHasLiteralPrefix(arg, "--check-build-system")) {
- this->CheckBuildSystemArgument = args[++i];
- this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
- } else if ((i < args.size() - 1) &&
- cmHasLiteralPrefix(arg, "--check-stamp-file")) {
- this->CheckStampFile = args[++i];
- } else if ((i < args.size() - 1) &&
- cmHasLiteralPrefix(arg, "--check-stamp-list")) {
- this->CheckStampList = args[++i];
- } else if (arg == "--regenerate-during-build"_s) {
- this->RegenerateDuringBuild = true;
+ auto PlatformLambda = [&](std::string const& value, cmake* state) -> bool {
+ if (havePlatform) {
+ cmSystemTools::Error("Multiple -A options not allowed");
+ return false;
}
-#if defined(CMAKE_HAVE_VS_GENERATORS)
- else if ((i < args.size() - 1) &&
- cmHasLiteralPrefix(arg, "--vs-solution-file")) {
- this->VSSolutionFile = args[++i];
+ state->SetGeneratorPlatform(value);
+ havePlatform = true;
+ return true;
+ };
+
+ auto ToolsetLamda = [&](std::string const& value, cmake* state) -> bool {
+ if (haveToolset) {
+ cmSystemTools::Error("Multiple -T options not allowed");
+ return false;
}
+ state->SetGeneratorToolset(value);
+ haveToolset = true;
+ return true;
+ };
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "-S", "No source directory specified for -S",
+ CommandArgument::Values::One, SourceArgLambda },
+ CommandArgument{ "-H", "No source directory specified for -H",
+ CommandArgument::Values::One, SourceArgLambda },
+ CommandArgument{ "-O", CommandArgument::Values::Zero,
+ IgnoreAndTrueLambda },
+ CommandArgument{ "-B", "No build directory specified for -B",
+ CommandArgument::Values::One, BuildArgLambda },
+ CommandArgument{ "-P", "-P must be followed by a file name.",
+ CommandArgument::Values::One,
+ [&](std::string const&, cmake*) -> bool {
+ scriptMode = true;
+ return true;
+ } },
+ CommandArgument{ "-D", "-D must be followed with VAR=VALUE.",
+ CommandArgument::Values::One, IgnoreAndTrueLambda },
+ CommandArgument{ "-C", "-C must be followed by a file name.",
+ CommandArgument::Values::One, IgnoreAndTrueLambda },
+ CommandArgument{ "-U", "-U must be followed with VAR.",
+ CommandArgument::Values::One, IgnoreAndTrueLambda },
+ CommandArgument{ "-W", "-W must be followed with [no-]<name>.",
+ CommandArgument::Values::One, IgnoreAndTrueLambda },
+ CommandArgument{ "-A", "No platform specified for -A",
+ CommandArgument::Values::One, PlatformLambda },
+ CommandArgument{ "-T", "No toolset specified for -T",
+ CommandArgument::Values::One, ToolsetLamda },
+
+ CommandArgument{ "--check-build-system", CommandArgument::Values::Two,
+ [](std::string const& value, cmake* state) -> bool {
+ std::vector<std::string> values = cmExpandedList(value);
+ state->CheckBuildSystemArgument = values[0];
+ state->ClearBuildSystem = (atoi(values[1].c_str()) > 0);
+ return true;
+ } },
+ CommandArgument{ "--check-stamp-file", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ state->CheckStampFile = value;
+ return true;
+ } },
+ CommandArgument{ "--check-stamp-list", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ state->CheckStampList = value;
+ return true;
+ } },
+ CommandArgument{ "--regenerate-during-build",
+ CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ state->RegenerateDuringBuild = true;
+ return true;
+ } },
+
+ CommandArgument{ "--find-package", CommandArgument::Values::Zero,
+ IgnoreAndTrueLambda },
+
+ CommandArgument{ "--graphviz", "No file specified for --graphviz",
+ CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ std::string path =
+ cmSystemTools::CollapseFullPath(value);
+ cmSystemTools::ConvertToUnixSlashes(path);
+ state->GraphVizFile = path;
+ return true;
+ } },
+
+ CommandArgument{ "--debug-trycompile", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "debug trycompile on\n";
+ state->DebugTryCompileOn();
+ return true;
+ } },
+ CommandArgument{ "--debug-output", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Running with debug output on.\n";
+ state->SetDebugOutputOn(true);
+ return true;
+ } },
+
+ CommandArgument{ "--log-level", "Invalid level specified for --log-level",
+ CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ const auto logLevel = StringToLogLevel(value);
+ if (logLevel == LogLevel::LOG_UNDEFINED) {
+ cmSystemTools::Error(
+ "Invalid level specified for --log-level");
+ return false;
+ }
+ state->SetLogLevel(logLevel);
+ state->LogLevelWasSetViaCLI = true;
+ return true;
+ } },
+ // This is supported for backward compatibility. This option only
+ // appeared in the 3.15.x release series and was renamed to
+ // --log-level in 3.16.0
+ CommandArgument{ "--loglevel", "Invalid level specified for --loglevel",
+ CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ const auto logLevel = StringToLogLevel(value);
+ if (logLevel == LogLevel::LOG_UNDEFINED) {
+ cmSystemTools::Error(
+ "Invalid level specified for --loglevel");
+ return false;
+ }
+ state->SetLogLevel(logLevel);
+ state->LogLevelWasSetViaCLI = true;
+ return true;
+ } },
+
+ CommandArgument{ "--log-context", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ state->SetShowLogContext(true);
+ return true;
+ } },
+ CommandArgument{
+ "--debug-find", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Running with debug output on for the `find` commands.\n";
+ state->SetDebugFindOutputOn(true);
+ return true;
+ } },
+ CommandArgument{ "--trace-expand", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Running with expanded trace output on.\n";
+ state->SetTrace(true);
+ state->SetTraceExpand(true);
+ return true;
+ } },
+ CommandArgument{ "--trace-format", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ state->SetTrace(true);
+ const auto traceFormat = StringToTraceFormat(value);
+ if (traceFormat == TraceFormat::TRACE_UNDEFINED) {
+ cmSystemTools::Error(
+ "Invalid format specified for --trace-format. "
+ "Valid formats are human, json-v1.");
+ return false;
+ }
+ state->SetTraceFormat(traceFormat);
+ return true;
+ } },
+ CommandArgument{ "--trace-source", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ std::string file(value);
+ cmSystemTools::ConvertToUnixSlashes(file);
+ state->AddTraceSource(file);
+ state->SetTrace(true);
+ return true;
+ } },
+ CommandArgument{ "--trace-redirect", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ std::string file(value);
+ cmSystemTools::ConvertToUnixSlashes(file);
+ state->SetTraceFile(file);
+ state->SetTrace(true);
+ return true;
+ } },
+ CommandArgument{ "--trace", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Running with trace output on.\n";
+ state->SetTrace(true);
+ state->SetTraceExpand(false);
+ return true;
+ } },
+ CommandArgument{ "--warn-uninitialized", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout << "Warn about uninitialized values.\n";
+ state->SetWarnUninitialized(true);
+ return true;
+ } },
+ CommandArgument{ "--warn-unused-vars", CommandArgument::Values::Zero,
+ IgnoreAndTrueLambda }, // Option was removed.
+ CommandArgument{ "--no-warn-unused-cli", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* state) -> bool {
+ std::cout
+ << "Not searching for unused variables given on the "
+ << "command line.\n";
+ state->SetWarnUnusedCli(false);
+ return true;
+ } },
+ CommandArgument{
+ "--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";
+ state->SetCheckSystemVars(true);
+ return true;
+ } }
+ };
+
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+ arguments.emplace_back("--vs-solution-file", CommandArgument::Values::One,
+ [](std::string const& value, cmake* state) -> bool {
+ state->VSSolutionFile = value;
+ return true;
+ });
#endif
- else if (cmHasLiteralPrefix(arg, "-D") || cmHasLiteralPrefix(arg, "-U") ||
- cmHasLiteralPrefix(arg, "-C")) {
- // skip for now
- // in case '-[DUC] argval' var' is given, also skip the next
- // in case '-[DUC]argval' is given, don't skip the next
- if (arg.size() == 2) {
- ++i;
- }
- // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
- // NOLINTNEXTLINE(bugprone-branch-clone)
- } else if (cmHasLiteralPrefix(arg, "-P")) {
- // skip for now
- i++;
- } else if (cmHasLiteralPrefix(arg, "--find-package")) {
- // skip for now
- i++;
- } else if (cmHasLiteralPrefix(arg, "-W")) {
- // skip for now
- } else if (cmHasLiteralPrefix(arg, "--graphviz=")) {
- std::string path = arg.substr(strlen("--graphviz="));
- path = cmSystemTools::CollapseFullPath(path);
- cmSystemTools::ConvertToUnixSlashes(path);
- this->GraphVizFile = path;
- if (this->GraphVizFile.empty()) {
- cmSystemTools::Error("No file specified for --graphviz");
- return;
- }
- } else if (cmHasLiteralPrefix(arg, "--debug-trycompile")) {
- std::cout << "debug trycompile on\n";
- this->DebugTryCompileOn();
- } else if (cmHasLiteralPrefix(arg, "--debug-output")) {
- std::cout << "Running with debug output on.\n";
- this->SetDebugOutputOn(true);
- } else if (cmHasLiteralPrefix(arg, "--log-level=")) {
- const auto logLevel =
- StringToLogLevel(arg.substr(sizeof("--log-level=") - 1));
- if (logLevel == LogLevel::LOG_UNDEFINED) {
- cmSystemTools::Error("Invalid level specified for --log-level");
- return;
- }
- this->SetLogLevel(logLevel);
- this->LogLevelWasSetViaCLI = true;
- } else if (cmHasLiteralPrefix(arg, "--loglevel=")) {
- // This is supported for backward compatibility. This option only
- // appeared in the 3.15.x release series and was renamed to
- // --log-level in 3.16.0
- const auto logLevel =
- StringToLogLevel(arg.substr(sizeof("--loglevel=") - 1));
- if (logLevel == LogLevel::LOG_UNDEFINED) {
- cmSystemTools::Error("Invalid level specified for --loglevel");
- return;
- }
- this->SetLogLevel(logLevel);
- this->LogLevelWasSetViaCLI = true;
- } else if (arg == "--log-context"_s) {
- this->SetShowLogContext(true);
- } else if (cmHasLiteralPrefix(arg, "--debug-find")) {
- std::cout << "Running with debug output on for the `find` commands.\n";
- this->SetDebugFindOutputOn(true);
- } else if (cmHasLiteralPrefix(arg, "--trace-expand")) {
- std::cout << "Running with expanded trace output on.\n";
- this->SetTrace(true);
- this->SetTraceExpand(true);
- } else if (cmHasLiteralPrefix(arg, "--trace-format=")) {
- this->SetTrace(true);
- const auto traceFormat =
- StringToTraceFormat(arg.substr(strlen("--trace-format=")));
- if (traceFormat == TraceFormat::TRACE_UNDEFINED) {
- cmSystemTools::Error("Invalid format specified for --trace-format. "
- "Valid formats are human, json-v1.");
- return;
- }
- this->SetTraceFormat(traceFormat);
- } else if (cmHasLiteralPrefix(arg, "--trace-source=")) {
- std::string file = arg.substr(strlen("--trace-source="));
- cmSystemTools::ConvertToUnixSlashes(file);
- this->AddTraceSource(file);
- this->SetTrace(true);
- } else if (cmHasLiteralPrefix(arg, "--trace-redirect=")) {
- std::string file = arg.substr(strlen("--trace-redirect="));
- cmSystemTools::ConvertToUnixSlashes(file);
- this->SetTraceFile(file);
- this->SetTrace(true);
- } else if (cmHasLiteralPrefix(arg, "--trace")) {
- std::cout << "Running with trace output on.\n";
- this->SetTrace(true);
- this->SetTraceExpand(false);
- } else if (cmHasLiteralPrefix(arg, "--warn-uninitialized")) {
- std::cout << "Warn about uninitialized values.\n";
- this->SetWarnUninitialized(true);
- } else if (cmHasLiteralPrefix(arg, "--warn-unused-vars")) {
- // Option was removed.
- } else if (cmHasLiteralPrefix(arg, "--no-warn-unused-cli")) {
- std::cout << "Not searching for unused variables given on the "
- << "command line.\n";
- this->SetWarnUnusedCli(false);
- } else if (cmHasLiteralPrefix(arg, "--check-system-vars")) {
- std::cout << "Also check system files when warning about unused and "
- << "uninitialized variables.\n";
- this->SetCheckSystemVars(true);
- } else if (cmHasLiteralPrefix(arg, "-A")) {
- std::string value = arg.substr(2);
- if (value.empty()) {
- ++i;
- if (i >= args.size()) {
- cmSystemTools::Error("No platform specified for -A");
- return;
- }
- value = args[i];
- }
- if (havePlatform) {
- cmSystemTools::Error("Multiple -A options not allowed");
- return;
- }
- this->SetGeneratorPlatform(value);
- havePlatform = true;
- } else if (cmHasLiteralPrefix(arg, "-T")) {
- std::string value = arg.substr(2);
- if (value.empty()) {
- ++i;
- if (i >= args.size()) {
- cmSystemTools::Error("No toolset specified for -T");
- return;
- }
- value = args[i];
- }
- if (haveToolset) {
- cmSystemTools::Error("Multiple -T options not allowed");
- return;
- }
- this->SetGeneratorToolset(value);
- haveToolset = true;
- } else if (cmHasLiteralPrefix(arg, "-G")) {
- std::string value = arg.substr(2);
- if (value.empty()) {
- ++i;
- if (i >= args.size()) {
- cmSystemTools::Error("No generator specified for -G");
- this->PrintGeneratorList();
- return;
- }
- value = args[i];
- }
- if (!this->CreateAndSetGlobalGenerator(value, true)) {
- return;
- }
+
#if !defined(CMAKE_BOOTSTRAP)
- } else if (cmHasLiteralPrefix(arg, "--profiling-format=")) {
- profilingFormat = arg.substr(strlen("--profiling-format="));
- if (profilingFormat.empty()) {
- cmSystemTools::Error("No format specified for --profiling-format");
- }
- } else if (cmHasLiteralPrefix(arg, "--profiling-output=")) {
- profilingOutput = arg.substr(strlen("--profiling-output="));
- profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput);
+ arguments.emplace_back("--profiling-format",
+ "No format specified for --profiling-format",
+ CommandArgument::Values::One,
+ [&](std::string const& value, cmake*) -> bool {
+ profilingFormat = value;
+ return true;
+ });
+ arguments.emplace_back(
+ "--profiling-output", "No path specified for --profiling-output",
+ CommandArgument::Values::One,
+ [&](std::string const& value, cmake*) -> bool {
+ profilingOutput = cmSystemTools::CollapseFullPath(value);
cmSystemTools::ConvertToUnixSlashes(profilingOutput);
- if (profilingOutput.empty()) {
- cmSystemTools::Error("No path specified for --profiling-output");
+ return true;
+ });
+ arguments.emplace_back("--preset", "No preset specified for --preset",
+ CommandArgument::Values::One,
+ [&](std::string const& value, cmake*) -> bool {
+ presetName = value;
+ return true;
+ });
+ arguments.emplace_back("--list-presets", CommandArgument::Values::Zero,
+ [&](std::string const&, cmake*) -> bool {
+ listPresets = true;
+ return true;
+ });
+
+#endif
+
+ bool badGeneratorName = false;
+ CommandArgument generatorCommand(
+ "-G", "No generator specified for -G", CommandArgument::Values::One,
+ [&](std::string const& value, cmake* state) -> bool {
+ bool valid = state->CreateAndSetGlobalGenerator(value, true);
+ badGeneratorName = !valid;
+ return valid;
+ });
+
+ for (decltype(args.size()) i = 1; i < args.size(); ++i) {
+ // iterate each argument
+ std::string const& arg = args[i];
+
+ // Generator flag has special handling for when to print help
+ // so it becomes the exception
+ if (generatorCommand.matches(arg)) {
+ bool parsed = generatorCommand.parse(arg, i, args, this);
+ if (!parsed && !badGeneratorName) {
+ this->PrintGeneratorList();
+ return;
}
- } else if (cmHasLiteralPrefix(arg, "--preset=")) {
- presetName = arg.substr(strlen("--preset="));
- if (presetName.empty()) {
- cmSystemTools::Error("No preset specified for --preset");
+ continue;
+ }
+
+ bool matched = false;
+ bool parsedCorrectly = true; // needs to be true so we can ignore
+ // arguments so as -E
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ matched = true;
+ parsedCorrectly = m.parse(arg, i, args, this);
+ break;
}
- } else if (cmHasLiteralPrefix(arg, "--list-presets")) {
- listPresets = true;
-#endif
}
- // no option assume it is the path to the source or an existing build
- else {
+
+ // We have an issue where arguments to a "-P" script mode
+ // can be provided before the "-P" argument. This means
+ // that we need to lazily check this argument after checking
+ // all args.
+ // Additionally it can't be the source/binary tree location
+ if (!parsedCorrectly) {
+ cmSystemTools::Error("Run 'cmake --help' for all supported options.");
+ exit(1);
+ } else if (!matched && cmHasLiteralPrefix(arg, "-")) {
+ possibleUnknownArg = arg;
+ } else if (!matched) {
this->SetDirectoriesFromFile(arg);
}
- // Empty instance, platform and toolset if only a generator is specified
- if (this->GlobalGenerator) {
- this->GeneratorInstance = "";
- if (!this->GeneratorPlatformSet) {
- this->GeneratorPlatform = "";
- }
- if (!this->GeneratorToolsetSet) {
- this->GeneratorToolset = "";
- }
+ }
+
+ if (!possibleUnknownArg.empty() && !scriptMode) {
+ cmSystemTools::Error(cmStrCat("Unknown argument ", possibleUnknownArg));
+ cmSystemTools::Error("Run 'cmake --help' for all supported options.");
+ exit(1);
+ }
+
+ // Empty instance, platform and toolset if only a generator is specified
+ if (this->GlobalGenerator) {
+ this->GeneratorInstance = "";
+ if (!this->GeneratorPlatformSet) {
+ this->GeneratorPlatform = "";
+ }
+ if (!this->GeneratorToolsetSet) {
+ this->GeneratorToolset = "";
}
}
@@ -1951,7 +2039,7 @@ int cmake::ActualConfigure()
}
}
- auto& mf = this->GlobalGenerator->GetMakefiles()[0];
+ const auto& mf = this->GlobalGenerator->GetMakefiles()[0];
if (mf->IsOn("CTEST_USE_LAUNCHERS") &&
!this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE")) {
cmSystemTools::Error(
@@ -2115,7 +2203,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
#endif
// Add any cache args
if (!this->SetCacheArgs(args)) {
- cmSystemTools::Error("Problem processing arguments. Aborting.\n");
+ cmSystemTools::Error("Run 'cmake --help' for all supported options.");
return -1;
}
#ifndef CMAKE_BOOTSTRAP
@@ -2293,12 +2381,12 @@ cmProp cmake::GetCacheDefinition(const std::string& name) const
return this->State->GetInitializedCacheValue(name);
}
-void cmake::AddScriptingCommands()
+void cmake::AddScriptingCommands() const
{
GetScriptingCommands(this->GetState());
}
-void cmake::AddProjectCommands()
+void cmake::AddProjectCommands() const
{
GetProjectCommands(this->GetState());
}
@@ -2573,8 +2661,7 @@ int cmake::CheckBuildSystem()
if (this->ClearBuildSystem) {
// Get the generator used for this build system.
- const char* genName =
- cmToCStr(mf.GetDefinition("CMAKE_DEPENDS_GENERATOR"));
+ std::string genName = mf.GetSafeDefinition("CMAKE_DEPENDS_GENERATOR");
if (!cmNonempty(genName)) {
genName = "Unix Makefiles";
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 1ecf2c2..d936f28 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -411,7 +411,7 @@ public:
WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
//! Debug the try compile stuff by not deleting the files
- bool GetDebugTryCompile() { return this->DebugTryCompile; }
+ bool GetDebugTryCompile() const { return this->DebugTryCompile; }
void DebugTryCompileOn() { this->DebugTryCompile = true; }
/**
@@ -456,11 +456,11 @@ public:
void SetShowLogContext(bool b) { this->LogContext = b; }
//! Do we want debug output during the cmake run.
- bool GetDebugOutput() { return this->DebugOutput; }
+ bool GetDebugOutput() const { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
//! Do we want debug output from the find commands during the cmake run.
- bool GetDebugFindOutput() { return this->DebugFindOutput; }
+ bool GetDebugFindOutput() const { return this->DebugFindOutput; }
void SetDebugFindOutputOn(bool b) { this->DebugFindOutput = b; }
//! Do we want trace output during the cmake run.
@@ -482,11 +482,11 @@ public:
void SetTraceFile(std::string const& file);
void PrintTraceFormatVersion();
- bool GetWarnUninitialized() { return this->WarnUninitialized; }
+ bool GetWarnUninitialized() const { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
- bool GetWarnUnusedCli() { return this->WarnUnusedCli; }
+ bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
- bool GetCheckSystemVars() { return this->CheckSystemVars; }
+ bool GetCheckSystemVars() const { return this->CheckSystemVars; }
void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
void MarkCliAsUsed(const std::string& variable);
@@ -591,8 +591,8 @@ protected:
using RegisteredExtraGeneratorsVector =
std::vector<cmExternalMakefileProjectGeneratorFactory*>;
RegisteredExtraGeneratorsVector ExtraGenerators;
- void AddScriptingCommands();
- void AddProjectCommands();
+ void AddScriptingCommands() const;
+ void AddProjectCommands() const;
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
@@ -811,6 +811,7 @@ private:
F(cxx_std_14) \
F(cxx_std_17) \
F(cxx_std_20) \
+ F(cxx_std_23) \
FOR_EACH_CXX98_FEATURE(F) \
FOR_EACH_CXX11_FEATURE(F) \
FOR_EACH_CXX14_FEATURE(F)
@@ -820,4 +821,5 @@ private:
F(cuda_std_11) \
F(cuda_std_14) \
F(cuda_std_17) \
- F(cuda_std_20)
+ F(cuda_std_20) \
+ F(cuda_std_23)
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f7734a6..ba471b7 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
-#include <cctype>
#include <climits>
#include <cstring>
#include <iostream>
@@ -19,6 +18,7 @@
#include <cm3p/uv.h>
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
@@ -213,61 +213,114 @@ int do_cmake(int ac, char const* const* av)
}
#endif
+ bool wizard_mode = false;
bool sysinfo = false;
bool list_cached = false;
bool list_all_cached = false;
bool list_help = false;
bool view_only = false;
cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
- std::vector<std::string> args;
- for (int i = 0; i < ac; ++i) {
- if (strcmp(av[i], "-i") == 0) {
- /* clang-format off */
- std::cerr <<
- "The \"cmake -i\" wizard mode is no longer supported.\n"
- "Use the -D option to set cache values on the command line.\n"
- "Use cmake-gui or ccmake for an interactive dialog.\n";
- /* clang-format on */
- return 1;
- }
- if (strcmp(av[i], "--system-information") == 0) {
- sysinfo = true;
- } else if (strcmp(av[i], "-N") == 0) {
- view_only = true;
- } else if (strcmp(av[i], "-L") == 0) {
- list_cached = true;
- } else if (strcmp(av[i], "-LA") == 0) {
- list_all_cached = true;
- } else if (strcmp(av[i], "-LH") == 0) {
- list_cached = true;
- list_help = true;
- } else if (strcmp(av[i], "-LAH") == 0) {
- list_all_cached = true;
- list_help = true;
- } else if (cmHasLiteralPrefix(av[i], "-P")) {
- if (i == ac - 1) {
- cmSystemTools::Error("No script specified for argument -P");
- return 1;
+ std::vector<std::string> parsedArgs;
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{
+ "-i", CommandArgument::Values::Zero,
+ [&wizard_mode](std::string const&) -> bool {
+ /* clang-format off */
+ std::cerr <<
+ "The \"cmake -i\" wizard mode is no longer supported.\n"
+ "Use the -D option to set cache values on the command line.\n"
+ "Use cmake-gui or ccmake for an interactive dialog.\n";
+ /* clang-format on */
+ wizard_mode = true;
+ return true;
+ } },
+ CommandArgument{ "--system-information", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ sysinfo = true;
+ return true;
+ } },
+ CommandArgument{ "-N", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ view_only = true;
+ return true;
+ } },
+ CommandArgument{ "-LAH", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_all_cached = true;
+ list_help = true;
+ return true;
+ } },
+ CommandArgument{ "-LA", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_all_cached = true;
+ return true;
+ } },
+ CommandArgument{ "-LH", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_cached = true;
+ list_help = true;
+ return true;
+ } },
+ CommandArgument{ "-L", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_cached = true;
+ return true;
+ } },
+ CommandArgument{ "-P", "No script specified for argument -P",
+ CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ workingMode = cmake::SCRIPT_MODE;
+ parsedArgs.emplace_back("-P");
+ parsedArgs.push_back(value);
+ return true;
+ } },
+ CommandArgument{ "--find-package", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ workingMode = cmake::FIND_PACKAGE_MODE;
+ parsedArgs.emplace_back("--find-package");
+ return true;
+ } },
+ CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ workingMode = cmake::HELP_MODE;
+ parsedArgs.emplace_back("--list-presets");
+ return true;
+ } },
+ };
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac);
+ cm::append(inputArgs, av, av + ac);
+
+ for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) {
+ std::string const& arg = inputArgs[i];
+ bool matched = false;
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (m.parse(arg, i, inputArgs)) {
+ break;
+ }
+ return 1; // failed to parse
}
- workingMode = cmake::SCRIPT_MODE;
- args.emplace_back(av[i]);
- i++;
- args.emplace_back(av[i]);
- } else if (cmHasLiteralPrefix(av[i], "--find-package")) {
- workingMode = cmake::FIND_PACKAGE_MODE;
- args.emplace_back(av[i]);
- } else if (strcmp(av[i], "--list-presets") == 0) {
- workingMode = cmake::HELP_MODE;
- args.emplace_back(av[i]);
- } else {
- args.emplace_back(av[i]);
}
+ if (!matched) {
+ parsedArgs.emplace_back(av[i]);
+ }
+ }
+
+ if (wizard_mode) {
+ return 1;
}
+
if (sysinfo) {
cmake cm(cmake::RoleProject, cmState::Project);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
- int ret = cm.GetSystemInformation(args);
+ int ret = cm.GetSystemInformation(parsedArgs);
return ret;
}
cmake::Role const role =
@@ -297,7 +350,7 @@ int do_cmake(int ac, char const* const* av)
});
cm.SetWorkingMode(workingMode);
- int res = cm.Run(args, view_only);
+ int res = cm.Run(parsedArgs, view_only);
if (list_cached || list_all_cached) {
std::cout << "-- Cache values" << std::endl;
std::vector<std::string> keys = cm.GetState()->GetCacheEntryKeys();
@@ -332,16 +385,9 @@ int do_cmake(int ac, char const* const* av)
}
#ifndef CMAKE_BOOTSTRAP
-int extract_job_number(int& index, char const* current, char const* next,
- int len_of_flag)
+int extract_job_number(std::string const& command,
+ std::string const& jobString)
{
- std::string command(current);
- std::string jobString = command.substr(len_of_flag);
- if (jobString.empty() && next && isdigit(next[0])) {
- ++index; // skip parsing the job number
- jobString = std::string(next);
- }
-
int jobs = -1;
unsigned long numJobs = 0;
if (jobString.empty()) {
@@ -356,8 +402,8 @@ int extract_job_number(int& index, char const* current, char const* next,
jobs = int(numJobs);
}
} else {
- std::cerr << "'" << command.substr(0, len_of_flag) << "' invalid number '"
- << jobString << "' given.\n\n";
+ std::cerr << "'" << command << "' invalid number '" << jobString
+ << "' given.\n\n";
}
return jobs;
}
@@ -374,88 +420,107 @@ int do_build(int ac, char const* const* av)
std::string config;
std::string dir;
std::vector<std::string> nativeOptions;
+ bool nativeOptionsPassed = false;
bool cleanFirst = false;
bool foundClean = false;
bool foundNonClean = false;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
- enum Doing
- {
- DoingNone,
- DoingDir,
- DoingTarget,
- DoingConfig,
- DoingNative
+ auto jLambda = [&](std::string const& value) -> bool {
+ jobs = extract_job_number("-j", value);
+ if (jobs < 0) {
+ dir.clear();
+ }
+ return true;
};
- Doing doing = DoingDir;
- for (int i = 2; i < ac; ++i) {
- if (doing == DoingNative) {
- nativeOptions.emplace_back(av[i]);
- } else if (cmHasLiteralPrefix(av[i], "-j")) {
- const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr);
- jobs = extract_job_number(i, av[i], nextArg, sizeof("-j") - 1);
- if (jobs < 0) {
- dir.clear();
- }
- doing = DoingNone;
- } else if (cmHasLiteralPrefix(av[i], "--parallel")) {
- const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr);
- jobs = extract_job_number(i, av[i], nextArg, sizeof("--parallel") - 1);
- if (jobs < 0) {
- dir.clear();
+ auto parallelLambda = [&](std::string const& value) -> bool {
+ jobs = extract_job_number("--parallel", value);
+ if (jobs < 0) {
+ dir.clear();
+ }
+ return true;
+ };
+ auto targetLambda = [&](std::string const& value) -> bool {
+ if (!value.empty()) {
+ std::vector<std::string> values = cmExpandedList(value);
+ for (auto const& v : values) {
+ targets.emplace_back(v);
+ if (v == "clean") {
+ foundClean = true;
+ } else {
+ foundNonClean = true;
+ }
}
- doing = DoingNone;
- } else if ((strcmp(av[i], "--target") == 0) ||
- (strcmp(av[i], "-t") == 0)) {
- doing = DoingTarget;
- } else if (strcmp(av[i], "--config") == 0) {
- doing = DoingConfig;
- } else if (strcmp(av[i], "--clean-first") == 0) {
- cleanFirst = true;
- doing = DoingNone;
- } else if ((strcmp(av[i], "--verbose") == 0) ||
- (strcmp(av[i], "-v") == 0)) {
- verbose = true;
- doing = DoingNone;
- } else if (strcmp(av[i], "--use-stderr") == 0) {
- /* tolerate legacy option */
- } else if (strcmp(av[i], "--") == 0) {
- doing = DoingNative;
- } else {
- switch (doing) {
- case DoingDir:
- dir = cmSystemTools::CollapseFullPath(av[i]);
- doing = DoingNone;
- break;
- case DoingTarget:
- if (strlen(av[i]) == 0) {
- std::cerr << "Warning: Argument number " << i
- << " after --target option is empty." << std::endl;
- } else {
- targets.emplace_back(av[i]);
- if (strcmp(av[i], "clean") == 0) {
- foundClean = true;
- } else {
- foundNonClean = true;
- }
- }
- if (foundClean && foundNonClean) {
- std::cerr << "Error: Building 'clean' and other targets together "
- "is not supported."
- << std::endl;
- dir.clear();
- }
- break;
- case DoingConfig:
- config = av[i];
- doing = DoingNone;
- break;
- default:
- std::cerr << "Unknown argument " << av[i] << std::endl;
- dir.clear();
+ return true;
+ }
+ return false;
+ };
+ auto verboseLambda = [&](std::string const&) -> bool {
+ verbose = true;
+ return true;
+ };
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda },
+ CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne,
+ parallelLambda },
+ CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda },
+ CommandArgument{ "--target", CommandArgument::Values::OneOrMore,
+ targetLambda },
+ CommandArgument{ "--config", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ config = value;
+ return true;
+ } },
+ CommandArgument{ "--clean-first", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ cleanFirst = true;
+ return true;
+ } },
+ CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero,
+ verboseLambda },
+ /* legacy option no-op*/
+ CommandArgument{ "--use-stderr", CommandArgument::Values::Zero,
+ [](std::string const&) -> bool { return true; } },
+ CommandArgument{ "--", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ nativeOptionsPassed = true;
+ return true;
+ } },
+ };
+
+ if (ac >= 3) {
+ dir = cmSystemTools::CollapseFullPath(av[2]);
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac - 3);
+ cm::append(inputArgs, av + 3, av + ac);
+
+ decltype(inputArgs.size()) i = 0;
+ for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
+
+ std::string const& arg = inputArgs[i];
+ for (auto const& m : arguments) {
+ if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
break;
+ }
}
}
+
+ if (nativeOptionsPassed) {
+ cm::append(nativeOptions, inputArgs.begin() + i, inputArgs.end());
+ }
+ }
+
+ if (foundClean && foundNonClean) {
+ std::cerr << "Error: Building 'clean' and other targets together "
+ "is not supported."
+ << std::endl;
+ dir.clear();
}
if (jobs == cmake::NO_BUILD_PARALLEL_LEVEL) {
@@ -658,60 +723,59 @@ int do_install(int ac, char const* const* av)
bool strip = false;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
- enum Doing
- {
- DoingNone,
- DoingDir,
- DoingConfig,
- DoingComponent,
- DoingPrefix,
- DoingDefaultDirectoryPermissions,
+ auto verboseLambda = [&](std::string const&) -> bool {
+ verbose = true;
+ return true;
};
- Doing doing = DoingDir;
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "--config", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ config = value;
+ return true;
+ } },
+ CommandArgument{ "--component", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ component = value;
+ return true;
+ } },
+ CommandArgument{ "--default-directory-permissions",
+ CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ defaultDirectoryPermissions = value;
+ return true;
+ } },
+ CommandArgument{ "--prefix", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ prefix = value;
+ return true;
+ } },
+ CommandArgument{ "--strip", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ strip = true;
+ return true;
+ } },
+ CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero,
+ verboseLambda }
+ };
- for (int i = 2; i < ac; ++i) {
- if (strcmp(av[i], "--config") == 0) {
- doing = DoingConfig;
- } else if (strcmp(av[i], "--component") == 0) {
- doing = DoingComponent;
- } else if (strcmp(av[i], "--prefix") == 0) {
- doing = DoingPrefix;
- } else if (strcmp(av[i], "--strip") == 0) {
- strip = true;
- doing = DoingNone;
- } else if ((strcmp(av[i], "--verbose") == 0) ||
- (strcmp(av[i], "-v") == 0)) {
- verbose = true;
- doing = DoingNone;
- } else if (strcmp(av[i], "--default-directory-permissions") == 0) {
- doing = DoingDefaultDirectoryPermissions;
- } else {
- switch (doing) {
- case DoingDir:
- dir = cmSystemTools::CollapseFullPath(av[i]);
- doing = DoingNone;
- break;
- case DoingConfig:
- config = av[i];
- doing = DoingNone;
- break;
- case DoingComponent:
- component = av[i];
- doing = DoingNone;
- break;
- case DoingPrefix:
- prefix = av[i];
- doing = DoingNone;
- break;
- case DoingDefaultDirectoryPermissions:
- defaultDirectoryPermissions = av[i];
- doing = DoingNone;
- break;
- default:
- std::cerr << "Unknown argument " << av[i] << std::endl;
- dir.clear();
+ if (ac >= 3) {
+ dir = cmSystemTools::CollapseFullPath(av[2]);
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac - 3);
+ cm::append(inputArgs, av + 3, av + ac);
+ for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) {
+
+ std::string const& arg = inputArgs[i];
+ for (auto const& m : arguments) {
+ if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
break;
+ }
}
}
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index e2ff8b7..851205e 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -20,6 +20,7 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTransformDepfile.h"
#include "cmUVProcessChain.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
@@ -28,12 +29,17 @@
#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmFileTime.h"
-# include "cmServer.h"
-# include "cmServerConnection.h"
# include "bindexplib.h"
#endif
+#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
+# include <algorithm>
+
+# include "cmCMakePath.h"
+# include "cmProcessTools.h"
+#endif
+
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
# include "cmVisualStudioWCEPlatformParser.h"
#endif
@@ -59,15 +65,15 @@
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
+#include "cmsys/RegularExpression.hxx"
#include "cmsys/Terminal.h"
-class cmConnection;
-
int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd);
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd);
+namespace {
void CMakeCommandUsage(const char* program)
{
std::ostringstream errorStream;
@@ -121,7 +127,6 @@ void CMakeCommandUsage(const char* program)
"(on one volume)\n"
<< " rm [-rRf] <file/dir>... - remove files or directories, use -f to "
"force it, r or R to remove directories and their contents recursively\n"
- << " server - start cmake in server mode\n"
<< " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
<< " - create or extract a tar or zip archive\n"
@@ -147,8 +152,7 @@ void CMakeCommandUsage(const char* program)
cmSystemTools::Error(errorStream.str());
}
-static bool cmTarFilesFrom(std::string const& file,
- std::vector<std::string>& files)
+bool cmTarFilesFrom(std::string const& file, std::vector<std::string>& files)
{
if (cmSystemTools::FileIsDirectory(file)) {
std::ostringstream e;
@@ -183,7 +187,7 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
-static void cmCatFile(const std::string& fileToAppend)
+void cmCatFile(const std::string& fileToAppend)
{
#ifdef _WIN32
_setmode(fileno(stdout), _O_BINARY);
@@ -193,7 +197,7 @@ static void cmCatFile(const std::string& fileToAppend)
std::cout << source.rdbuf();
}
-static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
+bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
{
if (cmSystemTools::FileIsSymlink(dir)) {
if (!cmSystemTools::RemoveFile(dir)) {
@@ -211,9 +215,122 @@ static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
return true;
}
-static int HandleIWYU(const std::string& runCmd,
- const std::string& /* sourceFile */,
- const std::vector<std::string>& orig_cmd)
+#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
+class CLIncludeParser : public cmProcessTools::LineParser
+{
+public:
+ CLIncludeParser(cm::string_view includePrefix, cmsys::ofstream& depFile,
+ std::ostream& output)
+ : IncludePrefix(includePrefix)
+ , DepFile(depFile)
+ , Output(output)
+ {
+ }
+
+private:
+ bool ProcessLine() override
+ {
+ if (cmHasPrefix(this->Line, this->IncludePrefix)) {
+ auto path =
+ cmTrimWhitespace(this->Line.c_str() + this->IncludePrefix.size());
+ cmSystemTools::ConvertToLongPath(path);
+ this->DepFile << cmCMakePath(path).GenericString() << std::endl;
+ } else {
+ this->Output << this->Line << std::endl << std::flush;
+ }
+
+ return true;
+ }
+
+ cm::string_view IncludePrefix;
+ cmsys::ofstream& DepFile;
+ std::ostream& Output;
+};
+
+class CLOutputLogger : public cmProcessTools::OutputLogger
+{
+public:
+ CLOutputLogger(std::ostream& log)
+ : cmProcessTools::OutputLogger(log)
+ {
+ }
+
+ bool ProcessLine() override
+ {
+ *this->Log << std::flush;
+ return true;
+ }
+};
+
+int CLCompileAndDependencies(const std::vector<std::string>& args)
+{
+ std::string depFile;
+ std::string currentBinaryDir;
+ std::string filterPrefix;
+ std::vector<std::string> command;
+ for (auto it = args.cbegin() + 2; it != args.cend(); it++) {
+ if (cmHasLiteralPrefix(*it, "--dep-file=")) {
+ depFile = it->substr(11);
+ } else if (cmHasLiteralPrefix(*it, "--working-dir=")) {
+ currentBinaryDir = it->substr(14);
+ } else if (cmHasLiteralPrefix(*it, "--filter-prefix=")) {
+ filterPrefix = it->substr(16);
+ } else if (*it == "--") {
+ command.insert(command.begin(), ++it, args.cend());
+ break;
+ } else {
+ return 1;
+ }
+ }
+
+ std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp(
+ cmsysProcess_New(), cmsysProcess_Delete);
+ std::vector<const char*> argv(command.size() + 1);
+ std::transform(command.begin(), command.end(), argv.begin(),
+ [](std::string const& s) { return s.c_str(); });
+ argv.back() = nullptr;
+ cmsysProcess_SetCommand(cp.get(), argv.data());
+ cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str());
+
+ cmsys::ofstream fout(depFile.c_str());
+ if (!fout) {
+ return 3;
+ }
+
+ CLIncludeParser includeParser(filterPrefix, fout, std::cout);
+ CLOutputLogger errLogger(std::cerr);
+
+ // Start the process.
+ cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger);
+
+ int status = 0;
+ // handle status of process
+ switch (cmsysProcess_GetState(cp.get())) {
+ case cmsysProcess_State_Exited:
+ status = cmsysProcess_GetExitValue(cp.get());
+ break;
+ case cmsysProcess_State_Exception:
+ status = 1;
+ break;
+ case cmsysProcess_State_Error:
+ status = 2;
+ break;
+ default:
+ break;
+ }
+
+ if (status != 0) {
+ // remove the dependencies file because potentially invalid
+ fout.close();
+ cmSystemTools::RemoveFile(depFile);
+ }
+
+ return status;
+}
+#endif
+
+int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
+ const std::vector<std::string>& orig_cmd)
{
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
@@ -238,8 +355,8 @@ static int HandleIWYU(const std::string& runCmd,
return 0;
}
-static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
- const std::vector<std::string>& orig_cmd)
+int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
+ const std::vector<std::string>& orig_cmd)
{
// Construct the clang-tidy command line by taking what was given
// and adding our compiler command line. The clang-tidy tool will
@@ -268,9 +385,8 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
return ret;
}
-static int HandleLWYU(const std::string& runCmd,
- const std::string& /* sourceFile */,
- const std::vector<std::string>&)
+int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */,
+ const std::vector<std::string>&)
{
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
@@ -301,9 +417,8 @@ static int HandleLWYU(const std::string& runCmd,
return 0;
}
-static int HandleCppLint(const std::string& runCmd,
- const std::string& sourceFile,
- const std::vector<std::string>&)
+int HandleCppLint(const std::string& runCmd, const std::string& sourceFile,
+ const std::vector<std::string>&)
{
// Construct the cpplint command line.
std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
@@ -329,9 +444,8 @@ static int HandleCppLint(const std::string& runCmd,
return 0;
}
-static int HandleCppCheck(const std::string& runCmd,
- const std::string& sourceFile,
- const std::vector<std::string>& orig_cmd)
+int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile,
+ const std::vector<std::string>& orig_cmd)
{
// Construct the cpplint command line.
std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
@@ -394,7 +508,7 @@ struct CoCompiler
bool NoOriginalCommand;
};
-static const std::array<CoCompiler, 5> CoCompilers = {
+const std::array<CoCompiler, 5> CoCompilers = {
{ // Table of options and handlers.
{ "--cppcheck=", HandleCppCheck, false },
{ "--cpplint=", HandleCppLint, false },
@@ -408,6 +522,7 @@ struct CoCompileJob
std::string Command;
CoCompileHandler Handler;
};
+}
// called when args[0] == "__run_co_compile"
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
@@ -589,7 +704,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
} else if (args[2] == "--ignore-eol") {
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
} else {
- ::CMakeCommandUsage(args[0].c_str());
+ CMakeCommandUsage(args[0].c_str());
return 2;
}
@@ -624,8 +739,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
}
if (outValid) {
- // The def file already exists and all input files are older than the
- // existing def file.
+ // The def file already exists and all input files are older than
+ // the existing def file.
return 0;
}
}
@@ -1156,6 +1271,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
+ snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str());
+ snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str());
cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
@@ -1165,12 +1282,19 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
return 1;
}
+#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
+ // Internal CMake compiler dependencies filtering
+ if (args[1] == "cmake_cl_compile_depends") {
+ return CLCompileAndDependencies(args);
+ }
+#endif
+
// Internal CMake link script support.
if (args[1] == "cmake_link_script" && args.size() >= 3) {
return cmcmd::ExecuteLinkScript(args);
}
-#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_NINJA)
+#if !defined(CMAKE_BOOTSTRAP)
// Internal CMake ninja dependency scanning support.
if (args[1] == "cmake_ninja_depends") {
return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
@@ -1359,47 +1483,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (args[1] == "server") {
- const std::string pipePrefix = "--pipe=";
- bool supportExperimental = false;
- bool isDebug = false;
- std::string pipe;
-
- for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (arg == "--experimental") {
- supportExperimental = true;
- } else if (arg == "--debug") {
- pipe.clear();
- isDebug = true;
- } else if (cmHasPrefix(arg, pipePrefix)) {
- isDebug = false;
- pipe = arg.substr(pipePrefix.size());
- if (pipe.empty()) {
- cmSystemTools::Error("No pipe given after --pipe=");
- return 2;
- }
- } else {
- cmSystemTools::Error("Unknown argument for server mode");
- return 1;
- }
- }
-#if !defined(CMAKE_BOOTSTRAP)
- cmConnection* conn;
- if (isDebug) {
- conn = new cmServerStdIoConnection;
- } else {
- conn = new cmServerPipeConnection(pipe);
- }
- cmServer server(conn, supportExperimental);
- std::string errorMessage;
- if (server.Serve(&errorMessage)) {
- return 0;
- }
- cmSystemTools::Error(errorMessage);
-#else
- static_cast<void>(supportExperimental);
- static_cast<void>(isDebug);
- cmSystemTools::Error("CMake was not built with server mode enabled");
-#endif
+ cmSystemTools::Error(
+ "CMake server mode has been removed in favor of the file-api.");
return 1;
}
@@ -1435,9 +1520,26 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
return cmcmd::WindowsCEEnvironment("9.0", args[2]);
}
#endif
+
+ // Internal depfile transformation
+ if (args[1] == "cmake_transform_depfile" && args.size() == 6) {
+ auto format = cmDepfileFormat::GccDepfile;
+ if (args[2] == "gccdepfile") {
+ format = cmDepfileFormat::GccDepfile;
+ } else if (args[2] == "vstlog") {
+ format = cmDepfileFormat::VsTlog;
+ } else {
+ return 1;
+ }
+ std::string prefix = args[3];
+ if (prefix == "./") {
+ prefix.clear();
+ }
+ return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1;
+ }
}
- ::CMakeCommandUsage(args[0].c_str());
+ CMakeCommandUsage(args[0].c_str());
return 1;
}
@@ -1737,7 +1839,6 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
const std::string& intermediate_file)
{
-
cmUVProcessChainBuilder builder;
uv_fs_t fs_req;
@@ -1769,7 +1870,6 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
return 1;
}
-
return 0;
}
@@ -1787,19 +1887,56 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
std::cerr << "Invalid cmake_llvm_rc arguments";
return 1;
}
+
const std::string& intermediate_file = args[3];
const std::string& source_file = args[2];
std::vector<std::string> preprocess;
std::vector<std::string> resource_compile;
std::vector<std::string>* pArgTgt = &preprocess;
+
+ static const cmsys::RegularExpression llvm_rc_only_single_arg("^[-/](N|Y)");
+ static const cmsys::RegularExpression llvm_rc_only_double_arg(
+ "^[-/](C|LN|L)(.)?");
+ static const cmsys::RegularExpression common_double_arg(
+ "^[-/](D|U|I|FO|fo|Fo)(.)?");
+ bool acceptNextArg = false;
+ bool skipNextArg = false;
for (std::string const& arg : cmMakeRange(args).advance(4)) {
- // We use ++ as seperator between the preprocessing step definition and the
- // rc compilation step becase we need to prepend a -- to seperate the
+ if (skipNextArg) {
+ skipNextArg = false;
+ continue;
+ }
+ // We use ++ as seperator between the preprocessing step definition and
+ // the rc compilation step becase we need to prepend a -- to seperate the
// source file properly from other options when using clang-cl for
// preprocessing.
if (arg == "++") {
pArgTgt = &resource_compile;
+ skipNextArg = false;
+ acceptNextArg = true;
} else {
+ cmsys::RegularExpressionMatch match;
+ if (!acceptNextArg) {
+ if (common_double_arg.find(arg.c_str(), match)) {
+ acceptNextArg = match.match(2).empty();
+ } else {
+ if (llvm_rc_only_single_arg.find(arg.c_str(), match)) {
+ if (pArgTgt == &preprocess) {
+ continue;
+ }
+ } else if (llvm_rc_only_double_arg.find(arg.c_str(), match)) {
+ if (pArgTgt == &preprocess) {
+ skipNextArg = match.match(2).empty();
+ continue;
+ }
+ acceptNextArg = match.match(2).empty();
+ } else if (pArgTgt == &resource_compile) {
+ continue;
+ }
+ }
+ } else {
+ acceptNextArg = false;
+ }
if (arg.find("SOURCE_DIR") != std::string::npos) {
std::string sourceDirArg = arg;
cmSystemTools::ReplaceString(
@@ -1819,10 +1956,15 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
std::cerr << "Empty resource compilation command";
return 1;
}
+ // Since we might have skipped the last argument to llvm-rc
+ // we need to make sure the llvm-rc source file is present in the
+ // commandline
+ if (resource_compile.back() != intermediate_file) {
+ resource_compile.push_back(intermediate_file);
+ }
auto result = RunPreprocessor(preprocess, intermediate_file);
if (result != 0) {
-
cmSystemTools::RemoveFile(intermediate_file);
return result;
}
@@ -1986,7 +2128,7 @@ static bool RunCommand(const char* comment,
<< NumberFormatter(exitFormat, retCode)
<< ") with the following output:\n"
<< output;
- } else {
+ } else if (verbose) {
// always print the output of the command, unless
// it is the dumb rc command banner
if (output.find("Resource Compiler Version") == std::string::npos) {
@@ -2084,7 +2226,7 @@ int cmVSLink::Link()
if (this->Verbose) {
std::cout << "Visual Studio Incremental Link with embedded manifests\n";
}
- return LinkIncremental();
+ return this->LinkIncremental();
}
if (this->Verbose) {
if (!this->Incremental) {
@@ -2093,7 +2235,7 @@ int cmVSLink::Link()
std::cout << "Visual Studio Incremental Link without manifests\n";
}
}
- return LinkNonIncremental();
+ return this->LinkNonIncremental();
}
static bool mtRetIsUpdate(int mtRet)
@@ -2109,8 +2251,8 @@ int cmVSLink::LinkIncremental()
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
// 1. Compiler compiles the application and generates the *.obj files.
- // 2. An empty manifest file is generated if this is a clean build and if
- // not the previous one is reused.
+ // 2. An empty manifest file is generated if this is a clean build and
+ // if not the previous one is reused.
// 3. The resource compiler (rc.exe) compiles the *.manifest file to a
// *.res file.
// 4. Linker generates the binary (EXE or DLL) with the /incremental
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index d0bc061..600df1d 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -111,6 +111,7 @@ static const char* cmDocumentationOptions[][2] = {
{ "--no-subproject-summary",
"Disable timing summary information for "
"subprojects." },
+ { "--test-dir <dir>", "Specify the directory in which to look for tests." },
{ "--build-and-test", "Configure, build and run a test." },
{ "--build-target", "Specify a specific target to build." },
{ "--build-nocmake", "Run the build without running cmake first." },
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 9c34a56..9607c00 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -447,6 +447,7 @@ public:
Motorola,
HP,
Hygon,
+ Zhaoxin,
UnknownManufacturer
};
@@ -1731,7 +1732,8 @@ const char* SystemInformationImplementation::GetVendorID()
case NexGen:
return "NexGen Inc., Advanced Micro Devices";
case IDT:
- return "IDT\\Centaur, Via Inc.";
+ return "IDT\\Centaur, Via Inc., Shanghai Zhaoxin Semiconductor Co., "
+ "Ltd.";
case UMC:
return "United Microelectronics Corp.";
case Rise:
@@ -1748,6 +1750,8 @@ const char* SystemInformationImplementation::GetVendorID()
return "Hewlett-Packard";
case Hygon:
return "Chengdu Haiguang IC Design Co., Ltd.";
+ case Zhaoxin:
+ return "Shanghai Zhaoxin Semiconductor Co., Ltd.";
case UnknownManufacturer:
default:
return "Unknown Manufacturer";
@@ -2109,7 +2113,10 @@ void SystemInformationImplementation::FindManufacturer(
else if (this->ChipID.Vendor == "NexGenDriven")
this->ChipManufacturer = NexGen; // NexGen Inc. (now AMD)
else if (this->ChipID.Vendor == "CentaurHauls")
- this->ChipManufacturer = IDT; // IDT/Centaur (now VIA)
+ this->ChipManufacturer = IDT; // original IDT/Centaur/VIA (now Zhaoxin)
+ else if (this->ChipID.Vendor == " Shanghai ")
+ this->ChipManufacturer =
+ Zhaoxin; // Shanghai Zhaoxin Semiconductor Co., Ltd.
else if (this->ChipID.Vendor == "RiseRiseRise")
this->ChipManufacturer = Rise; // Rise
else if (this->ChipID.Vendor == "GenuineTMx86")
@@ -3223,7 +3230,8 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
this->ChipID.ProcessorName = "C3";
break;
default:
- this->ChipID.ProcessorName = "Unknown IDT\\Centaur family";
+ this->ChipID.ProcessorName =
+ "Unknown IDT\\Centaur\\VIA\\Zhaoxin family";
return false;
}
break;
@@ -3232,13 +3240,63 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
case 6:
this->ChipID.ProcessorName = "VIA Cyrix III - Samuel";
break;
+ case 0xf:
+ this->ChipID.ProcessorName = "Zhaoxin zxc";
+ break;
+ default:
+ this->ChipID.ProcessorName =
+ "Unknown IDT\\Centaur\\VIA\\Zhaoxin family";
+ return false;
+ }
+ break;
+ case 7:
+ switch (this->ChipID.Model) {
+ case 0x1b:
+ this->ChipID.ProcessorName = "Zhaoxin kx5000";
+ break;
+ case 0x3b:
+ this->ChipID.ProcessorName = "Zhaoxin kx6000";
+ break;
+ default:
+ this->ChipID.ProcessorName =
+ "Unknown IDT\\Centaur\\VIA\\Zhaoxin family";
+ return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName =
+ "Unknown IDT\\Centaur\\VIA\\Zhaoxin family";
+ return false;
+ }
+ break;
+
+ case Zhaoxin:
+ switch (this->ChipID.Family) {
+ case 6:
+ switch (this->ChipID.Model) {
+ case 0x19:
+ this->ChipID.ProcessorName = "Zhaoxin zxc";
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown Zhaoxin family";
+ return false;
+ }
+ break;
+ case 7:
+ switch (this->ChipID.Model) {
+ case 0x1b:
+ this->ChipID.ProcessorName = "Zhaoxin kx5000";
+ break;
+ case 0x3b:
+ this->ChipID.ProcessorName = "Zhaoxin kx6000";
+ break;
default:
- this->ChipID.ProcessorName = "Unknown IDT\\Centaur family";
+ this->ChipID.ProcessorName = "Unknown Zhaoxin family";
return false;
}
break;
default:
- this->ChipID.ProcessorName = "Unknown IDT\\Centaur family";
+ this->ChipID.ProcessorName = "Unknown Zhaoxin family";
return false;
}
break;