summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-04-23 16:47:22 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2020-04-23 16:47:22 (GMT)
commitd837f8b6fb30c34e167c35f7e85ac3b7b19adccf (patch)
tree019af81ce98a755600df6a5b83efcfd312797961 /Source
parentb45976fe104902ed7f0495e0e4c822684a4455e7 (diff)
parent61ac8e6dfa06d82ff2ef3ae3f0076fb9aa65d542 (diff)
downloadCMake-d837f8b6fb30c34e167c35f7e85ac3b7b19adccf.zip
CMake-d837f8b6fb30c34e167c35f7e85ac3b7b19adccf.tar.gz
CMake-d837f8b6fb30c34e167c35f7e85ac3b7b19adccf.tar.bz2
Merge branch 'master' into ninja-order-only-fix
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt8
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx10
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx3
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.cxx4
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx16
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx32
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h5
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx15
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx22
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h8
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx36
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx3
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx5
-rw-r--r--Source/CPack/cmCPackGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackLog.cxx40
-rw-r--r--Source/CPack/cmCPackLog.h21
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx25
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h5
-rw-r--r--Source/CPack/cpack.cxx2
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx32
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx24
-rw-r--r--Source/CTest/cmCTestCVS.cxx6
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx5
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx44
-rw-r--r--Source/CTest/cmCTestGIT.cxx4
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx60
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx68
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx61
-rw-r--r--Source/CTest/cmCTestRunTest.h13
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx53
-rw-r--r--Source/CTest/cmCTestScriptHandler.h26
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx8
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx22
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx11
-rw-r--r--Source/CTest/cmCTestTestCommand.h1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx188
-rw-r--r--Source/CTest/cmCTestTestHandler.h4
-rw-r--r--Source/CTest/cmCTestVC.cxx2
-rw-r--r--Source/CTest/cmCTestVC.h2
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx34
-rw-r--r--Source/CTest/cmParseCacheCoverage.h5
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.h2
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx9
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h4
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx10
-rw-r--r--Source/CTest/cmProcess.cxx24
-rw-r--r--Source/CTest/cmProcess.h11
-rw-r--r--Source/Checks/cm_cxx_features.cmake2
-rw-r--r--Source/CursesDialog/ccmake.cxx5
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx16
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx3
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx25
-rw-r--r--Source/LexerParser/cmListFileLexer.c14
-rw-r--r--Source/LexerParser/cmListFileLexer.in.l14
-rw-r--r--Source/QtDialog/CMakeSetup.cxx6
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx16
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h4
-rw-r--r--Source/QtDialog/FirstConfigure.cxx49
-rw-r--r--Source/QtDialog/FirstConfigure.h5
-rw-r--r--Source/QtDialog/QCMake.cxx45
-rw-r--r--Source/QtDialog/QCMake.h3
-rw-r--r--Source/bindexplib.cxx6
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx5
-rw-r--r--Source/cmAlgorithms.h42
-rw-r--r--Source/cmArchiveWrite.cxx19
-rw-r--r--Source/cmArchiveWrite.h5
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx7
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx15
-rw-r--r--Source/cmBuildCommand.cxx2
-rw-r--r--Source/cmBuildNameCommand.cxx4
-rw-r--r--Source/cmCMakeCommand.cxx68
-rw-r--r--Source/cmCMakeCommand.h20
-rw-r--r--Source/cmCPluginAPI.cxx45
-rw-r--r--Source/cmCTest.cxx263
-rw-r--r--Source/cmCTest.h12
-rw-r--r--Source/cmCacheManager.cxx328
-rw-r--r--Source/cmCacheManager.h195
-rw-r--r--Source/cmCallVisualStudioMacro.cxx38
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx36
-rw-r--r--Source/cmCommandArgumentParserHelper.h3
-rw-r--r--Source/cmCommands.cxx2
-rw-r--r--Source/cmCommonTargetGenerator.cxx17
-rw-r--r--Source/cmCommonTargetGenerator.h3
-rw-r--r--Source/cmComputeLinkInformation.cxx45
-rw-r--r--Source/cmComputeTargetDepends.cxx27
-rw-r--r--Source/cmConditionEvaluator.cxx7
-rw-r--r--Source/cmConfigureFileCommand.cxx26
-rw-r--r--Source/cmConvertMSBuildXMLToJSON.py9
-rw-r--r--Source/cmCoreTryCompile.cxx46
-rw-r--r--Source/cmCustomCommand.cxx4
-rw-r--r--Source/cmCustomCommand.h7
-rw-r--r--Source/cmDefinePropertyCommand.cxx2
-rw-r--r--Source/cmDepends.cxx35
-rw-r--r--Source/cmDepends.h12
-rw-r--r--Source/cmDependsC.cxx37
-rw-r--r--Source/cmDependsC.h4
-rw-r--r--Source/cmDependsFortran.cxx50
-rw-r--r--Source/cmDependsFortran.h7
-rw-r--r--Source/cmDependsJavaParserHelper.cxx11
-rw-r--r--Source/cmDependsJavaParserHelper.h3
-rw-r--r--Source/cmDynamicLoader.cxx22
-rw-r--r--Source/cmExecuteProcessCommand.cxx22
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx9
-rw-r--r--Source/cmExportBuildFileGenerator.cxx5
-rw-r--r--Source/cmExportCommand.cxx27
-rw-r--r--Source/cmExportFileGenerator.cxx17
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx2
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx6
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx6
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx8
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx4
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx29
-rw-r--r--Source/cmExtraKateGenerator.cxx13
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx28
-rw-r--r--Source/cmFileAPICache.cxx5
-rw-r--r--Source/cmFileAPICodemodel.cxx33
-rw-r--r--Source/cmFileCommand.cxx374
-rw-r--r--Source/cmFindBase.cxx14
-rw-r--r--Source/cmFindBase.h10
-rw-r--r--Source/cmFindLibraryCommand.cxx12
-rw-r--r--Source/cmFindPackageCommand.cxx26
-rw-r--r--Source/cmFindPathCommand.cxx12
-rw-r--r--Source/cmFindProgramCommand.cxx14
-rw-r--r--Source/cmGeneratedFileStream.cxx1
-rw-r--r--Source/cmGeneratorExpression.cxx20
-rw-r--r--Source/cmGeneratorExpression.h13
-rw-r--r--Source/cmGeneratorExpressionContext.cxx1
-rw-r--r--Source/cmGeneratorExpressionContext.h1
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx84
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h12
-rw-r--r--Source/cmGeneratorExpressionNode.cxx242
-rw-r--r--Source/cmGeneratorTarget.cxx768
-rw-r--r--Source/cmGeneratorTarget.h71
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx12
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx15
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx4
-rw-r--r--Source/cmGetPropertyCommand.cxx26
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx4
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx96
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h1
-rw-r--r--Source/cmGlobalGenerator.cxx61
-rw-r--r--Source/cmGlobalGenerator.h3
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx105
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h2
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx157
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx139
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h18
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx15
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx44
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx107
-rw-r--r--Source/cmGlobalXCodeGenerator.h8
-rw-r--r--Source/cmGraphVizWriter.cxx108
-rw-r--r--Source/cmIncludeCommand.cxx35
-rw-r--r--Source/cmInstallCommand.cxx15
-rw-r--r--Source/cmInstallExportGenerator.cxx11
-rw-r--r--Source/cmInstallExportGenerator.h7
-rw-r--r--Source/cmInstalledFile.cxx6
-rw-r--r--Source/cmInstalledFile.h4
-rw-r--r--Source/cmJsonObjects.cxx23
-rw-r--r--Source/cmLinkItem.h11
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx5
-rw-r--r--Source/cmListCommand.cxx26
-rw-r--r--Source/cmListFileCache.cxx51
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmLoadCommandCommand.cxx10
-rw-r--r--Source/cmLocalCommonGenerator.cxx9
-rw-r--r--Source/cmLocalGenerator.cxx585
-rw-r--r--Source/cmLocalGenerator.h36
-rw-r--r--Source/cmLocalNinjaGenerator.cxx49
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx133
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx61
-rw-r--r--Source/cmLocalVisualStudio7Generator.h7
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx7
-rw-r--r--Source/cmMachO.cxx31
-rw-r--r--Source/cmMakefile.cxx298
-rw-r--r--Source/cmMakefile.h30
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx28
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx20
-rw-r--r--Source/cmMakefileProfilingData.cxx114
-rw-r--r--Source/cmMakefileProfilingData.h29
-rw-r--r--Source/cmMakefileTargetGenerator.cxx164
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx77
-rw-r--r--Source/cmNinjaTargetGenerator.cxx264
-rw-r--r--Source/cmOSXBundleGenerator.cxx26
-rw-r--r--Source/cmOSXBundleGenerator.h12
-rw-r--r--Source/cmOptionCommand.cxx4
-rw-r--r--Source/cmOutputConverter.cxx2
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx7
-rw-r--r--Source/cmPolicies.cxx2
-rw-r--r--Source/cmPolicies.h17
-rw-r--r--Source/cmProcessOutput.cxx23
-rw-r--r--Source/cmProjectCommand.cxx8
-rw-r--r--Source/cmPropertyDefinition.cxx26
-rw-r--r--Source/cmPropertyDefinition.h11
-rw-r--r--Source/cmPropertyDefinitionMap.cxx18
-rw-r--r--Source/cmPropertyDefinitionMap.h4
-rw-r--r--Source/cmPropertyMap.cxx10
-rw-r--r--Source/cmPropertyMap.h4
-rw-r--r--Source/cmQTWrapCPPCommand.cxx3
-rw-r--r--Source/cmQtAutoGen.cxx3
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx4
-rw-r--r--Source/cmQtAutoGenInitializer.cxx56
-rw-r--r--Source/cmQtAutoMocUic.cxx23
-rw-r--r--Source/cmRST.cxx10
-rw-r--r--Source/cmRulePlaceholderExpander.cxx13
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx5
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx2
-rw-r--r--Source/cmServer.cxx31
-rw-r--r--Source/cmServer.h7
-rw-r--r--Source/cmServerProtocol.cxx12
-rw-r--r--Source/cmSetCommand.cxx6
-rw-r--r--Source/cmSetPropertyCommand.cxx25
-rw-r--r--Source/cmSiteNameCommand.cxx3
-rw-r--r--Source/cmSourceFile.cxx31
-rw-r--r--Source/cmSourceFile.h4
-rw-r--r--Source/cmSourceFileLocation.cxx4
-rw-r--r--Source/cmSourceGroup.cxx11
-rw-r--r--Source/cmSourceGroup.h3
-rw-r--r--Source/cmSourceGroupCommand.cxx26
-rw-r--r--Source/cmStandardLexer.h13
-rw-r--r--Source/cmState.cxx139
-rw-r--r--Source/cmState.h17
-rw-r--r--Source/cmStateDirectory.cxx38
-rw-r--r--Source/cmStateDirectory.h6
-rw-r--r--Source/cmStateSnapshot.cxx5
-rw-r--r--Source/cmStringAlgorithms.h2
-rw-r--r--Source/cmStringCommand.cxx22
-rw-r--r--Source/cmSystemTools.cxx25
-rw-r--r--Source/cmTarget.cxx180
-rw-r--r--Source/cmTarget.h13
-rw-r--r--Source/cmTargetPropCommandBase.cxx8
-rw-r--r--Source/cmTargetPropertyComputer.h26
-rw-r--r--Source/cmTest.cxx9
-rw-r--r--Source/cmTestGenerator.cxx10
-rw-r--r--Source/cmTimestamp.cxx10
-rw-r--r--Source/cmTryRunCommand.cxx5
-rw-r--r--Source/cmUtilitySourceCommand.cxx12
-rw-r--r--Source/cmVariableWatchCommand.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx606
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h16
-rw-r--r--Source/cmVisualStudioSlnParser.cxx10
-rw-r--r--Source/cmVisualStudioSlnParser.h5
-rw-r--r--Source/cmWorkingDirectory.h2
-rw-r--r--Source/cmWriteFileCommand.cxx2
-rw-r--r--Source/cmXCode21Object.cxx13
-rw-r--r--Source/cmXCode21Object.h8
-rw-r--r--Source/cmXCodeObject.h9
-rw-r--r--Source/cmXCodeScheme.cxx4
-rw-r--r--Source/cm_get_date.c4
-rw-r--r--Source/cmake.cxx254
-rw-r--r--Source/cmake.h28
-rw-r--r--Source/cmakemain.cxx16
-rw-r--r--Source/cmcldeps.cxx58
-rw-r--r--Source/cmcmd.cxx83
-rw-r--r--Source/ctest.cxx1
-rw-r--r--Source/kwsys/Base64.c5
-rw-r--r--Source/kwsys/CMakeLists.txt1332
-rw-r--r--Source/kwsys/CommandLineArguments.cxx38
-rw-r--r--Source/kwsys/Directory.cxx18
-rw-r--r--Source/kwsys/Directory.hxx.in10
-rw-r--r--Source/kwsys/ExtraTest.cmake.in2
-rw-r--r--Source/kwsys/Glob.cxx6
-rw-r--r--Source/kwsys/MD5.c30
-rw-r--r--Source/kwsys/Process.h.in4
-rw-r--r--Source/kwsys/ProcessUNIX.c227
-rw-r--r--Source/kwsys/ProcessWin32.c2
-rw-r--r--Source/kwsys/System.c2
-rw-r--r--Source/kwsys/SystemInformation.cxx209
-rw-r--r--Source/kwsys/SystemTools.cxx336
-rw-r--r--Source/kwsys/SystemTools.hxx.in30
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake300
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx2
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx2
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testEncoding.cxx19
-rw-r--r--Source/kwsys/testHashSTL.cxx16
-rw-r--r--Source/kwsys/testProcess.c13
-rw-r--r--Source/kwsys/testSystemTools.cxx90
-rw-r--r--Source/kwsys/testSystemTools.h.in2
291 files changed, 7391 insertions, 5122 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c57f713..564e647 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1,6 +1,11 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
+# To ensure maximum portability across various compilers and platforms
+# deactivate any compiler extensions
+set(CMAKE_C_EXTENSIONS FALSE)
+set(CMAKE_CXX_EXTENSIONS FALSE)
+
include(CheckIncludeFile)
# Check if we can build support for ELF parsing.
if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
@@ -354,6 +359,7 @@ set(SRCS
cmMakefileTargetGenerator.cxx
cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx
+ cmMakefileProfilingData.cxx
cmMakefileUtilityTargetGenerator.cxx
cmMessageType.h
cmMessenger.cxx
@@ -484,6 +490,8 @@ set(SRCS
cmBuildCommand.h
cmBuildNameCommand.cxx
cmBuildNameCommand.h
+ cmCMakeCommand.cxx
+ cmCMakeCommand.h
cmCMakeHostSystemInformationCommand.cxx
cmCMakeHostSystemInformationCommand.h
cmCMakeMinimumRequired.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 454ba43..a21fd7d 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 17)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20200423)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 509ac65..2806c61 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -544,10 +544,7 @@ std::string cmCPackIFWGenerator::GetGroupPackageName(
if (group->ParentGroup) {
cmCPackIFWPackage* package = this->GetGroupPackage(group->ParentGroup);
bool dot = !this->ResolveDuplicateNames;
- if (dot && name.substr(0, package->Name.size()) == package->Name) {
- dot = false;
- }
- if (dot) {
+ if (dot && !cmHasPrefix(name, package->Name)) {
name = package->Name + "." + name;
}
}
@@ -576,10 +573,7 @@ std::string cmCPackIFWGenerator::GetComponentPackageName(
return package->Name;
}
bool dot = !this->ResolveDuplicateNames;
- if (dot && name.substr(0, package->Name.size()) == package->Name) {
- dot = false;
- }
- if (dot) {
+ if (dot && !cmHasPrefix(name, package->Name)) {
name = package->Name + "." + name;
}
}
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 9a9cd56..56a74c5 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -55,8 +55,7 @@ cmCPackIFWPackage::DependenceStruct::DependenceStruct(
if (dashPos != std::string::npos) {
pos = dashPos;
}
- this->Name =
- pos == std::string::npos ? dependence : dependence.substr(0, pos);
+ this->Name = dependence.substr(0, pos);
}
std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index a696549..f5e8744 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -21,11 +21,7 @@ bool cmCPackIFWRepository::IsValid() const
switch (this->Update) {
case cmCPackIFWRepository::None:
- valid = !this->Url.empty();
- break;
case cmCPackIFWRepository::Add:
- valid = !this->Url.empty();
- break;
case cmCPackIFWRepository::Remove:
valid = !this->Url.empty();
break;
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 21d27a0..bdaf779 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -5,6 +5,8 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
#include <CoreFoundation/CoreFoundation.h>
#include "cmsys/FStream.hxx"
@@ -26,7 +28,6 @@ int main(int argc, char* argv[])
CFStringRef fileName;
CFBundleRef appBundle;
CFURLRef scriptFileURL;
- UInt8* path;
// get CF URL for script
if (!(appBundle = CFBundleGetMainBundle())) {
@@ -41,13 +42,15 @@ int main(int argc, char* argv[])
}
// create path string
- if (!(path = new UInt8[PATH_MAX])) {
+ auto path = cm::make_unique<UInt8[]>(PATH_MAX);
+ if (!path) {
return 1;
}
// get the file system path of the url as a cstring
// in an encoding suitable for posix apis
- if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path, PATH_MAX)) {
+ if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path.get(),
+ PATH_MAX)) {
DebugError("CFURLGetFileSystemRepresentation failed");
return 1;
}
@@ -55,10 +58,10 @@ int main(int argc, char* argv[])
// dispose of the CF variable
CFRelease(scriptFileURL);
- std::string fullScriptPath = reinterpret_cast<char*>(path);
- delete[] path;
+ std::string fullScriptPath = reinterpret_cast<char*>(path.get());
+ path.reset();
- if (!cmsys::SystemTools::FileExists(fullScriptPath.c_str())) {
+ if (!cmsys::SystemTools::FileExists(fullScriptPath)) {
return 1;
}
@@ -80,7 +83,6 @@ int main(int argc, char* argv[])
cmsysProcess_SetTimeout(cp, 0);
cmsysProcess_Execute(cp);
- std::vector<char> tempOutput;
char* data;
int length;
while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index e71a38f..72af10b 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -4,14 +4,15 @@
#include <algorithm>
+#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
@@ -35,22 +36,16 @@
#include "cmCMakeToWixPath.h"
cmCPackWIXGenerator::cmCPackWIXGenerator()
- : Patch(0)
- , ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
+ : ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
{
}
-cmCPackWIXGenerator::~cmCPackWIXGenerator()
-{
- if (this->Patch) {
- delete this->Patch;
- }
-}
+cmCPackWIXGenerator::~cmCPackWIXGenerator() = default;
int cmCPackWIXGenerator::InitializeInternal()
{
componentPackageMethod = ONE_PACKAGE;
- this->Patch = new cmWIXPatch(this->Logger);
+ this->Patch = cm::make_unique<cmWIXPatch>(this->Logger);
return this->Superclass::InitializeInternal();
}
@@ -103,7 +98,7 @@ bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile,
command << " -ext " << QuotePath(ext);
}
- if (sourceFile.rfind(this->CPackTopLevel, 0) != 0) {
+ if (!cmHasSuffix(sourceFile, this->CPackTopLevel)) {
command << " " << QuotePath("-I" + this->CPackTopLevel);
}
@@ -355,8 +350,7 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
std::vector<std::string> options = GetOptions();
for (std::string const& name : options) {
- if (name.length() > prefix.length() &&
- name.substr(0, prefix.length()) == prefix) {
+ if (cmHasPrefix(name, prefix)) {
std::string id = name.substr(prefix.length());
std::string value = GetOption(name.c_str());
@@ -960,7 +954,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
shortcut.workingDirectoryId = directoryId;
shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
- if (cmContains(desktopExecutables, executableName)) {
+ if (cm::contains(desktopExecutables, executableName)) {
shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
}
}
@@ -1104,14 +1098,14 @@ std::string cmCPackWIXGenerator::CreateHashedId(
cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
std::string const hash = sha1.HashString(path);
- std::string identifier = cmStrCat(cm::string_view(hash).substr(0, 7), '_');
-
const size_t maxFileNameLength = 52;
+ std::string identifier =
+ cmStrCat(cm::string_view(hash).substr(0, 7), '_',
+ cm::string_view(normalizedFilename).substr(0, maxFileNameLength));
+
+ // if the name was truncated
if (normalizedFilename.length() > maxFileNameLength) {
- identifier += normalizedFilename.substr(0, maxFileNameLength - 3);
identifier += "...";
- } else {
- identifier += normalizedFilename;
}
return identifier;
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index d193348..d5a16ec 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -4,6 +4,7 @@
#define cmCPackWIXGenerator_h
#include <map>
+#include <memory>
#include <string>
#include "cmCPackGenerator.h"
@@ -24,6 +25,8 @@ public:
cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
cmCPackWIXGenerator();
+ cmCPackWIXGenerator(const cmCPackWIXGenerator&) = delete;
+ const cmCPackWIXGenerator& operator=(const cmCPackWIXGenerator&) = delete;
~cmCPackWIXGenerator();
protected:
@@ -157,7 +160,7 @@ private:
std::string CPackTopLevel;
- cmWIXPatch* Patch;
+ std::unique_ptr<cmWIXPatch> Patch;
cmWIXSourceWriter::GuidType ComponentGuidType;
};
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 3668b46..9685a7f 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXAccessControlList.h"
+#include <cm/string_view>
+
#include "cmCPackGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -35,12 +37,13 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
return;
}
- std::string user_and_domain = entry.substr(0, pos);
- std::string permission_string = entry.substr(pos + 1);
+ cm::string_view enview(entry);
+ cm::string_view user_and_domain = enview.substr(0, pos);
+ cm::string_view permission_string = enview.substr(pos + 1);
pos = user_and_domain.find('@');
- std::string user;
- std::string domain;
+ cm::string_view user;
+ cm::string_view domain;
if (pos != std::string::npos) {
user = user_and_domain.substr(0, pos);
domain = user_and_domain.substr(pos + 1);
@@ -51,9 +54,9 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
std::vector<std::string> permissions = cmTokenize(permission_string, ",");
this->SourceWriter.BeginElement("Permission");
- this->SourceWriter.AddAttribute("User", user);
+ this->SourceWriter.AddAttribute("User", std::string(user));
if (!domain.empty()) {
- this->SourceWriter.AddAttribute("Domain", domain);
+ this->SourceWriter.AddAttribute("Domain", std::string(domain));
}
for (std::string const& permission : permissions) {
this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index c0d879a..b4085d5 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -1,5 +1,10 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#if defined(__CYGWIN__)
+// For S_IWRITE symbol
+# define _DEFAULT_SOURCE
+#endif
+
#include "cmWIXFilesSourceWriter.h"
#include "cm_sys_stat.h"
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index ca232f9..122ffaf 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -41,7 +41,7 @@ void cmWIXPatch::ApplyFragment(std::string const& id,
void cmWIXPatch::ApplyElementChildren(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer)
{
- for (cmWIXPatchNode* node : element.children) {
+ for (const auto& node : element.children) {
switch (node->type()) {
case cmWIXPatchNode::ELEMENT:
ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index fd9103b..5588d2d 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXPatchParser.h"
+#include <utility>
+
+#include <cm/memory>
+
#include "cm_expat.h"
#include "cmCPackGenerator.h"
@@ -20,12 +24,8 @@ cmWIXPatchNode::~cmWIXPatchNode()
{
}
-cmWIXPatchElement::~cmWIXPatchElement()
-{
- for (cmWIXPatchNode* child : children) {
- delete child;
- }
-}
+cmWIXPatchElement::cmWIXPatchElement() = default;
+cmWIXPatchElement::~cmWIXPatchElement() = default;
cmWIXPatchParser::cmWIXPatchParser(fragment_map_t& fragments,
cmCPackLog* logger)
@@ -54,8 +54,7 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
} else if (State == INSIDE_FRAGMENT) {
cmWIXPatchElement& parent = *ElementStack.back();
- cmWIXPatchElement* element = new cmWIXPatchElement;
- parent.children.push_back(element);
+ auto element = cm::make_unique<cmWIXPatchElement>();
element->name = name;
@@ -66,7 +65,8 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
element->attributes[key] = value;
}
- ElementStack.push_back(element);
+ ElementStack.push_back(element.get());
+ parent.children.push_back(std::move(element));
}
}
@@ -130,10 +130,10 @@ void cmWIXPatchParser::CharacterDataHandler(const char* data, int length)
std::string::size_type last = text.find_last_not_of(whitespace);
if (first != std::string::npos && last != std::string::npos) {
- cmWIXPatchText* text_node = new cmWIXPatchText;
+ auto text_node = cm::make_unique<cmWIXPatchText>();
text_node->text = text.substr(first, last - first + 1);
- parent.children.push_back(text_node);
+ parent.children.push_back(std::move(text_node));
}
}
}
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index 87dd892..8d5d2ad 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -4,6 +4,7 @@
#define cmCPackWIXPatchParser_h
#include <map>
+#include <memory>
#include <vector>
#include "cmCPackLog.h"
@@ -33,9 +34,14 @@ struct cmWIXPatchElement : cmWIXPatchNode
{
virtual Type type();
+ cmWIXPatchElement();
+
+ cmWIXPatchElement(const cmWIXPatchElement&) = delete;
+ const cmWIXPatchElement& operator=(const cmWIXPatchElement&) = delete;
+
~cmWIXPatchElement();
- using child_list_t = std::vector<cmWIXPatchNode*>;
+ using child_list_t = std::vector<std::unique_ptr<cmWIXPatchNode>>;
using attributes_t = std::map<std::string, std::string>;
std::string name;
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 43f2946..aaa5318 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -8,6 +8,8 @@
#include <utility>
#include <vector>
+#include "cm_libarchive.h"
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -154,6 +156,20 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
} \
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat); \
do { \
+ if (!this->SetArchiveOptions(&archive)) { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, \
+ "Problem to set archive options <" \
+ << (filename) << ">, ERROR = " << (archive).GetError() \
+ << std::endl); \
+ return 0; \
+ } \
+ if (!archive.Open()) { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, \
+ "Problem to open archive <" \
+ << (filename) << ">, ERROR = " << (archive).GetError() \
+ << std::endl); \
+ return 0; \
+ } \
if (!(archive)) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to create archive <" \
@@ -328,3 +344,23 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
// (for backward compatibility reason)
return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
}
+
+bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive)
+{
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ // Upstream fixed an issue with their integer parsing in 3.4.0 which would
+ // cause spurious errors to be raised from `strtoull`.
+ if (this->Compress == cmArchiveWrite::CompressXZ) {
+ const char* threads = "1";
+ if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
+ threads = this->GetOption("CPACK_ARCHIVE_THREADS");
+ }
+
+ if (!archive->SetFilterOption("xz", "threads", threads)) {
+ return false;
+ }
+ }
+#endif
+
+ return true;
+}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 8d67720..7eb5665 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -86,6 +86,8 @@ private:
return this->OutputExtension.c_str();
}
+ bool SetArchiveOptions(cmArchiveWrite* archive);
+
private:
cmArchiveWrite::Compress Compress;
std::string ArchiveFormat;
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index d92acde..8eca2ff 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -173,6 +173,7 @@ bool DebGenerator::generateDataTar() const
}
cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType,
DebianArchiveType);
+ data_tar.Open();
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
@@ -291,6 +292,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
}
cmArchiveWrite control_tar(fileStream_control_tar,
cmArchiveWrite::CompressGZip, DebianArchiveType);
+ control_tar.Open();
// sets permissions and uid/gid for the files
control_tar.SetUIDAndGID(0u, 0u);
@@ -410,6 +412,7 @@ bool DebGenerator::generateDeb() const
cmGeneratedFileStream debStream;
debStream.Open(outputPath, false, true);
cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
+ deb.Open();
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index e3cc352..b673006 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
// Needed for ::open() and ::stat()
#include <algorithm>
@@ -285,8 +286,7 @@ int cmCPackFreeBSDGenerator::PackageFiles()
}
std::vector<std::string>::const_iterator fileIt;
- std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(toplevel);
+ cmWorkingDirectory wd(toplevel);
files.erase(std::remove_if(files.begin(), files.end(), ignore_file),
files.end());
@@ -332,6 +332,5 @@ int cmCPackFreeBSDGenerator::PackageFiles()
}
}
- cmSystemTools::ChangeDirectory(dir);
return 1;
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index e053144..08fd2a2 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -403,7 +403,6 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
/* rebuild symlinks in the installed tree */
if (!symlinkedFiles.empty()) {
- std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
std::string goToDir = cmStrCat(tempDir, '/', subdir);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Change dir to: " << goToDir << std::endl);
@@ -442,7 +441,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "Going back to: " << curDir << std::endl);
+ "Going back to: " << workdir.GetOldDirectory()
+ << std::endl);
}
}
}
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index ca675fd..49e4113 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -4,54 +4,38 @@
#include <iostream>
+#include <cm/memory>
+
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
cmCPackLog::cmCPackLog()
{
- this->Verbose = false;
- this->Debug = false;
- this->Quiet = false;
- this->NewLine = true;
-
- this->LastTag = cmCPackLog::NOTAG;
this->DefaultOutput = &std::cout;
this->DefaultError = &std::cerr;
-
- this->LogOutput = nullptr;
- this->LogOutputCleanup = false;
}
-cmCPackLog::~cmCPackLog()
-{
- this->SetLogOutputStream(nullptr);
-}
+cmCPackLog::~cmCPackLog() = default;
void cmCPackLog::SetLogOutputStream(std::ostream* os)
{
- if (this->LogOutputCleanup && this->LogOutput) {
- delete this->LogOutput;
- }
- this->LogOutputCleanup = false;
+ this->LogOutputStream.reset();
this->LogOutput = os;
}
bool cmCPackLog::SetLogOutputFile(const char* fname)
{
- cmGeneratedFileStream* cg = nullptr;
+ this->LogOutputStream.reset();
if (fname) {
- cg = new cmGeneratedFileStream(fname);
- }
- if (cg && !*cg) {
- delete cg;
- cg = nullptr;
+ this->LogOutputStream = cm::make_unique<cmGeneratedFileStream>(fname);
}
- this->SetLogOutputStream(cg);
- if (!cg) {
- return false;
+ if (this->LogOutputStream && !*this->LogOutputStream) {
+ this->LogOutputStream.reset();
}
- this->LogOutputCleanup = true;
- return true;
+
+ this->LogOutput = this->LogOutputStream.get();
+
+ return this->LogOutput != nullptr;
}
void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 1cb1643..68ffcce 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <ostream>
#include <string>
@@ -97,13 +98,13 @@ public:
void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; }
private:
- bool Verbose;
- bool Debug;
- bool Quiet;
+ bool Verbose = false;
+ bool Debug = false;
+ bool Quiet = false;
- bool NewLine;
+ bool NewLine = true;
- int LastTag;
+ int LastTag = cmCPackLog::NOTAG;
std::string Prefix;
std::string OutputPrefix;
@@ -112,13 +113,11 @@ private:
std::string WarningPrefix;
std::string ErrorPrefix;
- std::ostream* DefaultOutput;
- std::ostream* DefaultError;
+ std::ostream* DefaultOutput = nullptr;
+ std::ostream* DefaultError = nullptr;
- std::string LogOutputFileName;
- std::ostream* LogOutput;
- // Do we need to cleanup log output stream
- bool LogOutputCleanup;
+ std::ostream* LogOutput = nullptr;
+ std::unique_ptr<std::ostream> LogOutputStream;
};
class cmCPackLogWrite
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2a46627..058b090 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -9,10 +9,11 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/Directory.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -68,7 +69,7 @@ int cmCPackNSISGenerator::PackageFiles()
// Use the custom component install directory if we have one
if (pos != std::string::npos) {
- const std::string componentName = fileN.substr(0, pos);
+ auto componentName = cm::string_view(fileN).substr(0, pos);
outputDir = CustomComponentInstallDirectory(componentName);
} else {
outputDir = CustomComponentInstallDirectory(fileN);
@@ -103,7 +104,7 @@ int cmCPackNSISGenerator::PackageFiles()
componentName = fileN.substr(0, slash);
// Strip off the component part of the path.
- fileN = fileN.substr(slash + 1);
+ fileN.erase(0, slash + 1);
}
}
std::replace(fileN.begin(), fileN.end(), '/', '\\');
@@ -203,6 +204,11 @@ int cmCPackNSISGenerator::PackageFiles()
"!define MUI_FINISHPAGE_TITLE_3LINES");
}
+ if (this->IsSet("CPACK_NSIS_MANIFEST_DPI_AWARE")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_MANIFEST_DPI_AWARE_CODE",
+ "ManifestDPIAware true");
+ }
+
// Setup all of the component sections
if (this->Components.empty()) {
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
@@ -524,7 +530,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (cmContains(cpackPackageDesktopLinksVector, execName)) {
+ if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -672,7 +678,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
const std::string componentOutputDir =
CustomComponentInstallDirectory(component->Name);
- componentCode += " SetOutPath \"" + componentOutputDir + "\"\n";
+ componentCode += cmStrCat(" SetOutPath \"", componentOutputDir, "\"\n");
// Create the actual installation commands
if (component->IsDownloaded) {
@@ -921,12 +927,11 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription(
}
std::string cmCPackNSISGenerator::CustomComponentInstallDirectory(
- const std::string& componentName)
+ cm::string_view componentName)
{
- const char* outputDir =
- this->GetOption("CPACK_NSIS_" + componentName + "_INSTALL_DIRECTORY");
- const std::string componentOutputDir = (outputDir ? outputDir : "$INSTDIR");
- return componentOutputDir;
+ const char* outputDir = this->GetOption(
+ cmStrCat("CPACK_NSIS_", componentName, "_INSTALL_DIRECTORY"));
+ return outputDir ? outputDir : "$INSTDIR";
}
std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index 0af37af..88cba45 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -10,6 +10,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmCPackGenerator.h"
class cmCPackComponent;
@@ -75,8 +77,7 @@ protected:
/// Returns the custom install directory if available for the specified
/// component, otherwise $INSTDIR is returned.
- std::string CustomComponentInstallDirectory(
- const std::string& componentName);
+ std::string CustomComponentInstallDirectory(cm::string_view componentName);
/// Translations any newlines found in the string into \\r\\n, so that the
/// resulting string can be used within NSIS.
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index dc31623..2e5bde2 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -85,7 +85,7 @@ int cpackDefinitionArgument(const char* argument, const char* cValue,
return 0;
}
std::string key = value.substr(0, pos);
- value = value.substr(pos + 1);
+ value.erase(0, pos + 1);
def->Map[key] = value;
cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG,
"Set CPack variable: " << key << " to \"" << value << "\""
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 5e29386..db426b2 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -379,7 +379,7 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
const std::vector<std::string>& allArgs)
{
// --build-and-test options
- if (currentArg.find("--build-and-test", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-and-test") &&
idx < allArgs.size() - 1) {
if (idx + 2 < allArgs.size()) {
idx++;
@@ -397,25 +397,29 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
return 0;
}
}
- if (currentArg.find("--build-target", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-target") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildTargets.push_back(allArgs[idx]);
}
- if (currentArg.find("--build-nocmake", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) {
this->BuildNoCMake = true;
}
- if (currentArg.find("--build-run-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-run-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildRunDir = allArgs[idx];
}
- if (currentArg.find("--build-two-config", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-two-config")) {
this->BuildTwoConfig = true;
}
- if (currentArg.find("--build-exe-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->ExecutableDirectory = allArgs[idx];
}
- if (currentArg.find("--test-timeout", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-timeout") &&
+ idx < allArgs.size() - 1) {
idx++;
this->Timeout = cmDuration(atof(allArgs[idx].c_str()));
}
@@ -431,31 +435,33 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++;
this->BuildGeneratorToolset = allArgs[idx];
}
- if (currentArg.find("--build-project", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-project") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildProject = allArgs[idx];
}
- if (currentArg.find("--build-makeprogram", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") &&
idx < allArgs.size() - 1) {
idx++;
this->BuildMakeProgram = allArgs[idx];
}
- if (currentArg.find("--build-config-sample", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-config-sample") &&
idx < allArgs.size() - 1) {
idx++;
this->ConfigSample = allArgs[idx];
}
- if (currentArg.find("--build-noclean", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-noclean")) {
this->BuildNoClean = true;
}
- if (currentArg.find("--build-options", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-options")) {
while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" &&
allArgs[idx + 1] != "--test-command") {
++idx;
this->BuildOptions.push_back(allArgs[idx]);
}
}
- if (currentArg.find("--test-command", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-command") &&
+ idx < allArgs.size() - 1) {
++idx;
this->TestCommand = allArgs[idx];
while (idx + 1 < allArgs.size()) {
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 03a3fd3..35c2b11 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -386,24 +386,20 @@ int cmCTestBuildHandler::ProcessHandler()
if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
std::string srcdir =
this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
- for (cc = srcdir.size() - 2; cc > 0; cc--) {
- if (srcdir[cc] == '/') {
- srcdir = srcdir.substr(0, cc + 1);
- break;
- }
+ cc = srcdir.rfind('/', srcdir.size() - 2);
+ if (cc != std::string::npos) {
+ srcdir.resize(cc + 1);
+ this->SimplifySourceDir = std::move(srcdir);
}
- this->SimplifySourceDir = srcdir;
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
std::string bindir =
this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
- for (cc = bindir.size() - 2; cc > 0; cc--) {
- if (bindir[cc] == '/') {
- bindir = bindir.substr(0, cc + 1);
- break;
- }
+ cc = bindir.rfind('/', bindir.size() - 2);
+ if (cc != std::string::npos) {
+ bindir.resize(cc + 1);
+ this->SimplifyBuildDir = std::move(bindir);
}
- this->SimplifyBuildDir = bindir;
}
// Ok, let's do the build
@@ -545,11 +541,11 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
const char* fname = launchDir.GetFile(i);
if (this->IsLaunchedErrorFile(fname) && numErrorsAllowed) {
numErrorsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalErrors;
} else if (this->IsLaunchedWarningFile(fname) && numWarningsAllowed) {
numWarningsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalWarnings;
}
}
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 45ec390..1209e06 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -152,10 +152,12 @@ private:
this->FinishRevision();
}
} else if (this->Section == SectionRevisions) {
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if (!this->Rev.Log.empty()) {
// Continue the existing log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
} else if (this->Rev.Rev.empty() &&
this->RegexRevision.find(this->Line)) {
this->Rev.Rev = this->RegexRevision.match(1);
@@ -166,7 +168,7 @@ private:
} else if (!this->RegexBranches.find(this->Line)) {
// Start the log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
}
}
return this->Section != SectionEnd;
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be3..e335923 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,10 @@
#include <set>
+#include <cmext/algorithm>
+
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
@@ -22,7 +23,7 @@ void cmCTestCoverageCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
this->LabelsMentioned =
- !this->Labels.empty() || cmContains(keywords, "LABELS");
+ !this->Labels.empty() || cm::contains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 2c8f119..daa10c9 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -680,8 +680,9 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile* mf)
//
#ifdef _WIN32
# define fnc(s) cmSystemTools::LowerCase(s)
+# define fnc_prefix(s, t) fnc(s.substr(0, t.size())) == fnc(t)
#else
-# define fnc(s) s
+# define fnc_prefix(s, t) cmHasPrefix(s, t)
#endif
bool IsFileInDir(const std::string& infile, const std::string& indir)
@@ -689,8 +690,8 @@ bool IsFileInDir(const std::string& infile, const std::string& indir)
std::string file = cmSystemTools::CollapseFullPath(infile);
std::string dir = cmSystemTools::CollapseFullPath(indir);
- return file.size() > dir.size() &&
- fnc(file.substr(0, dir.size())) == fnc(dir) && file[dir.size()] == '/';
+ return file.size() > dir.size() && fnc_prefix(file, dir) &&
+ file[dir.size()] == '/';
}
int cmCTestCoverageHandler::HandlePHPCoverage(
@@ -1709,29 +1710,26 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
// Read the coverage count from the beginning of the Trace.py output
// line
- std::string prefix = nl.substr(0, 6);
- if (prefix[5] != ' ' && prefix[5] != ':') {
- // This is a hack. We should really do something more elaborate
- prefix = nl.substr(0, 7);
- if (prefix[6] != ' ' && prefix[6] != ':') {
- prefix = nl.substr(0, 8);
- if (prefix[7] != ' ' && prefix[7] != ':') {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Currently the limit is maximum coverage of 999999"
- << std::endl);
- }
+ std::string::size_type pos;
+ int cov = 0;
+ // This is a hack. We should really do something more elaborate
+ for (pos = 5; pos < 8; pos++) {
+ if (nl[pos] == ' ') {
+ // This line does not have ':' so no coverage here. That said,
+ // Trace.py does not handle not covered lines versus comments etc.
+ // So, this will be set to 0.
+ break;
+ }
+ if (nl[pos] == ':') {
+ cov = atoi(nl.substr(0, pos - 1).c_str());
+ break;
}
}
- int cov = atoi(prefix.c_str());
- if (prefix[prefix.size() - 1] != ':') {
- // This line does not have ':' so no coverage here. That said,
- // Trace.py does not handle not covered lines versus comments etc.
- // So, this will be set to 0.
- cov = 0;
+ if (pos == 8) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Currently the limit is maximum coverage of 999999"
+ << std::endl);
}
- cmCTestOptionalLog(
- this->CTest, DEBUG,
- "Prefix: " << prefix << " cov: " << cov << std::endl, this->Quiet);
// Read the line number starting at the 10th character of the gcov
// output line
long lineIdx = cnt;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 3f3c107..568b091 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -6,6 +6,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
+#include <utility>
#include <vector>
#include "cmsys/FStream.hxx"
@@ -193,7 +194,8 @@ bool cmCTestGIT::UpdateByFetchAndReset()
if (line.find("\tnot-for-merge\t") == std::string::npos) {
std::string::size_type pos = line.find('\t');
if (pos != std::string::npos) {
- sha1 = line.substr(0, pos);
+ sha1 = std::move(line);
+ sha1.resize(pos);
}
}
}
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index c1ecaf1..85b8ab1 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -10,11 +10,12 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmSystemTools.h"
@@ -297,9 +298,6 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf)
this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE",
this->CustomTestsIgnore);
- std::string cmake = cmSystemTools::GetCMakeCommand();
- this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(),
- this->Quiet);
}
int cmCTestMemCheckHandler::GetDefectCount()
@@ -490,31 +488,31 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"AddressSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"LeakSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::LEAK_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"ThreadSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"MemorySanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"UndefinedBehaviorSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
@@ -594,11 +592,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
std::string tempDrMemoryDir =
this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
- if (!cmContains(this->MemoryTesterOptions, "-quiet")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-quiet")) {
this->MemoryTesterOptions.emplace_back("-quiet");
}
- if (!cmContains(this->MemoryTesterOptions, "-batch")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-batch")) {
this->MemoryTesterOptions.emplace_back("-batch");
}
@@ -957,35 +955,25 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
"valgrind line " << lines[cc] << std::endl,
this->Quiet);
int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
- if (vgFIM.find(lines[cc])) {
+ auto& line = lines[cc];
+ if (vgFIM.find(line)) {
failure = cmCTestMemCheckHandler::FIM;
- } else if (vgFMM.find(lines[cc])) {
+ } else if (vgFMM.find(line)) {
failure = cmCTestMemCheckHandler::FMM;
- } else if (vgMLK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MLK;
- } else if (vgMLK2.find(lines[cc])) {
+ } else if (vgMLK1.find(line) || vgMLK2.find(line)) {
failure = cmCTestMemCheckHandler::MLK;
- } else if (vgPAR.find(lines[cc])) {
+ } else if (vgPAR.find(line)) {
failure = cmCTestMemCheckHandler::PAR;
- } else if (vgMPK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MPK;
- } else if (vgMPK2.find(lines[cc])) {
+ } else if (vgMPK1.find(line) || vgMPK2.find(line)) {
failure = cmCTestMemCheckHandler::MPK;
- } else if (vgUMC.find(lines[cc])) {
+ } else if (vgUMC.find(line)) {
failure = cmCTestMemCheckHandler::UMC;
- } else if (vgUMR1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR2.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR3.find(lines[cc])) {
+ } else if (vgUMR1.find(line) || vgUMR2.find(line) || vgUMR3.find(line) ||
+ vgUMR4.find(line) || vgUMR5.find(line)) {
failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR4.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR5.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgIPW.find(lines[cc])) {
+ } else if (vgIPW.find(line)) {
failure = cmCTestMemCheckHandler::IPW;
- } else if (vgABR.find(lines[cc])) {
+ } else if (vgABR.find(line)) {
failure = cmCTestMemCheckHandler::ABR;
}
@@ -1049,13 +1037,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckDrMemoryOutput(
ostr << l << std::endl;
if (drMemoryError.find(l)) {
defects++;
- if (unaddressableAccess.find(l)) {
+ if (unaddressableAccess.find(l) || uninitializedRead.find(l)) {
results[cmCTestMemCheckHandler::UMR]++;
- } else if (uninitializedRead.find(l)) {
- results[cmCTestMemCheckHandler::UMR]++;
- } else if (leak.find(l)) {
- results[cmCTestMemCheckHandler::MLK]++;
- } else if (handleLeak.find(l)) {
+ } else if (leak.find(l) || handleLeak.find(l)) {
results[cmCTestMemCheckHandler::MLK]++;
} else if (invalidHeapArgument.find(l)) {
results[cmCTestMemCheckHandler::FMM]++;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 2192843..5c37f97 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -12,13 +12,13 @@
#include <iomanip>
#include <iostream>
#include <list>
-#include <memory>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <utility>
#include <vector>
+#include <cm/memory>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
@@ -29,7 +29,6 @@
#include "cm_uv.h"
#include "cmAffinity.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestBinPacker.h"
#include "cmCTestRunTest.h"
@@ -138,7 +137,7 @@ void cmCTestMultiProcessHandler::RunTests()
uv_run(&this->Loop, UV_RUN_DEFAULT);
uv_loop_close(&this->Loop);
- if (!this->StopTimePassed) {
+ if (!this->StopTimePassed && !this->CheckStopOnFailure()) {
assert(this->Completed == this->Total);
assert(this->Tests.empty());
}
@@ -172,7 +171,8 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
- cmCTestRunTest* testRun = new cmCTestRunTest(*this);
+ auto testRun = cm::make_unique<cmCTestRunTest>(*this);
+
if (this->RepeatMode != cmCTest::Repeat::Never) {
testRun->SetRepeatMode(this->RepeatMode);
testRun->SetNumberOfRuns(this->RepeatCount);
@@ -187,7 +187,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// Find any failed dependencies for this test. We assume the more common
// scenario has no failed tests, so make it the outer loop.
for (std::string const& f : *this->Failed) {
- if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
+ if (cm::contains(this->Properties[test]->RequireSuccessDepends, f)) {
testRun->AddFailedDependency(f);
}
}
@@ -229,28 +229,25 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
e << "\n";
}
e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
- testRun->StartFailure(e.str(), "Insufficient resources");
- this->FinishTestProcess(testRun, false);
+ cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ "Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- testRun->StartFailure("Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
- } else {
- if (testRun->StartTest(this->Completed, this->Total)) {
- // Ownership of 'testRun' has moved to another structure.
- // When the test finishes, FinishTestProcess will be called.
- return true;
- }
+ cmCTestRunTest::StartFailure(std::move(testRun),
+ "Failed to change working directory to " +
+ this->Properties[test]->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
+ return false;
}
- // Pass ownership of 'testRun'.
- this->FinishTestProcess(testRun, false);
- return false;
+ // Ownership of 'testRun' has moved to another structure.
+ // When the test finishes, FinishTestProcess will be called.
+ return cmCTestRunTest::StartTest(std::move(testRun), this->Completed,
+ this->Total);
}
bool cmCTestMultiProcessHandler::AllocateResources(int index)
@@ -370,6 +367,11 @@ void cmCTestMultiProcessHandler::CheckResourcesAvailable()
}
}
+bool cmCTestMultiProcessHandler::CheckStopOnFailure()
+{
+ return this->CTest->GetStopOnFailure();
+}
+
bool cmCTestMultiProcessHandler::CheckStopTimePassed()
{
if (!this->StopTimePassed) {
@@ -447,7 +449,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
{
// Check for locked resources
for (std::string const& i : this->Properties[test]->LockedResources) {
- if (cmContains(this->LockedResources, i)) {
+ if (cm::contains(this->LockedResources, i)) {
return false;
}
}
@@ -486,6 +488,10 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ if (this->CheckStopOnFailure() && !this->Failed->empty()) {
+ return;
+ }
+
size_t numToStart = 0;
if (this->RunningCount < this->ParallelLevel) {
@@ -540,7 +546,8 @@ void cmCTestMultiProcessHandler::StartNextTests()
if (this->SerialTestRunning) {
break;
}
- // We can only start a RUN_SERIAL test if no other tests are also running.
+ // We can only start a RUN_SERIAL test if no other tests are also
+ // running.
if (this->Properties[test]->RunSerial && this->RunningCount > 0) {
continue;
}
@@ -618,8 +625,8 @@ void cmCTestMultiProcessHandler::OnTestLoadRetryCB(uv_timer_t* timer)
self->StartNextTests();
}
-void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
- bool started)
+void cmCTestMultiProcessHandler::FinishTestProcess(
+ std::unique_ptr<cmCTestRunTest> runner, bool started)
{
this->Completed++;
@@ -631,7 +638,8 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->SetStopTimePassed();
}
if (started) {
- if (!this->StopTimePassed && runner->StartAgain(this->Completed)) {
+ if (!this->StopTimePassed &&
+ cmCTestRunTest::StartAgain(std::move(runner), this->Completed)) {
this->Completed--; // remove the completed test because run again
return;
}
@@ -659,7 +667,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
}
properties->Affinity.clear();
- delete runner;
+ runner.reset();
if (started) {
this->StartNextTests();
}
@@ -802,7 +810,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// In parallel test runs add previously failed tests to the front
// of the cost list and queue other tests for further sorting
for (auto const& t : this->Tests) {
- if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
+ if (cm::contains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
// If the test failed last time, it should be run first.
this->SortedTests.push_back(t.first);
alreadySortedTests.insert(t.first);
@@ -841,7 +849,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
TestComparator(this));
for (auto const& j : sortedCopy) {
- if (!cmContains(alreadySortedTests, j)) {
+ if (!cm::contains(alreadySortedTests, j)) {
this->SortedTests.push_back(j);
alreadySortedTests.insert(j);
}
@@ -873,7 +881,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
TestSet alreadySortedTests;
for (int test : presortedList) {
- if (cmContains(alreadySortedTests, test)) {
+ if (cm::contains(alreadySortedTests, test)) {
continue;
}
@@ -881,7 +889,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
- if (!cmContains(alreadySortedTests, testDependency)) {
+ if (!cm::contains(alreadySortedTests, testDependency)) {
alreadySortedTests.insert(testDependency);
this->SortedTests.push_back(testDependency);
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 5b429d4..6e999f9 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -124,7 +125,7 @@ protected:
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
- void FinishTestProcess(cmCTestRunTest* runner, bool started);
+ void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
static void OnTestLoadRetryCB(uv_timer_t* timer);
@@ -137,6 +138,8 @@ protected:
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
+ bool CheckStopOnFailure();
+
bool CheckStopTimePassed();
void SetStopTimePassed();
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index ec54960..7d0f69b 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -314,23 +314,27 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
return passed || skipped;
}
-bool cmCTestRunTest::StartAgain(size_t completed)
+bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed)
{
- if (!this->RunAgain) {
+ auto* testRun = runner.get();
+
+ if (!testRun->RunAgain) {
return false;
}
- this->RunAgain = false; // reset
+ testRun->RunAgain = false; // reset
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
// change to tests directory
- cmWorkingDirectory workdir(this->TestProperties->Directory);
+ cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- this->StartFailure("Failed to change working directory to " +
- this->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
+ testRun->StartFailure("Failed to change working directory to " +
+ testRun->TestProperties->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
return true;
}
- this->StartTest(completed, this->TotalNumberOfTests);
+ testRun->StartTest(completed, testRun->TotalNumberOfTests);
return true;
}
@@ -382,6 +386,18 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index);
}
+void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+ testRun->StartFailure(output, detail);
+
+ testRun->FinalizeTest(false);
+}
+
void cmCTestRunTest::StartFailure(std::string const& output,
std::string const& detail)
{
@@ -413,7 +429,6 @@ void cmCTestRunTest::StartFailure(std::string const& output,
this->TestResult.Path = this->TestProperties->Directory;
this->TestResult.Output = output;
this->TestResult.FullCommandLine.clear();
- this->TestProcess = cm::make_unique<cmProcess>(*this);
}
std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -437,6 +452,21 @@ std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
return outputStream.str();
}
+bool cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+
+ if (!testRun->StartTest(completed, total)) {
+ testRun->FinalizeTest(false);
+ return false;
+ }
+
+ return true;
+}
+
// Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t completed, size_t total)
{
@@ -468,7 +498,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->TestProperties->Disabled) {
this->TestResult.CompletionStatus = "Disabled";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestResult.Output = "Disabled";
this->TestResult.FullCommandLine.clear();
return false;
@@ -482,7 +511,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
// its arguments are irrelevant. This matters for the case where a fixture
// dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg = "Failed test dependencies:";
for (std::string const& failedDep : this->FailedDependencies) {
msg += " " + failedDep;
@@ -499,7 +527,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
msg = "Test not available without configuration. (Missing \"-C "
@@ -521,7 +548,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
for (std::string const& file : this->TestProperties->RequiredFiles) {
if (!cmSystemTools::FileExists(file)) {
// Required file was not found
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find required file: " << file
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -537,7 +563,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->ActualCommand.empty()) {
// if the command was not found create a TestResult object
// that has that information
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find executable: " << args[1]
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -649,7 +674,6 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
std::vector<std::string>* environment,
std::vector<size_t>* affinity)
{
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
this->TestProcess->SetCommand(this->ActualCommand);
@@ -816,7 +840,8 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
"Testing " << this->TestProperties->Name << " ... ");
}
-void cmCTestRunTest::FinalizeTest()
+void cmCTestRunTest::FinalizeTest(bool started)
{
- this->MultiTestHandler.FinishTestProcess(this, true);
+ this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(),
+ started);
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 4988839..b1d188a 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -65,6 +65,15 @@ public:
// Read and store output. Returns true if it must be called again.
void CheckOutput(std::string const& line);
+ static bool StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total);
+ static bool StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed);
+
+ static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail);
+
// launch the test process, return whether it started correctly
bool StartTest(size_t completed, size_t total);
// capture and report the test results
@@ -74,8 +83,6 @@ public:
void ComputeWeightedCost();
- bool StartAgain(size_t completed);
-
void StartFailure(std::string const& output, std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
@@ -84,7 +91,7 @@ public:
const std::vector<std::string>& GetArguments() { return this->Arguments; }
- void FinalizeTest();
+ void FinalizeTest(bool started = true);
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7803e37..4fa4dc0 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -6,7 +6,6 @@
#include <cstdlib>
#include <cstring>
#include <map>
-#include <memory>
#include <ratio>
#include <sstream>
#include <utility>
@@ -51,22 +50,7 @@
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
-cmCTestScriptHandler::cmCTestScriptHandler()
-{
- this->Backup = false;
- this->EmptyBinDir = false;
- this->EmptyBinDirOnce = false;
- this->Makefile = nullptr;
- this->ParentMakefile = nullptr;
- this->CMake = nullptr;
- this->GlobalGenerator = nullptr;
-
- this->ScriptStartTime = std::chrono::steady_clock::time_point();
-
- // the *60 is because the settings are in minutes but GetTime is seconds
- this->MinimumInterval = 30 * 60;
- this->ContinuousDuration = -1;
-}
+cmCTestScriptHandler::cmCTestScriptHandler() = default;
void cmCTestScriptHandler::Initialize()
{
@@ -95,22 +79,15 @@ void cmCTestScriptHandler::Initialize()
// what time in seconds did this script start running
this->ScriptStartTime = std::chrono::steady_clock::time_point();
- delete this->Makefile;
- this->Makefile = nullptr;
+ this->Makefile.reset();
this->ParentMakefile = nullptr;
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
+ this->GlobalGenerator.reset();
- delete this->CMake;
+ this->CMake.reset();
}
-cmCTestScriptHandler::~cmCTestScriptHandler()
-{
- delete this->Makefile;
- delete this->GlobalGenerator;
- delete this->CMake;
-}
+cmCTestScriptHandler::~cmCTestScriptHandler() = default;
// just adds an argument to the vector
void cmCTestScriptHandler::AddConfigurationScript(const char* script,
@@ -247,23 +224,20 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
void cmCTestScriptHandler::CreateCMake()
{
// create a cmake instance to read the configuration script
- if (this->CMake) {
- delete this->CMake;
- delete this->GlobalGenerator;
- delete this->Makefile;
- }
- this->CMake = new cmake(cmake::RoleScript, cmState::CTest);
+ this->CMake = cm::make_unique<cmake>(cmake::RoleScript, cmState::CTest);
this->CMake->SetHomeDirectory("");
this->CMake->SetHomeOutputDirectory("");
this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
this->CMake->AddCMakePaths();
- this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
+ this->GlobalGenerator =
+ cm::make_unique<cmGlobalGenerator>(this->CMake.get());
cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
snapshot.GetDirectory().SetCurrentSource(cwd);
snapshot.GetDirectory().SetCurrentBinary(cwd);
- this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+ this->Makefile =
+ cm::make_unique<cmMakefile>(this->GlobalGenerator.get(), snapshot);
if (this->ParentMakefile) {
this->Makefile->SetRecursionDepth(
this->ParentMakefile->GetRecursionDepth());
@@ -310,12 +284,14 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
// if the argument has a , in it then it needs to be broken into the fist
// argument (which is the script) and the second argument which will be
// passed into the scripts as S_ARG
- std::string script = total_script_arg;
+ std::string script;
std::string script_arg;
const std::string::size_type comma_pos = total_script_arg.find(',');
if (comma_pos != std::string::npos) {
script = total_script_arg.substr(0, comma_pos);
script_arg = total_script_arg.substr(comma_pos + 1);
+ } else {
+ script = total_script_arg;
}
// make sure the file exists
if (!cmSystemTools::FileExists(script)) {
@@ -878,7 +854,7 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
const char* sname, bool InProcess,
int* returnValue)
{
- cmCTestScriptHandler* sh = new cmCTestScriptHandler();
+ auto sh = cm::make_unique<cmCTestScriptHandler>();
sh->SetCTestInstance(ctest);
sh->ParentMakefile = mf;
sh->AddConfigurationScript(sname, InProcess);
@@ -886,7 +862,6 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
if (returnValue) {
*returnValue = res;
}
- delete sh;
return true;
}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d003199..ebb7905 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -101,12 +101,14 @@ public:
cmDuration GetRemainingTimeAllowed();
cmCTestScriptHandler();
+ cmCTestScriptHandler(const cmCTestScriptHandler&) = delete;
+ const cmCTestScriptHandler& operator=(const cmCTestScriptHandler&) = delete;
~cmCTestScriptHandler() override;
void Initialize() override;
void CreateCMake();
- cmake* GetCMake() { return this->CMake; }
+ cmake* GetCMake() { return this->CMake.get(); }
void SetRunCurrentScript(bool value);
@@ -143,9 +145,9 @@ private:
bool ShouldRunCurrentScript;
- bool Backup;
- bool EmptyBinDir;
- bool EmptyBinDirOnce;
+ bool Backup = false;
+ bool EmptyBinDir = false;
+ bool EmptyBinDirOnce = false;
std::string SourceDir;
std::string BinaryDir;
@@ -161,16 +163,18 @@ private:
std::string CMOutFile;
std::vector<std::string> ExtraUpdates;
- double MinimumInterval;
- double ContinuousDuration;
+ // the *60 is because the settings are in minutes but GetTime is seconds
+ double MinimumInterval = 30 * 60;
+ double ContinuousDuration = -1;
// what time in seconds did this script start running
- std::chrono::steady_clock::time_point ScriptStartTime;
+ std::chrono::steady_clock::time_point ScriptStartTime =
+ std::chrono::steady_clock::time_point();
- cmMakefile* Makefile;
- cmMakefile* ParentMakefile;
- cmGlobalGenerator* GlobalGenerator;
- cmake* CMake;
+ std::unique_ptr<cmMakefile> Makefile;
+ cmMakefile* ParentMakefile = nullptr;
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
+ std::unique_ptr<cmake> CMake;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index acb75b2..5b2f2e6 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,10 +8,10 @@
#include <cm/memory>
#include <cm/vector>
+#include <cmext/algorithm>
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
@@ -172,8 +172,10 @@ void cmCTestSubmitCommand::BindArguments()
void cmCTestSubmitCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
- this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
- this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+ this->PartsMentioned =
+ !this->Parts.empty() || cm::contains(keywords, "PARTS");
+ this->FilesMentioned =
+ !this->Files.empty() || cm::contains(keywords, "FILES");
cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 22ab48f..811a7e8 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -260,11 +260,10 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
if (cm) {
- const char* subproject =
- cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
upload_as += "&subproject=";
- upload_as += ctest_curl.Escape(subproject);
+ upload_as += ctest_curl.Escape(*subproject);
}
}
}
@@ -506,18 +505,19 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
std::string url = this->CTest->GetSubmitURL();
- std::string fields;
- std::string::size_type pos = url.find('?');
- if (pos != std::string::npos) {
- fields = url.substr(pos + 1);
- url = url.substr(0, pos);
- }
if (!cmHasLiteralPrefix(url, "http://") &&
!cmHasLiteralPrefix(url, "https://")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
}
+
+ std::string fields;
+ std::string::size_type pos = url.find('?');
+ if (pos != std::string::npos) {
+ fields = url.substr(pos + 1);
+ url.erase(pos);
+ }
bool internalTest = cmIsOn(this->GetOption("InternalTest"));
// Get RETRY_COUNT and RETRY_DELAY values if they were set.
@@ -555,11 +555,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
// a "&subproject=subprojectname" to the first POST.
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
- const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
// TODO: Encode values for a URL instead of trusting caller.
std::ostringstream str;
if (subproject) {
- str << "subproject=" << curl.Escape(subproject) << "&";
+ str << "subproject=" << curl.Escape(*subproject) << "&";
}
auto timeNow =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 0f9b695..6b317cb 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -34,6 +34,7 @@ void cmCTestTestCommand::BindArguments()
this->Bind("STOP_TIME"_s, this->StopTime);
this->Bind("TEST_LOAD"_s, this->TestLoad);
this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
+ this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -52,6 +53,13 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
}
}
this->CTest->SetTimeOut(timeout);
+
+ const char* resourceSpecFile =
+ this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && resourceSpecFile) {
+ this->ResourceSpecFile = resourceSpecFile;
+ }
+
cmCTestGenericHandler* handler = this->InitializeActualHandler();
if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
handler->SetOption(
@@ -83,6 +91,9 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
handler->SetOption("ExcludeFixtureCleanupRegularExpression",
this->ExcludeFixtureCleanup.c_str());
}
+ if (this->StopOnFailure) {
+ handler->SetOption("StopOnFailure", "ON");
+ }
if (!this->ParallelLevel.empty()) {
handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 2345afb..7925586 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -60,6 +60,7 @@ protected:
std::string StopTime;
std::string TestLoad;
std::string ResourceSpecFile;
+ bool StopOnFailure = false;
};
#endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4f324ea..2408d57 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -18,15 +18,17 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include <cmsys/Base64.h>
#include <cmsys/Directory.hxx>
#include <cmsys/RegularExpression.hxx>
+#include "cm_static_string_view.hxx"
#include "cm_utf8.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestResourceGroupsLexerHelper.h"
@@ -406,7 +408,9 @@ int cmCTestTestHandler::ProcessHandler()
// start the real time clock
auto clock_start = std::chrono::steady_clock::now();
- this->ProcessDirectory(passed, failed);
+ if (!this->ProcessDirectory(passed, failed)) {
+ return -1;
+ }
auto clock_finish = std::chrono::steady_clock::now();
@@ -510,6 +514,10 @@ bool cmCTestTestHandler::ProcessOptions()
this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
}
+ if (this->GetOption("StopOnFailure")) {
+ this->CTest->SetStopOnFailure(true);
+ }
+
const char* val;
val = this->GetOption("LabelRegularExpression");
if (val) {
@@ -543,22 +551,11 @@ bool cmCTestTestHandler::ProcessOptions()
if (val) {
this->ExcludeFixtureCleanupRegExp = val;
}
- this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
-
val = this->GetOption("ResourceSpecFile");
if (val) {
- this->UseResourceSpec = true;
this->ResourceSpecFile = val;
- auto result = this->ResourceSpec.ReadFromJSONFile(val);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Could not read/parse resource spec file "
- << val << ": "
- << cmCTestResourceSpec::ResultToString(result)
- << std::endl);
- return false;
- }
}
+ this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
return true;
}
@@ -718,7 +715,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestTestProperties& p = *result.Properties;
for (std::string const& l : p.Labels) {
// only use labels found in labels
- if (cmContains(labels, l)) {
+ if (cm::contains(labels, l)) {
labelTimes[l] +=
result.ExecutionTime.count() * result.Properties->Processors;
++labelCounts[l];
@@ -860,14 +857,15 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion) {
// if it is not in the list and not in the regexp then skip
- if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) &&
+ if ((!this->TestsToRun.empty() &&
+ !cm::contains(this->TestsToRun, cnt)) &&
!tp.IsInBasedOnREOptions) {
continue;
}
} else {
// is this test in the list of tests to run? If not then skip it
if ((!this->TestsToRun.empty() &&
- !cmContains(this->TestsToRun, inREcnt)) ||
+ !cm::contains(this->TestsToRun, inREcnt)) ||
!tp.IsInBasedOnREOptions) {
continue;
}
@@ -896,7 +894,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
+ if (!this->TestsToRun.empty() && !cm::contains(this->TestsToRun, cnt)) {
continue;
}
@@ -1015,7 +1013,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
const std::string& setupTestName = sIt->second->Name;
tests[i].RequireSuccessDepends.insert(setupTestName);
- if (!cmContains(tests[i].Depends, setupTestName)) {
+ if (!cm::contains(tests[i].Depends, setupTestName)) {
tests[i].Depends.push_back(setupTestName);
}
}
@@ -1119,7 +1117,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& reqTestName = tests[index].Name;
- if (!cmContains(p.Depends, reqTestName)) {
+ if (!cm::contains(p.Depends, reqTestName)) {
p.Depends.push_back(reqTestName);
}
}
@@ -1132,7 +1130,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& setupTestName = tests[index].Name;
- if (!cmContains(p.Depends, setupTestName)) {
+ if (!cm::contains(p.Depends, setupTestName)) {
p.Depends.push_back(setupTestName);
}
}
@@ -1259,7 +1257,7 @@ bool cmCTestTestHandler::GetValue(const char* tag, std::string& value,
return ret;
}
-void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
+bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed)
{
this->ComputeTestList();
@@ -1267,7 +1265,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
this->StartTestTime = std::chrono::system_clock::now();
auto elapsed_time_start = std::chrono::steady_clock::now();
- cmCTestMultiProcessHandler* parallel = new cmCTestMultiProcessHandler;
+ auto parallel = cm::make_unique<cmCTestMultiProcessHandler>();
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
@@ -1283,7 +1281,17 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
- if (this->UseResourceSpec) {
+ if (!this->ResourceSpecFile.empty()) {
+ this->UseResourceSpec = true;
+ auto result = this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile);
+ if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not read/parse resource spec file "
+ << this->ResourceSpecFile << ": "
+ << cmCTestResourceSpec::ResultToString(result)
+ << std::endl);
+ return false;
+ }
parallel->InitResourceAllocator(this->ResourceSpec);
}
@@ -1338,12 +1346,13 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->RunTests();
}
- delete parallel;
this->EndTest = this->CTest->CurrentTime();
this->EndTestTime = std::chrono::system_clock::now();
this->ElapsedTestingTime =
std::chrono::steady_clock::now() - elapsed_time_start;
*this->LogFile << "End testing: " << this->CTest->CurrentTime() << std::endl;
+
+ return true;
}
void cmCTestTestHandler::GenerateTestCommand(
@@ -1742,6 +1751,10 @@ void cmCTestTestHandler::GetListOfTests()
if (cmSystemTools::GetErrorOccuredFlag()) {
return;
}
+ const char* specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && specFile) {
+ this->ResourceSpecFile = specFile;
+ }
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Done constructing a list of tests" << std::endl,
this->Quiet);
@@ -1894,7 +1907,8 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
continue;
}
- int val = atoi(line.substr(0, pos).c_str());
+ line.erase(pos);
+ int val = atoi(line.c_str());
this->TestsToRun.push_back(val);
}
ifs.close();
@@ -2016,13 +2030,13 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
| std::ios::binary
#endif
);
- unsigned char* file_buffer = new unsigned char[len + 1];
- ifs.read(reinterpret_cast<char*>(file_buffer), len);
- unsigned char* encoded_buffer = new unsigned char[static_cast<int>(
- static_cast<double>(len) * 1.5 + 5.0)];
+ auto file_buffer = cm::make_unique<unsigned char[]>(len + 1);
+ ifs.read(reinterpret_cast<char*>(file_buffer.get()), len);
+ auto encoded_buffer = cm::make_unique<unsigned char[]>(
+ static_cast<int>(static_cast<double>(len) * 1.5 + 5.0));
- size_t rlen =
- cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+ size_t rlen = cmsysBase64_Encode(file_buffer.get(), len,
+ encoded_buffer.get(), 1);
xml.StartElement("NamedMeasurement");
xml.Attribute(measurementfile.match(1).c_str(),
@@ -2039,8 +2053,6 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
}
xml.Element("Value", ostr.str());
xml.EndElement(); // NamedMeasurement
- delete[] file_buffer;
- delete[] encoded_buffer;
}
} else {
int idx = 4;
@@ -2085,19 +2097,18 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
if (cmSystemTools::FileExists(in)) {
cmsys::ifstream fin(in);
unsigned long filelen = cmSystemTools::FileLength(in);
- char* buff = new char[filelen + 1];
- fin.getline(buff, filelen);
+ auto buff = cm::make_unique<char[]>(filelen + 1);
+ fin.getline(buff.get(), filelen);
buff[fin.gcount()] = 0;
- this->TestsToRunString = buff;
- delete[] buff;
+ this->TestsToRunString = buff.get();
}
}
-bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
{
if (!length || length >= output.size() ||
output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
- return true;
+ return;
}
// Truncate at given length but do not break in the middle of a multi-byte
@@ -2118,7 +2129,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
++current;
}
}
- output = output.substr(0, current - begin);
+ output.erase(current - begin);
// Append truncation message.
std::ostringstream msg;
@@ -2128,7 +2139,6 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
"of "
<< length << " bytes.\n";
output += msg.str();
- return true;
}
bool cmCTestTestHandler::SetTestsProperties(
@@ -2149,16 +2159,16 @@ bool cmCTestTestHandler::SetTestsProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (std::string const& t : tests) {
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
- if (key == "_BACKTRACE_TRIPLES") {
+ if (key == "_BACKTRACE_TRIPLES"_s) {
std::vector<std::string> triples;
// allow empty args in the triples
cmExpandList(val, triples, true);
@@ -2182,91 +2192,70 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Backtrace = rt.Backtrace.Push(fc);
}
}
- }
- if (key == "WILL_FAIL") {
+ } else if (key == "WILL_FAIL"_s) {
rt.WillFail = cmIsOn(val);
- }
- if (key == "DISABLED") {
+ } else if (key == "DISABLED"_s) {
rt.Disabled = cmIsOn(val);
- }
- if (key == "ATTACHED_FILES") {
+ } else if (key == "ATTACHED_FILES"_s) {
cmExpandList(val, rt.AttachedFiles);
- }
- if (key == "ATTACHED_FILES_ON_FAIL") {
+ } else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
cmExpandList(val, rt.AttachOnFail);
- }
- if (key == "RESOURCE_LOCK") {
+ } else if (key == "RESOURCE_LOCK"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.LockedResources.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_SETUP") {
+ } else if (key == "FIXTURES_SETUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesSetup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_CLEANUP") {
+ } else if (key == "FIXTURES_CLEANUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesCleanup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_REQUIRED") {
+ } else if (key == "FIXTURES_REQUIRED"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesRequired.insert(lval.begin(), lval.end());
- }
- if (key == "TIMEOUT") {
+ } else if (key == "TIMEOUT"_s) {
rt.Timeout = cmDuration(atof(val.c_str()));
rt.ExplicitTimeout = true;
- }
- if (key == "COST") {
+ } else if (key == "COST"_s) {
rt.Cost = static_cast<float>(atof(val.c_str()));
- }
- if (key == "REQUIRED_FILES") {
+ } else if (key == "REQUIRED_FILES"_s) {
cmExpandList(val, rt.RequiredFiles);
- }
- if (key == "RUN_SERIAL") {
+ } else if (key == "RUN_SERIAL"_s) {
rt.RunSerial = cmIsOn(val);
- }
- if (key == "FAIL_REGULAR_EXPRESSION") {
+ } else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "SKIP_REGULAR_EXPRESSION") {
+ } else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "PROCESSORS") {
+ } else if (key == "PROCESSORS"_s) {
rt.Processors = atoi(val.c_str());
if (rt.Processors < 1) {
rt.Processors = 1;
}
- }
- if (key == "PROCESSOR_AFFINITY") {
+ } else if (key == "PROCESSOR_AFFINITY"_s) {
rt.WantAffinity = cmIsOn(val);
- }
- if (key == "RESOURCE_GROUPS") {
+ } else if (key == "RESOURCE_GROUPS"_s) {
if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
return false;
}
- }
- if (key == "SKIP_RETURN_CODE") {
+ } else if (key == "SKIP_RETURN_CODE"_s) {
rt.SkipReturnCode = atoi(val.c_str());
if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
rt.SkipReturnCode = -1;
}
- }
- if (key == "DEPENDS") {
+ } else if (key == "DEPENDS"_s) {
cmExpandList(val, rt.Depends);
- }
- if (key == "ENVIRONMENT") {
+ } else if (key == "ENVIRONMENT"_s) {
cmExpandList(val, rt.Environment);
- }
- if (key == "LABELS") {
+ } else if (key == "LABELS"_s) {
std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
@@ -2274,8 +2263,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// remove duplicates
auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
rt.Labels.erase(new_end, rt.Labels.end());
- }
- if (key == "MEASUREMENT") {
+ } else if (key == "MEASUREMENT"_s) {
size_t pos = val.find_first_of('=');
if (pos != std::string::npos) {
std::string mKey = val.substr(0, pos);
@@ -2284,17 +2272,14 @@ bool cmCTestTestHandler::SetTestsProperties(
} else {
rt.Measurements[val] = "1";
}
- }
- if (key == "PASS_REGULAR_EXPRESSION") {
+ } else if (key == "PASS_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "WORKING_DIRECTORY") {
+ } else if (key == "WORKING_DIRECTORY"_s) {
rt.Directory = val;
- }
- if (key == "TIMEOUT_AFTER_MATCH") {
+ } else if (key == "TIMEOUT_AFTER_MATCH"_s) {
std::vector<std::string> propArgs = cmExpandedList(val);
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
@@ -2334,16 +2319,16 @@ bool cmCTestTestHandler::SetDirectoryProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (cmCTestTestProperties& rt : this->TestList) {
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
- if (key == "LABELS") {
+ if (key == "LABELS"_s) {
std::vector<std::string> DirectoryLabels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
@@ -2422,10 +2407,9 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
test.SkipReturnCode = -1;
test.PreviousRuns = 0;
if (this->UseIncludeRegExpFlag &&
- !this->IncludeTestsRegularExpression.find(testname)) {
- test.IsInBasedOnREOptions = false;
- } else if (this->UseExcludeRegExpFlag && !this->UseExcludeRegExpFirst &&
- this->ExcludeTestsRegularExpression.find(testname)) {
+ (!this->IncludeTestsRegularExpression.find(testname) ||
+ (!this->UseExcludeRegExpFirst &&
+ this->ExcludeTestsRegularExpression.find(testname)))) {
test.IsInBasedOnREOptions = false;
}
this->TestList.push_back(test);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index b1c8755..55cecb6 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -235,7 +235,7 @@ protected:
void AttachFiles(cmXMLWriter& xml, cmCTestTestResult& result);
//! Clean test output to specified length
- bool CleanTestOutput(std::string& output, size_t length);
+ void CleanTestOutput(std::string& output, size_t length);
cmDuration ElapsedTestingTime;
@@ -278,7 +278,7 @@ private:
/**
* Run the tests for a directory and any subdirectories
*/
- void ProcessDirectory(std::vector<std::string>& passed,
+ bool ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed);
/**
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6026c69..452d714 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -38,7 +38,7 @@ void cmCTestVC::SetSourceDirectory(std::string const& dir)
this->SourceDirectory = dir;
}
-bool cmCTestVC::InitialCheckout(const char* command)
+bool cmCTestVC::InitialCheckout(const std::string& command)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT,
" First perform the initial checkout: " << command << "\n");
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 2a4765d..3037e01 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -36,7 +36,7 @@ public:
std::string GetNightlyTime();
/** Prepare the work tree. */
- bool InitialCheckout(const char* command);
+ bool InitialCheckout(const std::string& command);
/** Perform cleanup operations on the work tree. */
void Cleanup();
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index 8c4da75..84d7de0 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -4,6 +4,7 @@
#include <cstdlib>
#include <map>
#include <utility>
+#include <vector>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -19,7 +20,7 @@ cmParseCacheCoverage::cmParseCacheCoverage(
{
}
-bool cmParseCacheCoverage::LoadCoverageData(const char* d)
+bool cmParseCacheCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
@@ -69,26 +70,6 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles()
}
}
-bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
- std::string const& line)
-{
- std::string::size_type pos1 = 0;
- std::string::size_type pos2 = line.find(',', 0);
- if (pos2 == std::string::npos) {
- return false;
- }
- std::string arg;
- while (pos2 != std::string::npos) {
- arg = line.substr(pos1, pos2 - pos1);
- args.push_back(arg);
- pos1 = pos2 + 1;
- pos2 = line.find(',', pos1);
- }
- arg = line.substr(pos1);
- args.push_back(arg);
- return true;
-}
-
bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
cmsys::ifstream in(file);
@@ -97,7 +78,6 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
return false;
}
std::string line;
- std::vector<std::string> separateLine;
if (!cmSystemTools::GetLineFromStream(in, line)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Empty file : " << file
@@ -106,8 +86,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
<< line << "]\n");
return false;
}
- separateLine.clear();
- this->SplitString(separateLine, line);
+ std::vector<std::string> separateLine =
+ cmSystemTools::SplitString(line, ',');
if (separateLine.size() != 4 || separateLine[0] != "Routine" ||
separateLine[1] != "Line" || separateLine[2] != "RtnLine" ||
separateLine[3] != "Code") {
@@ -120,10 +100,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
std::string routine;
std::string filepath;
while (cmSystemTools::GetLineFromStream(in, line)) {
- // clear out line argument vector
- separateLine.clear();
// parse the comma separated line
- this->SplitString(separateLine, line);
+ separateLine = cmSystemTools::SplitString(line, ',');
// might have more because code could have a quoted , in it
// but we only care about the first 3 args anyway
if (separateLine.size() < 4) {
@@ -155,7 +133,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
// if we have a routine name, check for end of routine
else {
// Totals in arg 0 marks the end of a routine
- if (separateLine[0].substr(0, 6) == "Totals") {
+ if (cmHasLiteralPrefix(separateLine[0], "Totals")) {
routine.clear(); // at the end of this routine
filepath.clear();
continue; // move to next line
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index e89b9e4..a8200b7 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -6,7 +6,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <vector>
#include "cmParseMumpsCoverage.h"
@@ -26,13 +25,11 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// remove files with no coverage
void RemoveUnCoveredFiles();
// Read a single mcov file
bool ReadCMCovFile(const char* f);
- // split a string based on ,
- bool SplitString(std::vector<std::string>& args, std::string const& line);
};
#endif
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 05da84e..711a856 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -67,7 +67,7 @@ protected:
// Check if this is an absolute path that falls within our
// source or binary directories.
for (std::string const& filePath : FilePaths) {
- if (filename.find(filePath) == 0) {
+ if (cmHasPrefix(filename, filePath)) {
this->CurFileName = filename;
break;
}
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 1dc5b70..14417cc 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -19,7 +19,7 @@ cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
{
}
-bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+bool cmParseGTMCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index fe0ae0b..41cc7f5 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -25,7 +25,7 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// Read a single mcov file
bool ReadMCovFile(const char* f);
// find out what line in a mumps file (filepath) the given entry point
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index b16f101..dc3064d 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -39,9 +39,9 @@ bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
std::string type = line.substr(0, pos);
std::string path = line.substr(pos + 1);
if (type == "packages") {
- this->LoadPackages(path.c_str());
+ this->LoadPackages(path);
} else if (type == "coverage_dir") {
- this->LoadCoverageData(path.c_str());
+ this->LoadCoverageData(path);
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Parse Error in Mumps coverage file :\n"
@@ -105,7 +105,7 @@ void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
}
}
-bool cmParseMumpsCoverage::LoadPackages(const char* d)
+bool cmParseMumpsCoverage::LoadPackages(std::string const& d)
{
cmsys::Glob glob;
glob.RecurseOn();
@@ -113,7 +113,8 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
glob.FindFiles(pat);
for (std::string& file : glob.GetFiles()) {
std::string name = cmSystemTools::GetFilenameName(file);
- this->RoutineToDirectory[name.substr(0, name.size() - 2)] = file;
+ name.erase(name.size() - 2);
+ this->RoutineToDirectory[name] = file;
// initialize each file, this is left out until CDash is fixed
// to handle large numbers of files
this->InitializeMumpsFile(file);
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
index 2c54495..8c08702 100644
--- a/Source/CTest/cmParseMumpsCoverage.h
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -29,10 +29,10 @@ public:
protected:
// sub classes will use this to
// load all coverage files found in the given directory
- virtual bool LoadCoverageData(const char* d) = 0;
+ virtual bool LoadCoverageData(std::string const& d) = 0;
// search the package directory for mumps files and fill
// in the RoutineToDirectory map
- bool LoadPackages(const char* dir);
+ bool LoadPackages(std::string const& dir);
// initialize the coverage information for a single mumps file
void InitializeMumpsFile(std::string& file);
// Find mumps file for routine
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index a494b92..044f518 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -3,6 +3,8 @@
#include <cstdlib>
#include <cstring>
+#include <cm/memory>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -142,17 +144,15 @@ bool cmParsePHPCoverage::ReadFileInformation(std::istream& in)
int size = 0;
if (this->ReadInt(in, size)) {
size++; // add one for null termination
- char* s = new char[size + 1];
+ auto s = cm::make_unique<char[]>(size + 1);
// read open quote
if (in.get(c) && c != '"') {
- delete[] s;
return false;
}
// read the string data
- in.read(s, size - 1);
+ in.read(s.get(), size - 1);
s[size - 1] = 0;
- std::string fileName = s;
- delete[] s;
+ std::string fileName = s.get();
// read close quote
if (in.get(c) && c != '"') {
cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 6097aa5..2742fd7 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -5,6 +5,7 @@
#include <csignal>
#include <iostream>
#include <string>
+#include <utility>
#include <cmext/algorithm>
@@ -18,12 +19,11 @@
#if defined(_WIN32)
# include "cm_kwiml.h"
#endif
-#include <utility>
#define CM_PROCESS_BUF_SIZE 65536
-cmProcess::cmProcess(cmCTestRunTest& runner)
- : Runner(runner)
+cmProcess::cmProcess(std::unique_ptr<cmCTestRunTest> runner)
+ : Runner(std::move(runner))
, Conv(cmProcessOutput::UTF8, CM_PROCESS_BUF_SIZE)
{
this->Timeout = cmDuration::zero();
@@ -69,7 +69,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
cm::uv_timer_ptr timer;
int status = timer.init(loop, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing timer: " << uv_strerror(status)
<< std::endl);
return false;
@@ -84,7 +84,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
int fds[2] = { -1, -1 };
status = cmGetPipes(fds);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing pipe: " << uv_strerror(status)
<< std::endl);
return false;
@@ -127,7 +127,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error starting read events: " << uv_strerror(status)
<< std::endl);
return false;
@@ -135,7 +135,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
status = this->Process.spawn(loop, options, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Process not started\n " << this->Command << "\n["
<< uv_strerror(status) << "]\n");
return false;
@@ -152,7 +152,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
void cmProcess::StartTimer()
{
- auto properties = this->Runner.GetTestProperties();
+ auto properties = this->Runner->GetTestProperties();
auto msec =
std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
@@ -222,7 +222,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
cm::append(this->Output, strdata);
while (this->Output.GetLine(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
line.clear();
}
@@ -236,13 +236,13 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
// The process will provide no more data.
if (nread != UV_EOF) {
auto error = static_cast<int>(nread);
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error reading stream: " << uv_strerror(error) << std::endl);
}
// Look for partial last lines.
if (this->Output.GetLast(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
}
this->ReadHandleClosed = true;
@@ -339,7 +339,7 @@ void cmProcess::Finish()
if (this->TotalTime <= cmDuration::zero()) {
this->TotalTime = cmDuration::zero();
}
- this->Runner.FinalizeTest();
+ this->Runner->FinalizeTest();
}
cmProcess::State cmProcess::GetProcessStatus()
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index ea72a26..526c920 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,7 +6,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include <stddef.h>
@@ -28,7 +30,7 @@ class cmCTestRunTest;
class cmProcess
{
public:
- explicit cmProcess(cmCTestRunTest& runner);
+ explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
~cmProcess();
void SetCommand(std::string const& command);
void SetCommandArguments(std::vector<std::string> const& arg);
@@ -70,6 +72,11 @@ public:
Exception GetExitException();
std::string GetExitExceptionString();
+ std::unique_ptr<cmCTestRunTest> GetRunner()
+ {
+ return std::move(this->Runner);
+ }
+
private:
cmDuration Timeout;
std::chrono::steady_clock::time_point StartTime;
@@ -82,7 +89,7 @@ private:
cm::uv_timer_ptr Timer;
std::vector<char> Buf;
- cmCTestRunTest& Runner;
+ std::unique_ptr<cmCTestRunTest> Runner;
cmProcessOutput Conv;
int Signal = 0;
cmProcess::State ProcessState = cmProcess::State::Starting;
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index c16286c..3b00dfb 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -32,8 +32,6 @@ function(cm_check_cxx_feature name)
string(REGEX REPLACE "[^\n]* xcodebuild\\[[0-9]*:[0-9]*\\] warning: [^\n]*" "" check_output "${check_output}")
# Filter out ld warnings.
string(REGEX REPLACE "[^\n]*ld: warning: [^\n]*" "" check_output "${check_output}")
- # Filter out CUDA installation warnings.
- string(REGEX REPLACE "[^\n]*clang: warning: Unknown CUDA version[^\n]*" "" check_output "${check_output}")
# If using the feature causes warnings, treat it as broken/unavailable.
if(check_output MATCHES "(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]")
set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 01fce85..9a26db5 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -16,6 +16,7 @@
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -111,8 +112,8 @@ int main(int argc, char const* const* argv)
std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
for (i = 1; i < args.size(); ++i) {
- std::string arg = args[i];
- if (arg.find("-B", 0) == 0) {
+ std::string const& arg = args[i];
+ if (cmHasPrefix(arg, "-B")) {
cacheDir = arg.substr(2);
}
}
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index 4d3131b..9250fbc 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -48,42 +48,42 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " ");
}
- const char* value = state->GetCacheEntryValue(key);
+ cmProp value = state->GetCacheEntryValue(key);
assert(value);
switch (state->GetCacheEntryType(key)) {
case cmStateEnums::BOOL: {
auto bw = cm::make_unique<cmCursesBoolWidget>(this->EntryWidth, 1, 1, 1);
- bw->SetValueAsBool(cmIsOn(value));
+ bw->SetValueAsBool(cmIsOn(*value));
this->Entry = std::move(bw);
break;
}
case cmStateEnums::PATH: {
auto pw = cm::make_unique<cmCursesPathWidget>(this->EntryWidth, 1, 1, 1);
- pw->SetString(value);
+ pw->SetString(*value);
this->Entry = std::move(pw);
break;
}
case cmStateEnums::FILEPATH: {
auto fpw =
cm::make_unique<cmCursesFilePathWidget>(this->EntryWidth, 1, 1, 1);
- fpw->SetString(value);
+ fpw->SetString(*value);
this->Entry = std::move(fpw);
break;
}
case cmStateEnums::STRING: {
- const char* stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
+ cmProp stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
if (stringsProp) {
auto ow =
cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
- for (std::string const& opt : cmExpandedList(stringsProp)) {
+ for (std::string const& opt : cmExpandedList(*stringsProp)) {
ow->AddOption(opt);
}
- ow->SetOption(value);
+ ow->SetOption(*value);
this->Entry = std::move(ow);
} else {
auto sw =
cm::make_unique<cmCursesStringWidget>(this->EntryWidth, 1, 1, 1);
- sw->SetString(value);
+ sw->SetString(*value);
this->Entry = std::move(sw);
}
break;
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index afd2b6b..664ba2f 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -41,7 +41,8 @@ void cmCursesLongMessageForm::UpdateContent(std::string const& output,
this->Title = title;
if (!output.empty() && this->Messages.size() < MAX_CONTENT_SIZE) {
- this->Messages.append("\n" + output);
+ this->Messages.push_back('\n');
+ this->Messages.append(output);
form_driver(this->Form, REQ_NEW_LINE);
this->DrawMessage(output.c_str());
}
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 65376d1..df34283 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -161,7 +161,7 @@ void cmCursesMainForm::RePost()
// If normal mode, count only non-advanced entries
this->NumberOfVisibleEntries = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -182,7 +182,7 @@ void cmCursesMainForm::RePost()
// Assign fields
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -241,7 +241,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
// If normal, display only non-advanced entries
this->NumberOfVisibleEntries = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -259,7 +259,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
bool isNewPage;
int i = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -405,11 +405,12 @@ void cmCursesMainForm::UpdateStatusBar(cm::optional<std::string> message)
// Get the help string of the current entry
// and add it to the help string
auto cmakeState = this->CMakeInstance->GetState();
- const char* existingValue = cmakeState->GetCacheEntryValue(labelValue);
+ cmProp existingValue = cmakeState->GetCacheEntryValue(labelValue);
if (existingValue) {
- auto help = cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
+ cmProp help =
+ cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
if (help) {
- bar += help;
+ bar += *help;
}
}
}
@@ -616,10 +617,10 @@ void cmCursesMainForm::FillCacheManagerFromUI()
{
for (cmCursesCacheEntryComposite& entry : this->Entries) {
const std::string& cacheKey = entry.Key;
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey);
if (existingValue) {
- std::string oldValue = existingValue;
+ std::string oldValue = *existingValue;
std::string newValue = entry.Entry->GetValue();
std::string fixedOldValue;
std::string fixedNewValue;
@@ -802,9 +803,9 @@ void cmCursesMainForm::HandleInput()
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(
field_userptr(this->Fields[findex - 2]));
const char* curField = lbl->GetValue();
- const char* helpString = nullptr;
+ cmProp helpString = nullptr;
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
if (existingValue) {
helpString = this->CMakeInstance->GetState()->GetCacheEntryProperty(
@@ -813,7 +814,7 @@ void cmCursesMainForm::HandleInput()
if (helpString) {
this->HelpMessage[1] =
cmStrCat("Current option is: ", curField, '\n',
- "Help string for this option is: ", helpString, '\n');
+ "Help string for this option is: ", *helpString, '\n');
} else {
this->HelpMessage[1] = "";
}
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 15dcda0..ec7424c 100644
--- a/Source/LexerParser/cmListFileLexer.c
+++ b/Source/LexerParser/cmListFileLexer.c
@@ -2787,7 +2787,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -2801,21 +2801,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l
index fdf14d2..94cf8a5 100644
--- a/Source/LexerParser/cmListFileLexer.in.l
+++ b/Source/LexerParser/cmListFileLexer.in.l
@@ -500,7 +500,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -514,21 +514,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index ee81a7d..9d928b2 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -201,8 +201,7 @@ int main(int argc, char** argv)
cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
// check if argument is a directory containing CMakeCache.txt
- std::string buildFilePath =
- cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
+ std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt");
// check if argument is a CMakeCache.txt file
if (cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" &&
@@ -211,8 +210,7 @@ int main(int argc, char** argv)
}
// check if argument is a directory containing CMakeLists.txt
- std::string srcFilePath =
- cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
+ std::string srcFilePath = cmStrCat(filePath, "/CMakeLists.txt");
if (cmSystemTools::FileExists(buildFilePath.c_str())) {
dialog.setBinaryDirectory(QString::fromLocal8Bit(
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 436a904..4daf726 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "CMakeSetupDialog.h"
+#include <cm/memory>
+
#include <QCloseEvent>
#include <QCoreApplication>
#include <QDesktopServices>
@@ -39,23 +41,21 @@
QCMakeThread::QCMakeThread(QObject* p)
: QThread(p)
- , CMakeInstance(nullptr)
{
}
QCMake* QCMakeThread::cmakeInstance() const
{
- return this->CMakeInstance;
+ return this->CMakeInstance.get();
}
void QCMakeThread::run()
{
- this->CMakeInstance = new QCMake;
+ this->CMakeInstance = cm::make_unique<QCMake>();
// emit that this cmake thread is ready for use
emit this->cmakeInitialized();
this->exec();
- delete this->CMakeInstance;
- this->CMakeInstance = nullptr;
+ this->CMakeInstance.reset();
}
CMakeSetupDialog::CMakeSetupDialog()
@@ -804,6 +804,9 @@ bool CMakeSetupDialog::setupFirstConfigure()
QString systemVersion = dialog.getSystemVersion();
m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION",
tr("CMake System Version"), systemVersion, false);
+ QString systemProcessor = dialog.getSystemProcessor();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_PROCESSOR",
+ tr("CMake System Processor"), systemProcessor, false);
QString cxxCompiler = dialog.getCXXCompiler();
m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
tr("CXX compiler."), cxxCompiler, false);
@@ -1206,7 +1209,7 @@ void CMakeSetupDialog::setSearchFilter(const QString& str)
void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
{
- QMenu* menu = this->Output->createStandardContextMenu();
+ std::unique_ptr<QMenu> menu(this->Output->createStandardContextMenu());
menu->addSeparator();
menu->addAction(tr("Find..."), this, SLOT(doOutputFindDialog()),
@@ -1220,7 +1223,6 @@ void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
QKeySequence(Qt::Key_F8));
menu->exec(this->Output->mapToGlobal(pt));
- delete menu;
}
void CMakeSetupDialog::doOutputFindDialog()
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index f23aee6..d1e2035 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -3,6 +3,8 @@
#ifndef CMakeSetupDialog_h
#define CMakeSetupDialog_h
+#include <memory>
+
#include "QCMake.h"
#include <QEventLoop>
#include <QMainWindow>
@@ -143,7 +145,7 @@ signals:
protected:
virtual void run();
- QCMake* CMakeInstance;
+ std::unique_ptr<QCMake> CMakeInstance;
};
#endif // CMakeSetupDialog_h
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index ca28b19..3c24b9b 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -10,8 +10,12 @@
#include "Compilers.h"
-StartCompilerSetup::StartCompilerSetup(QWidget* p)
+StartCompilerSetup::StartCompilerSetup(QString defaultGeneratorPlatform,
+ QString defaultGeneratorToolset,
+ QWidget* p)
: QWizardPage(p)
+ , DefaultGeneratorPlatform(std::move(defaultGeneratorPlatform))
+ , DefaultGeneratorToolset(std::move(defaultGeneratorToolset))
{
QVBoxLayout* l = new QVBoxLayout(this);
l->addWidget(new QLabel(tr("Specify the generator for this project")));
@@ -68,6 +72,10 @@ QFrame* StartCompilerSetup::CreateToolsetWidgets()
Toolset = new QLineEdit(frame);
l->addWidget(Toolset);
+ // Default to CMAKE_GENERATOR_TOOLSET env var if set
+ if (!DefaultGeneratorToolset.isEmpty()) {
+ this->Toolset->setText(DefaultGeneratorToolset);
+ }
return frame;
}
@@ -199,6 +207,14 @@ void StartCompilerSetup::onGeneratorChanged(QString const& name)
this->PlatformOptions->addItems(platform_list);
PlatformFrame->show();
+
+ // Default to generator platform from environment
+ if (!DefaultGeneratorPlatform.isEmpty()) {
+ int platform_index = platforms.indexOf(DefaultGeneratorPlatform);
+ if (platform_index != -1) {
+ this->PlatformOptions->setCurrentIndex(platform_index);
+ }
+ }
} else {
PlatformFrame->hide();
}
@@ -421,8 +437,26 @@ void ToolchainCompilerSetup::setToolchainFile(const QString& t)
FirstConfigure::FirstConfigure()
{
+ const char* env_generator = std::getenv("CMAKE_GENERATOR");
+ const char* env_generator_platform = nullptr;
+ const char* env_generator_toolset = nullptr;
+ if (env_generator && std::strlen(env_generator)) {
+ mDefaultGenerator = env_generator;
+ env_generator_platform = std::getenv("CMAKE_GENERATOR_PLATFORM");
+ env_generator_toolset = std::getenv("CMAKE_GENERATOR_TOOLSET");
+ }
+
+ if (!env_generator_platform) {
+ env_generator_platform = "";
+ }
+
+ if (!env_generator_toolset) {
+ env_generator_toolset = "";
+ }
+
// this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
- this->mStartCompilerSetupPage = new StartCompilerSetup(this);
+ this->mStartCompilerSetupPage = new StartCompilerSetup(
+ env_generator_platform, env_generator_toolset, this);
this->setPage(Start, this->mStartCompilerSetupPage);
QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()),
this, SLOT(restart()));
@@ -504,6 +538,17 @@ void FirstConfigure::loadFromSettings()
this->mCrossCompilerSetupPage->setIncludeMode(
settings.value("IncludeMode", 0).toInt());
settings.endGroup();
+
+ // environment variables take precedence over application settings because...
+ // - they're harder to set
+ // - settings always exist after the program is run once, so the environment
+ // variables would never be used otherwise
+ // - platform and toolset are populated only from environment variables, so
+ // this prevents them from being taken from environment, while the
+ // generator is taken from application settings
+ if (!mDefaultGenerator.isEmpty()) {
+ this->mStartCompilerSetupPage->setCurrentGenerator(mDefaultGenerator);
+ }
}
void FirstConfigure::saveToSettings()
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index d1db5bf..c26f489 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -29,7 +29,8 @@ class StartCompilerSetup : public QWizardPage
{
Q_OBJECT
public:
- StartCompilerSetup(QWidget* p);
+ StartCompilerSetup(QString defaultGeneratorPlatform,
+ QString defaultGeneratorToolset, QWidget* p);
~StartCompilerSetup();
void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
void setCurrentGenerator(const QString& gen);
@@ -64,6 +65,7 @@ protected:
QStringList GeneratorsSupportingPlatform;
QMultiMap<QString, QString> GeneratorSupportedPlatforms;
QMap<QString, QString> GeneratorDefaultPlatform;
+ QString DefaultGeneratorPlatform, DefaultGeneratorToolset;
private:
QFrame* CreateToolsetWidgets();
@@ -197,6 +199,7 @@ protected:
NativeCompilerSetup* mNativeCompilerSetupPage;
CrossCompilerSetup* mCrossCompilerSetupPage;
ToolchainCompilerSetup* mToolchainCompilerSetupPage;
+ QString mDefaultGenerator;
};
#endif // FirstConfigure_h
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index a9089e5..776af81 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "QCMake.h"
+#include <cm/memory>
+
#include <QCoreApplication>
#include <QDir>
@@ -35,7 +37,8 @@ QCMake::QCMake(QObject* p)
cmSystemTools::SetStderrCallback(
[this](std::string const& msg) { this->stderrCallback(msg); });
- this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
+ this->CMakeInstance =
+ cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeGUICommand());
this->CMakeInstance->SetProgressCallback(
@@ -55,11 +58,7 @@ QCMake::QCMake(QObject* p)
}
}
-QCMake::~QCMake()
-{
- delete this->CMakeInstance;
- // cmDynamicLoader::FlushCache();
-}
+QCMake::~QCMake() = default;
void QCMake::loadCache(const QString& dir)
{
@@ -101,29 +100,28 @@ void QCMake::setBinaryDirectory(const QString& _dir)
QCMakePropertyList props = this->properties();
emit this->propertiesChanged(props);
- const char* homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+ cmProp homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (homeDir) {
- setSourceDirectory(QString::fromLocal8Bit(homeDir));
+ setSourceDirectory(QString::fromLocal8Bit(homeDir->c_str()));
}
- const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
if (gen) {
const std::string* extraGen =
state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string curGen =
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- gen, extraGen ? *extraGen : "");
+ *gen, extraGen ? *extraGen : "");
this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
}
- const char* platform =
- state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
+ cmProp platform = state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
if (platform) {
- this->setPlatform(QString::fromLocal8Bit(platform));
+ this->setPlatform(QString::fromLocal8Bit(platform->c_str()));
}
- const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ cmProp toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
if (toolset) {
- this->setToolset(QString::fromLocal8Bit(toolset));
+ this->setToolset(QString::fromLocal8Bit(toolset->c_str()));
}
checkOpenPossible();
@@ -304,27 +302,28 @@ QCMakePropertyList QCMake::properties() const
continue;
}
- const char* cachedValue = state->GetCacheEntryValue(key);
+ cmProp cachedValue = state->GetCacheEntryValue(key);
QCMakeProperty prop;
prop.Key = QString::fromLocal8Bit(key.c_str());
- prop.Help =
- QString::fromLocal8Bit(state->GetCacheEntryProperty(key, "HELPSTRING"));
- prop.Value = QString::fromLocal8Bit(cachedValue);
+ if (cmProp hs = state->GetCacheEntryProperty(key, "HELPSTRING")) {
+ prop.Help = QString::fromLocal8Bit(hs->c_str());
+ }
+ prop.Value = QString::fromLocal8Bit(cachedValue->c_str());
prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED");
if (t == cmStateEnums::BOOL) {
prop.Type = QCMakeProperty::BOOL;
- prop.Value = cmIsOn(cachedValue);
+ prop.Value = cmIsOn(*cachedValue);
} else if (t == cmStateEnums::PATH) {
prop.Type = QCMakeProperty::PATH;
} else if (t == cmStateEnums::FILEPATH) {
prop.Type = QCMakeProperty::FILEPATH;
} else if (t == cmStateEnums::STRING) {
prop.Type = QCMakeProperty::STRING;
- const char* stringsProperty =
- state->GetCacheEntryProperty(key, "STRINGS");
+ cmProp stringsProperty = state->GetCacheEntryProperty(key, "STRINGS");
if (stringsProperty) {
- prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";");
+ prop.Strings =
+ QString::fromLocal8Bit(stringsProperty->c_str()).split(";");
}
}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index fa4451b..110a971 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -12,6 +12,7 @@
# pragma warning(disable : 4512)
#endif
+#include <memory>
#include <vector>
#include <QAtomicInt>
@@ -165,7 +166,7 @@ signals:
void openPossible(bool possible);
protected:
- cmake* CMakeInstance;
+ std::unique_ptr<cmake> CMakeInstance;
bool interruptCallback();
void progressCallback(std::string const& msg, float percent);
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 0b2750d..fdfd4c0 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -352,14 +352,14 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
line.c_str());
return false;
}
- const std::string sym = line.substr(0, sym_end);
const char sym_type = line[sym_end + 1];
+ line.resize(sym_end);
switch (sym_type) {
case 'D':
- dataSymbols.insert(sym);
+ dataSymbols.insert(line);
break;
case 'T':
- symbols.insert(sym);
+ symbols.insert(line);
break;
}
}
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 35eabaf..83d6306 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -4,6 +4,8 @@
#include <cstring>
+#include <cm/string_view>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
@@ -86,7 +88,8 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
if (binLen > 0 && bin.back() == '/') {
--binLen;
}
- binPath = bin.substr(0, binLen) + srcPath.substr(srcLen);
+ binPath = cmStrCat(cm::string_view(bin).substr(0, binLen),
+ cm::string_view(srcPath).substr(srcLen));
} else {
// Use the binary directory specified.
// Interpret a relative path with respect to the current binary directory.
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index c0ac551..8b0aa5e 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -13,20 +13,12 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cm_kwiml.h"
#include "cmRange.h"
-template <std::size_t N>
-struct cmOverloadPriority : cmOverloadPriority<N - 1>
-{
-};
-
-template <>
-struct cmOverloadPriority<0>
-{
-};
-
template <typename FwdIt>
FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
{
@@ -37,34 +29,6 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
return first;
}
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>)
- -> decltype(range.exists(key))
-{
- return range.exists(key);
-}
-
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>)
- -> decltype(range.find(key) != range.end())
-{
- return range.find(key) != range.end();
-}
-
-template <typename Range, typename Key>
-bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>)
-{
- using std::begin;
- using std::end;
- return std::find(begin(range), end(range), key) != end(range);
-}
-
-template <typename Range, typename Key>
-bool cmContains(Range const& range, Key const& key)
-{
- return cmContainsImpl(range, key, cmOverloadPriority<2>{});
-}
-
namespace ContainerAlgorithms {
template <typename FwdIt>
@@ -158,7 +122,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
ForwardIterator result = first;
while (first != last) {
- if (!cmContains(uniq, first)) {
+ if (!cm::contains(uniq, first)) {
if (result != first) {
*result = std::move(*first);
}
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index d29b2ac..0f9b42c 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -170,15 +170,19 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
cm_archive_error_string(this->Archive));
return;
}
+}
+bool cmArchiveWrite::Open()
+{
if (archive_write_open(
this->Archive, this, nullptr,
reinterpret_cast<archive_write_callback*>(&Callback::Write),
nullptr) != ARCHIVE_OK) {
this->Error =
cmStrCat("archive_write_open: ", cm_archive_error_string(this->Archive));
- return;
+ return false;
}
+ return true;
}
cmArchiveWrite::~cmArchiveWrite()
@@ -365,3 +369,16 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
}
return true;
}
+
+bool cmArchiveWrite::SetFilterOption(const char* module, const char* key,
+ const char* value)
+{
+ if (archive_write_set_filter_option(this->Archive, module, key, value) !=
+ ARCHIVE_OK) {
+ this->Error = "archive_write_set_filter_option: ";
+ this->Error += cm_archive_error_string(this->Archive);
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index e791761..b643bce 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -62,6 +62,8 @@ public:
cmArchiveWrite(const cmArchiveWrite&) = delete;
cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
+ bool Open();
+
/**
* Add a path (file or directory) to the archive. Directories are
* added recursively. The "path" must be readable on disk, either
@@ -139,6 +141,9 @@ public:
this->Gname = "";
}
+ //! Set an option on a filter;
+ bool SetFilterOption(const char* module, const char* key, const char* value);
+
private:
bool Okay() const { return this->Error.empty(); }
bool AddPath(const char* path, size_t skip, const char* prefix,
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 289bb72..d6f7500e 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -6,6 +6,8 @@
#include <cstddef>
#include <utility>
+#include <cm/string_view>
+
#include "cmsys/Directory.hxx"
#include "cmExecutionStatus.h"
@@ -50,11 +52,10 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
// Split the filename into base and extension
std::string::size_type dotpos = file.rfind('.');
if (dotpos != std::string::npos) {
- std::string ext = file.substr(dotpos + 1);
- std::string base = file.substr(0, dotpos);
+ auto ext = cm::string_view(file).substr(dotpos + 1);
// Process only source files
auto cm = mf.GetCMakeInstance();
- if (!base.empty() && cm->IsSourceExtension(ext)) {
+ if (dotpos > 0 && cm->IsSourceExtension(ext)) {
std::string fullname = cmStrCat(templateDirectory, '/', file);
// add the file as a class file so
// depends can be done
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 0dea825..9ce403d 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -6,6 +6,7 @@
#include <sstream>
#include <cm/memory>
+#include <cm/string_view>
#include <cmsys/RegularExpression.hxx>
@@ -26,14 +27,16 @@ static std::string ReplaceOrigin(const std::string& rpath,
cmsys::RegularExpressionMatch match;
if (originRegex.find(rpath.c_str(), match)) {
- std::string begin = rpath.substr(0, match.start(1));
- std::string end = rpath.substr(match.end(1));
- return begin + origin + end;
+ cm::string_view pathv(rpath);
+ auto begin = pathv.substr(0, match.start(1));
+ auto end = pathv.substr(match.end(1));
+ return cmStrCat(begin, origin, end);
}
if (originCurlyRegex.find(rpath.c_str(), match)) {
- std::string begin = rpath.substr(0, match.start());
- std::string end = rpath.substr(match.end());
- return begin + origin + end;
+ cm::string_view pathv(rpath);
+ auto begin = pathv.substr(0, match.start());
+ auto end = pathv.substr(match.end());
+ return cmStrCat(begin, origin, end);
}
return rpath;
}
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 49c9439..b82fb9a 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -108,7 +108,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args,
if (cacheValue) {
return true;
}
- mf.AddCacheDefinition(define, makecommand.c_str(),
+ mf.AddCacheDefinition(define, makecommand,
"Command used to build entire project "
"from the command line.",
cmStateEnums::STRING);
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 3e517dc..ad4d665 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -28,7 +28,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(cv.begin(), cv.end(), '/', '_');
std::replace(cv.begin(), cv.end(), '(', '_');
std::replace(cv.begin(), cv.end(), ')', '_');
- mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], cv, "Name of build.",
cmStateEnums::STRING);
}
return true;
@@ -54,7 +54,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(buildname.begin(), buildname.end(), '(', '_');
std::replace(buildname.begin(), buildname.end(), ')', '_');
- mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], buildname, "Name of build.",
cmStateEnums::STRING);
return true;
}
diff --git a/Source/cmCMakeCommand.cxx b/Source/cmCMakeCommand.cxx
new file mode 100644
index 0000000..c11a003
--- /dev/null
+++ b/Source/cmCMakeCommand.cxx
@@ -0,0 +1,68 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCMakeCommand.h"
+
+#include <algorithm>
+#include <cstddef>
+
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+
+bool cmCMakeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.empty()) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ cmMakefile& makefile = status.GetMakefile();
+ cmListFileContext context = makefile.GetExecutionContext();
+
+ bool result = false;
+
+ if (args[0] == "INVOKE") {
+ if (args.size() == 1) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // First argument is the name of the function to call
+ cmListFileFunction func;
+ func.Name = args[1];
+ func.Line = context.Line;
+
+ // The rest of the arguments are passed to the function call above
+ func.Arguments.resize(args.size() - 1);
+ for (size_t i = 2; i < args.size(); ++i) {
+ cmListFileArgument lfarg;
+ lfarg.Line = context.Line;
+ lfarg.Value = args[i];
+ func.Arguments.emplace_back(lfarg);
+ }
+
+ result = makefile.ExecuteCommand(func, status);
+ } else if (args[0] == "EVAL") {
+ if (args.size() < 2) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ auto code_iter = std::find(args.begin(), args.end(), "CODE");
+ if (code_iter == args.end()) {
+ status.SetError("called without CODE argument");
+ return false;
+ }
+
+ const std::string code = cmJoin(cmMakeRange(++code_iter, args.end()), " ");
+ result = makefile.ReadListFileAsString(
+ code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
+ } else {
+ status.SetError("called with unknown meta-operation");
+ }
+
+ return result;
+}
diff --git a/Source/cmCMakeCommand.h b/Source/cmCMakeCommand.h
new file mode 100644
index 0000000..cf9f4c3
--- /dev/null
+++ b/Source/cmCMakeCommand.h
@@ -0,0 +1,20 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCMakeCommand_h
+#define cmCMakeCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+class cmExecutionStatus;
+
+/**
+ * \brief Calls a scripted or build-in command
+ *
+ */
+bool cmCMakeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index b5c7e96..697d435 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -488,24 +488,8 @@ struct cmCPluginAPISourceFile
// Keep a map from real cmSourceFile instances stored in a makefile to
// the CPluginAPI proxy source file.
-class cmCPluginAPISourceFileMap
- : public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
-{
-public:
- using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>;
- using iterator = derived::iterator;
- using value_type = derived::value_type;
- cmCPluginAPISourceFileMap() = default;
- ~cmCPluginAPISourceFileMap()
- {
- for (auto const& i : *this) {
- delete i.second;
- }
- }
- cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete;
- cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) =
- delete;
-};
+using cmCPluginAPISourceFileMap =
+ std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>;
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
void* CCONV cmCreateSourceFile(void)
@@ -536,7 +520,7 @@ void CCONV* cmGetSource(void* arg, const char* name)
auto i = cmCPluginAPISourceFiles.find(rsf);
if (i == cmCPluginAPISourceFiles.end()) {
// Create a proxy source file object for this source.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = rsf->ResolveFullPath();
sf->SourceName =
@@ -545,10 +529,9 @@ void CCONV* cmGetSource(void* arg, const char* name)
cmSystemTools::GetFilenameLastExtension(sf->FullPath);
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
- i = cmCPluginAPISourceFiles.insert(entry).first;
+ i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first;
}
- return i->second;
+ return i->second.get();
}
return nullptr;
}
@@ -569,15 +552,16 @@ void* CCONV cmAddSource(void* arg, void* arg2)
}
// Create the proxy for the real source file.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = osf->FullPath;
sf->SourceName = osf->SourceName;
sf->SourceExtension = osf->SourceExtension;
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFiles[rsf] = sf;
- return sf;
+ auto value = sf.get();
+ cmCPluginAPISourceFiles[rsf] = std::move(sf);
+ return value;
}
const char* CCONV cmSourceFileGetSourceName(void* arg)
@@ -596,12 +580,14 @@ const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop)
{
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
- return rsf->GetProperty(prop);
+ cmProp p = rsf->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
if (!strcmp(prop, "LOCATION")) {
return sf->FullPath.c_str();
}
- return sf->Properties.GetPropertyValue(prop);
+ cmProp retVal = sf->Properties.GetPropertyValue(prop);
+ return retVal ? retVal->c_str() : nullptr;
}
int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
@@ -791,8 +777,9 @@ void CCONV DefineSourceFileProperty(void* arg, const char* name,
const char* longDocs, int chained)
{
cmMakefile* mf = static_cast<cmMakefile*>(arg);
- mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE, briefDocs,
- longDocs, chained != 0);
+ mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE,
+ briefDocs ? briefDocs : "",
+ longDocs ? longDocs : "", chained != 0);
}
} // close the extern "C" scope
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 04f75bd..c2b2a09 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,6 +16,10 @@
#include <utility>
#include <vector>
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -32,8 +36,7 @@
# include <unistd.h> // IWYU pragma: keep
#endif
-#include <cm/memory>
-#include <cmext/algorithm>
+#include "cm_static_string_view.hxx"
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
@@ -89,6 +92,7 @@ struct cmCTest::Private
std::string ConfigType;
std::string ScheduleType;
std::chrono::system_clock::time_point StopTime;
+ bool StopOnFailure = false;
bool TestProgressOutput = false;
bool Verbose = false;
bool ExtraVerbose = false;
@@ -201,7 +205,7 @@ struct cmCTest::Private
int SubmitIndex = 0;
- cmGeneratedFileStream* OutputLogFile = nullptr;
+ std::unique_ptr<cmGeneratedFileStream> OutputLogFile;
int OutputLogFileLastTag = -1;
bool OutputTestOutputOnTestFailure = false;
@@ -271,9 +275,10 @@ bool cmCTest::GetTomorrowTag() const
return this->Impl->TomorrowTag;
}
-std::string cmCTest::CleanString(const std::string& str)
+std::string cmCTest::CleanString(const std::string& str,
+ std::string::size_type spos)
{
- std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
+ spos = str.find_first_not_of(" \n\t\r\f\v", spos);
std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
if (spos == std::string::npos) {
return std::string();
@@ -362,10 +367,7 @@ cmCTest::cmCTest()
cmSystemTools::EnableVSConsoleOutput();
}
-cmCTest::~cmCTest()
-{
- delete this->Impl->OutputLogFile;
-}
+cmCTest::~cmCTest() = default;
int cmCTest::GetParallelLevel() const
{
@@ -727,7 +729,7 @@ bool cmCTest::UpdateCTestConfiguration()
continue;
}
while (fin && (line.back() == '\\')) {
- line = line.substr(0, line.size() - 1);
+ line.resize(line.size() - 1);
buffer[0] = 0;
fin.getline(buffer, 1023);
buffer[1023] = 0;
@@ -741,7 +743,7 @@ bool cmCTest::UpdateCTestConfiguration()
continue;
}
std::string key = line.substr(0, cpos);
- std::string value = cmCTest::CleanString(line.substr(cpos + 1));
+ std::string value = cmCTest::CleanString(line, cpos + 1);
this->Impl->CTestConfiguration[key] = value;
}
fin.close();
@@ -1442,16 +1444,15 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
return;
}
// This code should go when cdash is changed to use labels only
- const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
xml.StartElement("Subproject");
- xml.Attribute("name", subproject);
- const char* labels =
+ xml.Attribute("name", *subproject);
+ cmProp labels =
ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
if (labels) {
xml.StartElement("Labels");
- std::string l = labels;
- std::vector<std::string> args = cmExpandedList(l);
+ std::vector<std::string> args = cmExpandedList(*labels);
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1461,10 +1462,10 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
}
// This code should stay when cdash only does label based sub-projects
- const char* label = cm->GetState()->GetGlobalProperty("Label");
+ cmProp label = cm->GetState()->GetGlobalProperty("Label");
if (label) {
xml.StartElement("Labels");
- xml.Element("Label", label);
+ xml.Element("Label", *label);
xml.EndElement();
}
}
@@ -1816,10 +1817,10 @@ void cmCTest::ErrorMessageUnknownDashDValue(std::string& val)
<< " ctest -D NightlyMemoryCheck" << std::endl);
}
-bool cmCTest::CheckArgument(const std::string& arg, const char* varg1,
+bool cmCTest::CheckArgument(const std::string& arg, cm::string_view varg1,
const char* varg2)
{
- return (varg1 && arg == varg1) || (varg2 && arg == varg2);
+ return (arg == varg1) || (varg2 && arg == varg2);
}
// Processes one command line argument (and its arguments if any)
@@ -1829,21 +1830,21 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
std::string& errormsg)
{
std::string arg = args[i];
- if (this->CheckArgument(arg, "-F")) {
+ if (this->CheckArgument(arg, "-F"_s)) {
this->Impl->Failover = true;
- }
- if (this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-j"_s, "--parallel") &&
+ i < args.size() - 1) {
i++;
int plevel = atoi(args[i].c_str());
this->SetParallelLevel(plevel);
this->Impl->ParallelLevelSetInCli = true;
- } else if (arg.find("-j") == 0) {
+ } else if (cmHasPrefix(arg, "-j")) {
int plevel = atoi(arg.substr(2).c_str());
this->SetParallelLevel(plevel);
this->Impl->ParallelLevelSetInCli = true;
}
- if (this->CheckArgument(arg, "--repeat-until-fail")) {
+ else if (this->CheckArgument(arg, "--repeat-until-fail"_s)) {
if (i >= args.size() - 1) {
errormsg = "'--repeat-until-fail' requires an argument";
return false;
@@ -1855,8 +1856,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i++;
long repeat = 1;
if (!cmStrToLong(args[i], &repeat)) {
- errormsg =
- "'--repeat-until-fail' given non-integer value '" + args[i] + "'";
+ errormsg = cmStrCat("'--repeat-until-fail' given non-integer value '",
+ args[i], "'");
return false;
}
this->Impl->RepeatCount = static_cast<int>(repeat);
@@ -1865,7 +1866,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "--repeat")) {
+ else if (this->CheckArgument(arg, "--repeat"_s)) {
if (i >= args.size() - 1) {
errormsg = "'--repeat' requires an argument";
return false;
@@ -1893,12 +1894,12 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
} else {
- errormsg = "'--repeat' given invalid value '" + args[i] + "'";
+ errormsg = cmStrCat("'--repeat' given invalid value '", args[i], "'");
return false;
}
}
- if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--test-load"_s) && i < args.size() - 1) {
i++;
unsigned long load;
if (cmStrToULong(args[i], &load)) {
@@ -1909,76 +1910,68 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "--no-compress-output")) {
+ else if (this->CheckArgument(arg, "--no-compress-output"_s)) {
this->Impl->CompressTestOutput = false;
}
- if (this->CheckArgument(arg, "--print-labels")) {
+ else if (this->CheckArgument(arg, "--print-labels"_s)) {
this->Impl->PrintLabels = true;
}
- if (this->CheckArgument(arg, "--http1.0")) {
+ else if (this->CheckArgument(arg, "--http1.0"_s)) {
this->Impl->UseHTTP10 = true;
}
- if (this->CheckArgument(arg, "--timeout") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--timeout"_s) && i < args.size() - 1) {
i++;
auto timeout = cmDuration(atof(args[i].c_str()));
this->Impl->GlobalTimeout = timeout;
}
- if (this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--stop-time"_s) && i < args.size() - 1) {
i++;
this->SetStopTime(args[i]);
}
- if (this->CheckArgument(arg, "-C", "--build-config") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--stop-on-failure"_s)) {
+ this->Impl->StopOnFailure = true;
+ }
+
+ else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
+ i < args.size() - 1) {
i++;
this->SetConfigType(args[i].c_str());
}
- if (this->CheckArgument(arg, "--debug")) {
+ else if (this->CheckArgument(arg, "--debug"_s)) {
this->Impl->Debug = true;
this->Impl->ShowLineNumbers = true;
- }
- if (this->CheckArgument(arg, "--group") && i < args.size() - 1) {
- i++;
- this->Impl->SpecificGroup = args[i];
- }
- // This is an undocumented / deprecated option.
- // "Track" has been renamed to "Group".
- if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
+ } else if ((this->CheckArgument(arg, "--group"_s) ||
+ // This is an undocumented / deprecated option.
+ // "Track" has been renamed to "Group".
+ this->CheckArgument(arg, "--track"_s)) &&
+ i < args.size() - 1) {
i++;
this->Impl->SpecificGroup = args[i];
- }
- if (this->CheckArgument(arg, "--show-line-numbers")) {
+ } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) {
this->Impl->ShowLineNumbers = true;
- }
- if (this->CheckArgument(arg, "--no-label-summary")) {
+ } else if (this->CheckArgument(arg, "--no-label-summary"_s)) {
this->Impl->LabelSummary = false;
- }
- if (this->CheckArgument(arg, "--no-subproject-summary")) {
+ } else if (this->CheckArgument(arg, "--no-subproject-summary"_s)) {
this->Impl->SubprojectSummary = false;
- }
- if (this->CheckArgument(arg, "-Q", "--quiet")) {
+ } else if (this->CheckArgument(arg, "-Q"_s, "--quiet")) {
this->Impl->Quiet = true;
- }
- if (this->CheckArgument(arg, "--progress")) {
+ } else if (this->CheckArgument(arg, "--progress"_s)) {
this->Impl->TestProgressOutput = true;
- }
- if (this->CheckArgument(arg, "-V", "--verbose")) {
+ } else if (this->CheckArgument(arg, "-V"_s, "--verbose")) {
this->Impl->Verbose = true;
- }
- if (this->CheckArgument(arg, "-VV", "--extra-verbose")) {
+ } else if (this->CheckArgument(arg, "-VV"_s, "--extra-verbose")) {
this->Impl->ExtraVerbose = true;
this->Impl->Verbose = true;
- }
- if (this->CheckArgument(arg, "--output-on-failure")) {
+ } else if (this->CheckArgument(arg, "--output-on-failure"_s)) {
this->Impl->OutputTestOutputOnTestFailure = true;
- }
- if (this->CheckArgument(arg, "--test-output-size-passed") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--test-output-size-passed"_s) &&
+ i < args.size() - 1) {
i++;
long outputSize;
if (cmStrToLong(args[i], &outputSize)) {
@@ -1988,9 +1981,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"Invalid value for '--test-output-size-passed': " << args[i]
<< "\n");
}
- }
- if (this->CheckArgument(arg, "--test-output-size-failed") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--test-output-size-failed"_s) &&
+ i < args.size() - 1) {
i++;
long outputSize;
if (cmStrToLong(args[i], &outputSize)) {
@@ -2000,11 +1992,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"Invalid value for '--test-output-size-failed': " << args[i]
<< "\n");
}
- }
- if (this->CheckArgument(arg, "-N", "--show-only")) {
+ } else if (this->CheckArgument(arg, "-N"_s, "--show-only")) {
this->Impl->ShowOnly = true;
- }
- if (cmHasLiteralPrefix(arg, "--show-only=")) {
+ } else if (cmHasLiteralPrefix(arg, "--show-only=")) {
this->Impl->ShowOnly = true;
// Check if a specific format is requested. Defaults to human readable
@@ -2022,27 +2012,26 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
+ i < args.size() - 1) {
i++;
this->SetOutputLogFileName(args[i].c_str());
}
- if (this->CheckArgument(arg, "--tomorrow-tag")) {
+ else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
this->Impl->TomorrowTag = true;
- }
- if (this->CheckArgument(arg, "--force-new-ctest-process")) {
+ } else if (this->CheckArgument(arg, "--force-new-ctest-process"_s)) {
this->Impl->ForceNewCTestProcess = true;
- }
- if (this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-W"_s, "--max-width") &&
+ i < args.size() - 1) {
i++;
this->Impl->MaxTestNameWidth = atoi(args[i].c_str());
- }
- if (this->CheckArgument(arg, "--interactive-debug-mode") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--interactive-debug-mode"_s) &&
+ i < args.size() - 1) {
i++;
this->Impl->InteractiveDebugMode = cmIsOn(args[i]);
- }
- if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--submit-index"_s) &&
+ i < args.size() - 1) {
i++;
this->Impl->SubmitIndex = atoi(args[i].c_str());
if (this->Impl->SubmitIndex < 0) {
@@ -2050,24 +2039,27 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "--overwrite") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--overwrite"_s) && i < args.size() - 1) {
i++;
this->AddCTestConfigurationOverwrite(args[i]);
- }
- if (this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-A"_s, "--add-notes") &&
+ i < args.size() - 1) {
this->Impl->ProduceXML = true;
this->SetTest("Notes");
i++;
this->SetNotesFiles(args[i].c_str());
+ return true;
}
- const std::string noTestsPrefix = "--no-tests=";
+ cm::string_view noTestsPrefix = "--no-tests=";
if (cmHasPrefix(arg, noTestsPrefix)) {
- const std::string noTestsMode = arg.substr(noTestsPrefix.length());
+ cm::string_view noTestsMode =
+ cm::string_view(arg).substr(noTestsPrefix.length());
if (noTestsMode == "error") {
this->Impl->NoTestsMode = cmCTest::NoTests::Error;
} else if (noTestsMode != "ignore") {
- errormsg = "'--no-tests=' given unknown value '" + noTestsMode + "'";
+ errormsg =
+ cmStrCat("'--no-tests=' given unknown value '", noTestsMode, '\'');
return false;
} else {
this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
@@ -2075,34 +2067,32 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
// options that control what tests are run
- if (this->CheckArgument(arg, "-I", "--tests-information") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-I"_s, "--tests-information") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-U", "--union")) {
+ } else if (this->CheckArgument(arg, "-U"_s, "--union")) {
this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
- }
- if (this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-R"_s, "--tests-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-LE", "--label-exclude") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeLabelRegularExpression", args[i].c_str());
@@ -2110,8 +2100,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeLabelRegularExpression", args[i].c_str());
}
- if (this->CheckArgument(arg, "-E", "--exclude-regex") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
args[i].c_str());
@@ -2119,24 +2109,22 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
args[i].c_str());
}
- if (this->CheckArgument(arg, "-FA", "--fixture-exclude-any") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureRegularExpression", args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureRegularExpression", args[i].c_str());
- }
- if (this->CheckArgument(arg, "-FS", "--fixture-exclude-setup") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureSetupRegularExpression", args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureSetupRegularExpression", args[i].c_str());
- }
- if (this->CheckArgument(arg, "-FC", "--fixture-exclude-cleanup") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
@@ -2144,8 +2132,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
}
- if (this->CheckArgument(arg, "--resource-spec-file") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--resource-spec-file"_s) &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
args[i].c_str());
@@ -2153,7 +2141,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
args[i].c_str());
}
- if (this->CheckArgument(arg, "--rerun-failed")) {
+ else if (this->CheckArgument(arg, "--rerun-failed"_s)) {
this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
}
@@ -2205,7 +2193,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
bool& SRArgumentSpecified)
{
std::string arg = args[i];
- if (this->CheckArgument(arg, "-SP", "--script-new-process") &&
+ if (this->CheckArgument(arg, "-SP"_s, "--script-new-process") &&
i < args.size() - 1) {
this->Impl->RunConfigurationScript = true;
i++;
@@ -2216,7 +2204,8 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
}
}
- if (this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-SR"_s, "--script-run") &&
+ i < args.size() - 1) {
SRArgumentSpecified = true;
this->Impl->RunConfigurationScript = true;
i++;
@@ -2224,7 +2213,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
ch->AddConfigurationScript(args[i].c_str(), true);
}
- if (this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-S"_s, "--script") && i < args.size() - 1) {
this->Impl->RunConfigurationScript = true;
i++;
cmCTestScriptHandler* ch = this->GetScriptHandler();
@@ -2274,7 +2263,8 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// --dashboard: handle a request for a dashboard
std::string arg = args[i];
- if (this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-D"_s, "--dashboard") &&
+ i < args.size() - 1) {
this->Impl->ProduceXML = true;
i++;
std::string targ = args[i];
@@ -2310,7 +2300,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
}
// --extra-submit
- if (this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "--extra-submit"_s) && i < args.size() - 1) {
this->Impl->ProduceXML = true;
this->SetTest("Submit");
i++;
@@ -2320,12 +2310,13 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
}
// --build-and-test options
- if (this->CheckArgument(arg, "--build-and-test") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "--build-and-test"_s) &&
+ i < args.size() - 1) {
cmakeAndTest = true;
}
// --schedule-random
- if (this->CheckArgument(arg, "--schedule-random")) {
+ if (this->CheckArgument(arg, "--schedule-random"_s)) {
this->Impl->ScheduleType = "Random";
}
@@ -2380,7 +2371,7 @@ bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i,
{
bool success = true;
std::string arg = args[i];
- if (this->CheckArgument(arg, "-T", "--test-action") &&
+ if (this->CheckArgument(arg, "-T"_s, "--test-action") &&
(i < args.size() - 1)) {
this->Impl->ProduceXML = true;
i++;
@@ -2412,15 +2403,15 @@ bool cmCTest::HandleTestModelArgument(const char* ctestExec, size_t& i,
{
bool success = true;
std::string arg = args[i];
- if (this->CheckArgument(arg, "-M", "--test-model") &&
+ if (this->CheckArgument(arg, "-M"_s, "--test-model") &&
(i < args.size() - 1)) {
i++;
std::string const& str = args[i];
- if (cmSystemTools::LowerCase(str) == "nightly") {
+ if (cmSystemTools::LowerCase(str) == "nightly"_s) {
this->SetTestModel(cmCTest::NIGHTLY);
- } else if (cmSystemTools::LowerCase(str) == "continuous") {
+ } else if (cmSystemTools::LowerCase(str) == "continuous"_s) {
this->SetTestModel(cmCTest::CONTINUOUS);
- } else if (cmSystemTools::LowerCase(str) == "experimental") {
+ } else if (cmSystemTools::LowerCase(str) == "experimental"_s) {
this->SetTestModel(cmCTest::EXPERIMENTAL);
} else {
success = false;
@@ -2507,6 +2498,16 @@ void cmCTest::SetNotesFiles(const char* notes)
this->Impl->NotesFiles = notes;
}
+bool cmCTest::GetStopOnFailure() const
+{
+ return this->Impl->StopOnFailure;
+}
+
+void cmCTest::SetStopOnFailure(bool stop)
+{
+ this->Impl->StopOnFailure = stop;
+}
+
std::chrono::system_clock::time_point cmCTest::GetStopTime() const
{
return this->Impl->StopTime;
@@ -2687,7 +2688,7 @@ std::string cmCTest::GetShortPathToFile(const char* cfname)
path = "./" + *res;
if (path.back() == '/') {
- path = path.substr(0, path.size() - 1);
+ path.resize(path.size() - 1);
}
}
@@ -2738,7 +2739,7 @@ std::string cmCTest::GetSubmitURL()
std::string site = this->GetCTestConfiguration("DropSite");
std::string location = this->GetCTestConfiguration("DropLocation");
- url = cmStrCat(method.empty() ? "http" : method, "://");
+ url = cmStrCat(method.empty() ? "http" : method, "://"_s);
if (!user.empty()) {
url += user;
if (!password.empty()) {
@@ -3086,12 +3087,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
void cmCTest::SetOutputLogFileName(const char* name)
{
- if (this->Impl->OutputLogFile) {
- delete this->Impl->OutputLogFile;
- this->Impl->OutputLogFile = nullptr;
- }
if (name) {
- this->Impl->OutputLogFile = new cmGeneratedFileStream(name);
+ this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
+ } else {
+ this->Impl->OutputLogFile.reset();
}
}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 7f8f913..a39b8fe 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -13,6 +13,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmDuration.h"
#include "cmProcessOutput.h"
@@ -140,7 +142,8 @@ public:
std::string GetTestModelString();
static int GetTestModelFromString(const char* str);
- static std::string CleanString(const std::string& str);
+ static std::string CleanString(const std::string& str,
+ std::string::size_type spos = 0);
std::string GetCTestConfiguration(const std::string& name);
void SetCTestConfiguration(const char* name, const char* value,
bool suppress = false);
@@ -201,6 +204,9 @@ public:
bool ShouldCompressTestOutput();
bool CompressString(std::string& str);
+ bool GetStopOnFailure() const;
+ void SetStopOnFailure(bool stop);
+
std::chrono::system_clock::time_point GetStopTime() const;
void SetStopTime(std::string const& time);
@@ -506,8 +512,8 @@ private:
std::vector<std::string> const& files);
/** Check if the argument is the one specified */
- bool CheckArgument(const std::string& arg, const char* varg1,
- const char* varg2 = nullptr);
+ static bool CheckArgument(const std::string& arg, cm::string_view varg1,
+ const char* varg2 = nullptr);
/** Output errors from a test */
void OutputTestErrors(std::vector<char> const& process_output);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index dc9aba1..35bd681 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -19,12 +19,6 @@
#include "cmSystemTools.h"
#include "cmVersion.h"
-cmCacheManager::cmCacheManager()
-{
- this->CacheMajorVersion = 0;
- this->CacheMinorVersion = 0;
-}
-
void cmCacheManager::CleanCMakeFiles(const std::string& path)
{
std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake");
@@ -77,7 +71,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
while (realbuffer[0] == '/' && realbuffer[1] == '/') {
if ((realbuffer[2] == '\\') && (realbuffer[3] == 'n')) {
- helpString += "\n";
+ helpString += '\n';
helpString += &realbuffer[4];
} else {
helpString += &realbuffer[2];
@@ -117,20 +111,20 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
} else {
std::ostringstream error;
- error << "Parse error in cache file " << cacheFile;
- error << " on line " << lineno << ". Offending entry: " << realbuffer;
+ error << "Parse error in cache file " << cacheFile << " on line "
+ << lineno << ". Offending entry: " << realbuffer;
cmSystemTools::Error(error.str());
}
}
this->CacheMajorVersion = 0;
this->CacheMinorVersion = 0;
- if (const std::string* cmajor =
+ if (cmProp cmajor =
this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) {
unsigned int v = 0;
if (sscanf(cmajor->c_str(), "%u", &v) == 1) {
this->CacheMajorVersion = v;
}
- if (const std::string* cminor =
+ if (cmProp cminor =
this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) {
if (sscanf(cminor->c_str(), "%u", &v) == 1) {
this->CacheMinorVersion = v;
@@ -150,8 +144,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
// check to make sure the cache directory has not
// been moved
- const std::string* oldDir =
- this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+ cmProp oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
if (internal && oldDir) {
std::string currentcwd = path;
std::string oldcwd = *oldDir;
@@ -159,8 +152,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
currentcwd += "/CMakeCache.txt";
oldcwd += "/CMakeCache.txt";
if (!cmSystemTools::SameFile(oldcwd, currentcwd)) {
- const std::string* dir =
- this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+ cmProp dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
std::ostringstream message;
message << "The current CMakeCache.txt directory " << currentcwd
<< " is different than the directory " << (dir ? *dir : "")
@@ -174,10 +166,10 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
const char* cmCacheManager::PersistentProperties[] = { "ADVANCED", "MODIFIED",
- "STRINGS", nullptr };
+ "STRINGS" };
-bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
- CacheEntry& e)
+bool cmCacheManager::ReadPropertyEntry(const std::string& entryKey,
+ const CacheEntry& e)
{
// All property entries are internal.
if (e.Type != cmStateEnums::INTERNAL) {
@@ -185,20 +177,18 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
}
const char* end = entryKey.c_str() + entryKey.size();
- for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
- std::string::size_type plen = strlen(*p) + 1;
+ for (const char* p : cmCacheManager::PersistentProperties) {
+ std::string::size_type plen = strlen(p) + 1;
if (entryKey.size() > plen && *(end - plen) == '-' &&
- strcmp(end - plen + 1, *p) == 0) {
+ strcmp(end - plen + 1, p) == 0) {
std::string key = entryKey.substr(0, entryKey.size() - plen);
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
- if (it.IsAtEnd()) {
+ if (auto entry = this->GetCacheEntry(key)) {
+ // Store this property on its entry.
+ entry->SetProperty(p, e.Value.c_str());
+ } else {
// Create an entry and store the property.
CacheEntry& ne = this->Cache[key];
- ne.Type = cmStateEnums::UNINITIALIZED;
- ne.SetProperty(*p, e.Value.c_str());
- } else {
- // Store this property on its entry.
- it.SetProperty(*p, e.Value.c_str());
+ ne.SetProperty(p, e.Value.c_str());
}
return true;
}
@@ -206,21 +196,23 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
return false;
}
-void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
- cmMessenger* messenger)
+void cmCacheManager::WritePropertyEntries(std::ostream& os,
+ const std::string& entryKey,
+ const CacheEntry& e,
+ cmMessenger* messenger) const
{
- for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
- if (const char* value = i.GetProperty(*p)) {
+ for (const char* p : cmCacheManager::PersistentProperties) {
+ if (cmProp value = e.GetProperty(p)) {
std::string helpstring =
- cmStrCat(*p, " property for variable: ", i.GetName());
+ cmStrCat(p, " property for variable: ", entryKey);
cmCacheManager::OutputHelpString(os, helpstring);
- std::string key = cmStrCat(i.GetName(), '-', *p);
+ std::string key = cmStrCat(entryKey, '-', p);
cmCacheManager::OutputKey(os, key);
os << ":INTERNAL=";
- cmCacheManager::OutputValue(os, value);
- os << "\n";
- cmCacheManager::OutputNewlineTruncationWarning(os, key, value,
+ cmCacheManager::OutputValue(os, *value);
+ os << '\n';
+ cmCacheManager::OutputNewlineTruncationWarning(os, key, *value,
messenger);
}
}
@@ -270,31 +262,29 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
/* clang-format off */
fout << "# This is the CMakeCache file.\n"
- << "# For build in directory: " << currentcwd << "\n"
- << "# It was generated by CMake: "
- << cmSystemTools::GetCMakeCommand() << std::endl;
- /* clang-format on */
-
- /* clang-format off */
- fout << "# You can edit this file to change values found and used by cmake."
- << std::endl
- << "# If you do not want to change any of the values, simply exit the "
- "editor." << std::endl
- << "# If you do want to change a value, simply edit, save, and exit "
- "the editor." << std::endl
- << "# The syntax for the file is as follows:\n"
- << "# KEY:TYPE=VALUE\n"
- << "# KEY is the name of a variable in the cache.\n"
- << "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT "
- "TYPE!." << std::endl
- << "# VALUE is the current value for the KEY.\n\n";
+ "# For build in directory: " << currentcwd << "\n"
+ "# It was generated by CMake: "
+ << cmSystemTools::GetCMakeCommand()
+ << "\n"
+ "# You can edit this file to change values found and used by cmake."
+ "\n"
+ "# If you do not want to change any of the values, simply exit the "
+ "editor.\n"
+ "# If you do want to change a value, simply edit, save, and exit "
+ "the editor.\n"
+ "# The syntax for the file is as follows:\n"
+ "# KEY:TYPE=VALUE\n"
+ "# KEY is the name of a variable in the cache.\n"
+ "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!."
+ "\n"
+ "# VALUE is the current value for the KEY.\n"
+ "\n"
+ "########################\n"
+ "# EXTERNAL cache entries\n"
+ "########################\n"
+ "\n";
/* clang-format on */
- fout << "########################\n";
- fout << "# EXTERNAL cache entries\n";
- fout << "########################\n";
- fout << "\n";
-
for (auto const& i : this->Cache) {
CacheEntry const& ce = i.second;
cmStateEnums::CacheEntryType t = ce.Type;
@@ -305,49 +295,48 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
*/
} else if (t != cmStateEnums::INTERNAL) {
// Format is key:type=value
- if (const char* help = ce.GetProperty("HELPSTRING")) {
- cmCacheManager::OutputHelpString(fout, help);
+ if (cmProp help = ce.GetProperty("HELPSTRING")) {
+ cmCacheManager::OutputHelpString(fout, *help);
} else {
cmCacheManager::OutputHelpString(fout, "Missing description");
}
cmCacheManager::OutputKey(fout, i.first);
- fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
+ fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
cmCacheManager::OutputValue(fout, ce.Value);
- fout << "\n";
+ fout << '\n';
cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value,
messenger);
- fout << "\n";
+ fout << '\n';
}
}
- fout << "\n";
- fout << "########################\n";
- fout << "# INTERNAL cache entries\n";
- fout << "########################\n";
- fout << "\n";
+ fout << "\n"
+ "########################\n"
+ "# INTERNAL cache entries\n"
+ "########################\n"
+ "\n";
- for (cmCacheManager::CacheIterator i = this->NewIterator(); !i.IsAtEnd();
- i.Next()) {
- if (!i.Initialized()) {
+ for (auto const& i : this->Cache) {
+ if (!i.second.Initialized) {
continue;
}
- cmStateEnums::CacheEntryType t = i.GetType();
- this->WritePropertyEntries(fout, i, messenger);
+ cmStateEnums::CacheEntryType t = i.second.GetType();
+ this->WritePropertyEntries(fout, i.first, i.second, messenger);
if (t == cmStateEnums::INTERNAL) {
// Format is key:type=value
- if (const char* help = i.GetProperty("HELPSTRING")) {
- cmCacheManager::OutputHelpString(fout, help);
+ if (cmProp help = i.second.GetProperty("HELPSTRING")) {
+ cmCacheManager::OutputHelpString(fout, *help);
}
- cmCacheManager::OutputKey(fout, i.GetName());
- fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
- cmCacheManager::OutputValue(fout, i.GetValue());
- fout << "\n";
- cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(),
- i.GetValue(), messenger);
+ cmCacheManager::OutputKey(fout, i.first);
+ fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
+ cmCacheManager::OutputValue(fout, i.second.GetValue());
+ fout << '\n';
+ cmCacheManager::OutputNewlineTruncationWarning(
+ fout, i.first, i.second.GetValue(), messenger);
}
}
- fout << "\n";
+ fout << '\n';
fout.Close();
std::string checkCacheFile = cmStrCat(path, "/CMakeFiles");
cmSystemTools::MakeDirectory(checkCacheFile);
@@ -385,7 +374,9 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
{
// support : in key name by double quoting
const char* q =
- (key.find(':') != std::string::npos || key.find("//") == 0) ? "\"" : "";
+ (key.find(':') != std::string::npos || cmHasLiteralPrefix(key, "//"))
+ ? "\""
+ : "";
fout << q << key << q;
}
@@ -430,7 +421,7 @@ void cmCacheManager::OutputHelpString(std::ostream& fout,
fout << "\\n";
}
oneLine = helpString.substr(pos, i - pos);
- fout << oneLine << "\n";
+ fout << oneLine << '\n';
pos = i;
}
}
@@ -452,7 +443,7 @@ void cmCacheManager::OutputWarningComment(std::ostream& fout,
fout << "\\n";
}
oneLine = message.substr(pos, i - pos);
- fout << oneLine << "\n";
+ fout << oneLine << '\n';
pos = i;
}
}
@@ -481,10 +472,7 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
void cmCacheManager::RemoveCacheEntry(const std::string& key)
{
- auto i = this->Cache.find(key);
- if (i != this->Cache.end()) {
- this->Cache.erase(i);
- }
+ this->Cache.erase(key);
}
cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
@@ -497,40 +485,39 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
return nullptr;
}
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
- const std::string& key)
-{
- return { *this, key.c_str() };
-}
-
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator()
+const cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
+ const std::string& key) const
{
- return { *this, nullptr };
+ auto i = this->Cache.find(key);
+ if (i != this->Cache.end()) {
+ return &i->second;
+ }
+ return nullptr;
}
-const std::string* cmCacheManager::GetInitializedCacheValue(
- const std::string& key) const
+cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const
{
- auto i = this->Cache.find(key);
- if (i != this->Cache.end() && i->second.Initialized) {
- return &i->second.Value;
+ if (auto entry = this->GetCacheEntry(key)) {
+ if (entry->Initialized) {
+ return &entry->GetValue();
+ }
}
return nullptr;
}
void cmCacheManager::PrintCache(std::ostream& out) const
{
- out << "=================================================" << std::endl;
- out << "CMakeCache Contents:" << std::endl;
+ out << "=================================================\n"
+ "CMakeCache Contents:\n";
for (auto const& i : this->Cache) {
if (i.second.Type != cmStateEnums::INTERNAL) {
- out << i.first << " = " << i.second.Value << std::endl;
+ out << i.first << " = " << i.second.Value << '\n';
}
}
- out << "\n\n";
- out << "To change values in the CMakeCache, " << std::endl
- << "edit CMakeCache.txt in your output directory.\n";
- out << "=================================================" << std::endl;
+ out << "\n\n"
+ "To change values in the CMakeCache, \n"
+ "edit CMakeCache.txt in your output directory.\n"
+ "=================================================\n";
}
void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
@@ -538,12 +525,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
cmStateEnums::CacheEntryType type)
{
CacheEntry& e = this->Cache[key];
- if (value) {
- e.Value = value;
- e.Initialized = true;
- } else {
- e.Value.clear();
- }
+ e.SetValue(value);
e.Type = type;
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
@@ -567,70 +549,41 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
: "(This variable does not exist and should not be used)");
}
-bool cmCacheManager::CacheIterator::IsAtEnd() const
-{
- return this->Position == this->Container.Cache.end();
-}
-
-void cmCacheManager::CacheIterator::Begin()
-{
- this->Position = this->Container.Cache.begin();
-}
-
-bool cmCacheManager::CacheIterator::Find(const std::string& key)
-{
- this->Position = this->Container.Cache.find(key);
- return !this->IsAtEnd();
-}
-
-void cmCacheManager::CacheIterator::Next()
-{
- if (!this->IsAtEnd()) {
- ++this->Position;
- }
-}
-
-std::vector<std::string> cmCacheManager::CacheIterator::GetPropertyList() const
+void cmCacheManager::CacheEntry::SetValue(const char* value)
{
- return this->GetEntry().GetPropertyList();
-}
-
-void cmCacheManager::CacheIterator::SetValue(const char* value)
-{
- if (this->IsAtEnd()) {
- return;
- }
- CacheEntry* entry = &this->GetEntry();
if (value) {
- entry->Value = value;
- entry->Initialized = true;
+ this->Value = value;
+ this->Initialized = true;
} else {
- entry->Value.clear();
+ this->Value.clear();
}
}
-bool cmCacheManager::CacheIterator::GetValueAsBool() const
-{
- return cmIsOn(this->GetEntry().Value);
-}
-
std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
{
return this->Properties.GetKeys();
}
-const char* cmCacheManager::CacheEntry::GetProperty(
- const std::string& prop) const
+cmProp cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
{
if (prop == "TYPE") {
- return cmState::CacheEntryTypeToString(this->Type).c_str();
+ return &cmState::CacheEntryTypeToString(this->Type);
}
if (prop == "VALUE") {
- return this->Value.c_str();
+ return &this->Value;
}
return this->Properties.GetPropertyValue(prop);
}
+bool cmCacheManager::CacheEntry::GetPropertyAsBool(
+ const std::string& prop) const
+{
+ if (cmProp value = this->GetProperty(prop)) {
+ return cmIsOn(*value);
+ }
+ return false;
+}
+
void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
const char* value)
{
@@ -643,6 +596,11 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
}
}
+void cmCacheManager::CacheEntry::SetProperty(const std::string& p, bool v)
+{
+ this->SetProperty(p, v ? "ON" : "OFF");
+}
+
void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
const std::string& value,
bool asString)
@@ -661,49 +619,3 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
this->Properties.AppendProperty(prop, value, asString);
}
}
-
-const char* cmCacheManager::CacheIterator::GetProperty(
- const std::string& prop) const
-{
- if (!this->IsAtEnd()) {
- return this->GetEntry().GetProperty(prop);
- }
- return nullptr;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p,
- const char* v)
-{
- if (!this->IsAtEnd()) {
- this->GetEntry().SetProperty(p, v);
- }
-}
-
-void cmCacheManager::CacheIterator::AppendProperty(const std::string& p,
- const std::string& v,
- bool asString)
-{
- if (!this->IsAtEnd()) {
- this->GetEntry().AppendProperty(p, v, asString);
- }
-}
-
-bool cmCacheManager::CacheIterator::GetPropertyAsBool(
- const std::string& prop) const
-{
- if (const char* value = this->GetProperty(prop)) {
- return cmIsOn(value);
- }
- return false;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p, bool v)
-{
- this->SetProperty(p, v ? "ON" : "OFF");
-}
-
-bool cmCacheManager::CacheIterator::PropertyExists(
- const std::string& prop) const
-{
- return this->GetProperty(prop) != nullptr;
-}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index d8be991..3d946b4 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -25,77 +25,33 @@ class cmMessenger;
*/
class cmCacheManager
{
-public:
- cmCacheManager();
- class CacheIterator;
- friend class cmCacheManager::CacheIterator;
-
-private:
- struct CacheEntry
+ class CacheEntry
{
- std::string Value;
- cmStateEnums::CacheEntryType Type = cmStateEnums::UNINITIALIZED;
- cmPropertyMap Properties;
- std::vector<std::string> GetPropertyList() const;
- const char* GetProperty(const std::string&) const;
- void SetProperty(const std::string& property, const char* value);
- void AppendProperty(const std::string& property, const std::string& value,
- bool asString = false);
- bool Initialized = false;
- };
+ friend class cmCacheManager;
-public:
- class CacheIterator
- {
public:
- void Begin();
- bool Find(const std::string&);
- bool IsAtEnd() const;
- void Next();
- std::string GetName() const { return this->Position->first; }
+ const std::string& GetValue() const { return this->Value; }
+ void SetValue(const char*);
+
+ cmStateEnums::CacheEntryType GetType() const { return this->Type; }
+ void SetType(cmStateEnums::CacheEntryType ty) { this->Type = ty; }
+
std::vector<std::string> GetPropertyList() const;
- const char* GetProperty(const std::string&) const;
- bool GetPropertyAsBool(const std::string&) const;
- bool PropertyExists(const std::string&) const;
+ cmProp GetProperty(const std::string& property) const;
+ bool GetPropertyAsBool(const std::string& property) const;
void SetProperty(const std::string& property, const char* value);
+ void SetProperty(const std::string& property, bool value);
void AppendProperty(const std::string& property, const std::string& value,
bool asString = false);
- void SetProperty(const std::string& property, bool value);
- const std::string& GetValue() const { return this->GetEntry().Value; }
- bool GetValueAsBool() const;
- void SetValue(const char*);
- cmStateEnums::CacheEntryType GetType() const
- {
- return this->GetEntry().Type;
- }
- void SetType(cmStateEnums::CacheEntryType ty)
- {
- this->GetEntry().Type = ty;
- }
- bool Initialized() { return this->GetEntry().Initialized; }
- cmCacheManager& Container;
- std::map<std::string, CacheEntry>::iterator Position;
- CacheIterator(cmCacheManager& cm)
- : Container(cm)
- {
- this->Begin();
- }
- CacheIterator(cmCacheManager& cm, const char* key)
- : Container(cm)
- {
- if (key) {
- this->Find(key);
- }
- }
private:
- CacheEntry const& GetEntry() const { return this->Position->second; }
- CacheEntry& GetEntry() { return this->Position->second; }
+ std::string Value;
+ cmStateEnums::CacheEntryType Type = cmStateEnums::UNINITIALIZED;
+ cmPropertyMap Properties;
+ bool Initialized = false;
};
- //! return an iterator to iterate through the cache map
- cmCacheManager::CacheIterator NewIterator() { return { *this }; }
-
+public:
//! Load a cache for given makefile. Loads from path/CMakeCache.txt.
bool LoadCache(const std::string& path, bool internal,
std::set<std::string>& excludes,
@@ -110,67 +66,82 @@ public:
//! Print the cache to a stream
void PrintCache(std::ostream&) const;
- //! Get the iterator for an entry with a given key.
- cmCacheManager::CacheIterator GetCacheIterator(const std::string& key);
- cmCacheManager::CacheIterator GetCacheIterator();
-
- //! Remove an entry from the cache
- void RemoveCacheEntry(const std::string& key);
+ //! Get a value from the cache given a key
+ cmProp GetInitializedCacheValue(const std::string& key) const;
- //! Get the number of entries in the cache
- int GetSize() { return static_cast<int>(this->Cache.size()); }
+ cmProp GetCacheEntryValue(const std::string& key) const
+ {
+ if (auto entry = this->GetCacheEntry(key)) {
+ return &entry->GetValue();
+ }
+ return nullptr;
+ }
- //! Get a value from the cache given a key
- const std::string* GetInitializedCacheValue(const std::string& key) const;
+ void SetCacheEntryValue(std::string const& key, std::string const& value)
+ {
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetValue(value.c_str());
+ }
+ }
- const char* GetCacheEntryValue(const std::string& key)
+ cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const
{
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
- if (it.IsAtEnd()) {
- return nullptr;
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetType();
}
- return it.GetValue().c_str();
+ return cmStateEnums::UNINITIALIZED;
}
- const char* GetCacheEntryProperty(std::string const& key,
- std::string const& propName)
+ std::vector<std::string> GetCacheEntryPropertyList(
+ std::string const& key) const
{
- return this->GetCacheIterator(key).GetProperty(propName);
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetPropertyList();
+ }
+ return {};
}
- cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key)
+ cmProp GetCacheEntryProperty(std::string const& key,
+ std::string const& propName) const
{
- return this->GetCacheIterator(key).GetType();
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetProperty(propName);
+ }
+ return nullptr;
}
bool GetCacheEntryPropertyAsBool(std::string const& key,
- std::string const& propName)
+ std::string const& propName) const
{
- return this->GetCacheIterator(key).GetPropertyAsBool(propName);
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetPropertyAsBool(propName);
+ }
+ return false;
}
void SetCacheEntryProperty(std::string const& key,
std::string const& propName,
std::string const& value)
{
- this->GetCacheIterator(key).SetProperty(propName, value.c_str());
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, value.c_str());
+ }
}
void SetCacheEntryBoolProperty(std::string const& key,
std::string const& propName, bool value)
{
- this->GetCacheIterator(key).SetProperty(propName, value);
- }
-
- void SetCacheEntryValue(std::string const& key, std::string const& value)
- {
- this->GetCacheIterator(key).SetValue(value.c_str());
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, value);
+ }
}
void RemoveCacheEntryProperty(std::string const& key,
std::string const& propName)
{
- this->GetCacheIterator(key).SetProperty(propName, nullptr);
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, nullptr);
+ }
}
void AppendCacheEntryProperty(std::string const& key,
@@ -178,16 +149,17 @@ public:
std::string const& value,
bool asString = false)
{
- this->GetCacheIterator(key).AppendProperty(propName, value, asString);
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->AppendProperty(propName, value, asString);
+ }
}
- std::vector<std::string> GetCacheEntryKeys()
+ std::vector<std::string> GetCacheEntryKeys() const
{
std::vector<std::string> definitions;
- definitions.reserve(this->GetSize());
- cmCacheManager::CacheIterator cit = this->GetCacheIterator();
- for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
- definitions.push_back(cit.GetName());
+ definitions.reserve(this->Cache.size());
+ for (auto const& i : this->Cache) {
+ definitions.push_back(i.first);
}
return definitions;
}
@@ -196,23 +168,22 @@ public:
unsigned int GetCacheMajorVersion() const { return this->CacheMajorVersion; }
unsigned int GetCacheMinorVersion() const { return this->CacheMinorVersion; }
-protected:
//! Add an entry into the cache
void AddCacheEntry(const std::string& key, const char* value,
const char* helpString,
cmStateEnums::CacheEntryType type);
+ //! Remove an entry from the cache
+ void RemoveCacheEntry(const std::string& key);
+
+private:
//! Get a cache entry object for a key
CacheEntry* GetCacheEntry(const std::string& key);
+ const CacheEntry* GetCacheEntry(const std::string& key) const;
+
//! Clean out the CMakeFiles directory if no CMakeCache.txt
void CleanCMakeFiles(const std::string& path);
- // Cache version info
- unsigned int CacheMajorVersion;
- unsigned int CacheMinorVersion;
-
-private:
- using CacheEntryMap = std::map<std::string, CacheEntry>;
static void OutputHelpString(std::ostream& fout,
const std::string& helpString);
static void OutputWarningComment(std::ostream& fout,
@@ -228,15 +199,15 @@ private:
std::string const& value);
static const char* PersistentProperties[];
- bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
- void WritePropertyEntries(std::ostream& os, CacheIterator i,
- cmMessenger* messenger);
-
- CacheEntryMap Cache;
- // Only cmake and cmState should be able to add cache values
- // the commands should never use the cmCacheManager directly
- friend class cmState; // allow access to add cache values
- friend class cmake; // allow access to add cache values
+ bool ReadPropertyEntry(const std::string& key, const CacheEntry& e);
+ void WritePropertyEntries(std::ostream& os, const std::string& entryKey,
+ const CacheEntry& e, cmMessenger* messenger) const;
+
+ std::map<std::string, CacheEntry> Cache;
+
+ // Cache version info
+ unsigned int CacheMajorVersion = 0;
+ unsigned int CacheMinorVersion = 0;
};
#endif
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index 9e152ff..94b6e18 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -43,8 +43,7 @@ static bool LogErrorsAsMessages;
if (LogErrorsAsMessages) { \
std::ostringstream _hresult_oss; \
_hresult_oss.flags(std::ios::hex); \
- _hresult_oss << context << " failed HRESULT, hr = 0x" << hr \
- << std::endl; \
+ _hresult_oss << context << " failed HRESULT, hr = 0x" << hr << '\n'; \
_hresult_oss.flags(std::ios::dec); \
_hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \
cmSystemTools::Message(_hresult_oss.str()); \
@@ -98,32 +97,37 @@ HRESULT InstanceCallMacro(IDispatch* vsIDE, const std::string& macro,
DISPATCH_METHOD, &params, &result, &excep, &arg);
std::ostringstream oss;
- oss << std::endl;
- oss << "Invoke(ExecuteCommand)" << std::endl;
- oss << " Macro: " << macro << std::endl;
- oss << " Args: " << args << std::endl;
+ /* clang-format off */
+ oss << "\nInvoke(ExecuteCommand)\n"
+ " Macro: " << macro << "\n"
+ " Args: " << args << '\n';
+ /* clang-format on */
if (DISP_E_EXCEPTION == hr) {
- oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl;
- oss << " wCode: " << excep.wCode << std::endl;
- oss << " wReserved: " << excep.wReserved << std::endl;
+ /* clang-format off */
+ oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << "\n"
+ " wCode: " << excep.wCode << "\n"
+ " wReserved: " << excep.wReserved << '\n';
+ /* clang-format on */
if (excep.bstrSource) {
oss << " bstrSource: " << (const char*)(_bstr_t)excep.bstrSource
- << std::endl;
+ << '\n';
}
if (excep.bstrDescription) {
oss << " bstrDescription: "
- << (const char*)(_bstr_t)excep.bstrDescription << std::endl;
+ << (const char*)(_bstr_t)excep.bstrDescription << '\n';
}
if (excep.bstrHelpFile) {
oss << " bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile
- << std::endl;
+ << '\n';
}
- oss << " dwHelpContext: " << excep.dwHelpContext << std::endl;
- oss << " pvReserved: " << excep.pvReserved << std::endl;
- oss << " pfnDeferredFillIn: "
- << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << std::endl;
- oss << " scode: " << excep.scode << std::endl;
+ /* clang-format off */
+ oss << " dwHelpContext: " << excep.dwHelpContext << "\n"
+ " pvReserved: " << excep.pvReserved << "\n"
+ " pfnDeferredFillIn: "
+ << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << "\n"
+ " scode: " << excep.scode << '\n';
+ /* clang-format on */
}
std::string exstr(oss.str());
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 613ae06..379836a 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,6 +5,9 @@
#include <cstring>
#include <iostream>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
@@ -40,10 +43,10 @@ const char* cmCommandArgumentParserHelper::AddString(const std::string& str)
if (str.empty()) {
return "";
}
- char* stVal = new char[str.size() + 1];
- strcpy(stVal, str.c_str());
- this->Variables.push_back(stVal);
- return stVal;
+ auto stVal = cm::make_unique<char[]>(str.size() + 1);
+ strcpy(stVal.get(), str.c_str());
+ this->Variables.push_back(std::move(stVal));
+ return this->Variables.back().get();
}
const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
@@ -136,11 +139,11 @@ const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1,
return in1;
}
size_t len = strlen(in1) + strlen(in2) + 1;
- char* out = new char[len];
- strcpy(out, in1);
- strcat(out, in2);
- this->Variables.push_back(out);
- return out;
+ auto out = cm::make_unique<char[]>(len);
+ strcpy(out.get(), in1);
+ strcat(out.get(), in2);
+ this->Variables.push_back(std::move(out));
+ return this->Variables.back().get();
}
void cmCommandArgumentParserHelper::AllocateParserType(
@@ -153,11 +156,11 @@ void cmCommandArgumentParserHelper::AllocateParserType(
if (len == 0) {
return;
}
- char* out = new char[len + 1];
- memcpy(out, str, len);
- out[len] = 0;
- pt->str = out;
- this->Variables.push_back(out);
+ auto out = cm::make_unique<char[]>(len + 1);
+ memcpy(out.get(), str, len);
+ out.get()[len] = 0;
+ pt->str = out.get();
+ this->Variables.push_back(std::move(out));
}
bool cmCommandArgumentParserHelper::HandleEscapeSymbol(
@@ -235,10 +238,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
void cmCommandArgumentParserHelper::CleanupParser()
{
- for (char* var : this->Variables) {
- delete[] var;
- }
- this->Variables.erase(this->Variables.begin(), this->Variables.end());
+ this->Variables.clear();
}
int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 25e6892..b46edcb 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -69,7 +70,7 @@ private:
void CleanupParser();
void SetError(std::string const& msg);
- std::vector<char*> Variables;
+ std::vector<std::unique_ptr<char[]>> Variables;
const cmMakefile* Makefile;
std::string Result;
std::string ErrorString;
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 896b6a9..28b4267 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -91,6 +91,7 @@
# include "cmAddLinkOptionsCommand.h"
# include "cmAuxSourceDirectoryCommand.h"
# include "cmBuildNameCommand.h"
+# include "cmCMakeCommand.h"
# include "cmCMakeHostSystemInformationCommand.h"
# include "cmExportCommand.h"
# include "cmExportLibraryDependenciesCommand.h"
@@ -196,6 +197,7 @@ void GetScriptingCommands(cmState* state)
"match the opening WHILE command.");
#if !defined(CMAKE_BOOTSTRAP)
+ state->AddBuiltinCommand("cmake_command", cmCMakeCommand);
state->AddBuiltinCommand("cmake_host_system_information",
cmCMakeHostSystemInformationCommand);
state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 033cb60..673936c 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -73,9 +73,9 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(
void cmCommonTargetGenerator::AppendFortranFormatFlags(
std::string& flags, cmSourceFile const& source)
{
- const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+ cmProp srcfmt = source.GetProperty("Fortran_FORMAT");
cmOutputConverter::FortranFormat format =
- cmOutputConverter::GetFortranFormat(srcfmt);
+ cmOutputConverter::GetFortranFormat(srcfmt ? srcfmt->c_str() : nullptr);
if (format == cmOutputConverter::FortranFormatNone) {
const char* tgtfmt = this->GeneratorTarget->GetProperty("Fortran_FORMAT");
format = cmOutputConverter::GetFortranFormat(tgtfmt);
@@ -98,17 +98,20 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
- const std::string& config)
+ const std::string& config,
+ const std::string& arch)
{
- auto i = this->Configs[config].FlagsByLanguage.find(l);
- if (i == this->Configs[config].FlagsByLanguage.end()) {
+ const std::string key = config + arch;
+
+ auto i = this->Configs[key].FlagsByLanguage.find(l);
+ if (i == this->Configs[key].FlagsByLanguage.end()) {
std::string flags;
this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
- config, l, flags);
+ config, l, flags, arch);
ByLanguageMap::value_type entry(l, flags);
- i = this->Configs[config].FlagsByLanguage.insert(entry).first;
+ i = this->Configs[key].FlagsByLanguage.insert(entry).first;
}
return i->second;
}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index b40a2ed..78cedf5 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -51,7 +51,8 @@ protected:
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
- std::string GetFlags(const std::string& l, const std::string& config);
+ std::string GetFlags(const std::string& l, const std::string& config,
+ const std::string& arch = std::string());
std::string GetDefines(const std::string& l, const std::string& config);
std::string GetIncludes(std::string const& l, const std::string& config);
std::string GetManifests(const std::string& config);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 11570d6..f0174d9 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -9,8 +9,8 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -610,7 +610,7 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
runtimeLibrary)) {
std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -627,7 +627,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
if (const char* libs = this->Makefile->GetDefinition(libVar)) {
std::vector<std::string> libsVec = cmExpandedList(libs);
for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -998,15 +998,16 @@ std::string cmComputeLinkInformation::CreateExtensionRegex(
std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
{
std::string ret;
+ ret.reserve(strlen(str) * 4);
const char* s = str;
while (*s) {
if (*s == '.') {
ret += *s;
} else {
- ret += "[";
+ ret += '[';
ret += static_cast<char>(tolower(*s));
ret += static_cast<char>(toupper(*s));
- ret += "]";
+ ret += ']';
}
s++;
}
@@ -1063,8 +1064,8 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1117,8 +1118,8 @@ void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item)
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1137,7 +1138,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// Check if this item is in an implicit link directory.
std::string dir = cmSystemTools::GetFilenamePath(item);
- if (!cmContains(this->ImplicitLinkDirs, dir)) {
+ if (!cm::contains(this->ImplicitLinkDirs, dir)) {
// Only libraries in implicit link directories are converted to
// pathless items.
return false;
@@ -1200,7 +1201,8 @@ void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
// CMP0003 so put it in OldUserFlagItems, if it is not a -l
// or -Wl,-l (-framework -pthread), then allow it without a
// CMP0003 as -L will not affect those other linker flags
- if (item.Value.find("-l") == 0 || item.Value.find("-Wl,-l") == 0) {
+ if (cmHasLiteralPrefix(item.Value, "-l") ||
+ cmHasLiteralPrefix(item.Value, "-Wl,-l")) {
// This is a linker option provided by the user.
this->OldUserFlagItems.push_back(item.Value);
}
@@ -1439,7 +1441,6 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
}
case cmPolicies::OLD:
// OLD behavior does not warn.
- break;
case cmPolicies::NEW:
// NEW behavior will not get here.
break;
@@ -1796,11 +1797,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// support or if using the link path as an rpath.
if (use_build_rpath) {
std::string d = ri;
- if (!rootPath.empty() && d.find(rootPath) == 0) {
- d = d.substr(rootPath.size());
- } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
- std::string suffix = d.substr(strlen(stagePath));
- d = cmStrCat(installPrefix, '/', suffix);
+ if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+ d.erase(0, rootPath.size());
+ } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+ d.erase(0, strlen(stagePath));
+ d = cmStrCat(installPrefix, '/', d);
cmSystemTools::ConvertToUnixSlashes(d);
} else if (use_relative_build_rpath) {
// If expansion of the $ORIGIN token is supported and permitted per
@@ -1827,11 +1828,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
!cmSystemTools::IsSubDirectory(ri, topSourceDir) &&
!cmSystemTools::IsSubDirectory(ri, topBinaryDir)) {
std::string d = ri;
- if (!rootPath.empty() && d.find(rootPath) == 0) {
- d = d.substr(rootPath.size());
- } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
- std::string suffix = d.substr(strlen(stagePath));
- d = cmStrCat(installPrefix, '/', suffix);
+ if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+ d.erase(0, rootPath.size());
+ } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+ d.erase(0, strlen(stagePath));
+ d = cmStrCat(installPrefix, '/', d);
cmSystemTools::ConvertToUnixSlashes(d);
}
if (emitted.insert(d).second) {
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index a98a608..41f5346 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -198,6 +198,20 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
std::vector<std::string> const& configs =
depender->Makefile->GetGeneratorConfigs();
for (std::string const& it : configs) {
+ cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
+
+ // A target should not depend on itself.
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
+ for (cmLinkImplItem const& lib : impl->Libraries) {
+ // Don't emit the same library twice for this target.
+ if (emitted.insert(lib).second) {
+ this->AddTargetDepend(depender_index, lib, true, false);
+ this->AddInterfaceDepends(depender_index, lib, it, emitted);
+ }
+ }
+
+ // Add dependencies on object libraries not otherwise handled above.
std::vector<cmSourceFile const*> objectFiles;
depender->GetExternalObjects(objectFiles, it);
for (cmSourceFile const* o : objectFiles) {
@@ -222,19 +236,6 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
}
}
}
-
- cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
-
- // A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
- emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
- for (cmLinkImplItem const& lib : impl->Libraries) {
- // Don't emit the same library twice for this target.
- if (emitted.insert(lib).second) {
- this->AddTargetDepend(depender_index, lib, true, false);
- this->AddInterfaceDepends(depender_index, lib, it, emitted);
- }
- }
}
}
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index fda687f..7a3a3e8 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -13,7 +13,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
@@ -494,12 +493,12 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
if (this->IsKeyword(keyDEFINED, *arg) && argP1 != newArgs.end()) {
size_t argP1len = argP1->GetValue().size();
bool bdef = false;
- if (argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+ if (argP1len > 4 && cmHasLiteralPrefix(argP1->GetValue(), "ENV{") &&
argP1->GetValue().operator[](argP1len - 1) == '}') {
std::string env = argP1->GetValue().substr(4, argP1len - 5);
bdef = cmSystemTools::HasEnv(env);
} else if (argP1len > 6 &&
- argP1->GetValue().substr(0, 6) == "CACHE{" &&
+ cmHasLiteralPrefix(argP1->GetValue(), "CACHE{") &&
argP1->GetValue().operator[](argP1len - 1) == '}') {
std::string cache = argP1->GetValue().substr(6, argP1len - 7);
bdef =
@@ -673,7 +672,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
if (def2) {
std::vector<std::string> list = cmExpandedList(def2, true);
- result = cmContains(list, def);
+ result = cm::contains(list, def);
}
this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 8767386..bac9337 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -2,6 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConfigureFileCommand.h"
+#include <set>
+
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -56,6 +62,18 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
bool copyOnly = false;
bool escapeQuotes = false;
+ static std::set<cm::string_view> noopOptions = {
+ /* Legacy. */
+ "IMMEDIATE"_s,
+ /* Handled by NewLineStyle member. */
+ "NEWLINE_STYLE"_s,
+ "LF"_s,
+ "UNIX"_s,
+ "CRLF"_s,
+ "WIN32"_s,
+ "DOS"_s,
+ };
+
std::string unknown_args;
bool atOnly = false;
for (unsigned int i = 2; i < args.size(); ++i) {
@@ -70,12 +88,8 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
escapeQuotes = true;
} else if (args[i] == "@ONLY") {
atOnly = true;
- } else if (args[i] == "IMMEDIATE") {
- /* Ignore legacy option. */
- } 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 if (noopOptions.find(args[i]) != noopOptions.end()) {
+ /* Ignore no-op options. */
} else {
unknown_args += " ";
unknown_args += args[i];
diff --git a/Source/cmConvertMSBuildXMLToJSON.py b/Source/cmConvertMSBuildXMLToJSON.py
index 02074ba..2be3781 100644
--- a/Source/cmConvertMSBuildXMLToJSON.py
+++ b/Source/cmConvertMSBuildXMLToJSON.py
@@ -35,12 +35,14 @@ def vsflags(*args):
return values
-def read_msbuild_xml(path, values={}):
+def read_msbuild_xml(path, values=None):
"""Reads the MS Build XML file at the path and returns its contents.
Keyword arguments:
values -- The map to append the contents to (default {})
"""
+ if values is None:
+ values = {}
# Attempt to read the file contents
try:
@@ -76,12 +78,15 @@ def read_msbuild_xml(path, values={}):
return values
-def read_msbuild_json(path, values=[]):
+def read_msbuild_json(path, values=None):
"""Reads the MS Build JSON file at the path and returns its contents.
Keyword arguments:
values -- The list to append the contents to (default [])
"""
+ if values is None:
+ values = []
+
if not os.path.exists(path):
logging.info('Could not find MS Build JSON file at %s', path)
return values
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index da04396..dc2df14 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -40,6 +40,10 @@ static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
"CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
"CMAKE_CXX_LINK_PIE_SUPPORTED";
+static std::string const kCMAKE_CUDA_ARCHITECTURES =
+ "CMAKE_CUDA_ARCHITECTURES";
+static std::string const kCMAKE_CUDA_COMPILER_TARGET =
+ "CMAKE_CUDA_COMPILER_TARGET";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
@@ -101,29 +105,23 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
this->SrcFileSignature = true;
cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
- const char* tt =
- this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
- if (!isTryRun && tt && *tt) {
- if (strcmp(tt, cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) ==
- 0) {
+ const std::string* tt =
+ this->Makefile->GetDef("CMAKE_TRY_COMPILE_TARGET_TYPE");
+ if (!isTryRun && tt && !tt->empty()) {
+ if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
targetType = cmStateEnums::EXECUTABLE;
- } else if (strcmp(tt,
- cmState::GetTargetTypeName(
- cmStateEnums::STATIC_LIBRARY)) == 0) {
+ } else if (*tt ==
+ cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
targetType = cmStateEnums::STATIC_LIBRARY;
} else {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- std::string("Invalid value '") + tt +
- "' for "
- "CMAKE_TRY_COMPILE_TARGET_TYPE. Only "
- "'" +
- cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE) +
- "' and "
- "'" +
- cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY) +
- "' "
- "are allowed.");
+ cmStrCat("Invalid value '", *tt,
+ "' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only '",
+ cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE),
+ "' and '",
+ cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY),
+ "' are allowed."));
return -1;
}
}
@@ -296,12 +294,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
default:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- "Only libraries may be used as try_compile or try_run IMPORTED "
- "LINK_LIBRARIES. Got " +
- std::string(tgt->GetName()) +
- " of "
- "type " +
- cmState::GetTargetTypeName(tgt->GetType()) + ".");
+ cmStrCat("Only libraries may be used as try_compile or try_run "
+ "IMPORTED LINK_LIBRARIES. Got ",
+ tgt->GetName(), " of type ",
+ cmState::GetTargetTypeName(tgt->GetType()), "."));
return -1;
}
if (tgt->IsImported()) {
@@ -719,6 +715,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_C_COMPILER_TARGET);
vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+ vars.insert(kCMAKE_CUDA_ARCHITECTURES);
+ vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
vars.insert(kCMAKE_ENABLE_EXPORTS);
vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
vars.insert(kCMAKE_LINK_SEARCH_START_STATIC);
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 0dd8722..149f5e9 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -11,7 +11,8 @@ cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs,
std::vector<std::string> depends,
cmCustomCommandLines commandLines,
cmListFileBacktrace lfbt, const char* comment,
- const char* workingDirectory)
+ const char* workingDirectory,
+ bool stdPipesUTF8)
: Outputs(std::move(outputs))
, Byproducts(std::move(byproducts))
, Depends(std::move(depends))
@@ -20,6 +21,7 @@ cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs,
, Comment(comment ? comment : "")
, WorkingDirectory(workingDirectory ? workingDirectory : "")
, HaveComment(comment != nullptr)
+ , StdPipesUTF8(stdPipesUTF8)
{
}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index d300fa5..aa572ad 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -30,7 +30,8 @@ public:
std::vector<std::string> byproducts,
std::vector<std::string> depends,
cmCustomCommandLines commandLines, cmListFileBacktrace lfbt,
- const char* comment, const char* workingDirectory);
+ const char* comment, const char* workingDirectory,
+ bool stdPipesUTF8);
/** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const;
@@ -53,6 +54,9 @@ public:
/** Get the comment string for the command. */
const char* GetComment() const;
+ /** Get a value indicating if the command uses UTF-8 output pipes. */
+ bool GetStdPipesUTF8() const { return this->StdPipesUTF8; }
+
/** Append to the list of command lines. */
void AppendCommands(const cmCustomCommandLines& commandLines);
@@ -108,6 +112,7 @@ private:
bool EscapeOldStyle = true;
bool UsesTerminal = false;
bool CommandExpandLists = false;
+ bool StdPipesUTF8 = false;
};
#endif
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index f4e4fda..4e2d9b0 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -95,7 +95,7 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
// Actually define the property.
status.GetMakefile().GetState()->DefineProperty(
- PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited);
+ PropertyName, scope, BriefDocs, FullDocs, inherited);
return true;
}
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 129a5f7..d8aa730 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDepends.h"
-#include <sstream>
#include <utility>
#include "cmsys/FStream.hxx"
@@ -10,12 +9,12 @@
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-cmDepends::cmDepends(cmLocalGenerator* lg, std::string targetDir)
+cmDepends::cmDepends(cmLocalUnixMakefileGenerator3* lg, std::string targetDir)
: LocalGenerator(lg)
, TargetDirectory(std::move(targetDir))
{
@@ -81,16 +80,14 @@ void cmDepends::Clear(const std::string& file)
{
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ cmStrCat("Clearing dependencies in \"", file, "\".\n"));
}
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(file);
depFileStream << "# Empty dependencies file\n"
- << "# This may be replaced when dependencies are built."
- << std::endl;
+ "# This may be replaced when dependencies are built.\n";
}
bool cmDepends::WriteDependencies(const std::set<std::string>& /*unused*/,
@@ -172,10 +169,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee << "\" does not exist for depender \""
- << depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" does not exist for depender \"",
+ depender, "\".\n"));
}
} else if (dependerExists) {
// The dependee and depender both exist. Compare file times.
@@ -185,10 +181,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee << "\" is newer than depender \""
- << depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" is newer than depender \"",
+ depender, "\".\n"));
}
}
} else {
@@ -200,11 +195,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee
- << "\" is newer than depends file \"" << internalDependsFileName
- << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" is newer than depends file \"",
+ internalDependsFileName, "\".\n"));
}
}
}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d938775..8cf528f 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
#include <vector>
class cmFileTimeCache;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDepends
* \brief Dependency scanner superclass.
@@ -29,7 +29,8 @@ public:
public:
/** Instances need to know the build directory name and the relative
path from the build directory to the target file. */
- cmDepends(cmLocalGenerator* lg = nullptr, std::string targetDir = "");
+ cmDepends(cmLocalUnixMakefileGenerator3* lg = nullptr,
+ std::string targetDir = "");
cmDepends(cmDepends const&) = delete;
cmDepends& operator=(cmDepends const&) = delete;
@@ -38,7 +39,10 @@ public:
scanning dependencies. This is not a full local generator; it
has been setup to do relative path conversions for the current
directory. */
- void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
+ void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
+ {
+ this->LocalGenerator = lg;
+ }
/** Set the specific language to be scanned. */
void SetLanguage(const std::string& lang) { this->Language = lang; }
@@ -92,7 +96,7 @@ protected:
std::ostream& internalDepends);
// The local generator.
- cmLocalGenerator* LocalGenerator;
+ cmLocalUnixMakefileGenerator3* LocalGenerator;
// Flag for verbose output.
bool Verbose = false;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index e30d959..4499a66 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -7,7 +7,7 @@
#include "cmsys/FStream.hxx"
#include "cmFileTime.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -22,8 +22,9 @@
cmDependsC::cmDependsC() = default;
-cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
- const std::string& lang, const DependencyMap* validDeps)
+cmDependsC::cmDependsC(cmLocalUnixMakefileGenerator3* lg,
+ const std::string& targetDir, const std::string& lang,
+ const DependencyMap* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
{
@@ -211,18 +212,18 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
- internalDepends << obj_i << std::endl;
+ std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i);
+ internalDepends << obj_i << '\n';
for (std::string const& dep : dependencies) {
makeDepends << obj_m << ": "
- << cmSystemTools::ConvertToOutputPath(
+ << this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir,
dep))
- << std::endl;
- internalDepends << " " << dep << std::endl;
+ << '\n';
+ internalDepends << ' ' << dep << '\n';
}
- makeDepends << std::endl;
+ makeDepends << '\n';
return true;
}
@@ -264,19 +265,19 @@ void cmDependsC::ReadCacheFile()
// file doesn't exist, check that the regular expressions
// haven't changed
else if (!res) {
- if (line.find(INCLUDE_REGEX_LINE_MARKER) == 0) {
+ if (cmHasLiteralPrefix(line, INCLUDE_REGEX_LINE_MARKER)) {
if (line != this->IncludeRegexLineString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_SCAN_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_SCAN_MARKER)) {
if (line != this->IncludeRegexScanString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_COMPLAIN_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_COMPLAIN_MARKER)) {
if (line != this->IncludeRegexComplainString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_TRANSFORM_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_TRANSFORM_MARKER)) {
if (line != this->IncludeRegexTransformString) {
return;
}
@@ -312,17 +313,17 @@ void cmDependsC::WriteCacheFile() const
for (auto const& fileIt : this->FileCache) {
if (fileIt.second.Used) {
- cacheOut << fileIt.first << std::endl;
+ cacheOut << fileIt.first << '\n';
for (UnscannedEntry const& inc : fileIt.second.UnscannedEntries) {
- cacheOut << inc.FileName << std::endl;
+ cacheOut << inc.FileName << '\n';
if (inc.QuotedLocation.empty()) {
- cacheOut << "-" << std::endl;
+ cacheOut << '-' << '\n';
} else {
- cacheOut << inc.QuotedLocation << std::endl;
+ cacheOut << inc.QuotedLocation << '\n';
}
}
- cacheOut << std::endl;
+ cacheOut << '\n';
}
}
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 868c94a..e01faa4 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -16,7 +16,7 @@
#include "cmDepends.h"
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsC
* \brief Dependency scanner for C and C++ object files.
@@ -27,7 +27,7 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
- cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
+ cmDependsC(cmLocalUnixMakefileGenerator3* lg, const std::string& targetDir,
const std::string& lang, const DependencyMap* validDeps);
/** Virtual destructor to cleanup subclasses properly. */
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 3692202..95dfc4e 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -12,7 +12,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
@@ -29,12 +29,10 @@ static void cmFortranModuleAppendUpperLower(std::string const& mod,
std::string& mod_lower)
{
std::string::size_type ext_len = 0;
- if (cmHasLiteralSuffix(mod, ".mod")) {
+ if (cmHasLiteralSuffix(mod, ".mod") || cmHasLiteralSuffix(mod, ".sub")) {
ext_len = 4;
} else if (cmHasLiteralSuffix(mod, ".smod")) {
ext_len = 5;
- } else if (cmHasLiteralSuffix(mod, ".sub")) {
- ext_len = 4;
}
std::string const& name = mod.substr(0, mod.size() - ext_len);
std::string const& ext = mod.substr(mod.size() - ext_len);
@@ -72,7 +70,7 @@ public:
cmDependsFortran::cmDependsFortran() = default;
-cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
+cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
: cmDepends(lg)
, Internal(new cmDependsFortranInternals)
{
@@ -102,10 +100,7 @@ cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
this->SModExt = mf->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
}
-cmDependsFortran::~cmDependsFortran()
-{
- delete this->Internal;
-}
+cmDependsFortran::~cmDependsFortran() = default;
bool cmDependsFortran::WriteDependencies(const std::set<std::string>& sources,
const std::string& obj,
@@ -188,7 +183,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
fiStream << "provides\n";
std::set<std::string> const& provides = this->Internal->TargetProvides;
for (std::string const& i : provides) {
- fiStream << " " << i << "\n";
+ fiStream << ' ' << i << '\n';
}
// Create a script to clean the modules.
@@ -205,14 +200,14 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
std::string mod_lower = cmStrCat(mod_dir, '/');
cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower);
std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp");
- fcStream << "\n";
- fcStream << " \""
+ fcStream << "\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
- << "\"\n";
- fcStream << " \""
+ << "\"\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_upper)
- << "\"\n";
- fcStream << " \""
+ << "\"\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, stamp)
<< "\"\n";
}
@@ -329,16 +324,15 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
- internalDepends << obj_i << std::endl;
- internalDepends << " " << src << std::endl;
+ internalDepends << obj_i << "\n " << src << '\n';
for (std::string const& i : info.Includes) {
makeDepends << obj_m << ": "
<< cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, i))
- << std::endl;
- internalDepends << " " << i << std::endl;
+ << '\n';
+ internalDepends << ' ' << i << '\n';
}
- makeDepends << std::endl;
+ makeDepends << '\n';
// Write module requirements to the output stream.
for (std::string const& i : info.Requires) {
@@ -357,7 +351,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// This module is known. Depend on its timestamp file.
std::string stampFile = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, required->second));
- makeDepends << obj_m << ": " << stampFile << "\n";
+ makeDepends << obj_m << ": " << stampFile << '\n';
} else {
// This module is not known to CMake. Try to locate it where
// the compiler will and depend on that.
@@ -365,7 +359,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
if (this->FindModule(i, module)) {
module = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, module));
- makeDepends << obj_m << ": " << module << "\n";
+ makeDepends << obj_m << ": " << module << '\n';
}
}
}
@@ -394,7 +388,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
cmSystemTools::ConvertToOutputPath(stampFile);
makeDepends << obj_m << ".provides.build"
- << ": " << stampFileForMake << "\n";
+ << ": " << stampFileForMake << '\n';
// Note that when cmake_copy_f90_mod finds that a module file
// and the corresponding stamp file have no differences, the stamp
// file is not updated. In such case the stamp file will be always
@@ -402,15 +396,15 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// on each new build. This is expected behavior for incremental
// builds and can not be changed without preforming recursive make
// calls that would considerably slow down the building process.
- makeDepends << stampFileForMake << ": " << obj_m << "\n";
+ makeDepends << stampFileForMake << ": " << obj_m << '\n';
makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile
- << " " << stampFileForShell;
+ << ' ' << stampFileForShell;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
if (cid && *cid) {
- makeDepends << " " << cid;
+ makeDepends << ' ' << cid;
}
- makeDepends << "\n";
+ makeDepends << '\n';
}
makeDepends << obj_m << ".provides.build:\n";
// After copying the modules update the timestamp file.
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 0485115..3e306dd 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -14,7 +15,7 @@
class cmDependsFortranInternals;
class cmFortranSourceInfo;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsFortran
* \brief Dependency scanner for Fortran object files.
@@ -30,7 +31,7 @@ public:
path from the build directory to the target file, the source
file from which to start scanning, the include file search
path, and the target directory. */
- cmDependsFortran(cmLocalGenerator* lg);
+ cmDependsFortran(cmLocalUnixMakefileGenerator3* lg);
/** Virtual destructor to cleanup subclasses properly. */
~cmDependsFortran() override;
@@ -84,7 +85,7 @@ protected:
std::set<std::string> PPDefinitions;
// Internal implementation details.
- cmDependsFortranInternals* Internal = nullptr;
+ std::unique_ptr<cmDependsFortranInternals> Internal;
private:
std::string MaybeConvertToRelativePath(std::string const& base,
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 516bbbf..fc1bbdd 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -8,6 +8,7 @@
#include <iostream>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
#include "cmsys/FStream.hxx"
@@ -169,10 +170,11 @@ void cmDependsJavaParserHelper::AllocateParserType(
return;
}
this->UnionsAvailable++;
- pt->str = new char[len + 1];
+ auto up = cm::make_unique<char[]>(len + 1);
+ pt->str = up.get();
strncpy(pt->str, str, len);
pt->str[len] = 0;
- this->Allocates.push_back(pt->str);
+ this->Allocates.push_back(std::move(up));
}
void cmDependsJavaParserHelper::StartClass(const char* cls)
@@ -275,10 +277,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
void cmDependsJavaParserHelper::CleanupParser()
{
- for (char* allocate : this->Allocates) {
- delete[] allocate;
- }
- this->Allocates.erase(this->Allocates.begin(), this->Allocates.end());
+ this->Allocates.clear();
}
int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
index a673b5b..c545ee2 100644
--- a/Source/cmDependsJavaParserHelper.h
+++ b/Source/cmDependsJavaParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -81,7 +82,7 @@ private:
int CurrentDepth;
int Verbose;
- std::vector<char*> Allocates;
+ std::vector<std::unique_ptr<char[]>> Allocates;
void PrintClasses();
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 0b72a94..a3731c1 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -6,6 +6,7 @@
#include <string>
#include <utility>
+namespace {
class cmDynamicLoaderCache
{
public:
@@ -15,14 +16,15 @@ public:
cmsys::DynamicLoader::LibraryHandle& /*p*/);
bool FlushCache(const char* path);
void FlushCache();
- static cmDynamicLoaderCache* GetInstance();
+ static cmDynamicLoaderCache& GetInstance();
private:
std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap;
- static cmDynamicLoaderCache* Instance;
+ static cmDynamicLoaderCache Instance;
};
-cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr;
+cmDynamicLoaderCache cmDynamicLoaderCache::Instance;
+}
cmDynamicLoaderCache::~cmDynamicLoaderCache() = default;
@@ -64,15 +66,11 @@ void cmDynamicLoaderCache::FlushCache()
for (auto const& it : this->CacheMap) {
cmsys::DynamicLoader::CloseLibrary(it.second);
}
- delete cmDynamicLoaderCache::Instance;
- cmDynamicLoaderCache::Instance = nullptr;
+ this->CacheMap.clear();
}
-cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance()
+cmDynamicLoaderCache& cmDynamicLoaderCache::GetInstance()
{
- if (!cmDynamicLoaderCache::Instance) {
- cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache;
- }
return cmDynamicLoaderCache::Instance;
}
@@ -80,15 +78,15 @@ cmsys::DynamicLoader::LibraryHandle cmDynamicLoader::OpenLibrary(
const char* libname)
{
cmsys::DynamicLoader::LibraryHandle lh;
- if (cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh)) {
+ if (cmDynamicLoaderCache::GetInstance().GetCacheFile(libname, lh)) {
return lh;
}
lh = cmsys::DynamicLoader::OpenLibrary(libname);
- cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh);
+ cmDynamicLoaderCache::GetInstance().CacheFile(libname, lh);
return lh;
}
void cmDynamicLoader::FlushCache()
{
- cmDynamicLoaderCache::GetInstance()->FlushCache();
+ cmDynamicLoaderCache::GetInstance().FlushCache();
}
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 5be5bce..08a0f7e 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -61,6 +61,8 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
bool ErrorQuiet = false;
bool OutputStripTrailingWhitespace = false;
bool ErrorStripTrailingWhitespace = false;
+ bool EchoOutputVariable = false;
+ bool EchoErrorVariable = false;
std::string Encoding;
};
@@ -83,7 +85,9 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
&Arguments::OutputStripTrailingWhitespace)
.Bind("ERROR_STRIP_TRAILING_WHITESPACE"_s,
&Arguments::ErrorStripTrailingWhitespace)
- .Bind("ENCODING"_s, &Arguments::Encoding);
+ .Bind("ENCODING"_s, &Arguments::Encoding)
+ .Bind("ECHO_OUTPUT_VARIABLE"_s, &Arguments::EchoOutputVariable)
+ .Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable);
std::vector<std::string> unparsedArguments;
std::vector<std::string> keywordsMissingValue;
@@ -241,28 +245,32 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
// Put the output in the right place.
if (p == cmsysProcess_Pipe_STDOUT && !arguments.OutputQuiet) {
- if (arguments.OutputVariable.empty()) {
+ if (arguments.OutputVariable.empty() || arguments.EchoOutputVariable) {
processOutput.DecodeText(data, length, strdata, 1);
cmSystemTools::Stdout(strdata);
- } else {
+ }
+ if (!arguments.OutputVariable.empty()) {
cmExecuteProcessCommandAppend(tempOutput, data, length);
}
} else if (p == cmsysProcess_Pipe_STDERR && !arguments.ErrorQuiet) {
- if (arguments.ErrorVariable.empty()) {
+ if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
processOutput.DecodeText(data, length, strdata, 2);
cmSystemTools::Stderr(strdata);
- } else {
+ }
+ if (!arguments.ErrorVariable.empty()) {
cmExecuteProcessCommandAppend(tempError, data, length);
}
}
}
- if (!arguments.OutputQuiet && arguments.OutputVariable.empty()) {
+ if (!arguments.OutputQuiet &&
+ (arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
cmSystemTools::Stdout(strdata);
}
}
- if (!arguments.ErrorQuiet && arguments.ErrorVariable.empty()) {
+ if (!arguments.ErrorQuiet &&
+ (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable)) {
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
cmSystemTools::Stderr(strdata);
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 561e830..0ee1259 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -5,7 +5,8 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmMakefile.h"
@@ -118,13 +119,13 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
} else {
bool relpath = false;
if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
- relpath = lib.substr(0, 3) == "../";
+ relpath = cmHasLiteralPrefix(lib, "../");
}
// check for full path or if it already has a -l, or
// in the case of an install check for relative paths
// if it is full or a link library then use string directly
if (cmSystemTools::FileIsFullPath(lib) ||
- lib.substr(0, 2) == "-l" || relpath) {
+ cmHasLiteralPrefix(lib, "-l") || relpath) {
ldlibs += " " + lib;
// if it is not a path and does not have a -l then add -l
} else if (!lib.empty()) {
@@ -165,7 +166,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
// Tell the NDK build system if prebuilt static libraries use C++.
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
cmLinkImplementation const* li = target->GetLinkImplementation(config);
- if (cmContains(li->Languages, "CXX")) {
+ if (cm::contains(li->Languages, "CXX")) {
os << "LOCAL_HAS_CPP := true\n";
}
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index d22bd48..dd700c5 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -8,7 +8,8 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -307,7 +308,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
const auto& exportSet = exp.second;
std::vector<std::string> targets;
exportSet->GetTargets(targets);
- if (cmContains(targets, name)) {
+ if (cm::contains(targets, name)) {
exportFiles.push_back(exp.first);
ns = exportSet->GetNamespace();
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index e49c174..ad632ee 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -7,12 +7,12 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportBuildAndroidMKGenerator.h"
@@ -24,6 +24,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -146,7 +147,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
exportSet = &it->second;
} else if (!arguments.Targets.empty() ||
- cmContains(keywordsMissingValue, "TARGETS")) {
+ cm::contains(keywordsMissingValue, "TARGETS")) {
for (std::string const& currentTarget : arguments.Targets) {
if (mf.IsAlias(currentTarget)) {
std::ostringstream e;
@@ -183,6 +184,28 @@ bool cmExportCommand(std::vector<std::string> const& args,
return false;
}
+ // if cmExportBuildFileGenerator is already defined for the file
+ // and APPEND is not specified, if CMP0103 is OLD ignore previous definition
+ // else raise an error
+ if (gg->GetExportedTargetsFile(fname) != nullptr) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
+ case cmPolicies::WARN:
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103), '\n',
+ "export() command already specified for the file\n ",
+ arguments.Filename, "\nDid you miss 'APPEND' keyword?"));
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ default:
+ status.SetError(cmStrCat("command already specified for the file\n ",
+ arguments.Filename,
+ "\nDid you miss 'APPEND' keyword?"));
+ return false;
+ }
+ }
+
// Setup export file generation.
std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
if (android) {
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 6441e6f..ea31417 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -276,8 +276,7 @@ static bool checkInterfaceDirs(const std::string& prepro,
<< "\"\nhowever it is also "
"a subdirectory of the "
<< (inBinary ? "build" : "source") << " tree:\n \""
- << (inBinary ? topBinaryDir : topSourceDir) << "\""
- << std::endl;
+ << (inBinary ? topBinaryDir : topSourceDir) << "\"\n";
target->GetLocalGenerator()->IssueMessage(
MessageType::AUTHOR_WARNING, s.str());
CM_FALLTHROUGH;
@@ -1116,7 +1115,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(
return;
}
/* clang-format off */
- os << "# Make sure the targets which have been exported in some other \n"
+ os << "# Make sure the targets which have been exported in some other\n"
"# export set exist.\n"
"unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
"foreach(_target ";
@@ -1215,9 +1214,9 @@ bool cmExportFileGenerator::PopulateExportProperties(
std::string& errorMessage)
{
auto& targetProperties = gte->Target->GetProperties();
- if (const char* exportProperties =
+ if (cmProp exportProperties =
targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
- for (auto& prop : cmExpandedList(exportProperties)) {
+ for (auto& prop : cmExpandedList(*exportProperties)) {
/* Black list reserved properties */
if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
cmHasLiteralPrefix(prop, "INTERFACE_")) {
@@ -1228,15 +1227,15 @@ bool cmExportFileGenerator::PopulateExportProperties(
errorMessage = e.str();
return false;
}
- auto propertyValue = targetProperties.GetPropertyValue(prop);
+ cmProp propertyValue = targetProperties.GetPropertyValue(prop);
if (propertyValue == nullptr) {
// Asked to export a property that isn't defined on the target. Do not
// consider this an error, there's just nothing to export.
continue;
}
std::string evaluatedValue = cmGeneratorExpression::Preprocess(
- propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
- if (evaluatedValue != propertyValue) {
+ *propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
+ if (evaluatedValue != *propertyValue) {
std::ostringstream e;
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
<< prop << "\" in EXPORT_PROPERTIES but this property contains a "
@@ -1244,7 +1243,7 @@ bool cmExportFileGenerator::PopulateExportProperties(
errorMessage = e.str();
return false;
}
- properties[prop] = propertyValue;
+ properties[prop] = *propertyValue;
}
}
return true;
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 9702e0e..80f776e 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -66,7 +66,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode(
os << "LOCAL_MODULE := ";
os << targetName << "\n";
os << "LOCAL_SRC_FILES := $(_IMPORT_PREFIX)/";
- os << target->Target->GetProperty("__dest") << "/";
+ os << target->Target->GetSafeProperty("__dest") << "/";
std::string config;
if (!this->Configurations.empty()) {
config = this->Configurations[0];
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 6011ba4..be63278 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -23,6 +23,8 @@
class cmListFileBacktrace;
+using cmProp = const std::string*;
+
static void FinalAction(cmMakefile& makefile, std::string const& filename,
bool append)
{
@@ -95,8 +97,8 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename,
// Handle simple output name changes. This command is
// deprecated so we do not support full target name
// translation (which requires per-configuration info).
- if (const char* outname = libtgt->GetProperty("OUTPUT_NAME")) {
- lib = outname;
+ if (cmProp outname = libtgt->GetProperty("OUTPUT_NAME")) {
+ lib = *outname;
}
}
valueOld += lib;
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 3df6a5c..807ebed 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -97,9 +97,9 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
properties[p] = target->GetProperty(p);
- if (p.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
- p.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0 ||
- p.find("INTERFACE_LINK_LIBRARIES") == 0) {
+ if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") ||
+ cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") ||
+ cmHasLiteralPrefix(p, "INTERFACE_LINK_LIBRARIES")) {
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index b710467..42fd0ea 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -218,7 +218,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Convert
for (std::string const& listFile : listFiles) {
// don't put cmake's own files into the project (#12110):
- if (listFile.find(cmSystemTools::GetCMakeRoot()) == 0) {
+ if (cmHasPrefix(listFile, cmSystemTools::GetCMakeRoot())) {
continue;
}
@@ -301,11 +301,11 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index de40c77..bf7555d 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -204,9 +204,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
case cmStateEnums::STATIC_LIBRARY: {
projectType = "Static Library";
} break;
- case cmStateEnums::SHARED_LIBRARY: {
- projectType = "Dynamic Library";
- } break;
+ case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
projectType = "Dynamic Library";
} break;
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 78cabce..b65f097 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -187,10 +187,10 @@ void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
return;
}
- fout << "eclipse.preferences.version=1" << std::endl;
+ fout << "eclipse.preferences.version=1\n";
const char* encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING");
if (encoding) {
- fout << "encoding/<project>=" << encoding << std::endl;
+ fout << "encoding/<project>=" << encoding << '\n';
}
}
@@ -255,8 +255,8 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
// The variable is in the env, but not in the cache. Use it and put it
// in the cache
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
- cacheEntryName.c_str(), cmStateEnums::STRING, true);
+ mf->AddCacheDefinition(cacheEntryName, valueToUse, cacheEntryName.c_str(),
+ cmStateEnums::STRING, true);
mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
} else if (!envVarSet && cacheValue != nullptr) {
// It is already in the cache, but not in the env, so use it from the cache
@@ -270,7 +270,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
valueToUse = *cacheValue;
if (valueToUse.find(envVarValue) == std::string::npos) {
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+ mf->AddCacheDefinition(cacheEntryName, valueToUse,
cacheEntryName.c_str(), cmStateEnums::STRING,
true);
mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
@@ -415,9 +415,9 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
xml.Element("nature", n);
}
- if (const char* extraNaturesProp =
+ if (cmProp extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp);
+ std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp);
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -754,11 +754,11 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
emmited.clear();
for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
- if (const char* cdefs =
+ if (cmProp cdefs =
lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
std::vector<std::string> defs;
- cmGeneratorExpression::Split(cdefs, defs);
+ cmGeneratorExpression::Split(*cdefs, defs);
for (std::string const& d : defs) {
if (cmGeneratorExpression::Find(d) != std::string::npos) {
@@ -936,11 +936,11 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -981,7 +981,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
}
} break;
case cmStateEnums::INTERFACE_LIBRARY:
- break;
default:
break;
}
@@ -1033,9 +1032,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
xml.EndElement(); // storageModule
// Append additional cproject contents without applying any XML formatting
- if (const char* extraCProjectContents =
+ if (cmProp extraCProjectContents =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) {
- fout << extraCProjectContents;
+ fout << *extraCProjectContents;
}
xml.EndElement(); // cproject
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index 3a22846..01fac5a 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -129,9 +129,8 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
if (targetName == "edit_cache") {
const char* editCommand =
localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND");
- if (editCommand == nullptr) {
- insertTarget = false;
- } else if (strstr(editCommand, "ccmake") != nullptr) {
+ if (editCommand == nullptr ||
+ strstr(editCommand, "ccmake") != nullptr) {
insertTarget = false;
}
}
@@ -144,11 +143,11 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -274,7 +273,7 @@ std::string cmExtraKateGenerator::GenerateProjectName(
const std::string& name, const std::string& type,
const std::string& path) const
{
- return name + (type.empty() ? "" : "-") + type + "@" + path;
+ return name + (type.empty() ? "" : "-") + type + '@' + path;
}
std::string cmExtraKateGenerator::GetPathBasename(
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 413449c..6dbc7b7 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -23,6 +23,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
+using cmProp = const std::string*; // just to silence IWYU
+
/*
Sublime Text 2 Generator
Author: Morné Chamberlain
@@ -199,11 +201,11 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -358,14 +360,14 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
return flags;
@@ -387,17 +389,17 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
// Add preprocessor definitions for this target and configuration.
lg->GetTargetDefines(target, config, language, defines);
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
lg->AppendDefines(
- defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
}
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
lg->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
}
std::string definesString;
@@ -419,9 +421,9 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
// Add include directories for this source file
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
lg->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*source);
}
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index ef77795..5d2ddf9 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -67,7 +67,7 @@ Json::Value Cache::DumpEntry(std::string const& name)
entry["name"] = name;
entry["type"] =
cmState::CacheEntryTypeToString(this->State->GetCacheEntryType(name));
- entry["value"] = this->State->GetCacheEntryValue(name);
+ entry["value"] = this->State->GetSafeCacheEntryValue(name);
Json::Value properties = this->DumpEntryProperties(name);
if (!properties.empty()) {
@@ -94,7 +94,8 @@ Json::Value Cache::DumpEntryProperty(std::string const& name,
{
Json::Value property = Json::objectValue;
property["name"] = prop;
- property["value"] = this->State->GetCacheEntryProperty(name, prop);
+ cmProp p = this->State->GetCacheEntryProperty(name, prop);
+ property["value"] = p ? *p : "";
return property;
}
}
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 955195f..f4237cb 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -855,8 +855,8 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
fd.Language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
- std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+ std::string flags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
fd.Flags.emplace_back(std::move(flags), JBTIndex());
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
@@ -872,14 +872,27 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
}
// Add precompile headers compile options.
- const std::string pchSource =
- this->GT->GetPchSource(this->Config, fd.Language);
+ std::vector<std::string> architectures;
+ this->GT->GetAppleArchs(this->Config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::unordered_map<std::string, std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GT->GetPchSource(this->Config, fd.Language, arch);
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
- if (!pchSource.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (sf->ResolveFullPath() == pchSource) {
- pchOptions =
- this->GT->GetPchCreateCompileOptions(this->Config, fd.Language);
+ auto pchIt = pchSources.find(sf->ResolveFullPath());
+ if (pchIt != pchSources.end()) {
+ pchOptions = this->GT->GetPchCreateCompileOptions(
+ this->Config, fd.Language, pchIt->second);
} else {
pchOptions =
this->GT->GetPchUseCompileOptions(this->Config, fd.Language);
@@ -936,10 +949,10 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
std::set<std::string> configFileDefines;
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config);
- if (const char* config_defs = sf->GetProperty(defPropName)) {
+ if (cmProp config_defs = sf->GetProperty(defPropName)) {
lg->AppendDefines(
configFileDefines,
- genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
}
fd.Defines.reserve(fileDefines.size() + configFileDefines.size());
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index e36abdc..4ec128e 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -8,6 +8,7 @@
#include <cmath>
#include <cstdio>
#include <cstdlib>
+#include <iterator>
#include <map>
#include <set>
#include <sstream>
@@ -33,12 +34,14 @@
#include "cmFileInstaller.h"
#include "cmFileLockPool.h"
#include "cmFileTimes.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmHexFileConverter.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmNewLineStyle.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmRuntimeDependencyArchive.h"
@@ -47,6 +50,7 @@
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
@@ -1606,7 +1610,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
if (i != args.end()) {
tls_verify = cmIsOn(*i);
} else {
- status.SetError("TLS_VERIFY missing bool value.");
+ status.SetError("DOWNLOAD missing bool value for TLS_VERIFY.");
return false;
}
} else if (*i == "TLS_CAINFO") {
@@ -1614,7 +1618,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
if (i != args.end()) {
cainfo = i->c_str();
} else {
- status.SetError("TLS_CAFILE missing file value.");
+ status.SetError("DOWNLOAD missing file value for TLS_CAINFO.");
return false;
}
} else if (*i == "NETRC_FILE") {
@@ -1756,11 +1760,12 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// check to see if TLS verification is requested
if (tls_verify) {
res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
- check_curl_result(res, "Unable to set TLS/SSL Verify on: ");
+ check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify on: ");
} else {
res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
- check_curl_result(res, "Unable to set TLS/SSL Verify off: ");
+ check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify off: ");
}
+
// check to see if a CAINFO file has been specified
// command arg comes first
std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
@@ -1925,6 +1930,8 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
std::string logVar;
std::string statusVar;
bool showProgress = false;
+ bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY");
+ const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
std::string userpwd;
std::string netrc_level =
status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
@@ -1966,6 +1973,22 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
statusVar = *i;
} else if (*i == "SHOW_PROGRESS") {
showProgress = true;
+ } else if (*i == "TLS_VERIFY") {
+ ++i;
+ if (i != args.end()) {
+ tls_verify = cmIsOn(*i);
+ } else {
+ status.SetError("UPLOAD missing bool value for TLS_VERIFY.");
+ return false;
+ }
+ } else if (*i == "TLS_CAINFO") {
+ ++i;
+ if (i != args.end()) {
+ cainfo = i->c_str();
+ } else {
+ status.SetError("UPLOAD missing file value for TLS_CAINFO.");
+ return false;
+ }
} else if (*i == "NETRC_FILE") {
++i;
if (i != args.end()) {
@@ -2051,8 +2074,18 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
cmFileCommandCurlDebugCallback);
check_curl_result(res, "UPLOAD cannot set debug function: ");
- // make sure default CAInfo is set
- std::string const& cainfo_err = cmCurlSetCAInfo(curl, nullptr);
+ // check to see if TLS verification is requested
+ if (tls_verify) {
+ res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
+ check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify on: ");
+ } else {
+ res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify off: ");
+ }
+
+ // check to see if a CAINFO file has been specified
+ // command arg comes first
+ std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
if (!cainfo_err.empty()) {
status.SetError(cainfo_err);
return false;
@@ -2330,12 +2363,9 @@ bool HandleLockCommand(std::vector<std::string> const& args,
path += "/cmake.lock";
}
- if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path;
- }
-
// Unify path (remove '//', '/../', ...)
- path = cmSystemTools::CollapseFullPath(path);
+ path = cmSystemTools::CollapseFullPath(
+ path, status.GetMakefile().GetCurrentSourceDirectory());
// Create file and directories if needed
std::string parentDir = cmSystemTools::GetParentDirectory(path);
@@ -2783,6 +2813,325 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 5) {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+ if (args[1] != "OUTPUT") {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+ if (args[3] != "CONTENT") {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+
+ std::string errorMessage;
+ cmNewLineStyle newLineStyle;
+ if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
+ status.SetError(cmStrCat("CONFIGURE ", errorMessage));
+ 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 = args[2];
+
+ std::string::size_type pos = input.find_first_of("<>");
+ if (pos != std::string::npos) {
+ status.SetError(cmStrCat("CONFIGURE called with CONTENT containing a \"",
+ input[pos],
+ "\". This character is not allowed."));
+ return false;
+ }
+
+ pos = outputFile.find_first_of("<>");
+ if (pos != std::string::npos) {
+ status.SetError(cmStrCat("CONFIGURE called with OUTPUT containing a \"",
+ outputFile[pos],
+ "\". This character is not allowed."));
+ return false;
+ }
+
+ cmMakefile& makeFile = status.GetMakefile();
+ if (!makeFile.CanIWriteThisFile(outputFile)) {
+ cmSystemTools::Error("Attempt to write file: " + outputFile +
+ " into a source directory.");
+ return false;
+ }
+
+ cmSystemTools::ConvertToUnixSlashes(outputFile);
+
+ // Re-generate if non-temporary outputs are missing.
+ // when we finalize the configuration we will remove all
+ // output files that now don't exist.
+ makeFile.AddCMakeOutputFile(outputFile);
+
+ // Create output directory
+ const std::string::size_type slashPos = outputFile.rfind('/');
+ if (slashPos != std::string::npos) {
+ const std::string path = outputFile.substr(0, slashPos);
+ cmSystemTools::MakeDirectory(path);
+ }
+
+ std::string newLineCharacters;
+ bool open_with_binary_flag = false;
+ if (newLineStyle.IsValid()) {
+ open_with_binary_flag = true;
+ newLineCharacters = newLineStyle.GetCharacters();
+ }
+
+ cmGeneratedFileStream fout;
+ fout.Open(outputFile, false, open_with_binary_flag);
+ if (!fout) {
+ cmSystemTools::Error("Could not open file for write in copy operation " +
+ outputFile);
+ cmSystemTools::ReportLastSystemError("");
+ return false;
+ }
+ fout.SetCopyIfDifferent(true);
+
+ // copy intput to output and expand variables from input at the same time
+ std::stringstream sin(input, std::ios::in);
+ std::string inLine;
+ std::string outLine;
+ while (cmSystemTools::GetLineFromStream(sin, inLine)) {
+ outLine.clear();
+ makeFile.ConfigureString(inLine, outLine, atOnly, escapeQuotes);
+ fout << outLine << newLineCharacters;
+ }
+
+ // close file before attempting to copy
+ fout.close();
+
+ return true;
+}
+
+bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ struct Arguments
+ {
+ std::string Output;
+ std::string Format;
+ std::string Type;
+ std::string MTime;
+ bool Verbose = false;
+ std::vector<std::string> Files;
+ std::vector<std::string> Directories;
+ };
+
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("FORMAT"_s, &Arguments::Format)
+ .Bind("TYPE"_s, &Arguments::Type)
+ .Bind("MTIME"_s, &Arguments::MTime)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("FILES"_s, &Arguments::Files)
+ .Bind("DIRECTORY"_s, &Arguments::Directories);
+
+ std::vector<std::string> unrecognizedArguments;
+ std::vector<std::string> keywordsMissingValues;
+ auto parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+ &keywordsMissingValues);
+ auto argIt = unrecognizedArguments.begin();
+ if (argIt != unrecognizedArguments.end()) {
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const std::vector<std::string> LIST_ARGS = {
+ "OUTPUT", "FORMAT", "TYPE", "MTIME", "FILES", "DIRECTORY",
+ };
+ auto kwbegin = keywordsMissingValues.cbegin();
+ auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
+ if (kwend != kwbegin) {
+ status.SetError(cmStrCat("Keywords missing values:\n ",
+ cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const char* knownFormats[] = {
+ "7zip", "gnutar", "pax", "paxr", "raw", "zip"
+ };
+
+ if (!parsedArgs.Format.empty() &&
+ !cm::contains(knownFormats, parsedArgs.Format)) {
+ status.SetError(
+ cmStrCat("archive format ", parsedArgs.Format, " not supported"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const char* zipFileFormats[] = { "7zip", "zip" };
+ if (!parsedArgs.Type.empty() &&
+ cm::contains(zipFileFormats, parsedArgs.Format)) {
+ status.SetError(cmStrCat("archive format ", parsedArgs.Format,
+ " does not support TYPE arguments"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ static std::map<std::string, cmSystemTools::cmTarCompression>
+ compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
+ { "BZip2", cmSystemTools::TarCompressBZip2 },
+ { "GZip", cmSystemTools::TarCompressGZip },
+ { "XZ", cmSystemTools::TarCompressXZ },
+ { "Zstd", cmSystemTools::TarCompressZstd } };
+
+ std::string const& outFile = parsedArgs.Output;
+ std::vector<std::string> files = parsedArgs.Files;
+ std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
+ std::back_inserter(files));
+
+ cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
+ auto typeIt = compressionTypeMap.find(parsedArgs.Type);
+ if (typeIt != compressionTypeMap.end()) {
+ compress = typeIt->second;
+ } else if (!parsedArgs.Type.empty()) {
+ status.SetError(
+ cmStrCat("compression type ", parsedArgs.Type, " is not supported"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (files.empty()) {
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING,
+ "No files or directories specified");
+ }
+
+ if (!cmSystemTools::CreateTar(outFile, files, compress, parsedArgs.Verbose,
+ parsedArgs.MTime, parsedArgs.Format)) {
+ status.SetError(cmStrCat("failed to compress: ", outFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ return true;
+}
+
+bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ struct Arguments
+ {
+ std::string Input;
+ bool Verbose = false;
+ bool ListOnly = false;
+ std::string Destination;
+ std::vector<std::string> Files;
+ std::vector<std::string> Directories;
+ };
+
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("INPUT"_s, &Arguments::Input)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
+ .Bind("DESTINATION"_s, &Arguments::Destination)
+ .Bind("FILES"_s, &Arguments::Files)
+ .Bind("DIRECTORY"_s, &Arguments::Directories);
+
+ std::vector<std::string> unrecognizedArguments;
+ std::vector<std::string> keywordsMissingValues;
+ auto parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+ &keywordsMissingValues);
+ auto argIt = unrecognizedArguments.begin();
+ if (argIt != unrecognizedArguments.end()) {
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const std::vector<std::string> LIST_ARGS = {
+ "INPUT",
+ "DESTINATION",
+ "FILES",
+ "DIRECTORY",
+ };
+ auto kwbegin = keywordsMissingValues.cbegin();
+ auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
+ if (kwend != kwbegin) {
+ status.SetError(cmStrCat("Keywords missing values:\n ",
+ cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ std::string inFile = parsedArgs.Input;
+ std::vector<std::string> files = parsedArgs.Files;
+ std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
+ std::back_inserter(files));
+
+ if (parsedArgs.ListOnly) {
+ if (!cmSystemTools::ListTar(inFile, files, parsedArgs.Verbose)) {
+ status.SetError(cmStrCat("failed to list: ", inFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ } else {
+ std::string destDir = cmSystemTools::GetCurrentWorkingDirectory();
+ if (!parsedArgs.Destination.empty()) {
+ if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
+ destDir = parsedArgs.Destination;
+ } else {
+ destDir = cmStrCat(destDir, "/", parsedArgs.Destination);
+ }
+
+ if (!cmSystemTools::MakeDirectory(destDir)) {
+ status.SetError(cmStrCat("failed to create directory: ", destDir));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(inFile)) {
+ inFile =
+ cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+ }
+ }
+
+ cmWorkingDirectory workdir(destDir);
+ if (workdir.Failed()) {
+ status.SetError(
+ cmStrCat("failed to change working directory to: ", destDir));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!cmSystemTools::ExtractTar(inFile, files, parsedArgs.Verbose)) {
+ status.SetError(cmStrCat("failed to extract: ", inFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace
bool cmFileCommand(std::vector<std::string> const& args,
@@ -2836,6 +3185,9 @@ bool cmFileCommand(std::vector<std::string> const& args,
{ "READ_SYMLINK"_s, HandleReadSymlinkCommand },
{ "CREATE_LINK"_s, HandleCreateLinkCommand },
{ "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
+ { "CONFIGURE"_s, HandleConfigureCommand },
+ { "ARCHIVE_CREATE"_s, HandleArchiveCreateCommand },
+ { "ARCHIVE_EXTRACT"_s, HandleArchiveExtractCommand },
};
return subcommand(args[0], args, status);
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index bec99bb..b5553b8 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -22,10 +22,6 @@ class cmExecutionStatus;
cmFindBase::cmFindBase(cmExecutionStatus& status)
: cmFindCommon(status)
{
- this->AlreadyInCache = false;
- this->AlreadyInCacheWithoutMetaInfo = false;
- this->NamesPerDir = false;
- this->NamesPerDirAllowed = false;
}
bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
@@ -115,6 +111,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
} else if (args[j] == "NO_SYSTEM_PATH") {
doing = DoingNone;
this->NoDefaultPath = true;
+ } else if (args[j] == "REQUIRED") {
+ doing = DoingNone;
+ this->Required = true;
+ newStyle = true;
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
@@ -296,7 +296,7 @@ bool cmFindBase::CheckForVariableInCache()
if (const char* cacheValue =
this->Makefile->GetDefinition(this->VariableName)) {
cmState* state = this->Makefile->GetState();
- const char* cacheEntry = state->GetCacheEntryValue(this->VariableName);
+ cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
bool found = !cmIsNOTFOUND(cacheValue);
bool cached = cacheEntry != nullptr;
if (found) {
@@ -312,9 +312,9 @@ bool cmFindBase::CheckForVariableInCache()
return true;
}
if (cached) {
- const char* hs =
+ cmProp hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
- this->VariableDocumentation = hs ? hs : "(none)";
+ this->VariableDocumentation = hs ? *hs : "(none)";
}
}
return false;
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index fce0b11..4cbf09e 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -44,14 +44,16 @@ protected:
std::string VariableDocumentation;
std::string VariableName;
std::vector<std::string> Names;
- bool NamesPerDir;
- bool NamesPerDirAllowed;
+ bool NamesPerDir = false;
+ bool NamesPerDirAllowed = false;
// CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
std::string EnvironmentPath; // LIB,INCLUDE
- bool AlreadyInCache;
- bool AlreadyInCacheWithoutMetaInfo;
+ bool AlreadyInCache = false;
+ bool AlreadyInCacheWithoutMetaInfo = false;
+
+ bool Required = false;
private:
// Add pieces of the search.
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index d5a4bde..31f1201 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -12,6 +12,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -75,15 +76,22 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const library = this->FindLibrary();
if (!library.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, library.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, library,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
std::string notfound = this->VariableName + "-NOTFOUND";
- this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, notfound,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following names: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 297c72b..d1517fe 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -279,9 +279,13 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} else if (args[i] == "MODULE") {
moduleArgs.insert(i);
doing = DoingNone;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "CONFIG") {
configArgs.insert(i);
doing = DoingNone;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_MODULE") {
configArgs.insert(i);
doing = DoingNone;
@@ -318,6 +322,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->NoSystemRegistry = true;
configArgs.insert(i);
doing = DoingNone;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_CMAKE_BUILDS_PATH") {
// Ignore legacy option.
configArgs.insert(i);
@@ -1060,8 +1066,8 @@ bool cmFindPackageCommand::FindConfig()
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
// We force the value since we do not get here if it was already set.
- this->Makefile->AddCacheDefinition(this->Variable, init.c_str(),
- help.c_str(), cmStateEnums::PATH, true);
+ this->Makefile->AddCacheDefinition(this->Variable, init, help.c_str(),
+ cmStateEnums::PATH, true);
return found;
}
@@ -1114,12 +1120,10 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
void cmFindPackageCommand::AppendToFoundProperty(bool found)
{
std::vector<std::string> foundContents;
- const char* foundProp =
+ cmProp foundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
- if (foundProp && *foundProp) {
- std::string tmp = foundProp;
-
- cmExpandList(tmp, foundContents, false);
+ if (foundProp && !foundProp->empty()) {
+ cmExpandList(*foundProp, foundContents, false);
auto nameIt =
std::find(foundContents.begin(), foundContents.end(), this->Name);
if (nameIt != foundContents.end()) {
@@ -1128,12 +1132,10 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
}
std::vector<std::string> notFoundContents;
- const char* notFoundProp =
+ cmProp notFoundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
- if (notFoundProp && *notFoundProp) {
- std::string tmp = notFoundProp;
-
- cmExpandList(tmp, notFoundContents, false);
+ if (notFoundProp && !notFoundProp->empty()) {
+ cmExpandList(*notFoundProp, notFoundContents, false);
auto nameIt =
std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
if (nameIt != notFoundContents.end()) {
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 908f0c1..4bab469 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -5,6 +5,7 @@
#include "cmsys/Glob.hxx"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -43,14 +44,21 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string result = this->FindHeader();
if (!result.empty()) {
this->Makefile->AddCacheDefinition(
- this->VariableName, result.c_str(), this->VariableDocumentation.c_str(),
+ this->VariableName, result, this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following files: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 3e49172..599b1d2 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -3,6 +3,7 @@
#include "cmFindProgramCommand.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -84,7 +85,7 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
- bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ bool exists = cmSystemTools::FileIsExecutable(this->TestPath);
exists ? this->DebugSearches.FoundAt(this->TestPath)
: this->DebugSearches.FailedAt(this->TestPath);
if (exists) {
@@ -127,15 +128,22 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const result = FindProgram();
if (!result.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, result,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following names: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2af04b6..f76e205 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -180,6 +180,7 @@ int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
}
FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
if (!ifs) {
+ gzclose(gf);
return 0;
}
size_t res;
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 81d1e46..6e293d5 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -32,12 +32,6 @@ std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
}
-std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
- const char* input) const
-{
- return this->Parse(std::string(input ? input : ""));
-}
-
std::string cmGeneratorExpression::Evaluate(
std::string input, cmLocalGenerator* lg, const std::string& config,
cmGeneratorTarget const* headTarget,
@@ -52,17 +46,6 @@ std::string cmGeneratorExpression::Evaluate(
return input;
}
-std::string cmGeneratorExpression::Evaluate(
- const char* input, cmLocalGenerator* lg, const std::string& config,
- cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
- cmGeneratorTarget const* currentTarget, std::string const& language)
-{
- return input ? Evaluate(std::string(input), lg, config, headTarget,
- dagChecker, currentTarget, language)
- : "";
-}
-
const std::string& cmCompiledGeneratorExpression::Evaluate(
cmLocalGenerator* lg, const std::string& config,
const cmGeneratorTarget* headTarget,
@@ -103,6 +86,8 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
if (!context.HadError) {
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+ this->HadLinkLanguageSensitiveCondition =
+ context.HadLinkLanguageSensitiveCondition;
this->SourceSensitiveTargets = context.SourceSensitiveTargets;
}
@@ -119,6 +104,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
, Quiet(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index c4be3a1..75bba02 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -42,8 +42,6 @@ public:
std::unique_ptr<cmCompiledGeneratorExpression> Parse(
std::string input) const;
- std::unique_ptr<cmCompiledGeneratorExpression> Parse(
- const char* input) const;
static std::string Evaluate(
std::string input, cmLocalGenerator* lg, const std::string& config,
@@ -51,12 +49,6 @@ public:
cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
cmGeneratorTarget const* currentTarget = nullptr,
std::string const& language = std::string());
- static std::string Evaluate(
- const char* input, cmLocalGenerator* lg, const std::string& config,
- cmGeneratorTarget const* headTarget = nullptr,
- cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
- cmGeneratorTarget const* currentTarget = nullptr,
- std::string const& language = std::string());
enum PreprocessContext
{
@@ -137,6 +129,10 @@ public:
{
return this->HadHeadSensitiveCondition;
}
+ bool GetHadLinkLanguageSensitiveCondition() const
+ {
+ return this->HadLinkLanguageSensitiveCondition;
+ }
std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
{
return this->SourceSensitiveTargets;
@@ -178,6 +174,7 @@ private:
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
mutable bool HadHeadSensitiveCondition;
+ mutable bool HadLinkLanguageSensitiveCondition;
mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
};
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
index 6d97331..42cbe2a 100644
--- a/Source/cmGeneratorExpressionContext.cxx
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -19,6 +19,7 @@ cmGeneratorExpressionContext::cmGeneratorExpressionContext(
, HadError(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
, EvaluateForBuildsystem(evaluateForBuildsystem)
{
}
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 4709fa0..bceff12 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -40,6 +40,7 @@ struct cmGeneratorExpressionContext
bool HadError;
bool HadContextSensitiveCondition;
bool HadHeadSensitiveCondition;
+ bool HadLinkLanguageSensitiveCondition;
bool EvaluateForBuildsystem;
};
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 643ba34..b4ba1a1 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -6,6 +6,10 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
@@ -44,12 +48,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
void cmGeneratorExpressionDAGChecker::Initialize()
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* p = this->Parent;
- while (p) {
- top = p;
- p = p->Parent;
- }
+ const auto* top = this->Top();
this->CheckResult = this->CheckGraph();
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||
@@ -140,61 +139,57 @@ cmGeneratorExpressionDAGChecker::CheckGraph() const
return DAG;
}
-bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
+bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly() const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ return this->Top()->TransitivePropertiesOnly;
+}
- return top->TransitivePropertiesOnly;
+bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() const
+{
+ return cmHasLiteralPrefix(this->Property, "TARGET_GENEX_EVAL:") ||
+ cmHasLiteralPrefix(this->Property, "GENEX_EVAL:");
}
-bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression() const
{
- return this->Property.find("TARGET_GENEX_EVAL:") == 0 ||
- this->Property.find("GENEX_EVAL:", 0) == 0;
+ return this->Top()->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
}
-bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ cm::string_view property(this->Top()->Property);
+
+ return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
+ property == "LINK_DEPENDS"_s;
+}
+
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
+{
+ cm::string_view property(this->Top()->Property);
- return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
+ return property == "LINK_OPTIONS"_s;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
- cmGeneratorTarget const* tgt)
+ cmGeneratorTarget const* tgt) const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ const auto* top = this->Top();
- const char* prop = top->Property.c_str();
+ cm::string_view prop(top->Property);
if (tgt) {
- return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
+ return top->Target == tgt && prop == "LINK_LIBRARIES"_s;
}
- return (strcmp(prop, "LINK_LIBRARIES") == 0 ||
- strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 ||
- strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
- cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
- cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) ||
- strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
+ return prop == "LINK_LIBRARIES"_s || prop == "LINK_INTERFACE_LIBRARIES"_s ||
+ prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s ||
+ cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
+ cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_") ||
+ prop == "INTERFACE_LINK_LIBRARIES"_s;
}
-cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
+cmGeneratorExpressionDAGChecker const* cmGeneratorExpressionDAGChecker::Top()
+ const
{
const cmGeneratorExpressionDAGChecker* top = this;
const cmGeneratorExpressionDAGChecker* parent = this->Parent;
@@ -202,7 +197,12 @@ cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
top = parent;
parent = parent->Parent;
}
- return top->Target;
+ return top;
+}
+
+cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
+{
+ return this->Top()->Target;
}
enum TransitiveProperty
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index f2c49bb..c2c5b6b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -66,9 +66,12 @@ struct cmGeneratorExpressionDAGChecker
void ReportError(cmGeneratorExpressionContext* context,
const std::string& expr);
- bool EvaluatingGenexExpression();
- bool EvaluatingPICExpression();
- bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
+ bool EvaluatingGenexExpression() const;
+ bool EvaluatingPICExpression() const;
+ bool EvaluatingLinkExpression() const;
+ bool EvaluatingLinkOptionsExpression() const;
+
+ bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr) const;
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
@@ -76,9 +79,10 @@ struct cmGeneratorExpressionDAGChecker
#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
- bool GetTransitivePropertiesOnly();
+ bool GetTransitivePropertiesOnly() const;
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
+ cmGeneratorExpressionDAGChecker const* Top() const;
cmGeneratorTarget const* TopTarget() const;
private:
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 14478c2..d48427e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -15,6 +15,8 @@
#include <cm/iterator>
#include <cm/string_view>
+#include <cm/vector>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
@@ -62,6 +64,9 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
if (cge->GetHadHeadSensitiveCondition()) {
context->HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
return result;
}
@@ -310,7 +315,7 @@ static const struct InListNode : public cmGeneratorExpressionNode
break;
}
- return cmContains(values, parameters.front()) ? "1" : "0";
+ return cm::contains(values, parameters.front()) ? "1" : "0";
}
} inListNode;
@@ -904,11 +909,11 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
}
if (context->CurrentTarget && context->CurrentTarget->IsImported()) {
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (context->CurrentTarget->Target->GetMappedConfig(
- context->Config, &loc, &imp, suffix)) {
+ if (context->CurrentTarget->Target->GetMappedConfig(context->Config, loc,
+ imp, suffix)) {
// This imported target has an appropriate location
// for this (possibly mapped) config.
// Check if there is a proper config mapping for the tested config.
@@ -918,8 +923,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
if (const char* mapValue =
context->CurrentTarget->GetProperty(mapProp)) {
cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
- return cmContains(mappedConfigs,
- cmSystemTools::UpperCase(parameters.front()))
+ return cm::contains(mappedConfigs,
+ cmSystemTools::UpperCase(parameters.front()))
? "1"
: "0";
}
@@ -1039,6 +1044,214 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
}
} languageAndIdNode;
+static const struct LinkLanguageNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE:...> may only be used with binary targets "
+ "to specify link libraries, link directories, link options "
+ "and link depends.");
+ return std::string();
+ }
+ if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE> is not supported in link libraries expression.");
+ return std::string();
+ }
+
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string genName = gg->GetName();
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE:...> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ if (parameters.empty()) {
+ return context->Language;
+ }
+
+ for (auto& param : parameters) {
+ if (context->Language == param) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+} linkLanguageNode;
+
+namespace {
+struct LinkerId
+{
+ static std::string Evaluate(const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ const std::string& lang)
+ {
+ std::string const& linkerId =
+ context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
+ "_COMPILER_ID");
+ if (parameters.empty()) {
+ return linkerId;
+ }
+ if (linkerId.empty()) {
+ return parameters.front().empty() ? "1" : "0";
+ }
+ static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
+
+ for (auto& param : parameters) {
+ if (!linkerIdValidator.find(param)) {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+
+ if (param == linkerId) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+};
+}
+
+static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "to specify link libraries, link directories, link options, and link "
+ "depends.");
+ return std::string();
+ }
+
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string genName = gg->GetName();
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ const std::string& lang = context->Language;
+ if (lang == parameters.front()) {
+ std::vector<std::string> idParameter((parameters.cbegin() + 1),
+ parameters.cend());
+ return LinkerId::Evaluate(idParameter, context, content, lang);
+ }
+ return "0";
+ }
+} linkLanguageAndIdNode;
+
+static const struct HostLinkNode : public cmGeneratorExpressionNode
+{
+ HostLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkOptionsExpression()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<HOST_LINK:...> may only be used with binary targets "
+ "to specify link options.");
+ return std::string();
+ }
+
+ return context->HeadTarget->IsDeviceLink() ? std::string()
+ : cmJoin(parameters, ";");
+ }
+} hostLinkNode;
+
+static const struct DeviceLinkNode : public cmGeneratorExpressionNode
+{
+ DeviceLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkOptionsExpression()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<DEVICE_LINK:...> may only be used with binary targets "
+ "to specify link options.");
+ return std::string();
+ }
+
+ if (context->HeadTarget->IsDeviceLink()) {
+ std::vector<std::string> list;
+ cmExpandLists(parameters.begin(), parameters.end(), list);
+ const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+ const auto DL_END = "</DEVICE_LINK>"_s;
+ cm::erase_if(list, [&](const std::string& item) {
+ return item == DL_BEGIN || item == DL_END;
+ });
+
+ list.insert(list.begin(), static_cast<std::string>(DL_BEGIN));
+ list.push_back(static_cast<std::string>(DL_END));
+
+ return cmJoin(list, ";");
+ }
+
+ return std::string();
+ }
+} deviceLinkNode;
+
std::string getLinkedTargetsContent(
cmGeneratorTarget const* target, std::string const& prop,
cmGeneratorExpressionContext* context,
@@ -1156,6 +1369,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
"It may not be used with add_custom_command or add_custom_target. "
+ " "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
return std::string();
@@ -1418,11 +1632,11 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
std::vector<std::string> objects;
if (gt->IsImported()) {
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
- cmExpandList(loc, objects);
+ if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
+ cmExpandList(*loc, objects);
}
context->HadContextSensitiveCondition = true;
} else {
@@ -1512,7 +1726,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
"CMAKE_" + lit.first + "_STANDARD_DEFAULT");
for (std::string const& it : lit.second) {
- if (!cmContains(langAvailable, it)) {
+ if (!cm::contains(langAvailable, it)) {
return "0";
}
if (standardDefault && !*standardDefault) {
@@ -2314,6 +2528,10 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "LINK_ONLY", &linkOnlyNode },
{ "COMPILE_LANG_AND_ID", &languageAndIdNode },
{ "COMPILE_LANGUAGE", &languageNode },
+ { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
+ { "LINK_LANGUAGE", &linkLanguageNode },
+ { "HOST_LINK", &hostLinkNode },
+ { "DEVICE_LINK", &deviceLinkNode },
{ "SHELL_PATH", &shellPathNode }
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ba2e314..fd863a3 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -17,9 +17,12 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
+#include "cm_static_string_view.hxx"
+
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
@@ -51,11 +54,11 @@
class cmMessenger;
template <>
-const char* cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
cmListFileBacktrace const& /* context */)
{
- return tgt->GetSourcesProperty().c_str();
+ return &tgt->GetSourcesProperty();
}
template <>
@@ -308,6 +311,13 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->SourceEntries, true);
this->PolicyMap = t->GetPolicyMap();
+
+ // Get hard-coded linker language
+ if (this->Target->GetProperty("HAS_CXX")) {
+ this->LinkerLanguage = "CXX";
+ } else {
+ this->LinkerLanguage = this->Target->GetSafeProperty("LINKER_LANGUAGE");
+ }
}
cmGeneratorTarget::~cmGeneratorTarget() = default;
@@ -368,14 +378,15 @@ const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
this->GetBacktrace())) {
return nullptr;
}
- if (const char* result = cmTargetPropertyComputer::GetProperty(
+ if (cmProp result = cmTargetPropertyComputer::GetProperty(
this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
- return result;
+ return result->c_str();
}
if (cmSystemTools::GetFatalErrorOccured()) {
return nullptr;
}
- return this->Target->GetProperty(prop);
+ cmProp retval = this->Target->GetProperty(prop);
+ return retval ? retval->c_str() : nullptr;
}
const char* cmGeneratorTarget::GetSafeProperty(const std::string& prop) const
@@ -531,15 +542,43 @@ std::string cmGeneratorTarget::GetFileSuffix(
std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
{
const char* postfix = nullptr;
+ std::string frameworkPostfix;
if (!config.empty()) {
std::string configProp =
cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
postfix = this->GetProperty(configProp);
- // Mac application bundles and frameworks have no postfix.
+
+ // Mac application bundles and frameworks have no regular postfix like
+ // libraries do.
if (!this->IsImported() && postfix &&
(this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) {
postfix = nullptr;
}
+
+ // Frameworks created by multi config generators can have a special
+ // framework postfix.
+ frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
+ if (!frameworkPostfix.empty()) {
+ postfix = frameworkPostfix.c_str();
+ }
+ }
+ return postfix ? postfix : std::string();
+}
+
+std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
+ const std::string& config) const
+{
+ const char* postfix = nullptr;
+ if (!config.empty()) {
+ std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+ cmSystemTools::UpperCase(config));
+ postfix = this->GetProperty(configProp);
+
+ if (!this->IsImported() && postfix &&
+ (this->IsFrameworkOnApple() &&
+ !GetGlobalGenerator()->IsMultiConfig())) {
+ postfix = nullptr;
+ }
}
return postfix ? postfix : std::string();
}
@@ -1190,7 +1229,6 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
return result;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
- return result;
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
// No error. We have already seen this transitive property.
return result;
@@ -1246,6 +1284,87 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
+std::string AddSwiftInterfaceIncludeDirectories(
+ const cmGeneratorTarget* root, const cmGeneratorTarget* target,
+ const std::string& config, cmGeneratorExpressionDAGChecker* context)
+{
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ context };
+ switch (dag.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dag.ReportError(nullptr,
+ "$<TARGET_PROPERTY:" + target->GetName() +
+ ",Swift_MODULE_DIRECTORY>");
+ CM_FALLTHROUGH;
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We have already seen this transitive property.
+ return "";
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ std::string directories;
+ if (const auto* interface =
+ target->GetLinkInterfaceLibraries(config, root, true)) {
+ for (const cmLinkItem& library : interface->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
+ std::string value =
+ dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+ if (value.empty()) {
+ value =
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ }
+
+ if (!directories.empty()) {
+ directories += ";";
+ }
+ directories += value;
+ }
+ }
+ }
+ }
+ return directories;
+}
+
+void AddSwiftImplicitIncludeDirectories(
+ const cmGeneratorTarget* target, const std::string& config,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
+{
+ if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ nullptr };
+
+ for (const cmLinkImplItem& library : libraries->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
+ EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
+
+ if (const char* val =
+ dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+ entry.Values.emplace_back(val);
+ } else {
+ entry.Values.emplace_back(
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ }
+
+ cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
+ config, &dag),
+ entry.Values);
+
+ entries.emplace_back(std::move(entry));
+ }
+ }
+ }
+ }
+}
+
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
@@ -1407,7 +1526,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
}
bool debugSources =
- !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
+ !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
this->DebugSourcesDone = true;
@@ -1572,10 +1691,14 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (this->Target->GetType() == cmStateEnums::UTILITY) {
kind = SourceKindExtra;
} else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
kind = SourceKindUnityBatched;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) {
kind = SourceKindHeader;
} else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
@@ -1907,7 +2030,7 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
if (cmGeneratorTarget::ImportInfo const* info =
this->GetImportInfo(config)) {
if (!info->NoSOName && !info->SOName.empty()) {
- if (info->SOName.find("@rpath/") == 0) {
+ if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
install_name_is_rpath = true;
}
} else {
@@ -2024,7 +2147,7 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return cmSystemTools::GetFilenameName(info->Location);
}
// Use the soname given if any.
- if (info->SOName.find("@rpath/") == 0) {
+ if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
return info->SOName.substr(6);
}
return info->SOName;
@@ -2223,11 +2346,12 @@ public:
cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
std::string config,
std::unordered_set<std::string>& languages,
- cmGeneratorTarget const* head)
+ cmGeneratorTarget const* head, bool secondPass)
: Config(std::move(config))
, Languages(languages)
, HeadTarget(head)
, Target(target)
+ , SecondPass(secondPass)
{
this->Visited.insert(target);
}
@@ -2269,11 +2393,14 @@ public:
if (!this->Visited.insert(item.Target).second) {
return;
}
- cmLinkInterface const* iface =
- item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+ cmLinkInterface const* iface = item.Target->GetLinkInterface(
+ this->Config, this->HeadTarget, this->SecondPass);
if (!iface) {
return;
}
+ if (iface->HadLinkLanguageSensitiveCondition) {
+ this->HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& language : iface->Languages) {
this->Languages.insert(language);
@@ -2284,12 +2411,19 @@ public:
}
}
+ bool GetHadLinkLanguageSensitiveCondition()
+ {
+ return HadLinkLanguageSensitiveCondition;
+ }
+
private:
std::string Config;
std::unordered_set<std::string>& Languages;
cmGeneratorTarget const* HeadTarget;
const cmGeneratorTarget* Target;
std::set<cmGeneratorTarget const*> Visited;
+ bool SecondPass;
+ bool HadLinkLanguageSensitiveCondition = false;
};
cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
@@ -2320,7 +2454,7 @@ public:
{
this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
}
- void Consider(const char* lang)
+ void Consider(const std::string& lang)
{
int preference = this->GG->GetLinkerPreference(lang);
if (preference > this->Preference) {
@@ -2353,40 +2487,36 @@ public:
}
};
-void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
- LinkClosure& lc) const
+bool cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc,
+ bool secondPass) const
{
// Get languages built in this target.
std::unordered_set<std::string> languages;
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
assert(impl);
- for (std::string const& li : impl->Languages) {
- languages.insert(li);
- }
+ languages.insert(impl->Languages.cbegin(), impl->Languages.cend());
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, this);
+ // cmTargetCollectLinkLanguages cll(this, config, languages, this,
+ // secondPass);
+ cmTargetCollectLinkLanguages cll(this, config, languages, this, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
cll.Visit(lib);
}
// Store the transitive closure of languages.
- for (std::string const& lang : languages) {
- lc.Languages.push_back(lang);
- }
+ cm::append(lc.Languages, languages);
// Choose the language whose linker should be used.
- if (this->GetProperty("HAS_CXX")) {
- lc.LinkerLanguage = "CXX";
- } else if (const char* linkerLang = this->GetProperty("LINKER_LANGUAGE")) {
- lc.LinkerLanguage = linkerLang;
- } else {
+ if (secondPass || lc.LinkerLanguage.empty()) {
// Find the language with the highest preference value.
cmTargetSelectLinker tsl(this);
// First select from the languages compiled directly in this target.
for (std::string const& l : impl->Languages) {
- tsl.Consider(l.c_str());
+ tsl.Consider(l);
}
// Now consider languages that propagate from linked targets.
@@ -2394,12 +2524,50 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
std::string propagates =
"CMAKE_" + lang + "_LINKER_PREFERENCE_PROPAGATES";
if (this->Makefile->IsOn(propagates)) {
- tsl.Consider(lang.c_str());
+ tsl.Consider(lang);
}
}
lc.LinkerLanguage = tsl.Choose();
}
+
+ return impl->HadLinkLanguageSensitiveCondition ||
+ cll.GetHadLinkLanguageSensitiveCondition();
+}
+
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
+{
+ bool secondPass = false;
+
+ {
+ LinkClosure linkClosure;
+ linkClosure.LinkerLanguage = this->LinkerLanguage;
+
+ // Get languages built in this target.
+ secondPass = this->ComputeLinkClosure(config, linkClosure, false);
+ this->LinkerLanguage = linkClosure.LinkerLanguage;
+ if (!secondPass) {
+ lc = std::move(linkClosure);
+ }
+ }
+
+ if (secondPass) {
+ LinkClosure linkClosure;
+
+ this->ComputeLinkClosure(config, linkClosure, secondPass);
+ lc = std::move(linkClosure);
+
+ // linker language must not be changed between the two passes
+ if (this->LinkerLanguage != lc.LinkerLanguage) {
+ std::ostringstream e;
+ e << "Evaluation of $<LINK_LANGUAGE:...> or $<LINK_LAND_AND_ID:...> "
+ "changes\nthe linker language for target \""
+ << this->GetName() << "\" (from '" << this->LinkerLanguage << "' to '"
+ << lc.LinkerLanguage << "') which is invalid.";
+ cmSystemTools::Error(e.str());
+ }
+ }
}
void cmGeneratorTarget::GetFullNameComponents(
@@ -2642,7 +2810,7 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
for (cmSourceFile* sf : sources) {
const std::set<cmGeneratorTarget const*> tgts =
this->GlobalGenerator->GetFilenameTargetDepends(sf);
- if (cmContains(tgts, this->GeneratorTarget)) {
+ if (cm::contains(tgts, this->GeneratorTarget)) {
std::ostringstream e;
e << "Evaluation output file\n \"" << sf->ResolveFullPath()
<< "\"\ndepends on the sources of a target it is used in. This "
@@ -2675,8 +2843,8 @@ void cmTargetTraceDependencies::Trace()
this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf];
// Queue dependencies added explicitly by the user.
- if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps = cmExpandedList(additionalDeps);
+ if (cmProp additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> objDeps = cmExpandedList(*additionalDeps);
for (std::string& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
@@ -2921,6 +3089,95 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
}
}
+void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+{
+ struct CudaArchitecture
+ {
+ std::string name;
+ bool real{ true };
+ bool virtual_{ true };
+ };
+ std::vector<CudaArchitecture> architectures;
+
+ {
+ std::vector<std::string> options;
+ cmExpandList(this->GetSafeProperty("CUDA_ARCHITECTURES"), options);
+
+ if (options.empty()) {
+ switch (this->GetPolicyStatusCMP0104()) {
+ case cmPolicies::WARN:
+ if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
+ "\nCUDA_ARCHITECTURES is empty for target \"" +
+ this->GetName() + "\".");
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ default:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
+ "\".");
+ }
+ }
+
+ for (std::string& option : options) {
+ CudaArchitecture architecture;
+
+ // Architecture name is up to the first specifier.
+ std::size_t pos = option.find_first_of('-');
+ architecture.name = option.substr(0, pos);
+
+ if (pos != std::string::npos) {
+ cm::string_view specifier{ option.c_str() + pos + 1,
+ option.length() - pos - 1 };
+
+ if (specifier == "real") {
+ architecture.real = true;
+ architecture.virtual_ = false;
+ } else if (specifier == "virtual") {
+ architecture.real = false;
+ architecture.virtual_ = true;
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Uknown CUDA architecture specifier \"" + std::string(specifier) +
+ "\".");
+ }
+ }
+
+ architectures.emplace_back(architecture);
+ }
+ }
+
+ std::string const& compiler =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+ if (compiler == "NVIDIA") {
+ for (CudaArchitecture& architecture : architectures) {
+ flags +=
+ " --generate-code=arch=compute_" + architecture.name + ",code=[";
+
+ if (architecture.virtual_) {
+ flags += "compute_" + architecture.name;
+
+ if (architecture.real) {
+ flags += ",";
+ }
+ }
+
+ if (architecture.real) {
+ flags += "sm_" + architecture.name;
+ }
+
+ flags += "]";
+ }
+ }
+}
+
//----------------------------------------------------------------------------
std::string cmGeneratorTarget::GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
@@ -3086,7 +3343,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
}
bool debugIncludes = !this->DebugIncludesDone &&
- cmContains(debugProperties, "INCLUDE_DIRECTORIES");
+ cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugIncludesDone = true;
@@ -3096,6 +3353,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
this->IncludeDirectoriesEntries);
+ if (lang == "Swift") {
+ AddSwiftImplicitIncludeDirectories(this, config, entries);
+ }
+
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries);
@@ -3133,22 +3394,38 @@ enum class OptionsParse
};
namespace {
+const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+const auto DL_END = "</DEVICE_LINK>"_s;
+
void processOptions(cmGeneratorTarget const* tgt,
std::vector<EvaluatedTargetPropertyEntry> const& entries,
std::vector<BT<std::string>>& options,
std::unordered_set<std::string>& uniqueOptions,
- bool debugOptions, const char* logName, OptionsParse parse)
+ bool debugOptions, const char* logName, OptionsParse parse,
+ bool processDeviceOptions = false)
{
+ bool splitOption = !processDeviceOptions;
for (EvaluatedTargetPropertyEntry const& entry : entries) {
std::string usedOptions;
for (std::string const& opt : entry.Values) {
+ if (processDeviceOptions && (opt == DL_BEGIN || opt == DL_END)) {
+ options.emplace_back(opt, entry.Backtrace);
+ splitOption = opt == DL_BEGIN;
+ continue;
+ }
+
if (uniqueOptions.insert(opt).second) {
if (parse == OptionsParse::Shell &&
cmHasLiteralPrefix(opt, "SHELL:")) {
- std::vector<std::string> tmp;
- cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
- for (std::string& o : tmp) {
- options.emplace_back(std::move(o), entry.Backtrace);
+ if (splitOption) {
+ std::vector<std::string> tmp;
+ cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
+ for (std::string& o : tmp) {
+ options.emplace_back(std::move(o), entry.Backtrace);
+ }
+ } else {
+ options.emplace_back(std::string(opt.c_str() + 6),
+ entry.Backtrace);
}
} else {
options.emplace_back(opt, entry.Backtrace);
@@ -3167,6 +3444,63 @@ void processOptions(cmGeneratorTarget const* tgt,
}
}
}
+
+std::vector<BT<std::string>> wrapOptions(
+ std::vector<std::string>& options, const cmListFileBacktrace& bt,
+ const std::vector<std::string>& wrapperFlag, const std::string& wrapperSep,
+ bool concatFlagAndArgs)
+{
+ std::vector<BT<std::string>> result;
+
+ if (options.empty()) {
+ return result;
+ }
+
+ if (wrapperFlag.empty() || cmHasLiteralPrefix(options.front(), "LINKER:")) {
+ // nothing specified or LINKER wrapper, insert elements as is
+ result.reserve(options.size());
+ for (std::string& o : options) {
+ result.emplace_back(std::move(o), bt);
+ }
+ } else {
+ if (!wrapperSep.empty()) {
+ if (concatFlagAndArgs) {
+ // insert flag elements except last one
+ for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
+ result.emplace_back(*i, bt);
+ }
+ // concatenate last flag element and all list values
+ // in one option
+ result.emplace_back(wrapperFlag.back() + cmJoin(options, wrapperSep),
+ bt);
+ } else {
+ for (std::string const& i : wrapperFlag) {
+ result.emplace_back(i, bt);
+ }
+ // concatenate all list values in one option
+ result.emplace_back(cmJoin(options, wrapperSep), bt);
+ }
+ } else {
+ // prefix each element of list with wrapper
+ if (concatFlagAndArgs) {
+ std::transform(options.begin(), options.end(), options.begin(),
+ [&wrapperFlag](std::string const& o) -> std::string {
+ return wrapperFlag.back() + o;
+ });
+ }
+ for (std::string& o : options) {
+ for (auto i = wrapperFlag.begin(),
+ e = concatFlagAndArgs ? wrapperFlag.end() - 1
+ : wrapperFlag.end();
+ i != e; ++i) {
+ result.emplace_back(*i, bt);
+ }
+ result.emplace_back(std::move(o), bt);
+ }
+ }
+ }
+ return result;
+}
}
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3197,7 +3531,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
}
bool debugOptions = !this->DebugCompileOptionsDone &&
- cmContains(debugProperties, "COMPILE_OPTIONS");
+ cm::contains(debugProperties, "COMPILE_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileOptionsDone = true;
@@ -3243,7 +3577,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
}
bool debugFeatures = !this->DebugCompileFeaturesDone &&
- cmContains(debugProperties, "COMPILE_FEATURES");
+ cm::contains(debugProperties, "COMPILE_FEATURES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileFeaturesDone = true;
@@ -3291,7 +3625,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
bool debugDefines = !this->DebugCompileDefinitionsDone &&
- cmContains(debugProperties, "COMPILE_DEFINITIONS");
+ cm::contains(debugProperties, "COMPILE_DEFINITIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileDefinitionsDone = true;
@@ -3374,7 +3708,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
}
std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
- const std::string& language) const
+ const std::string& language,
+ const std::string& arch) const
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
@@ -3389,7 +3724,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
const auto inserted =
- this->PchHeaders.insert(std::make_pair(language + config, ""));
+ this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
const std::vector<BT<std::string>> headers =
this->GetPrecompileHeaders(config, language);
@@ -3421,7 +3756,8 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
}
filename =
- cmStrCat(filename, "/cmake_pch", languageToExtension.at(language));
+ cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
const std::string filename_tmp = cmStrCat(filename, ".tmp");
if (!pchReuseFrom) {
@@ -3480,16 +3816,17 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
}
std::string cmGeneratorTarget::GetPchSource(const std::string& config,
- const std::string& language) const
+ const std::string& language,
+ const std::string& arch) const
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
return std::string();
}
const auto inserted =
- this->PchSources.insert(std::make_pair(language + config, ""));
+ this->PchSources.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
- const std::string pchHeader = this->GetPchHeader(config, language);
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
if (pchHeader.empty()) {
return std::string();
}
@@ -3516,13 +3853,15 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
{ "OBJCXX", ".objcxx.hxx.mm" }
};
- filename += languageToExtension.at(language);
+ filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
} else {
const std::map<std::string, std::string> languageToExtension = {
{ "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
};
- filename += languageToExtension.at(language);
+ filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
}
const std::string filename_tmp = cmStrCat(filename, ".tmp");
@@ -3539,16 +3878,17 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
}
std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
- const std::string& language)
+ const std::string& language,
+ const std::string& arch)
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
return std::string();
}
const auto inserted =
- this->PchObjectFiles.insert(std::make_pair(language + config, ""));
+ this->PchObjectFiles.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
- const std::string pchSource = this->GetPchSource(config, language);
+ const std::string pchSource = this->GetPchSource(config, language, arch);
if (pchSource.empty()) {
return std::string();
}
@@ -3565,10 +3905,11 @@ std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
}
std::string cmGeneratorTarget::GetPchFile(const std::string& config,
- const std::string& language)
+ const std::string& language,
+ const std::string& arch)
{
const auto inserted =
- this->PchFiles.insert(std::make_pair(language + config, ""));
+ this->PchFiles.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& pchFile = inserted.first->second;
@@ -3596,12 +3937,12 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
}
const std::string pchFileObject =
- generatorTarget->GetPchFileObject(config, language);
+ generatorTarget->GetPchFileObject(config, language, arch);
if (!pchExtension.empty()) {
pchFile = replaceExtension(pchFileObject, pchExtension);
}
} else {
- pchFile = this->GetPchHeader(config, language);
+ pchFile = this->GetPchHeader(config, language, arch);
pchFile += pchExtension;
}
}
@@ -3609,19 +3950,27 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
}
std::string cmGeneratorTarget::GetPchCreateCompileOptions(
- const std::string& config, const std::string& language)
+ const std::string& config, const std::string& language,
+ const std::string& arch)
{
const auto inserted = this->PchCreateCompileOptions.insert(
- std::make_pair(language + config, ""));
+ std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& createOptionList = inserted.first->second;
+ if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+ createOptionList = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+ }
+
const std::string createOptVar =
cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH");
- createOptionList = this->Makefile->GetSafeDefinition(createOptVar);
- const std::string pchHeader = this->GetPchHeader(config, language);
- const std::string pchFile = this->GetPchFile(config, language);
+ createOptionList = cmStrCat(
+ createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
+
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
+ const std::string pchFile = this->GetPchFile(config, language, arch);
cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
@@ -3630,19 +3979,32 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
}
std::string cmGeneratorTarget::GetPchUseCompileOptions(
- const std::string& config, const std::string& language)
+ const std::string& config, const std::string& language,
+ const std::string& arch)
{
- const auto inserted =
- this->PchUseCompileOptions.insert(std::make_pair(language + config, ""));
+ const auto inserted = this->PchUseCompileOptions.insert(
+ std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& useOptionList = inserted.first->second;
+ if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+ useOptionList = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+ }
+
const std::string useOptVar =
- cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
- useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+ cmStrCat(language, "_COMPILE_OPTIONS_USE_PCH");
+
+ const std::string useOptionListProperty = this->GetSafeProperty(useOptVar);
- const std::string pchHeader = this->GetPchHeader(config, language);
- const std::string pchFile = this->GetPchFile(config, language);
+ useOptionList = cmStrCat(
+ useOptionList, ";",
+ useOptionListProperty.empty()
+ ? this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_", useOptVar))
+ : useOptionListProperty);
+
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
+ const std::string pchFile = this->GetPchFile(config, language, arch);
cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
@@ -3671,6 +4033,12 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
{
+ if (this->IsDeviceLink() &&
+ this->GetPolicyStatusCMP0105() != cmPolicies::NEW) {
+ // link options are not propagated to the device link step
+ return;
+ }
+
std::vector<BT<std::string>> tmp = this->GetLinkOptions(config, language);
result.reserve(tmp.size());
for (BT<std::string>& v : tmp) {
@@ -3694,8 +4062,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmExpandList(debugProp, debugProperties);
}
- bool debugOptions =
- !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS");
+ bool debugOptions = !this->DebugLinkOptionsDone &&
+ cm::contains(debugProperties, "LINK_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkOptionsDone = true;
@@ -3710,15 +4078,65 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, debugOptions,
- "link options", OptionsParse::Shell);
+ "link options", OptionsParse::Shell, this->IsDeviceLink());
+
+ if (this->IsDeviceLink()) {
+ // wrap host link options
+ const std::string wrapper(this->Makefile->GetSafeDefinition(
+ "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG"));
+ std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ const std::string wrapperSep(this->Makefile->GetSafeDefinition(
+ "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG_SEP"));
+ bool concatFlagAndArgs = true;
+ if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
+ concatFlagAndArgs = false;
+ wrapperFlag.pop_back();
+ }
+
+ auto it = result.begin();
+ while (it != result.end()) {
+ if (it->Value == DL_BEGIN) {
+ // device link options, no treatment
+ it = result.erase(it);
+ it = std::find_if(it, result.end(), [](const BT<std::string>& item) {
+ return item.Value == DL_END;
+ });
+ if (it != result.end()) {
+ it = result.erase(it);
+ }
+ } else {
+ // host link options must be wrapped
+ std::vector<std::string> options;
+ cmSystemTools::ParseUnixCommandLine(it->Value.c_str(), options);
+ auto hostOptions = wrapOptions(options, it->Backtrace, wrapperFlag,
+ wrapperSep, concatFlagAndArgs);
+ it = result.erase(it);
+ // some compilers (like gcc 4.8 or Intel 19.0 or XLC 16) do not respect
+ // C++11 standard: 'std::vector::insert()' do not returns an iterator,
+ // so need to recompute the iterator after insertion.
+ if (it == result.end()) {
+ cm::append(result, hostOptions);
+ it = result.end();
+ } else {
+ auto index = it - result.begin();
+ result.insert(it, hostOptions.begin(), hostOptions.end());
+ it = result.begin() + index + hostOptions.size();
+ }
+ }
+ }
+ }
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
+ "CMAKE_" + language +
+ (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
+ : "_LINKER_WRAPPER_FLAG")));
std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
+ "CMAKE_" + language +
+ (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
+ : "_LINKER_WRAPPER_FLAG_SEP")));
bool concatFlagAndArgs = true;
if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
concatFlagAndArgs = false;
@@ -3764,51 +4182,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
return result;
}
- std::vector<BT<std::string>> options;
- if (wrapperFlag.empty()) {
- // nothing specified, insert elements as is
- options.reserve(linkerOptions.size());
- for (std::string& o : linkerOptions) {
- options.emplace_back(std::move(o), bt);
- }
- } else {
- if (!wrapperSep.empty()) {
- if (concatFlagAndArgs) {
- // insert flag elements except last one
- for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
- options.emplace_back(*i, bt);
- }
- // concatenate last flag element and all LINKER list values
- // in one option
- options.emplace_back(
- wrapperFlag.back() + cmJoin(linkerOptions, wrapperSep), bt);
- } else {
- for (std::string const& i : wrapperFlag) {
- options.emplace_back(i, bt);
- }
- // concatenate all LINKER list values in one option
- options.emplace_back(cmJoin(linkerOptions, wrapperSep), bt);
- }
- } else {
- // prefix each element of LINKER list with wrapper
- if (concatFlagAndArgs) {
- std::transform(linkerOptions.begin(), linkerOptions.end(),
- linkerOptions.begin(),
- [&wrapperFlag](std::string const& o) -> std::string {
- return wrapperFlag.back() + o;
- });
- }
- for (std::string& o : linkerOptions) {
- for (auto i = wrapperFlag.begin(),
- e = concatFlagAndArgs ? wrapperFlag.end() - 1
- : wrapperFlag.end();
- i != e; ++i) {
- options.emplace_back(*i, bt);
- }
- options.emplace_back(std::move(o), bt);
- }
- }
- }
+ std::vector<BT<std::string>> options = wrapOptions(
+ linkerOptions, bt, wrapperFlag, wrapperSep, concatFlagAndArgs);
result.insert(entry, options.begin(), options.end());
}
return result;
@@ -3951,7 +4326,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
}
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
- cmContains(debugProperties, "LINK_DIRECTORIES");
+ cm::contains(debugProperties, "LINK_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkDirectoriesDone = true;
@@ -4188,8 +4563,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
targetNames.Real += this->GetFrameworkVersion();
targetNames.Real += "/";
}
- targetNames.Real += targetNames.Base;
- targetNames.SharedObject = targetNames.Real;
+ targetNames.Real += targetNames.Base + suffix;
+ targetNames.SharedObject = targetNames.Real + suffix;
} else {
// The library's soname.
this->ComputeVersionedName(targetNames.SharedObject, prefix,
@@ -4364,7 +4739,15 @@ void cmGeneratorTarget::GetFullNameInternal(
outBase += this->GetOutputName(config, artifact);
// Append the per-configuration postfix.
- outBase += configPostfix;
+ // When using Xcode, the postfix should be part of the suffix rather than
+ // the base, because the suffix ends up being used in Xcode's
+ // EXECUTABLE_SUFFIX attribute.
+ if (this->IsFrameworkOnApple() &&
+ GetGlobalGenerator()->GetName() == "Xcode") {
+ targetSuffix = configPostfix.c_str();
+ } else {
+ outBase += configPostfix;
+ }
// Name shared libraries with their version number on some platforms.
if (const char* soversion = this->GetProperty("SOVERSION")) {
@@ -4503,16 +4886,16 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
} else {
// Handle the MACOSX_PACKAGE_LOCATION property on source files that
// were not listed in one of the other lists.
- if (const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
- flags.MacFolder = location;
+ if (cmProp location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
+ flags.MacFolder = location->c_str();
const bool stripResources =
this->GlobalGenerator->ShouldStripResourcePath(this->Makefile);
- if (strcmp(location, "Resources") == 0) {
+ if (*location == "Resources") {
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
if (stripResources) {
flags.MacFolder = "";
}
- } else if (cmHasLiteralPrefix(location, "Resources/")) {
+ } else if (cmHasLiteralPrefix(*location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
flags.MacFolder += strlen("Resources/");
@@ -4855,7 +5238,8 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
std::ostringstream e;
e << "Property \"" << prop << "\" appears in both the " << propsString
<< " property in the dependencies of target \"" << this->GetName()
- << "\". This is not allowed. A property may only require compatibility "
+ << "\". This is not allowed. A property may only require "
+ "compatibility "
"in a boolean interpretation, a numeric minimum, a numeric maximum "
"or a "
"string interpretation, but not a mixture.";
@@ -5104,7 +5488,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
- const bool explicitlySet = cmContains(headPropKeys, p);
+ const bool explicitlySet = cm::contains(headPropKeys, p);
const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
@@ -5144,7 +5528,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
- const bool ifaceIsSet = cmContains(propKeys, interfaceProperty);
+ const bool ifaceIsSet = cm::contains(propKeys, interfaceProperty);
PropertyType ifacePropContent = getTypedProperty<PropertyType>(
theTarget, interfaceProperty, genexInterpreter.get());
@@ -5237,6 +5621,13 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
return propContent;
}
+bool cmGeneratorTarget::SetDeviceLink(bool deviceLink)
+{
+ bool previous = this->DeviceLink;
+ this->DeviceLink = deviceLink;
+ return previous;
+}
+
bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
const std::string& p, const std::string& config) const
{
@@ -5435,8 +5826,8 @@ void cmGeneratorTarget::ReportPropertyOrigin(
cmExpandList(debugProp, debugProperties);
}
- bool debugOrigin =
- !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p);
+ bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
+ cm::contains(debugProperties, p);
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompatiblePropertiesDone[p] = true;
@@ -5492,31 +5883,42 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
void cmGeneratorTarget::ExpandLinkItems(
std::string const& prop, std::string const& value, std::string const& config,
cmGeneratorTarget const* headTarget, bool usage_requirements_only,
- std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
+ std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const
{
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
- // The $<LINK_ONLY> expression may be in a link interface to specify private
- // link dependencies that are otherwise excluded from usage requirements.
+ // The $<LINK_ONLY> expression may be in a link interface to specify
+ // private link dependencies that are otherwise excluded from usage
+ // requirements.
if (usage_requirements_only) {
dagChecker.SetTransitivePropertiesOnly();
}
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- cmExpandList(
- cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this),
- libs);
+ cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
+ &dagChecker, this, headTarget->LinkerLanguage),
+ libs);
this->LookupLinkItems(libs, cge->GetBacktrace(), items);
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+ hadLinkLanguageSensitiveCondition =
+ cge->GetHadLinkLanguageSensitiveCondition();
}
cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
const std::string& config, cmGeneratorTarget const* head) const
{
+ return this->GetLinkInterface(config, head, false);
+}
+
+cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
+ const std::string& config, cmGeneratorTarget const* head,
+ bool secondPass) const
+{
// Imported targets have their own link interface.
if (this->IsImported()) {
- return this->GetImportLinkInterface(config, head, false);
+ return this->GetImportLinkInterface(config, head, false, secondPass);
}
// Link interfaces are not supported for executables that do not
@@ -5529,6 +5931,10 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
// Lookup any existing link interface for this configuration.
cmHeadToLinkInterfaceMap& hm = this->GetHeadToLinkInterfaceMap(config);
+ if (secondPass) {
+ hm.erase(head);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -5543,7 +5949,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
if (!iface.AllDone) {
iface.AllDone = true;
if (iface.Exists) {
- this->ComputeLinkInterface(config, iface, head);
+ this->ComputeLinkInterface(config, iface, head, secondPass);
}
}
@@ -5554,6 +5960,13 @@ void cmGeneratorTarget::ComputeLinkInterface(
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget) const
{
+ this->ComputeLinkInterface(config, iface, headTarget, false);
+}
+
+void cmGeneratorTarget::ComputeLinkInterface(
+ const std::string& config, cmOptionalLinkInterface& iface,
+ cmGeneratorTarget const* headTarget, bool secondPass) const
+{
if (iface.Explicit) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -5565,7 +5978,8 @@ void cmGeneratorTarget::ComputeLinkInterface(
emitted.insert(lib);
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
if (emitted.insert(lib).second) {
if (lib.Target) {
@@ -5575,9 +5989,9 @@ void cmGeneratorTarget::ComputeLinkInterface(
}
} else {
// TODO: Recognize shared library file names. Perhaps this
- // should be moved to cmComputeLinkInformation, but that creates
- // a chicken-and-egg problem since this list is needed for its
- // construction.
+ // should be moved to cmComputeLinkInformation, but that
+ // creates a chicken-and-egg problem since this list is needed
+ // for its construction.
}
}
}
@@ -5595,7 +6009,7 @@ void cmGeneratorTarget::ComputeLinkInterface(
if (this->LinkLanguagePropagatesToDependents()) {
// Targets using this archive need its language runtime libraries.
if (cmLinkImplementation const* impl =
- this->GetLinkImplementation(config)) {
+ this->GetLinkImplementation(config, secondPass)) {
iface.Languages = impl->Languages;
}
}
@@ -5638,7 +6052,6 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries(
}
// Lookup any existing link interface for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
cmHeadToLinkInterfaceMap& hm =
(usage_requirements_only
? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
@@ -5991,7 +6404,8 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ iface.HadHeadSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
} else if (!cmp0022NEW)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
@@ -6011,9 +6425,11 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
bool hadHeadSensitiveConditionDummy = false;
+ bool hadLinkLanguageSensitiveConditionDummy = false;
this->ExpandLinkItems(newProp, newExplicitLibraries, config,
headTarget, usage_requirements_only, ifaceLibs,
- hadHeadSensitiveConditionDummy);
+ hadHeadSensitiveConditionDummy,
+ hadLinkLanguageSensitiveConditionDummy);
}
if (ifaceLibs != iface.Libraries) {
std::string oldLibraries = cmJoin(impl->Libraries, ";");
@@ -6050,19 +6466,22 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
const std::string& config, cmGeneratorTarget const* headTarget,
- bool usage_requirements_only) const
+ bool usage_requirements_only, bool secondPass) const
{
cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
if (!info) {
return nullptr;
}
- std::string CONFIG = cmSystemTools::UpperCase(config);
cmHeadToLinkInterfaceMap& hm =
(usage_requirements_only
? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
: this->GetHeadToLinkInterfaceMap(config));
+ if (secondPass) {
+ hm.erase(headTarget);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -6076,7 +6495,8 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ iface.HadHeadSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -6132,10 +6552,10 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Initialize members.
info.NoSOName = false;
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+ if (!this->Target->GetMappedConfig(desired_config, loc, imp, suffix)) {
return;
}
@@ -6162,7 +6582,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
if (loc) {
- info.LibName = loc;
+ info.LibName = *loc;
}
return;
}
@@ -6172,7 +6592,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the location.
if (loc) {
- info.Location = loc;
+ info.Location = *loc;
} else {
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
if (const char* config_location = this->GetProperty(impProp)) {
@@ -6205,7 +6625,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the import library.
if (imp) {
- info.ImportLibrary = imp;
+ info.ImportLibrary = *imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
@@ -6266,28 +6686,36 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
cmHeadToLinkInterfaceMap& cmGeneratorTarget::GetHeadToLinkInterfaceMap(
const std::string& config) const
{
- std::string CONFIG = cmSystemTools::UpperCase(config);
- return this->LinkInterfaceMap[CONFIG];
+ return this->LinkInterfaceMap[cmSystemTools::UpperCase(config)];
}
cmHeadToLinkInterfaceMap&
cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
const std::string& config) const
{
- std::string CONFIG = cmSystemTools::UpperCase(config);
- return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+ return this
+ ->LinkInterfaceUsageRequirementsOnlyMap[cmSystemTools::UpperCase(config)];
}
const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
const std::string& config) const
{
+ return this->GetLinkImplementation(config, false);
+}
+
+const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
+ const std::string& config, bool secondPass) const
+{
// There is no link implementation for imported targets.
if (this->IsImported()) {
return nullptr;
}
- std::string CONFIG = cmSystemTools::UpperCase(config);
- cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
+ cmOptionalLinkImplementation& impl =
+ this->LinkImplMap[cmSystemTools::UpperCase(config)][this];
+ if (secondPass) {
+ impl = cmOptionalLinkImplementation();
+ }
if (!impl.LibrariesDone) {
impl.LibrariesDone = true;
this->ComputeLinkImplementationLibraries(config, impl, this);
@@ -6543,8 +6971,8 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
}
// Populate the link implementation libraries for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
- HeadToLinkImplementationMap& hm = this->LinkImplMap[CONFIG];
+ HeadToLinkImplementationMap& hm =
+ this->LinkImplMap[cmSystemTools::UpperCase(config)];
// If the link implementation does not depend on the head target
// then return the one we computed first.
@@ -6563,7 +6991,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
const std::string& p) const
{
- return cmContains(this->LinkImplicitNullProperties, p);
+ return cm::contains(this->LinkImplicitNullProperties, p);
}
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
@@ -6585,11 +7013,15 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
std::string const& evaluated =
- cge->Evaluate(this->LocalGenerator, config, head, &dagChecker);
+ cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
+ this->LinkerLanguage);
cmExpandList(evaluated, llibs);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ impl.HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& lib : llibs) {
if (this->IsLinkLookupScope(lib, lg)) {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index d81bb3d..dd46bb9 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -204,6 +204,24 @@ public:
const char* GetLinkInterfaceDependentNumberMaxProperty(
const std::string& p, const std::string& config) const;
+ class DeviceLinkSetter
+ {
+ public:
+ DeviceLinkSetter(cmGeneratorTarget& target)
+ : Target(target)
+ {
+ this->PreviousState = target.SetDeviceLink(true);
+ }
+ ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); };
+
+ private:
+ cmGeneratorTarget& Target;
+ bool PreviousState;
+ };
+
+ bool SetDeviceLink(bool deviceLink);
+ bool IsDeviceLink() const { return this->DeviceLink; }
+
cmLinkInterface const* GetLinkInterface(
const std::string& config, const cmGeneratorTarget* headTarget) const;
void ComputeLinkInterface(const std::string& config,
@@ -357,7 +375,6 @@ public:
};
LinkClosure const* GetLinkClosure(const std::string& config) const;
- void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
cmLinkImplementation const* GetLinkImplementation(
const std::string& config) const;
@@ -422,6 +439,8 @@ public:
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
+ void AddCUDAArchitectureFlags(std::string& flags) const;
+
std::string GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
std::string const& config) const;
@@ -479,17 +498,23 @@ public:
const std::string& config, const std::string& language) const;
std::string GetPchHeader(const std::string& config,
- const std::string& language) const;
+ const std::string& language,
+ const std::string& arch = std::string()) const;
std::string GetPchSource(const std::string& config,
- const std::string& language) const;
+ const std::string& language,
+ const std::string& arch = std::string()) const;
std::string GetPchFileObject(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
std::string GetPchFile(const std::string& config,
- const std::string& language);
- std::string GetPchCreateCompileOptions(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
+ std::string GetPchCreateCompileOptions(
+ const std::string& config, const std::string& language,
+ const std::string& arch = std::string());
std::string GetPchUseCompileOptions(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
void AddSourceFileToUnityBatch(const std::string& sourceFilename);
bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
@@ -589,6 +614,9 @@ public:
/** Get target file postfix */
std::string GetFilePostfix(const std::string& config) const;
+ /** Get framework multi-config-specific postfix */
+ std::string GetFrameworkMultiConfigPostfix(const std::string& config) const;
+
/** Clears cached meta data for local and external source files.
* The meta data will be recomputed on demand.
*/
@@ -816,8 +844,10 @@ private:
std::string& outPrefix, std::string& outBase,
std::string& outSuffix) const;
+ mutable std::string LinkerLanguage;
using LinkClosureMapType = std::map<std::string, LinkClosure>;
mutable LinkClosureMapType LinkClosureMap;
+ bool DeviceLink = false;
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
const char* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
@@ -850,6 +880,10 @@ private:
void CheckPropertyCompatibility(cmComputeLinkInformation& info,
const std::string& config) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+ bool ComputeLinkClosure(const std::string& config, LinkClosure& lc,
+ bool secondPass) const;
+
struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
{
bool Done = false;
@@ -868,6 +902,17 @@ private:
std::string GetLinkInterfaceDependentStringAsBoolProperty(
const std::string& p, const std::string& config) const;
+ friend class cmTargetCollectLinkLanguages;
+ cmLinkInterface const* GetLinkInterface(const std::string& config,
+ const cmGeneratorTarget* headTarget,
+ bool secondPass) const;
+ void ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface& iface,
+ const cmGeneratorTarget* head,
+ bool secondPass) const;
+ cmLinkImplementation const* GetLinkImplementation(const std::string& config,
+ bool secondPass) const;
+
// Cache import information from properties for each configuration.
struct ImportInfo
{
@@ -894,9 +939,10 @@ private:
the link dependencies of this target. */
std::string CheckCMP0004(std::string const& item) const;
- cmLinkInterface const* GetImportLinkInterface(
- const std::string& config, const cmGeneratorTarget* head,
- bool usage_requirements_only) const;
+ cmLinkInterface const* GetImportLinkInterface(const std::string& config,
+ const cmGeneratorTarget* head,
+ bool usage_requirements_only,
+ bool secondPass = false) const;
using KindedSourcesMapType = std::map<std::string, KindedSources>;
mutable KindedSourcesMapType KindedSourcesMap;
@@ -940,7 +986,8 @@ private:
const cmGeneratorTarget* headTarget,
bool usage_requirements_only,
std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const;
+ bool& hadHeadSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const;
void LookupLinkItems(std::vector<std::string> const& names,
cmListFileBacktrace const& bt,
std::vector<cmLinkItem>& items) const;
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index ff4e312..0480876 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -23,25 +23,25 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
std::string output = "NOTFOUND";
if (args[1] == "VARIABLES") {
- if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
- output = varsProp;
+ if (cmProp varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
+ output = *varsProp;
}
} else if (args[1] == "MACROS") {
output.clear();
- if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) {
- output = macrosProp;
+ if (cmProp macrosProp = status.GetMakefile().GetProperty("MACROS")) {
+ output = *macrosProp;
}
} else if (args[1] == "COMPONENTS") {
const std::set<std::string>* components =
status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
output = cmJoin(*components, ";");
} else {
- const char* prop = nullptr;
+ cmProp prop = nullptr;
if (!args[1].empty()) {
prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]);
}
if (prop) {
- output = prop;
+ output = *prop;
}
}
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 64438d5..2833977 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -7,7 +7,6 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace {
@@ -37,14 +36,8 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
"DIRECTORY argument provided without subsequent arguments");
return false;
}
- std::string sd = *i;
- // make sure the start dir is a full path
- if (!cmSystemTools::FileIsFullPath(sd)) {
- sd = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
- }
-
- // The local generators are associated with collapsed paths.
- sd = cmSystemTools::CollapseFullPath(sd);
+ std::string sd = cmSystemTools::CollapseFullPath(
+ *i, status.GetMakefile().GetCurrentSourceDirectory());
// lookup the makefile from the directory name
dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd);
@@ -92,7 +85,9 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
break;
}
}
- prop = dir->GetProperty(*i);
+ if (cmProp p = dir->GetProperty(*i)) {
+ prop = p->c_str();
+ }
}
StoreResult(status.GetMakefile(), variable, prop);
return true;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 7d91a75..811421a 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -120,11 +120,11 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
if (args.size() >= 4 && args.back() == "CACHE") {
if (!programArgs.empty() && !storeArgs.empty()) {
status.GetMakefile().AddCacheDefinition(
- storeArgs, programArgs.c_str(), "",
+ storeArgs, programArgs, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
}
status.GetMakefile().AddCacheDefinition(
- args.front(), result.c_str(), "",
+ args.front(), result, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
} else {
if (!programArgs.empty() && !storeArgs.empty()) {
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 947d893..c3ac672 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -241,8 +241,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,
- cm->GetState()->GetGlobalProperty(propertyName));
+ p ? p->c_str() : nullptr);
}
bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -256,14 +257,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
if (!name.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = name;
- if (!cmSystemTools::FileIsFullPath(dir)) {
- dir =
- cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', name);
- }
-
- // The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir);
+ std::string dir = cmSystemTools::CollapseFullPath(
+ name, status.GetMakefile().GetCurrentSourceDirectory());
// Lookup the generator.
mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
@@ -294,8 +289,9 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
}
// Get the property.
+ cmProp p = mf->GetProperty(propertyName);
return StoreResult(infoType, status.GetMakefile(), variable,
- mf->GetProperty(propertyName));
+ p ? p->c_str() : nullptr);
}
bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -315,7 +311,7 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
}
return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
}
- const char* prop_cstr = nullptr;
+ cmProp prop_cstr = nullptr;
cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
cmMessenger* messenger = status.GetMakefile().GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(
@@ -325,7 +321,8 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
prop_cstr = target->GetProperty(propertyName);
}
}
- return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr);
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ prop_cstr ? prop_cstr->c_str() : nullptr);
}
status.SetError(cmStrCat("could not find TARGET ", name,
". Perhaps it has not yet been created."));
@@ -393,12 +390,13 @@ bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
return false;
}
- const char* value = nullptr;
+ cmProp value = nullptr;
if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
value = status.GetMakefile().GetState()->GetCacheEntryProperty(
name, propertyName);
}
- StoreResult(infoType, status.GetMakefile(), variable, value);
+ StoreResult(infoType, status.GetMakefile(), variable,
+ value ? value->c_str() : nullptr);
return true;
}
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 7f5df9c..6b850d1 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -34,7 +34,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
prop_exists = true;
}
} else if (!args[2].empty()) {
- const char* prop_cstr = nullptr;
+ cmProp prop_cstr = nullptr;
cmListFileBacktrace bt = mf.GetBacktrace();
cmMessenger* messenger = mf.GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
@@ -45,7 +45,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
}
}
if (prop_cstr) {
- prop = prop_cstr;
+ prop = *prop_cstr;
prop_exists = true;
}
}
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 5e2248e..f0c6d48 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -165,13 +165,15 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
outpath = this->GeneratorTarget->GetDirectory(config);
outpath =
this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath);
- fout << " :binDirRelative=\"" << outpath << "\"" << std::endl;
- fout << " -o \"" << this->TargetNameReal << "\"" << std::endl;
+ /* clang-format off */
+ fout << " :binDirRelative=\"" << outpath << "\"\n"
+ " -o \"" << this->TargetNameReal << "\"\n";
+ /* clang-format on */
}
// set target object file destination
outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- fout << " :outputDirRelative=\"" << outpath << "\"" << std::endl;
+ fout << " :outputDirRelative=\"" << outpath << "\"\n";
}
void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
@@ -180,15 +182,12 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
auto i = this->FlagsByLanguage.find(language);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
- const char* lang = language.c_str();
-
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
- config);
-
- this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
- config);
+ this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ language, config);
+ this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
+ language, config);
this->LocalGenerator->AddVisibilityPresetFlags(
- flags, this->GeneratorTarget, lang);
+ flags, this->GeneratorTarget, language);
// Append old-style preprocessor definition flags.
if (this->Makefile->GetDefineFlags() != " ") {
@@ -197,8 +196,8 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
}
// Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
- config);
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ language, config);
std::map<std::string, std::string>::value_type entry(language, flags);
i = this->FlagsByLanguage.insert(entry).first;
@@ -211,13 +210,12 @@ std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
auto i = this->DefinesByLanguage.find(language);
if (i == this->DefinesByLanguage.end()) {
std::set<std::string> defines;
- const char* lang = language.c_str();
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config,
language, defines);
std::string definesString;
- this->LocalGenerator->JoinDefines(defines, definesString, lang);
+ this->LocalGenerator->JoinDefines(defines, definesString, language);
std::map<std::string, std::string>::value_type entry(language,
definesString);
@@ -235,8 +233,8 @@ void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
if (!flagsByLangI->second.empty()) {
std::vector<std::string> ghsCompFlags =
cmSystemTools::ParseArguments(flagsByLangI->second);
- for (auto& f : ghsCompFlags) {
- fout << " " << f << std::endl;
+ for (const std::string& f : ghsCompFlags) {
+ fout << " " << f << '\n';
}
}
}
@@ -249,7 +247,7 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
language);
for (std::string const& compileDefinition : compileDefinitions) {
- fout << " -D" << compileDefinition << std::endl;
+ fout << " -D" << compileDefinition << '\n';
}
}
@@ -262,7 +260,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
language, config);
for (std::string const& include : includes) {
- fout << " -I\"" << include << "\"" << std::endl;
+ fout << " -I\"" << include << "\"\n";
}
}
@@ -290,15 +288,15 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
// write out link options
std::vector<std::string> lopts = cmSystemTools::ParseArguments(linkFlags);
- for (auto& l : lopts) {
- fout << " " << l << std::endl;
+ for (const std::string& l : lopts) {
+ fout << " " << l << '\n';
}
// write out link search paths
// must be quoted for paths that contain spaces
std::vector<std::string> lpath = cmSystemTools::ParseArguments(linkPath);
- for (auto& l : lpath) {
- fout << " -L\"" << l << "\"" << std::endl;
+ for (const std::string& l : lpath) {
+ fout << " -L\"" << l << "\"\n";
}
// write out link libs
@@ -307,12 +305,12 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
std::vector<std::string> llibs =
cmSystemTools::ParseArguments(linkLibraries);
- for (auto& l : llibs) {
+ for (const std::string& l : llibs) {
if (l.compare(0, 2, "-l") == 0) {
- fout << " \"" << l << "\"" << std::endl;
+ fout << " \"" << l << "\"\n";
} else {
std::string rl = cmSystemTools::CollapseFullPath(l, cbd);
- fout << " -l\"" << rl << "\"" << std::endl;
+ fout << " -l\"" << rl << "\"\n";
}
}
}
@@ -353,13 +351,12 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
this->WriteCustomCommandsHelper(f, ccg);
f.Close();
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
- fout << " :" << cmd << "=\"" << fname << "\"" << std::endl;
+ fout << " :" << cmd << "=\"" << fname << "\"\n";
} else {
- fout << fname << std::endl;
- fout << " :outputName=\"" << fname << ".rule\"" << std::endl;
+ fout << fname << "\n :outputName=\"" << fname << ".rule\"\n";
}
for (auto& byp : ccg.GetByproducts()) {
- fout << " :extraOutputFile=\"" << byp << "\"" << std::endl;
+ fout << " :extraOutputFile=\"" << byp << "\"\n";
}
}
}
@@ -451,8 +448,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// push back the custom commands
for (auto const& c : cmdLines) {
- fout << c << std::endl;
- fout << check_error << std::endl;
+ fout << c << '\n' << check_error << '\n';
}
}
@@ -460,11 +456,11 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
std::ostream& fout, const cmSourceFile* sf, std::string const& propName,
std::string const& propFlag)
{
- const char* prop = sf->GetProperty(propName);
+ cmProp prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list = cmExpandedList(prop);
- for (auto& p : list) {
- fout << " " << propFlag << p << std::endl;
+ std::vector<std::string> list = cmExpandedList(*prop);
+ for (const std::string& p : list) {
+ fout << " " << propFlag << p << '\n';
}
}
}
@@ -483,7 +479,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
/* for each source file assign it to its group */
std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
std::set<std::string> groupNames;
- for (auto& sf : sources) {
+ for (cmSourceFile* sf : sources) {
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(sf->ResolveFullPath(), sourceGroups);
std::string gn = sourceGroup->GetFullName();
@@ -579,12 +575,12 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
if (useProjectFile) {
if (sg.empty()) {
- *fout << "{comment} Others" << std::endl;
+ *fout << "{comment} Others" << '\n';
} else {
- *fout << "{comment} " << sg << std::endl;
+ *fout << "{comment} " << sg << '\n';
}
} else if (sg.empty()) {
- *fout << "{comment} Others" << std::endl;
+ *fout << "{comment} Others\n";
}
if (sg != "CMake Rules") {
@@ -612,7 +608,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
compile = false;
}
- *fout << comment << fname << std::endl;
+ *fout << comment << fname << '\n';
if (compile) {
if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
"bsp" != si->GetExtension()) {
@@ -628,7 +624,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
std::string objectName = this->GeneratorTarget->GetObjectName(si);
if (!objectName.empty() &&
this->GeneratorTarget->HasExplicitObjectName(si)) {
- *fout << " -o " << objectName << std::endl;
+ *fout << " -o " << objectName << '\n';
}
}
}
@@ -695,14 +691,14 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
*/
bool specifyExtra = true;
for (auto& out : ccg.GetOutputs()) {
- fout << fname << std::endl;
- fout << " :outputName=\"" << out << "\"" << std::endl;
+ fout << fname << '\n';
+ fout << " :outputName=\"" << out << "\"\n";
if (specifyExtra) {
for (auto& byp : ccg.GetByproducts()) {
- fout << " :extraOutputFile=\"" << byp << "\"" << std::endl;
+ fout << " :extraOutputFile=\"" << byp << "\"\n";
}
for (auto& dep : ccg.GetDepends()) {
- fout << " :depends=\"" << dep << "\"" << std::endl;
+ fout << " :depends=\"" << dep << "\"\n";
}
specifyExtra = false;
}
@@ -712,12 +708,12 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
std::ostream& fout, const cmSourceFile* sourceFile)
{
- const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
+ cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (nullptr != rawLangProp) {
- std::string sourceLangProp(rawLangProp);
+ std::string sourceLangProp(*rawLangProp);
std::string const& extension = sourceFile->GetExtension();
if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
- fout << " -dotciscxx" << std::endl;
+ fout << " -dotciscxx\n";
}
}
}
@@ -730,7 +726,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
}
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
- for (auto& sf : sources) {
+ for (const cmSourceFile* sf : sources) {
if ("int" == sf->GetExtension()) {
return true;
}
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 9af0eac..3c97955 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -46,6 +46,7 @@ public:
bool AllowNotParallel() const override { return false; }
bool AllowDeleteOnError() const override { return false; }
+ bool CanEscapeOctothorpe() const override { return true; }
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 6a2d4c7..a6ca75f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -14,6 +14,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -246,11 +247,10 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
cmSystemTools::ConvertToUnixSlashes(cnameString);
cmSystemTools::ConvertToUnixSlashes(pathString);
if (cnameString != pathString) {
- const char* cvars =
- this->GetCMakeInstance()->GetState()->GetGlobalProperty(
- "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+ cmProp cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
if (cvars) {
- changeVars += cvars;
+ changeVars += *cvars;
changeVars += ";";
}
changeVars += langComp;
@@ -404,7 +404,7 @@ bool cmGlobalGenerator::IsExportedTargetsFile(
if (it == this->BuildExportSets.end()) {
return false;
}
- return !cmContains(this->BuildExportExportSets, filename);
+ return !cm::contains(this->BuildExportExportSets, filename);
}
// Find the make program for the generator, required for try compiles
@@ -445,8 +445,8 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
cmSystemTools::GetShortPath(makeProgram, makeProgram);
cmSystemTools::SplitProgramPath(makeProgram, dir, file);
makeProgram = cmStrCat(dir, '/', saveFile);
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
- "make program", cmStateEnums::FILEPATH);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram, "make program",
+ cmStateEnums::FILEPATH);
}
return true;
}
@@ -530,7 +530,7 @@ void cmGlobalGenerator::EnableLanguage(
if (lang == "NONE") {
this->SetLanguageEnabled("NONE", mf);
} else {
- if (!cmContains(this->LanguagesReady, lang)) {
+ if (!cm::contains(this->LanguagesReady, lang)) {
std::ostringstream e;
e << "The test project needs language " << lang
<< " which is not enabled.";
@@ -1095,7 +1095,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
{
// use LanguageToLinkerPreference to detect whether this functions has
// run before
- if (cmContains(this->LanguageToLinkerPreference, l)) {
+ if (cm::contains(this->LanguageToLinkerPreference, l)) {
return;
}
@@ -1679,8 +1679,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
for (std::string const& c : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
- if (const char* val = mf->GetProperty(defPropName)) {
- t->AppendProperty(defPropName, val);
+ if (cmProp val = mf->GetProperty(defPropName)) {
+ t->AppendProperty(defPropName, *val);
}
}
}
@@ -1791,14 +1791,13 @@ void cmGlobalGenerator::CheckTargetProperties()
}
}
std::vector<std::string> incs;
- const char* incDirProp =
- target.second.GetProperty("INCLUDE_DIRECTORIES");
+ cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
}
std::string incDirs = cmGeneratorExpression::Preprocess(
- incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+ *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
cmExpandList(incDirs, incs);
@@ -2229,7 +2228,7 @@ void cmGlobalGenerator::AddAlias(const std::string& name,
bool cmGlobalGenerator::IsAlias(const std::string& name) const
{
- return cmContains(this->AliasTargets, name);
+ return cm::contains(this->AliasTargets, name);
}
void cmGlobalGenerator::IndexTarget(cmTarget* t)
@@ -2255,10 +2254,12 @@ std::string cmGlobalGenerator::IndexGeneratorTargetUniquely(
// Use a ":" prefix to avoid conflict with project-defined targets.
// We must satisfy cmGeneratorExpression::IsValidTargetName so use no
// other special characters.
- char buf[1 + sizeof(gt) * 2];
+ constexpr size_t sizeof_ptr =
+ sizeof(gt); // NOLINT(bugprone-sizeof-expression)
+ char buf[1 + sizeof_ptr * 2];
char* b = buf;
*b++ = ':';
- for (size_t i = 0; i < sizeof(gt); ++i) {
+ for (size_t i = 0; i < sizeof_ptr; ++i) {
unsigned char const c = reinterpret_cast<unsigned char const*>(&gt)[i];
*b++ = hexDigits[(c & 0xf0) >> 4];
*b++ = hexDigits[(c & 0x0f)];
@@ -2545,6 +2546,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
singleLine.push_back("No interactive CMake dialog available.");
gti.Message = "No interactive CMake dialog available...";
gti.UsesTerminal = false;
+ gti.StdPipesUTF8 = true;
}
gti.CommandLines.push_back(std::move(singleLine));
@@ -2569,6 +2571,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.CommandLines.push_back(std::move(singleLine));
+ gti.StdPipesUTF8 = true;
targets.push_back(std::move(gti));
}
@@ -2605,6 +2608,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
gti.Name = this->GetInstallTargetName();
gti.Message = "Install the project...";
gti.UsesTerminal = true;
+ gti.StdPipesUTF8 = true;
cmCustomCommandLine singleLine;
if (this->GetPreinstallTargetName()) {
gti.Depends.emplace_back(this->GetPreinstallTargetName());
@@ -2674,13 +2678,13 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
}
}
-const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
+std::string cmGlobalGenerator::GetPredefinedTargetsFolder()
{
- const char* prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"PREDEFINED_TARGETS_FOLDER");
if (prop) {
- return prop;
+ return *prop;
}
return "CMakePredefinedTargets";
@@ -2688,13 +2692,13 @@ const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
bool cmGlobalGenerator::UseFolderProperty() const
{
- const char* prop =
+ cmProp prop =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
// If this property is defined, let the setter turn this on or off...
//
if (prop) {
- return cmIsOn(prop);
+ return cmIsOn(*prop);
}
// By default, this feature is OFF, since it is not supported in the
@@ -2716,7 +2720,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
std::vector<std::string> no_depends;
// Store the custom command in the target.
cmCustomCommand cc(no_outputs, no_byproducts, no_depends, gti.CommandLines,
- cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str());
+ cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str(),
+ gti.StdPipesUTF8);
cc.SetUsesTerminal(gti.UsesTerminal);
target.AddPostBuildCommand(std::move(cc));
if (!gti.Message.empty()) {
@@ -2788,7 +2793,7 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
"clean", "edit_cache", "rebuild_cache",
"ZERO_CHECK" };
- return cmContains(reservedTargets, name);
+ return cm::contains(reservedTargets, name);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
@@ -3036,7 +3041,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
#ifndef CMAKE_BOOTSTRAP
// Check whether labels are enabled for this target.
const char* targetLabels = target->GetProperty("LABELS");
- const char* directoryLabels =
+ cmProp directoryLabels =
target->Target->GetMakefile()->GetProperty("LABELS");
const char* cmakeDirectoryLabels =
target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS");
@@ -3070,7 +3075,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::vector<std::string> cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmExpandList(directoryLabels, directoryLabelsList);
+ cmExpandList(*directoryLabels, directoryLabelsList);
}
if (cmakeDirectoryLabels) {
@@ -3105,10 +3110,10 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::string const& sfp = sf->ResolveFullPath();
fout << sfp << "\n";
lj_source["file"] = sfp;
- if (const char* svalue = sf->GetProperty("LABELS")) {
+ if (cmProp svalue = sf->GetProperty("LABELS")) {
labels.clear();
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
- cmExpandList(svalue, labels);
+ cmExpandList(*svalue, labels);
for (std::string const& label : labels) {
fout << " " << label << "\n";
lj_source_labels.append(label);
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 7dc4822..a76ab3c 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -554,6 +554,7 @@ protected:
std::string WorkingDir;
bool UsesTerminal = false;
bool PerConfig = true;
+ bool StdPipesUTF8 = false;
};
void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
@@ -588,7 +589,7 @@ protected:
cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
- const char* GetPredefinedTargetsFolder();
+ std::string GetPredefinedTargetsFolder();
private:
using TargetMap = std::unordered_map<std::string, cmTarget*>;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index bb9dd37..24559e6 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -9,8 +9,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -90,7 +91,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
/* store the full toolset for later use
* -- already done if -T<toolset> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp,
"Location of generator toolset.",
cmStateEnums::INTERNAL);
}
@@ -112,8 +113,8 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
}
/* store the toolset that is being used for this build */
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
- "build program to use", cmStateEnums::INTERNAL, true);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild, "build program to use",
+ cmStateEnums::INTERNAL, true);
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
@@ -132,7 +133,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
/* store the platform name for later use
* -- already done if -A<arch> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch,
"Name of generator platform.",
cmStateEnums::INTERNAL);
} else {
@@ -166,7 +167,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
if (cmIsOff(bspName) && platform.find("integrity") != std::string::npos) {
bspName = "sim" + arch;
/* write back the calculate name for next time */
- mf->AddCacheDefinition("GHS_BSP_NAME", bspName.c_str(),
+ mf->AddCacheDefinition("GHS_BSP_NAME", bspName,
"Name of GHS target platform.",
cmStateEnums::STRING, true);
std::string m = cmStrCat(
@@ -253,14 +254,15 @@ void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
{
- fout << "#!gbuild" << std::endl;
- fout << "#" << std::endl
- << "# CMAKE generated file: DO NOT EDIT!" << std::endl
- << "# Generated by \"" << GetActualName() << "\""
- << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
- << cmVersion::GetMinorVersion() << std::endl
- << "#" << std::endl
- << std::endl;
+ /* clang-format off */
+ fout << "#!gbuild\n"
+ "#\n"
+ "# CMAKE generated file: DO NOT EDIT!\n"
+ "# Generated by \"" << GetActualName() << "\""
+ " Generator, CMake Version " << cmVersion::GetMajorVersion() << '.'
+ << cmVersion::GetMinorVersion() << "\n"
+ "#\n\n";
+ /* clang-format on */
}
void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
@@ -268,36 +270,36 @@ void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
fout << "Commands {\n"
" Custom_Rule_Command {\n"
" name = \"Custom Rule Command\"\n"
- " exec = \"";
+ " exec = \""
#ifdef _WIN32
- fout << "cmd.exe";
+ "cmd.exe"
#else
- fout << "/bin/sh";
+ "/bin/sh"
#endif
- fout << "\"\n"
+ "\"\n"
" options = {\"SpecialOptions\"}\n"
" }\n"
- "}\n";
+ "}\n"
- fout << "\n\n";
- fout << "FileTypes {\n"
+ "\n\n"
+ "FileTypes {\n"
" CmakeRule {\n"
" name = \"Custom Rule\"\n"
" action = \"&Run\"\n"
- " extensions = {\"";
+ " extensions = {\""
#ifdef _WIN32
- fout << "bat";
+ "bat"
#else
- fout << "sh";
+ "sh"
#endif
- fout << "\"}\n"
+ "\"}\n"
" grepable = false\n"
" command = \"Custom Rule Command\"\n"
- " commandLine = \"$COMMAND ";
+ " commandLine = \"$COMMAND "
#ifdef _WIN32
- fout << "/c";
+ "/c"
#endif
- fout << " $INPUTFILE\"\n"
+ " $INPUTFILE\"\n"
" progress = \"Processing Custom Rule\"\n"
" promoteToFirstPass = true\n"
" outputType = \"None\"\n"
@@ -327,13 +329,13 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
this->WriteHighLevelDirectives(root, fout);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
- fout << "# Top Level Project File" << std::endl;
+ fout << "# Top Level Project File\n";
// Specify BSP option if supplied by user
const char* bspName =
this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
if (!cmIsOff(bspName)) {
- fout << " -bsp " << bspName << std::endl;
+ fout << " -bsp " << bspName << '\n';
}
// Specify OS DIR if supplied by user
@@ -348,14 +350,14 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
} else {
fout << osDirOption;
}
- fout << "\"" << this->OsDir << "\"" << std::endl;
+ fout << "\"" << this->OsDir << "\"\n";
}
}
void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
std::string& all_target)
{
- fout << "CMakeFiles/" << all_target << " [Project]" << std::endl;
+ fout << "CMakeFiles/" << all_target << " [Project]\n";
// All known targets
for (cmGeneratorTarget const* target : this->ProjectTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -366,7 +368,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
continue;
}
fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
- << " [Project]" << std::endl;
+ << " [Project]\n";
}
}
@@ -390,7 +392,7 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::string projFile = dir + projName + FILE_EXTENSION;
fout << projFile;
- fout << " " << projType << std::endl;
+ fout << ' ' << projType << '\n';
} else {
/* Should never happen */
std::string message =
@@ -583,14 +585,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
/* if multiple top-projects are found in build directory
* then prefer projectName top-project.
*/
- if (!cmContains(files, proj)) {
+ if (!cm::contains(files, proj)) {
proj = files.at(0);
}
}
makeCommand.Add("-top", proj);
if (!targetNames.empty()) {
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("-clean");
} else {
for (const auto& tname : targetNames) {
@@ -612,14 +614,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
cmLocalGenerator* root)
{
- fout << "macro PROJ_NAME=" << root->GetProjectName() << std::endl;
+ fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
if (nullptr != ghsGpjMacros) {
std::vector<std::string> expandedList =
cmExpandedList(std::string(ghsGpjMacros));
for (std::string const& arg : expandedList) {
- fout << "macro " << arg << std::endl;
+ fout << "macro " << arg << '\n';
}
}
}
@@ -642,30 +644,27 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
tgt = cmStrCat((a ? a : ""), '_', (p ? p : ""), ".tgt");
}
- fout << "primaryTarget=" << tgt << std::endl;
- fout << "customization=" << root->GetBinaryDirectory()
- << "/CMakeFiles/custom_rule.bod" << std::endl;
- fout << "customization=" << root->GetBinaryDirectory()
- << "/CMakeFiles/custom_target.bod" << std::endl;
+ /* clang-format off */
+ fout << "primaryTarget=" << tgt << "\n"
+ "customization=" << root->GetBinaryDirectory()
+ << "/CMakeFiles/custom_rule.bod\n"
+ "customization=" << root->GetBinaryDirectory()
+ << "/CMakeFiles/custom_target.bod" << '\n';
+ /* clang-format on */
char const* const customization =
this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
if (nullptr != customization && strlen(customization) > 0) {
- fout << "customization=" << this->TrimQuotes(customization) << std::endl;
+ fout << "customization="
+ << cmGlobalGhsMultiGenerator::TrimQuotes(customization) << '\n';
this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
}
}
-std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string const& str)
+std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string str)
{
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch != '"') {
- result += *ch;
- }
- }
- return result;
+ cm::erase(str, '"');
+ return str;
}
bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index b82e9f5..12ca8b6 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -111,7 +111,7 @@ private:
std::vector<cmLocalGenerator*>& generators,
std::string& all_target);
- std::string TrimQuotes(std::string const& str);
+ static std::string TrimQuotes(std::string str);
std::string OsDir;
static const char* DEFAULT_BUILD_PROGRAM;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index b6c343c..8ef19cc 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -18,7 +18,6 @@
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
@@ -46,7 +45,8 @@
#include "cmake.h"
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
-const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
+const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE =
+ "CMakeFiles/rules.ninja";
const char* cmGlobalNinjaGenerator::INDENT = " ";
#ifdef _WIN32
std::string const cmGlobalNinjaGenerator::SHELL_NOOP = "cd .";
@@ -147,15 +147,15 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Make sure there is a rule.
if (build.Rule.empty()) {
- cmSystemTools::Error("No rule for WriteBuild! called with comment: " +
- build.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No rule for WriteBuild! called with comment: ", build.Comment));
return;
}
// Make sure there is at least one output file.
if (build.Outputs.empty()) {
- cmSystemTools::Error(
- "No output files for WriteBuild! called with comment: " + build.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No output files for WriteBuild! called with comment: ", build.Comment));
return;
}
@@ -166,7 +166,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Write explicit outputs
for (std::string const& output : build.Outputs) {
- buildStr += " " + EncodePath(output);
+ buildStr += cmStrCat(' ', EncodePath(output));
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(output);
}
@@ -175,14 +175,13 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.ImplicitOuts.empty()) {
buildStr += " |";
for (std::string const& implicitOut : build.ImplicitOuts) {
- buildStr += " " + EncodePath(implicitOut);
+ buildStr += cmStrCat(' ', EncodePath(implicitOut));
}
}
- buildStr += ":";
+ buildStr += ':';
// Write the rule.
- buildStr += " ";
- buildStr += build.Rule;
+ buildStr += cmStrCat(' ', build.Rule);
}
std::string arguments;
@@ -191,14 +190,14 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
// Write explicit dependencies.
for (std::string const& explicitDep : build.ExplicitDeps) {
- arguments += " " + EncodePath(explicitDep);
+ arguments += cmStrCat(' ', EncodePath(explicitDep));
}
// Write implicit dependencies.
if (!build.ImplicitDeps.empty()) {
arguments += " |";
for (std::string const& implicitDep : build.ImplicitDeps) {
- arguments += " " + EncodePath(implicitDep);
+ arguments += cmStrCat(' ', EncodePath(implicitDep));
}
}
@@ -206,11 +205,11 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.OrderOnlyDeps.empty()) {
arguments += " ||";
for (std::string const& orderOnlyDep : build.OrderOnlyDeps) {
- arguments += " " + EncodePath(orderOnlyDep);
+ arguments += cmStrCat(' ', EncodePath(orderOnlyDep));
}
}
- arguments += "\n";
+ arguments += '\n';
}
// Write the variables bound to this build statement.
@@ -309,7 +308,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
cmNinjaRule rule("COPY_OSX_CONTENT");
- rule.Command = CMakeCmd() + " -E copy $in $out";
+ rule.Command = cmStrCat(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);
@@ -334,23 +333,24 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
// -- Parameter checks
// Make sure the rule has a name.
if (rule.Name.empty()) {
- cmSystemTools::Error("No name given for WriteRule! called with comment: " +
- rule.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No name given for WriteRule! called with comment: ", rule.Comment));
return;
}
// Make sure a command is given.
if (rule.Command.empty()) {
- cmSystemTools::Error(
- "No command given for WriteRule! called with comment: " + rule.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No command given for WriteRule! called with comment: ", rule.Comment));
return;
}
// Make sure response file content is given
if (!rule.RspFile.empty() && rule.RspContent.empty()) {
- cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! "
- "called with comment: " +
- rule.Comment);
+ cmSystemTools::Error(
+ cmStrCat("rspfile but no rspfile_content given for WriteRule! "
+ "called with comment: ",
+ rule.Comment));
return;
}
@@ -392,9 +392,9 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
{
// Make sure we have a name.
if (name.empty()) {
- cmSystemTools::Error("No name given for WriteVariable! called "
- "with comment: " +
- comment);
+ cmSystemTools::Error(cmStrCat("No name given for WriteVariable! called "
+ "with comment: ",
+ comment));
return;
}
@@ -435,8 +435,6 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
#endif
- // // Ninja is not ported to non-Unix OS yet.
- // this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
}
@@ -558,11 +556,11 @@ void cmGlobalNinjaGenerator::CleanMetaData()
nullptr,
cmSystemTools::OUTPUT_NONE)) {
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- "Running\n '" +
- cmJoin(command, "' '") +
- "'\n"
- "failed with:\n " +
- error);
+ cmStrCat("Running\n '",
+ cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ error));
cmSystemTools::SetFatalErrorOccured();
}
};
@@ -626,10 +624,10 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
nullptr,
cmSystemTools::OUTPUT_NONE)) {
mf->IssueMessage(MessageType::FATAL_ERROR,
- "Running\n '" + cmJoin(command, "' '") +
- "'\n"
- "failed with:\n " +
- error);
+ cmStrCat("Running\n '", cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ error));
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -686,10 +684,10 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
bool cmGlobalNinjaGenerator::CheckLanguages(
std::vector<std::string> const& languages, cmMakefile* mf) const
{
- if (cmContains(languages, "Fortran")) {
+ if (cm::contains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
- if (cmContains(languages, "Swift")) {
+ if (cm::contains(languages, "Swift")) {
const std::string architectures =
mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
if (architectures.find_first_of(';') != std::string::npos) {
@@ -713,7 +711,7 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
/* clang-format off */
e <<
"The Ninja generator does not support Fortran using Ninja version\n"
- " " + this->NinjaVersion + "\n"
+ " " << this->NinjaVersion << "\n"
"due to lack of required features. Ninja 1.10 or higher is required."
;
/* clang-format on */
@@ -991,7 +989,8 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
std::string buildFileDir =
this->GetCMakeInstance()->GetHomeOutputDirectory();
if (!this->CompileCommandsStream) {
- std::string buildFilePath = buildFileDir + "/compile_commands.json";
+ std::string buildFilePath =
+ cmStrCat(buildFileDir, "/compile_commands.json");
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(
this->NinjaOutputPath("compile_commands.json"));
@@ -1000,9 +999,9 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
// Get a stream where to generate things.
this->CompileCommandsStream =
cm::make_unique<cmGeneratedFileStream>(buildFilePath);
- *this->CompileCommandsStream << "[";
+ *this->CompileCommandsStream << "[\n";
} else {
- *this->CompileCommandsStream << "," << std::endl;
+ *this->CompileCommandsStream << ",\n";
}
std::string sourceFileName = sourceFile;
@@ -1012,7 +1011,7 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
}
/* clang-format off */
- *this->CompileCommandsStream << "\n{\n"
+ *this->CompileCommandsStream << "{\n"
<< R"( "directory": ")"
<< cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n"
<< R"( "command": ")"
@@ -1095,8 +1094,8 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
case cmStateEnums::GLOBAL_TARGET:
case cmStateEnums::UTILITY: {
std::string path =
- target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
- std::string("/") + target->GetName();
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+ target->GetName());
std::string output = this->ConvertToNinjaPath(path);
if (target->Target->IsPerConfig()) {
output = this->BuildAlias(output, config);
@@ -1120,8 +1119,8 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
for (BT<std::pair<std::string, bool>> const& util :
target->GetUtilities()) {
std::string d =
- target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
- util.Value.first;
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+ util.Value.first);
outputs.push_back(this->BuildAlias(this->ConvertToNinjaPath(d), config));
}
} else {
@@ -1348,12 +1347,13 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
// Setup target
cmNinjaDeps configDeps;
- build.Comment = "Folder: " + currentBinaryDir;
+ build.Comment = cmStrCat("Folder: ", currentBinaryDir);
build.Outputs.emplace_back();
+ std::string const buildDirAllTarget =
+ this->ConvertToNinjaPath(cmStrCat(currentBinaryDir, "/all"));
for (auto const& config : configs) {
build.ExplicitDeps.clear();
- build.Outputs.front() = this->BuildAlias(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"), config);
+ build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
configDeps.emplace_back(build.Outputs.front());
for (DirectoryTarget::Target const& t : dt.Targets) {
if (!t.ExcludeFromAll) {
@@ -1363,7 +1363,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
for (DirectoryTarget::Dir const& d : dt.Children) {
if (!d.ExcludeFromAll) {
build.ExplicitDeps.emplace_back(this->BuildAlias(
- this->ConvertToNinjaPath(d.Path + "/all"), config));
+ this->ConvertToNinjaPath(cmStrCat(d.Path, "/all")), config));
}
}
// Write target
@@ -1377,21 +1377,18 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
// Add shortcut target
if (this->IsMultiConfig()) {
for (auto const& config : configs) {
- build.ExplicitDeps = { this->BuildAlias(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
- build.Outputs.front() =
- this->ConvertToNinjaPath(currentBinaryDir + "/all");
+ build.ExplicitDeps = { this->BuildAlias(buildDirAllTarget, config) };
+ build.Outputs.front() = buildDirAllTarget;
this->WriteBuild(*this->GetConfigFileStream(config), build);
}
if (!this->DefaultFileConfig.empty()) {
build.ExplicitDeps.clear();
for (auto const& config : this->DefaultConfigs) {
- build.ExplicitDeps.push_back(this->BuildAlias(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+ build.ExplicitDeps.push_back(
+ this->BuildAlias(buildDirAllTarget, config));
}
- build.Outputs.front() =
- this->ConvertToNinjaPath(currentBinaryDir + "/all");
+ build.Outputs.front() = buildDirAllTarget;
this->WriteBuild(*this->GetDefaultFileStream(), build);
}
}
@@ -1400,11 +1397,10 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
if (this->EnableCrossConfigBuild()) {
build.ExplicitDeps.clear();
for (auto const& config : this->CrossConfigs) {
- build.ExplicitDeps.push_back(this->BuildAlias(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+ build.ExplicitDeps.push_back(
+ this->BuildAlias(buildDirAllTarget, config));
}
- build.Outputs.front() = this->BuildAlias(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"), "all");
+ build.Outputs.front() = this->BuildAlias(buildDirAllTarget, "all");
this->WriteBuild(os, build);
}
}
@@ -1616,7 +1612,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmNinjaBuild phonyBuild("phony");
phonyBuild.Comment = "Phony target to force glob verification run.";
- phonyBuild.Outputs.push_back(cm->GetGlobVerifyScript() + "_force");
+ phonyBuild.Outputs.push_back(
+ cmStrCat(cm->GetGlobVerifyScript(), "_force"));
this->WriteBuild(os, phonyBuild);
reBuild.Variables["restat"] = "1";
@@ -1807,7 +1804,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
// Write rule
{
cmNinjaRule rule("CLEAN");
- rule.Command = NinjaCmd() + " $FILE_ARG -t clean $TARGETS";
+ rule.Command = cmStrCat(NinjaCmd(), " $FILE_ARG -t clean $TARGETS");
rule.Description = "Cleaning all built files...";
rule.Comment = "Rule for cleaning all built files.";
WriteRule(*this->RulesFileStream, rule);
@@ -1921,7 +1918,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
{
cmNinjaRule rule("HELP");
- rule.Command = NinjaCmd() + " -t targets";
+ rule.Command = cmStrCat(NinjaCmd(), " -t targets");
rule.Description = "All primary targets available:";
rule.Comment = "Rule for printing all primary targets available.";
WriteRule(*this->RulesFileStream, rule);
@@ -1948,7 +1945,7 @@ std::string cmGlobalNinjaGenerator::NinjaOutputPath(
if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
return path;
}
- return this->OutputPathPrefix + path;
+ return cmStrCat(this->OutputPathPrefix, path);
}
void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
@@ -2076,7 +2073,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
} else if (cmHasLiteralPrefix(arg, "--lang=")) {
arg_lang = arg.substr(7);
} else {
- cmSystemTools::Error("-E cmake_ninja_depends unknown argument: " + arg);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends unknown argument: ", arg));
return 1;
}
}
@@ -2147,7 +2145,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
cmGeneratedFileStream ddif(arg_ddi);
ddif << ddi;
if (!ddif) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to write " + arg_ddi);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
return 1;
}
return 0;
@@ -2193,7 +2192,8 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
std::set<std::string> defines;
cmFortranParser parser(fc, includes, defines, finfo);
if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to open " + arg_pp);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp));
return nullptr;
}
if (cmFortran_yyparse(parser.Scanner) != 0) {
@@ -2296,7 +2296,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
Json::Value tm = Json::objectValue;
for (cmDyndepObjectInfo const& object : objects) {
for (std::string const& p : object.Provides) {
- std::string const mod = module_dir + p;
+ std::string const mod = cmStrCat(module_dir, p);
mod_files[p] = mod;
tm[p] = mod;
}
@@ -2332,8 +2332,8 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// Store the map of modules provided by this target in a file for
// use by dependents that reference this target in linked-target-dirs.
- std::string const target_mods_file =
- cmSystemTools::GetFilenamePath(arg_dd) + "/" + arg_lang + "Modules.json";
+ std::string const target_mods_file = cmStrCat(
+ cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
cmGeneratedFileStream tmf(target_mods_file);
tmf << tm;
@@ -2366,7 +2366,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
cmHasLiteralSuffix(arg, ".ddi")) {
arg_ddis.push_back(arg);
} else {
- cmSystemTools::Error("-E cmake_ninja_dyndep unknown argument: " + arg);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep unknown argument: ", arg));
return 1;
}
}
@@ -2402,7 +2403,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::string const dir_top_src = tdi["dir-top-src"].asString();
std::string module_dir = tdi["module-dir"].asString();
if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
- module_dir += "/";
+ module_dir += '/';
}
std::vector<std::string> linked_target_dirs;
Json::Value const& tdi_linked_target_dirs = tdi["linked-target-dirs"];
@@ -2430,9 +2431,7 @@ void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
const std::string& suffix, std::string& dir)
{
if (!config.empty() && this->IsMultiConfig()) {
- dir += prefix;
- dir += config;
- dir += suffix;
+ dir += cmStrCat(prefix, config, suffix);
}
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 90c9ef0..5363ea5 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -41,7 +41,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
#else
this->UseLinkScript = true;
#endif
- this->CommandDatabase = nullptr;
this->IncludeDirective = "include";
this->DefineWindowsNULL = false;
@@ -49,6 +48,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
this->UnixCD = true;
}
+cmGlobalUnixMakefileGenerator3::~cmGlobalUnixMakefileGenerator3() = default;
+
void cmGlobalUnixMakefileGenerator3::EnableLanguage(
std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
{
@@ -116,6 +117,12 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
gt->ObjectDirectory = dir;
}
+bool cmGlobalUnixMakefileGenerator3::CanEscapeOctothorpe() const
+{
+ // Make tools that use UNIX-style '/' paths also support '\' escaping.
+ return this->ForceUnixPaths;
+}
+
void cmGlobalUnixMakefileGenerator3::Configure()
{
// Initialize CMAKE_EDIT_COMMAND cache entry.
@@ -157,10 +164,9 @@ void cmGlobalUnixMakefileGenerator3::Generate()
this->WriteMainMakefile2();
this->WriteMainCMakefile();
- if (this->CommandDatabase != nullptr) {
- *this->CommandDatabase << std::endl << "]";
- delete this->CommandDatabase;
- this->CommandDatabase = nullptr;
+ if (this->CommandDatabase) {
+ *this->CommandDatabase << "\n]";
+ this->CommandDatabase.reset();
}
}
@@ -168,26 +174,26 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string& sourceFile, const std::string& workingDirectory,
const std::string& compileCommand)
{
- if (this->CommandDatabase == nullptr) {
+ if (!this->CommandDatabase) {
std::string commandDatabaseName =
this->GetCMakeInstance()->GetHomeOutputDirectory() +
"/compile_commands.json";
- this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName);
- *this->CommandDatabase << "[" << std::endl;
+ this->CommandDatabase =
+ cm::make_unique<cmGeneratedFileStream>(commandDatabaseName);
+ *this->CommandDatabase << "[\n";
} else {
- *this->CommandDatabase << "," << std::endl;
+ *this->CommandDatabase << ",\n";
}
- *this->CommandDatabase << "{" << std::endl
+ *this->CommandDatabase << "{\n"
<< R"( "directory": ")"
<< cmGlobalGenerator::EscapeJSON(workingDirectory)
- << "\"," << std::endl
+ << "\",\n"
<< R"( "command": ")"
<< cmGlobalGenerator::EscapeJSON(compileCommand)
- << "\"," << std::endl
+ << "\",\n"
<< R"( "file": ")"
- << cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
- << std::endl
- << "}";
+ << cmGlobalGenerator::EscapeJSON(sourceFile)
+ << "\"\n}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
@@ -343,19 +349,18 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
const std::string& binDir = lg.GetBinaryDirectory();
// CMake must rerun if a byproduct is missing.
- {
- cmakefileStream << "# Byproducts of CMake generate step:\n"
- << "set(CMAKE_MAKEFILE_PRODUCTS\n";
- for (std::string const& outfile : lg.GetMakefile()->GetOutputFiles()) {
+ cmakefileStream << "# Byproducts of CMake generate step:\n"
+ << "set(CMAKE_MAKEFILE_PRODUCTS\n";
+
+ // add in any byproducts and all the directory information files
+ std::string tmpStr;
+ for (const auto& localGen : this->LocalGenerators) {
+ for (std::string const& outfile :
+ localGen->GetMakefile()->GetOutputFiles()) {
cmakefileStream << " \""
<< lg.MaybeConvertToRelativePath(binDir, outfile)
<< "\"\n";
}
- }
-
- // add in all the directory information files
- std::string tmpStr;
- for (const auto& localGen : this->LocalGenerators) {
tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
"/CMakeFiles/CMakeDirectoryInformation.cmake");
cmakefileStream << " \""
@@ -481,6 +486,78 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
}
}
+namespace {
+std::string ConvertToMakefilePathForUnix(std::string const& path)
+{
+ std::string result;
+ result.reserve(path.size());
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '\\':
+ case ' ':
+ case '#':
+ result.push_back('\\');
+ CM_FALLTHROUGH;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ return result;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::string ConvertToMakefilePathForWindows(std::string const& path)
+{
+ bool const quote = path.find_first_of(" #") != std::string::npos;
+ std::string result;
+ result.reserve(path.size() + (quote ? 2 : 0));
+ if (quote) {
+ result.push_back('"');
+ }
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '/':
+ result.push_back('\\');
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ if (quote) {
+ result.push_back('"');
+ }
+ return result;
+}
+#endif
+}
+
+std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!this->ForceUnixPaths) {
+ return ConvertToMakefilePathForWindows(path);
+ }
+#endif
+ return ConvertToMakefilePathForUnix(path);
+}
+
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
@@ -674,10 +751,10 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
bool targetMessages = true;
- if (const char* tgtMsg =
+ if (cmProp tgtMsg =
this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"TARGET_MESSAGES")) {
- targetMessages = cmIsOn(tgtMsg);
+ targetMessages = cmIsOn(*tgtMsg);
}
if (targetMessages) {
@@ -697,9 +774,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
- progCmd << lg.ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress.Dir),
- cmOutputConverter::SHELL);
+ progCmd << lg.ConvertToOutputFormat(progress.Dir,
+ cmOutputConverter::SHELL);
//
std::set<cmGeneratorTarget const*> emitted;
progCmd << " "
@@ -711,9 +787,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << lg.ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress.Dir),
- cmOutputConverter::SHELL);
+ progCmd << lg.ConvertToOutputFormat(progress.Dir,
+ cmOutputConverter::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 340a7ef..1caa4b7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -68,6 +68,13 @@ public:
new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
}
+ ~cmGlobalUnixMakefileGenerator3() override;
+
+ cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) =
+ delete;
+ cmGlobalUnixMakefileGenerator3& operator=(
+ const cmGlobalUnixMakefileGenerator3&) = delete;
+
//! Get the name for the generator.
std::string GetName() const override
{
@@ -129,6 +136,12 @@ public:
or dependencies. */
std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// change the build command for speed
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
@@ -150,6 +163,9 @@ public:
/** Does the make tool tolerate .DELETE_ON_ERROR? */
virtual bool AllowDeleteOnError() const { return true; }
+ /** Does the make tool interpret '\#' as '#'? */
+ virtual bool CanEscapeOctothorpe() const;
+
bool IsIPOSupported() const override { return true; }
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
@@ -232,7 +248,7 @@ protected:
std::set<cmGeneratorTarget const*>& emitted);
size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
- cmGeneratedFileStream* CommandDatabase;
+ std::unique_ptr<cmGeneratedFileStream> CommandDatabase;
private:
const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index ccb6c50..5166de6 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -19,6 +19,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
@@ -313,7 +314,7 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
version.clear();
}
- if (version.find(this->GetPlatformToolsetString()) != 0) {
+ if (!cmHasPrefix(version, this->GetPlatformToolsetString())) {
std::ostringstream e;
/* clang-format off */
e <<
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 9799124..4b8010a 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -128,7 +128,7 @@ void cmGlobalVisualStudio7Generator::EnableLanguage(
// does not know about.
std::string extraPath;
if (cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH", extraPath)) {
- mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath.c_str(),
+ mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath,
"Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
cmStateEnums::STATIC);
}
@@ -505,13 +505,13 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
const std::vector<std::string> propKeys =
root->GetMakefile()->GetPropertyKeys();
for (std::string const& it : propKeys) {
- if (it.find("VS_GLOBAL_SECTION_") == 0) {
+ if (cmHasLiteralPrefix(it, "VS_GLOBAL_SECTION_")) {
std::string sectionType;
std::string name = it.substr(18);
- if (name.find("PRE_") == 0) {
+ if (cmHasLiteralPrefix(name, "PRE_")) {
name = name.substr(4);
sectionType = "preSolution";
- } else if (name.find("POST_") == 0) {
+ } else if (cmHasLiteralPrefix(name, "POST_")) {
name = name.substr(5);
sectionType = "postSolution";
} else
@@ -526,8 +526,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
extensibilityAddInsOverridden = true;
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
- std::vector<std::string> keyValuePairs =
- cmExpandedList(root->GetMakefile()->GetProperty(it));
+ cmProp p = root->GetMakefile()->GetProperty(it);
+ std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : "");
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
@@ -676,7 +676,8 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
for (std::string const& i : configs) {
const char* propertyValue =
target->Target->GetMakefile()->GetDefinition(propertyName);
- if (cmIsOn(cmGeneratorExpression::Evaluate(
+ if (propertyValue &&
+ cmIsOn(cmGeneratorExpression::Evaluate(
propertyValue, target->GetLocalGenerator(), i))) {
activeConfigs.insert(i);
}
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 1c62fbd..1df76ca 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -142,6 +142,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Add a custom rule to re-run CMake if any input files changed.
{
+ // The custom rule runs cmake so set UTF-8 pipes.
+ bool stdPipesUTF8 = true;
+
// Collect the input files used to generate all targets in this
// project.
std::vector<std::string> listFiles;
@@ -160,7 +163,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
lg.AddCustomCommandToTarget(
CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
verifyCommandLines, cmCustomCommandType::PRE_BUILD,
- "Checking File Globs", no_working_directory, false);
+ "Checking File Globs", no_working_directory, stdPipesUTF8);
// Ensure ZERO_CHECK always runs in Visual Studio using MSBuild,
// otherwise the prebuild command will not be run.
@@ -192,7 +195,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
if (cmSourceFile* file = lg.AddCustomCommandToOutput(
stamps, no_byproducts, listFiles, no_main_dependency,
no_implicit_depends, commandLines, "Checking Build System",
- no_working_directory, true, false)) {
+ no_working_directory, true, false, false, false, "", "",
+ stdPipesUTF8)) {
gt->AddSource(file->ResolveFullPath());
} else {
cmSystemTools::Error("Error adding rule for " + stamps[0]);
@@ -275,23 +279,31 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
bool cmGlobalVisualStudio8Generator::NeedsDeploy(
cmGeneratorTarget const& target, const char* config) const
{
- cmStateEnums::TargetType type = target.GetType();
- bool noDeploy = DeployInhibited(target, config);
- return !noDeploy &&
- (type == cmStateEnums::EXECUTABLE ||
- type == cmStateEnums::SHARED_LIBRARY) &&
- this->TargetSystemSupportsDeployment();
-}
+ cmStateEnums::TargetType const type = target.GetType();
+ if (type != cmStateEnums::EXECUTABLE &&
+ type != cmStateEnums::SHARED_LIBRARY) {
+ // deployment only valid on executables and shared libraries.
+ return false;
+ }
-bool cmGlobalVisualStudio8Generator::DeployInhibited(
- cmGeneratorTarget const& target, const char* config) const
-{
- bool rVal = false;
- if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
- rVal = cmIsOn(
+ if (const char* prop = target.GetProperty("VS_SOLUTION_DEPLOY")) {
+ // If set, it dictates behavior
+ return cmIsOn(
cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
}
- return rVal;
+
+ // To be deprecated, disable deployment even if target supports it.
+ if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
+ if (cmIsOn(cmGeneratorExpression::Evaluate(prop, target.LocalGenerator,
+ config))) {
+ // If true, always disable deployment
+ return false;
+ }
+ }
+
+ // Legacy behavior, enabled deployment based on 'hard-coded' target
+ // platforms.
+ return this->TargetSystemSupportsDeployment();
}
bool cmGlobalVisualStudio8Generator::TargetSystemSupportsDeployment() const
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 8f8e33b..6ce67d3 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -57,10 +57,6 @@ protected:
virtual bool NeedsDeploy(cmGeneratorTarget const& target,
const char* config) const;
- /** Returns true if deployment has been disabled in cmake file. */
- bool DeployInhibited(cmGeneratorTarget const& target,
- const char* config) const;
-
/** Returns true if the target system support debugging deployment. */
virtual bool TargetSystemSupportsDeployment() const;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 1ec1559..b9f4609 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -507,9 +507,9 @@ std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(
std::string cmGlobalVisualStudioGenerator::GetStartupProjectName(
cmLocalGenerator const* root) const
{
- const char* n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
- if (n && *n) {
- std::string startup = n;
+ cmProp n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
+ if (n && !n->empty()) {
+ std::string startup = *n;
if (this->FindTarget(startup)) {
return startup;
} else {
@@ -932,7 +932,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
{ cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file });
cmCustomCommand command(outputs, empty, empty, commandLines,
gt->Target->GetMakefile()->GetBacktrace(),
- "Auto build dll exports", ".");
+ "Auto build dll exports", ".", true);
commands.push_back(std::move(command));
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index e0005a4..1a753e2 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -8,13 +8,13 @@
#include <cstring>
#include <iomanip>
#include <sstream>
+#include <utility>
#include <cm/memory>
#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -33,6 +33,7 @@
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmXCode21Object.h"
@@ -361,7 +362,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
std::string projectArg = cmStrCat(projectName, ".xcodeproj");
makeCommand.Add(projectArg);
}
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("clean");
makeCommand.Add("-target", "ALL_BUILD");
} else {
@@ -642,7 +643,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
<< "\n";
}
-static bool objectIdLessThan(cmXCodeObject* l, cmXCodeObject* r)
+static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
+ const std::unique_ptr<cmXCodeObject>& r)
{
return l->GetId() < r->GetId();
}
@@ -656,9 +658,6 @@ void cmGlobalXCodeGenerator::SortXCodeObjects()
void cmGlobalXCodeGenerator::ClearXCodeObjects()
{
this->TargetDoneSet.clear();
- for (auto& obj : this->XCodeObjects) {
- delete obj;
- }
this->XCodeObjects.clear();
this->XCodeObjectIDs.clear();
this->XCodeObjectMap.clear();
@@ -668,7 +667,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
this->FileRefs.clear();
}
-void cmGlobalXCodeGenerator::addObject(cmXCodeObject* obj)
+void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
{
if (obj->GetType() == cmXCodeObject::OBJECT) {
const std::string& id = obj->GetId();
@@ -683,22 +682,24 @@ void cmGlobalXCodeGenerator::addObject(cmXCodeObject* obj)
this->XCodeObjectIDs.insert(id);
}
- this->XCodeObjects.push_back(obj);
+ this->XCodeObjects.push_back(std::move(obj));
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
cmXCodeObject::PBXType ptype)
{
- cmXCodeObject* obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
- this->addObject(obj);
- return obj;
+ auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT);
+ auto ptr = obj.get();
+ this->addObject(std::move(obj));
+ return ptr;
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
{
- cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
- this->addObject(obj);
- return obj;
+ auto obj = cm::make_unique<cmXCodeObject>(cmXCodeObject::None, type);
+ auto ptr = obj.get();
+ this->addObject(std::move(obj));
+ return ptr;
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateString(const std::string& s)
@@ -768,11 +769,15 @@ public:
XCodeGeneratorExpressionInterpreter& operator=(
XCodeGeneratorExpressionInterpreter const&) = delete;
- using cmGeneratorExpressionInterpreter::Evaluate;
-
const std::string& Evaluate(const char* expression,
const std::string& property)
{
+ return this->Evaluate(std::string(expression ? expression : ""), property);
+ }
+
+ const std::string& Evaluate(const std::string& expression,
+ const std::string& property)
+ {
const std::string& processed =
this->cmGeneratorExpressionInterpreter::Evaluate(expression, property);
if (this->CompiledGeneratorExpression->GetHadContextSensitiveCondition()) {
@@ -803,8 +808,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add flags from target and source file properties.
std::string flags;
- const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
- switch (cmOutputConverter::GetFortranFormat(srcfmt)) {
+ cmProp srcfmt = sf->GetProperty("Fortran_FORMAT");
+ switch (
+ cmOutputConverter::GetFortranFormat(srcfmt ? srcfmt->c_str() : nullptr)) {
case cmOutputConverter::FortranFormatFixed:
flags = "-fixed " + flags;
break;
@@ -815,22 +821,22 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
break;
}
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = sf->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
// Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false);
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
this->AppendDefines(
flagsBuild,
- genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS).c_str(),
+ genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS).c_str(),
true);
}
@@ -848,9 +854,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add per-source include directories.
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
lg->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*sf);
}
lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
@@ -879,10 +885,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
}
// Add user-specified file attributes.
- const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
+ cmProp extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes = cmExpandedList(extraFileAttributes);
+ std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes);
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -904,7 +910,7 @@ void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
"/CMakeLists.txt");
cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(
listfile, false, cmSourceFileLocationKind::Known);
- if (!cmContains(sources, srcCMakeLists)) {
+ if (!cm::contains(sources, srcCMakeLists)) {
sources.push_back(srcCMakeLists);
}
}
@@ -993,11 +999,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
bool useLastKnownFileType = false;
std::string fileType;
if (sf) {
- if (const char* e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
- fileType = e;
- } else if (const char* l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
+ if (cmProp e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+ fileType = *e;
+ } else if (cmProp l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
useLastKnownFileType = true;
- fileType = l;
+ fileType = *l;
}
}
if (fileType.empty()) {
@@ -1420,8 +1426,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
- return cmContains(this->CMakeInstance->GetHeaderExtensions(),
- sf->GetExtension());
+ return cm::contains(this->CMakeInstance->GetHeaderExtensions(),
+ sf->GetExtension());
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
@@ -1462,6 +1468,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
std::string str_link_file =
cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
+ bool stdPipesUTF8 = true;
cmCustomCommandLines cmd = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
str_file, str_so_file, str_link_file });
@@ -1469,7 +1476,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
cmCustomCommand command(
std::vector<std::string>(), std::vector<std::string>(),
std::vector<std::string>(), cmd, this->CurrentMakefile->GetBacktrace(),
- "Creating symlinks", "");
+ "Creating symlinks", "", stdPipesUTF8);
postbuild.push_back(std::move(command));
}
@@ -1859,7 +1866,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
gtgt->GetType() == cmStateEnums::STATIC_LIBRARY) {
this->CurrentLocalGenerator->GetStaticLibraryFlags(
- extraLinkOptions, cmSystemTools::UpperCase(configName), llang, gtgt);
+ extraLinkOptions, configName, llang, gtgt);
} else {
const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
@@ -2406,12 +2413,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Convert "XCODE_ATTRIBUTE_*" properties directly.
{
for (auto const& prop : gtgt->GetPropertyKeys()) {
- if (prop.find("XCODE_ATTRIBUTE_") == 0) {
+ if (cmHasLiteralPrefix(prop, "XCODE_ATTRIBUTE_")) {
std::string attribute = prop.substr(16);
this->FilterConfigurationAttribute(configName, attribute);
if (!attribute.empty()) {
+ const char* pr = gtgt->GetProperty(prop);
std::string processed = cmGeneratorExpression::Evaluate(
- gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName);
+ pr ? pr : "", this->CurrentLocalGenerator, configName);
buildSettings->AddAttribute(attribute,
this->CreateString(processed));
}
@@ -3141,12 +3149,12 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
// Put this last so it can override existing settings
// Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
for (const auto& var : this->CurrentMakefile->GetDefinitions()) {
- if (var.find("CMAKE_XCODE_ATTRIBUTE_") == 0) {
+ if (cmHasLiteralPrefix(var, "CMAKE_XCODE_ATTRIBUTE_")) {
std::string attribute = var.substr(22);
this->FilterConfigurationAttribute(config.first, attribute);
if (!attribute.empty()) {
std::string processed = cmGeneratorExpression::Evaluate(
- this->CurrentMakefile->GetDefinition(var),
+ this->CurrentMakefile->GetSafeDefinition(var),
this->CurrentLocalGenerator, config.first);
buildSettingsForCfg->AddAttribute(attribute,
this->CreateString(processed));
@@ -3390,7 +3398,7 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
// collect all tests for the targets
std::map<std::string, cmXCodeScheme::TestObjects> testables;
- for (auto obj : this->XCodeObjects) {
+ for (const auto& obj : this->XCodeObjects) {
if (obj->GetType() != cmXCodeObject::OBJECT ||
obj->GetIsA() != cmXCodeObject::PBXNativeTarget) {
continue;
@@ -3405,7 +3413,7 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
continue;
}
- testables[testee].push_back(obj);
+ testables[testee].push_back(obj.get());
}
// generate scheme
@@ -3414,14 +3422,14 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
// Since the lowest available Xcode version for testing was 6.4,
// I'm setting this as a limit then
if (this->XcodeVersion >= 64) {
- for (auto obj : this->XCodeObjects) {
+ for (const auto& obj : this->XCodeObjects) {
if (obj->GetType() == cmXCodeObject::OBJECT &&
(obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
obj->GetIsA() == cmXCodeObject::PBXAggregateTarget) &&
(root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
obj->GetTarget()->GetPropertyAsBool("XCODE_GENERATE_SCHEME"))) {
const std::string& targetName = obj->GetTarget()->GetName();
- cmXCodeScheme schm(root, obj, testables[targetName],
+ cmXCodeScheme schm(root, obj.get(), testables[targetName],
this->CurrentConfigurationTypes,
this->XcodeVersion);
schm.WriteXCodeSharedScheme(xcProjDir,
@@ -3547,7 +3555,7 @@ std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p)
{
- if (p.find(' ') != std::string::npos) {
+ if (p.find_first_of(" []") != std::string::npos) {
std::string t = cmStrCat('"', p, '"');
return t;
}
@@ -3693,15 +3701,14 @@ bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation(
bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
{
- const char* epnValue =
- this->GetCMakeInstance()->GetState()->GetGlobalProperty(
- "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
+ cmProp epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
if (!epnValue) {
return mf->PlatformIsAppleEmbedded();
}
- return cmIsOn(epnValue);
+ return cmIsOn(*epnValue);
}
bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index df68f80..e380f1c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -37,6 +37,10 @@ public:
unsigned int version_number);
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
+ cmGlobalXCodeGenerator(const cmGlobalXCodeGenerator&) = delete;
+ const cmGlobalXCodeGenerator& operator=(const cmGlobalXCodeGenerator&) =
+ delete;
+
//! Get the name for the generator.
std::string GetName() const override
{
@@ -249,7 +253,7 @@ protected:
unsigned int XcodeVersion;
std::string VersionString;
std::set<std::string> XCodeObjectIDs;
- std::vector<cmXCodeObject*> XCodeObjects;
+ std::vector<std::unique_ptr<cmXCodeObject>> XCodeObjects;
cmXCodeObject* RootObject;
private:
@@ -273,7 +277,7 @@ private:
void ComputeArchitectures(cmMakefile* mf);
void ComputeObjectDirArch(cmMakefile* mf);
- void addObject(cmXCodeObject* obj);
+ void addObject(std::unique_ptr<cmXCodeObject> obj);
std::string PostBuildMakeTarget(std::string const& tName,
std::string const& configName);
cmXCodeObject* MainGroupChildren;
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 1b77678..0fcda4e 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -298,13 +298,13 @@ void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& fs,
const std::string& name)
{
auto const escapedGraphName = EscapeForDotFile(name);
- fs << "digraph \"" << escapedGraphName << "\" {" << std::endl;
- fs << this->GraphHeader << std::endl;
+ fs << "digraph \"" << escapedGraphName << "\" {\n"
+ << this->GraphHeader << '\n';
}
void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& fs)
{
- fs << "}" << std::endl;
+ fs << "}\n";
}
void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
@@ -312,52 +312,46 @@ void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
// Note that the subgraph name must start with "cluster", as done here, to
// make Graphviz layout engines do the right thing and keep the nodes
// together.
- fs << "subgraph clusterLegend {" << std::endl;
- fs << " label = \"Legend\";" << std::endl;
- // Set the color of the box surrounding the legend.
- fs << " color = black;" << std::endl;
- // We use invisible edges just to enforce the layout.
- fs << " edge [ style = invis ];" << std::endl;
-
- // Nodes.
- fs << " legendNode0 [ label = \"Executable\", shape = "
- << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];" << std::endl;
-
- fs << " legendNode1 [ label = \"Static Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];" << std::endl;
- fs << " legendNode2 [ label = \"Shared Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];" << std::endl;
- fs << " legendNode3 [ label = \"Module Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];" << std::endl;
-
- fs << " legendNode4 [ label = \"Interface Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];" << std::endl;
- fs << " legendNode5 [ label = \"Object Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];" << std::endl;
- fs << " legendNode6 [ label = \"Unknown Library\", shape = "
- << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];" << std::endl;
-
- fs << " legendNode7 [ label = \"Custom Target\", shape = "
- << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];" << std::endl;
-
- // Edges.
- // Some of those are dummy (invisible) edges to enforce a layout.
- fs << " legendNode0 -> legendNode1 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
- fs << " legendNode0 -> legendNode2 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
- fs << " legendNode0 -> legendNode3;" << std::endl;
-
- fs << " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
- << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];" << std::endl;
- fs << " legendNode2 -> legendNode5 [ label = \"Private\", style = "
- << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];" << std::endl;
- fs << " legendNode3 -> legendNode6 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
- << " ];" << std::endl;
-
- fs << " legendNode0 -> legendNode7;" << std::endl;
-
- fs << "}" << std::endl;
+ /* clang-format off */
+ fs << "subgraph clusterLegend {\n"
+ " label = \"Legend\";\n"
+ // Set the color of the box surrounding the legend.
+ " color = black;\n"
+ // We use invisible edges just to enforce the layout.
+ " edge [ style = invis ];\n"
+ // Nodes.
+ " legendNode0 [ label = \"Executable\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];\n"
+ " legendNode1 [ label = \"Static Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];\n"
+ " legendNode2 [ label = \"Shared Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];\n"
+ " legendNode3 [ label = \"Module Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];\n"
+ " legendNode4 [ label = \"Interface Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];\n"
+ " legendNode5 [ label = \"Object Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];\n"
+ " legendNode6 [ label = \"Unknown Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];\n"
+ " legendNode7 [ label = \"Custom Target\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];\n"
+ // Edges.
+ // Some of those are dummy (invisible) edges to enforce a layout.
+ " legendNode0 -> legendNode1 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode2 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode3;\n"
+ " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
+ << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];\n"
+ " legendNode2 -> legendNode5 [ label = \"Private\", style = "
+ << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];\n"
+ " legendNode3 -> legendNode6 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode7;\n"
+ "}\n";
+ /* clang-format off */
}
void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
@@ -370,7 +364,7 @@ void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel
- << "\", shape = " << getShapeForTarget(item) << " ];" << std::endl;
+ << "\", shape = " << getShapeForTarget(item) << " ];\n";
}
void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
@@ -382,11 +376,9 @@ void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
auto const& dependeeName = dependee.AsStr();
fs << " \"" << this->NodeNames[dependerName] << "\" -> \""
- << this->NodeNames[dependeeName] << "\" ";
-
- fs << edgeStyle;
-
- fs << " // " << dependerName << " -> " << dependeeName << std::endl;
+ << this->NodeNames[dependeeName] << "\" "
+ << edgeStyle
+ << " // " << dependerName << " -> " << dependeeName << '\n';
}
bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
@@ -402,9 +394,9 @@ bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
}
if (item.Target->GetType() == cmStateEnums::UTILITY) {
- if ((itemName.find("Nightly") == 0) ||
- (itemName.find("Continuous") == 0) ||
- (itemName.find("Experimental") == 0)) {
+ if (cmHasLiteralPrefix(itemName, "Nightly") ||
+ cmHasLiteralPrefix(itemName, "Continuous") ||
+ cmHasLiteralPrefix(itemName, "Experimental")) {
return true;
}
}
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 14264f4..ae801bb 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -2,7 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIncludeCommand.h"
+#include <map>
#include <sstream>
+#include <utility>
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
@@ -16,6 +18,11 @@
bool cmIncludeCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
+ static std::map<std::string, cmPolicies::PolicyID> DeprecatedModules;
+ if (DeprecatedModules.empty()) {
+ DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
+ }
+
if (args.empty() || args.size() > 4) {
status.SetError("called with wrong number of arguments. "
"include() only takes one file.");
@@ -65,9 +72,35 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
}
if (!cmSystemTools::FileIsFullPath(fname)) {
+ bool system = false;
// Not a path. Maybe module.
std::string module = cmStrCat(fname, ".cmake");
- std::string mfile = status.GetMakefile().GetModulesFile(module);
+ std::string mfile = status.GetMakefile().GetModulesFile(module, system);
+
+ if (system) {
+ auto ModulePolicy = DeprecatedModules.find(fname);
+ if (ModulePolicy != DeprecatedModules.end()) {
+ cmPolicies::PolicyStatus PolicyStatus =
+ status.GetMakefile().GetPolicyStatus(ModulePolicy->second);
+ switch (PolicyStatus) {
+ case cmPolicies::WARN: {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy->second),
+ "\n"));
+ CM_FALLTHROUGH;
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ mfile = "";
+ break;
+ }
+ }
+ }
+
if (!mfile.empty()) {
fname = mfile;
}
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index d669ed7..c9b22b6 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -661,7 +661,6 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
// Nothing to do. An INTERFACE_LIBRARY can be installed, but the
// only effect of that is to make it exportable. It installs no
// other files itself.
- break;
default:
// This should never happen due to the above type check.
// Ignore the case.
@@ -680,9 +679,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
- const char* files = target.GetProperty("PRIVATE_HEADER");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ cmProp files = target.GetProperty("PRIVATE_HEADER");
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
@@ -703,8 +702,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
files = target.GetProperty("PUBLIC_HEADER");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
@@ -725,8 +724,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
files = target.GetProperty("RESOURCE");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 2c53a28..6e3508c 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
@@ -33,18 +35,15 @@ cmInstallExportGenerator::cmInstallExportGenerator(
{
if (android) {
#ifndef CMAKE_BOOTSTRAP
- this->EFGen = new cmExportInstallAndroidMKGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallAndroidMKGenerator>(this);
#endif
} else {
- this->EFGen = new cmExportInstallFileGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallFileGenerator>(this);
}
exportSet->AddInstallation(this);
}
-cmInstallExportGenerator::~cmInstallExportGenerator()
-{
- delete this->EFGen;
-}
+cmInstallExportGenerator::~cmInstallExportGenerator() = default;
bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
{
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index cf28b35..43dd00d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -30,8 +31,12 @@ public:
bool exclude_from_all, std::string filename,
std::string name_space, bool exportOld,
bool android);
+ cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
~cmInstallExportGenerator() override;
+ cmInstallExportGenerator& operator=(const cmInstallExportGenerator&) =
+ delete;
+
cmExportSet* GetExportSet() { return this->ExportSet; }
bool Compute(cmLocalGenerator* lg) override;
@@ -61,7 +66,7 @@ protected:
std::string TempDir;
std::string MainImportFile;
- cmExportInstallFileGenerator* EFGen;
+ std::unique_ptr<cmExportInstallFileGenerator> EFGen;
};
#endif
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index a65ae03..32395d1 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -42,7 +42,8 @@ void cmInstalledFile::RemoveProperty(const std::string& prop)
}
void cmInstalledFile::SetProperty(cmMakefile const* mf,
- const std::string& prop, const char* value)
+ const std::string& prop,
+ const std::string& value)
{
this->RemoveProperty(prop);
this->AppendProperty(mf, prop, value);
@@ -50,7 +51,8 @@ void cmInstalledFile::SetProperty(cmMakefile const* mf,
void cmInstalledFile::AppendProperty(cmMakefile const* mf,
const std::string& prop,
- const char* value, bool /*asString*/)
+ const std::string& value,
+ bool /*asString*/)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
cmGeneratorExpression ge(backtrace);
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index 698151e..07f7081 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -49,10 +49,10 @@ public:
void RemoveProperty(const std::string& prop);
void SetProperty(cmMakefile const* mf, const std::string& prop,
- const char* value);
+ const std::string& value);
void AppendProperty(cmMakefile const* mf, const std::string& prop,
- const char* value, bool asString = false);
+ const std::string& value, bool asString = false);
bool HasProperty(const std::string& prop) const;
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index dd36386..a4f78bc 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -90,7 +90,8 @@ void cmGetCMakeInputs(const cmGlobalGenerator* gg,
const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
const bool isInternal = (startOfFile == cmakeRootDir);
- const bool isTemporary = !isInternal && (lf.find(buildDir + '/') == 0);
+ const bool isTemporary =
+ !isInternal && (cmHasPrefix(lf, buildDir + '/'));
std::string toAdd = lf;
if (!sourceDir.empty()) {
@@ -274,14 +275,14 @@ static Json::Value DumpSourceFilesList(
std::string compileFlags = ld.Flags;
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = file->GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
lg->AppendFlags(compileFlags,
- genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
fileData.Flags = compileFlags;
@@ -289,9 +290,9 @@ static Json::Value DumpSourceFilesList(
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
for (const auto& include : includes) {
@@ -308,17 +309,17 @@ static Json::Value DumpSourceFilesList(
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
std::set<std::string> defines;
- if (const char* defs = file->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
lg->AppendDefines(
- defines, genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
}
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- if (const char* config_defs = file->GetProperty(defPropName)) {
+ if (cmProp config_defs = file->GetProperty(defPropName)) {
lg->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
}
defines.insert(ld.Defines.begin(), ld.Defines.end());
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 0ea25c0..f27648c 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -10,7 +10,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTargetLinkLibraryType.h"
@@ -81,6 +82,9 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
std::vector<cmLinkItem> WrongConfigLibraries;
bool ImplementationIsInterface = false;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
struct cmOptionalLinkInterface : public cmLinkInterface
@@ -100,6 +104,9 @@ struct cmLinkImplementation : public cmLinkImplementationLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
// Cache link implementation computation from each configuration.
@@ -121,7 +128,7 @@ inline cmTargetLinkLibraryType CMP0003_ComputeLinkType(
// Check if any entry in the list matches this configuration.
std::string configUpper = cmSystemTools::UpperCase(config);
- if (cmContains(debugConfigs, configUpper)) {
+ if (cm::contains(debugConfigs, configUpper)) {
return DEBUG_LibraryType;
}
// The current configuration is not a debug configuration.
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 65ed34c..b9a73b0 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -6,7 +6,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -188,7 +189,7 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- if (cmContains(closure->Languages, "CUDA")) {
+ if (cm::contains(closure->Languages, "CUDA")) {
if (const char* separableCompilation =
target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
if (cmIsOn(separableCompilation)) {
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 5200a16..1d82dfc 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,6 +16,7 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -66,7 +67,7 @@ bool GetList(std::vector<std::string>& list, const std::string& var,
// expand the variable into a list
cmExpandList(listString, list, true);
// if no empty elements then just return
- if (!cmContains(list, std::string())) {
+ if (!cm::contains(list, std::string())) {
return true;
}
// if we have empty elements we need to check policy CMP0007
@@ -1051,6 +1052,7 @@ public:
UNINITIALIZED,
STRING,
FILE_BASENAME,
+ NATURAL,
};
enum class CaseSensitivity
{
@@ -1074,10 +1076,25 @@ protected:
: nullptr;
}
+ using ComparisonFunction =
+ std::function<bool(const std::string&, const std::string&)>;
+ ComparisonFunction GetComparisonFunction(Compare compare)
+ {
+ if (compare == Compare::NATURAL) {
+ return std::function<bool(const std::string&, const std::string&)>(
+ [](const std::string& x, const std::string& y) {
+ return cmSystemTools::strverscmp(x, y) < 0;
+ });
+ }
+ return std::function<bool(const std::string&, const std::string&)>(
+ [](const std::string& x, const std::string& y) { return x < y; });
+ }
+
public:
cmStringSorter(Compare compare, CaseSensitivity caseSensitivity,
Order desc = Order::ASCENDING)
: filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) }
+ , sortMethod(GetComparisonFunction(compare))
, descending(desc == Order::DESCENDING)
{
}
@@ -1099,15 +1116,16 @@ public:
std::string bf = ApplyFilter(b);
bool result;
if (descending) {
- result = bf < af;
+ result = sortMethod(bf, af);
} else {
- result = af < bf;
+ result = sortMethod(af, bf);
}
return result;
}
protected:
StringFilter filters[2] = { nullptr, nullptr };
+ ComparisonFunction sortMethod;
bool descending;
};
@@ -1142,6 +1160,8 @@ bool HandleSortCommand(std::vector<std::string> const& args,
sortCompare = cmStringSorter::Compare::STRING;
} else if (argument == "FILE_BASENAME") {
sortCompare = cmStringSorter::Compare::FILE_BASENAME;
+ } else if (argument == "NATURAL") {
+ sortCompare = cmStringSorter::Compare::NATURAL;
} else {
std::string error =
cmStrCat(messageHint, "value \"", argument, "\" for option \"",
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 47679c9..7ebb02f 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -26,13 +26,15 @@ cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=(
struct cmListFileParser
{
cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger, const char* filename);
+ cmMessenger* messenger);
~cmListFileParser();
cmListFileParser(const cmListFileParser&) = delete;
cmListFileParser& operator=(const cmListFileParser&) = delete;
void IssueFileOpenError(std::string const& text) const;
void IssueError(std::string const& text) const;
- bool ParseFile();
+ bool ParseFile(const char* filename);
+ bool ParseString(const char* str, const char* virtual_filename);
+ bool Parse();
bool ParseFunction(const char* name, long line);
bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
@@ -51,12 +53,11 @@ struct cmListFileParser
};
cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger,
- const char* filename)
+ cmMessenger* messenger)
: ListFile(lf)
, Backtrace(std::move(lfbt))
, Messenger(messenger)
- , FileName(filename)
+ , FileName(nullptr)
, Lexer(cmListFileLexer_New())
{
}
@@ -83,8 +84,10 @@ void cmListFileParser::IssueError(const std::string& text) const
cmSystemTools::SetFatalErrorOccured();
}
-bool cmListFileParser::ParseFile()
+bool cmListFileParser::ParseFile(const char* filename)
{
+ this->FileName = filename;
+
// Open the file.
cmListFileLexer_BOM bom;
if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) {
@@ -107,6 +110,24 @@ bool cmListFileParser::ParseFile()
return false;
}
+ return Parse();
+}
+
+bool cmListFileParser::ParseString(const char* str,
+ const char* virtual_filename)
+{
+ this->FileName = virtual_filename;
+
+ if (!cmListFileLexer_SetString(this->Lexer, str)) {
+ this->IssueFileOpenError("cmListFileCache: cannot allocate buffer.");
+ return false;
+ }
+
+ return Parse();
+}
+
+bool cmListFileParser::Parse()
+{
// Use a simple recursive-descent parser to process the token
// stream.
bool haveNewline = true;
@@ -155,8 +176,22 @@ bool cmListFile::ParseFile(const char* filename, cmMessenger* messenger,
bool parseError = false;
{
- cmListFileParser parser(this, lfbt, messenger, filename);
- parseError = !parser.ParseFile();
+ cmListFileParser parser(this, lfbt, messenger);
+ parseError = !parser.ParseFile(filename);
+ }
+
+ return !parseError;
+}
+
+bool cmListFile::ParseString(const char* str, const char* virtual_filename,
+ cmMessenger* messenger,
+ const cmListFileBacktrace& lfbt)
+{
+ bool parseError = false;
+
+ {
+ cmListFileParser parser(this, lfbt, messenger);
+ parseError = !parser.ParseString(str, virtual_filename);
}
return !parseError;
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 9cae827..89902ff 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -184,6 +184,9 @@ struct cmListFile
bool ParseFile(const char* path, cmMessenger* messenger,
cmListFileBacktrace const& lfbt);
+ bool ParseString(const char* str, const char* virtual_filename,
+ cmMessenger* messenger, cmListFileBacktrace const& lfbt);
+
std::vector<cmListFileFunction> Functions;
};
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 92258e2..5790e16 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -1,5 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmLoadCommandCommand.h"
#include <csignal>
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 025ef7e..278ec8b 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -50,6 +50,15 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
mod_dir);
this->AppendFlags(flags, modflag);
+ // Some compilers do not search their own module output directory
+ // for using other modules. Add an include directory explicitly
+ // for consistency with compilers that do search it.
+ std::string incflag =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
+ if (!incflag.empty()) {
+ incflag = cmStrCat(incflag, mod_dir);
+ this->AppendFlags(flags, incflag);
+ }
}
// If there is a separate module path flag then duplicate the
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c2ec5f5..829f9cc 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -20,7 +20,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -35,7 +34,6 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
-#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -310,29 +308,35 @@ void cmLocalGenerator::GenerateTestFiles()
cmGeneratedFileStream fout(file);
fout.SetCopyIfDifferent(true);
- fout << "# CMake generated Testfile for " << std::endl
- << "# Source directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
- << "# Build directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentBinary() << std::endl
- << "# " << std::endl
- << "# This file includes the relevant testing commands "
- << "required for " << std::endl
- << "# testing this directory and lists subdirectories to "
- << "be tested as well." << std::endl;
-
- const char* testIncludeFile =
- this->Makefile->GetProperty("TEST_INCLUDE_FILE");
+ fout << "# CMake generated Testfile for \n"
+ "# Source directory: "
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << "\n"
+ "# Build directory: "
+ << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+ << "\n"
+ "# \n"
+ "# This file includes the relevant testing commands "
+ "required for \n"
+ "# testing this directory and lists subdirectories to "
+ "be tested as well.\n";
+
+ std::string resourceSpecFile =
+ this->Makefile->GetSafeDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (!resourceSpecFile.empty()) {
+ fout << "set(CTEST_RESOURCE_SPEC_FILE \"" << resourceSpecFile << "\")\n";
+ }
+
+ cmProp testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE");
if (testIncludeFile) {
- fout << "include(\"" << testIncludeFile << "\")" << std::endl;
+ fout << "include(\"" << *testIncludeFile << "\")\n";
}
- const char* testIncludeFiles =
- this->Makefile->GetProperty("TEST_INCLUDE_FILES");
+ cmProp testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList = cmExpandedList(testIncludeFiles);
+ std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles);
for (std::string const& i : includesList) {
- fout << "include(\"" << i << "\")" << std::endl;
+ fout << "include(\"" << i << "\")\n";
}
}
@@ -349,18 +353,18 @@ void cmLocalGenerator::GenerateTestFiles()
std::string outP = i.GetDirectory().GetCurrentBinary();
outP = this->MaybeConvertToRelativePath(parentBinDir, outP);
outP = cmOutputConverter::EscapeForCMake(outP);
- fout << "subdirs(" << outP << ")" << std::endl;
+ fout << "subdirs(" << outP << ")\n";
}
// Add directory labels property
const char* directoryLabels =
this->Makefile->GetDefinition("CMAKE_DIRECTORY_LABELS");
- const char* labels = this->Makefile->GetProperty("LABELS");
+ cmProp labels = this->Makefile->GetProperty("LABELS");
if (labels || directoryLabels) {
fout << "set_directory_properties(PROPERTIES LABELS ";
if (labels) {
- fout << cmOutputConverter::EscapeForCMake(labels);
+ fout << cmOutputConverter::EscapeForCMake(*labels);
}
if (labels && directoryLabels) {
fout << ";";
@@ -368,7 +372,7 @@ void cmLocalGenerator::GenerateTestFiles()
if (directoryLabels) {
fout << cmOutputConverter::EscapeForCMake(directoryLabels);
}
- fout << ")" << std::endl;
+ fout << ")\n";
}
}
@@ -489,16 +493,17 @@ void cmLocalGenerator::GenerateInstallRules()
fout.SetCopyIfDifferent(true);
// Write the header.
+ /* clang-format off */
fout << "# Install script for directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
- << std::endl;
- fout << "# Set the install prefix" << std::endl
- << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
- << " set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
- << "endif()" << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << "\n\n"
+ "# Set the install prefix\n"
+ "if(NOT DEFINED CMAKE_INSTALL_PREFIX)\n"
+ " set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")\n"
+ "endif()\n"
<< R"(string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX )"
- << "\"${CMAKE_INSTALL_PREFIX}\")" << std::endl
- << std::endl;
+ << "\"${CMAKE_INSTALL_PREFIX}\")\n\n";
+ /* clang-format on */
// Write support code for generating per-configuration install rules.
/* clang-format off */
@@ -572,6 +577,71 @@ void cmLocalGenerator::GenerateInstallRules()
/* clang-format on */
}
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same platform variable as when running cmake
+ if (const char* platform = this->Makefile->GetDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM \""
+ << platform << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same tool selected as when running cmake
+ if (const char* command =
+ this->Makefile->GetDefinition("CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same path to the tool as when running cmake
+ if (const char* command = this->Makefile->GetDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_OBJDUMP so that installed code that uses
+ // `file(GET_RUNTIME_DEPENDENCIES)` and hasn't specified
+ // CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND has consistent
+ // logic to fallback to CMAKE_OBJDUMP when `objdump` is
+ // not on the path
+ if (const char* command = this->Makefile->GetDefinition("CMAKE_OBJDUMP")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_OBJDUMP)\n"
+ " set(CMAKE_OBJDUMP \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
// Ask each install generator to write its code.
cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082);
auto const& installers = this->Makefile->GetInstallGenerators();
@@ -613,8 +683,7 @@ void cmLocalGenerator::GenerateInstallRules()
if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
std::string odir = c.GetDirectory().GetCurrentBinary();
cmSystemTools::ConvertToUnixSlashes(odir);
- fout << " include(\"" << odir << "/cmake_install.cmake\")"
- << std::endl;
+ fout << " include(\"" << odir << "/cmake_install.cmake\")\n";
}
}
fout << "\n";
@@ -795,7 +864,8 @@ const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
if (target) {
return target->GetProperty(prop);
}
- return this->Makefile->GetProperty(prop);
+ cmProp p = this->Makefile->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -899,7 +969,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) {
flags.back() = ' ';
}
- return flags;
+ return cmTrimWhitespace(flags);
}
void cmLocalGenerator::AddCompileOptions(std::string& flags,
@@ -971,8 +1041,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
<< "\". "
"This is not permitted. The COMPILE_FEATURES may not both depend "
"on "
- "and be depended on by the link implementation."
- << std::endl;
+ "and be depended on by the link implementation.\n";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
@@ -1018,7 +1087,8 @@ cmTarget* cmLocalGenerator::AddCustomCommandToTarget(
const cmCustomCommandLines& commandLines, cmCustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile, const std::string& job_pool,
- bool command_expand_lists, cmObjectLibraryCommands objLibCommands)
+ bool command_expand_lists, cmObjectLibraryCommands objLibCommands,
+ bool stdPipesUTF8)
{
cmTarget* t = this->Makefile->GetCustomCommandTarget(
target, objLibCommands, this->DirectoryBacktrace);
@@ -1029,7 +1099,7 @@ cmTarget* cmLocalGenerator::AddCustomCommandToTarget(
detail::AddCustomCommandToTarget(
*this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts,
depends, commandLines, type, comment, workingDir, escapeOldStyle,
- uses_terminal, depfile, job_pool, command_expand_lists);
+ uses_terminal, depfile, job_pool, command_expand_lists, stdPipesUTF8);
return t;
}
@@ -1039,14 +1109,14 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
const std::string& main_dependency, const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir, bool replace,
bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
- const std::string& depfile, const std::string& job_pool)
+ const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
{
std::vector<std::string> no_byproducts;
cmImplicitDependsList no_implicit_depends;
return this->AddCustomCommandToOutput(
{ output }, no_byproducts, depends, main_dependency, no_implicit_depends,
commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
}
cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
@@ -1057,7 +1127,7 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
// Make sure there is at least one output.
if (outputs.empty()) {
@@ -1069,7 +1139,7 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
*this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs,
byproducts, depends, main_dependency, implicit_depends, commandLines,
comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
}
cmTarget* cmLocalGenerator::AddUtilityCommand(
@@ -1078,7 +1148,7 @@ cmTarget* cmLocalGenerator::AddUtilityCommand(
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
const char* comment, bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
cmTarget* target =
this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll);
@@ -1092,7 +1162,7 @@ cmTarget* cmLocalGenerator::AddUtilityCommand(
*this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target,
this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends,
commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
- job_pool);
+ job_pool, stdPipesUTF8);
return target;
}
@@ -1183,7 +1253,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// directly. In this case adding -I/usr/include can hide SDK headers so we
// must still exclude it.
if ((lang == "C" || lang == "CXX" || lang == "CUDA") &&
- !cmContains(impDirVec, "/usr/include") &&
+ !cm::contains(impDirVec, "/usr/include") &&
std::find_if(impDirVec.begin(), impDirVec.end(),
[](std::string const& d) {
return cmHasLiteralSuffix(d, "/usr/include");
@@ -1204,13 +1274,14 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
&lang](std::string const& dir) {
return (
// Do not exclude directories that are not in an excluded set.
- ((!cmContains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
- (!cmContains(implicitExclude, dir)))
+ ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
+ (!cm::contains(implicitExclude, dir)))
// Do not exclude entries of the CPATH environment variable even though
// they are implicitly searched by the compiler. They are meant to be
// user-specified directories that can be re-ordered or converted to
// -isystem without breaking real compiler builtin headers.
- || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir)));
+ ||
+ ((lang == "C" || lang == "CXX") && cm::contains(this->EnvCPATH, dir)));
};
// Get the target-specific include directories.
@@ -1257,7 +1328,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
if (!stripImplicitDirs) {
// Append implicit directories that were requested by the user only
for (BT<std::string> const& udr : userDirs) {
- if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
+ if (cm::contains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
emitBT(udr);
}
}
@@ -1314,14 +1385,15 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
std::string const& config, std::string const& linkLanguage,
cmGeneratorTarget* target)
{
+ const std::string configUpper = cmSystemTools::UpperCase(config);
std::vector<BT<std::string>> flags;
if (linkLanguage != "Swift") {
std::string staticLibFlags;
this->AppendFlags(
staticLibFlags,
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
- if (!config.empty()) {
- std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
+ if (!configUpper.empty()) {
+ std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + configUpper;
this->AppendFlags(staticLibFlags,
this->Makefile->GetSafeDefinition(name));
}
@@ -1333,8 +1405,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
std::string staticLibFlags;
this->AppendFlags(staticLibFlags,
target->GetSafeProperty("STATIC_LIBRARY_FLAGS"));
- if (!config.empty()) {
- std::string name = "STATIC_LIBRARY_FLAGS_" + config;
+ if (!configUpper.empty()) {
+ std::string name = "STATIC_LIBRARY_FLAGS_" + configUpper;
this->AppendFlags(staticLibFlags, target->GetSafeProperty(name));
}
@@ -1350,6 +1422,30 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
return flags;
}
+void cmLocalGenerator::GetDeviceLinkFlags(
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
+ std::string& linkPath, cmGeneratorTarget* target)
+{
+ cmGeneratorTarget::DeviceLinkSetter setter(*target);
+
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
+ const std::string linkLanguage =
+ linkLineComputer->GetLinkerLanguage(target, config);
+
+ if (pcli) {
+ // Compute the required cuda device link libraries when
+ // resolving cuda device symbols
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath,
+ linkPath);
+ }
+
+ std::vector<std::string> linkOpts;
+ target->GetLinkOptions(linkOpts, config, linkLanguage);
+ // LINK_OPTIONS are escaped.
+ this->AppendCompileOptions(linkFlags, linkOpts);
+}
+
void cmLocalGenerator::GetTargetFlags(
cmLinkLineComputer* linkLineComputer, const std::string& config,
std::string& linkLibs, std::string& flags, std::string& linkFlags,
@@ -1371,23 +1467,17 @@ void cmLocalGenerator::GetTargetFlags(
std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target)
{
- const std::string buildType = cmSystemTools::UpperCase(config);
+ const std::string configUpper = cmSystemTools::UpperCase(config);
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const char* libraryLinkVariable =
"CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
const std::string linkLanguage =
- linkLineComputer->GetLinkerLanguage(target, buildType);
+ linkLineComputer->GetLinkerLanguage(target, config);
switch (target->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
- linkFlags = this->GetStaticLibraryFlags(buildType, linkLanguage, target);
- if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) {
- // Compute the required cuda device link libraries when
- // resolving cuda device symbols
- this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
- frameworkPath, linkPath);
- }
+ linkFlags = this->GetStaticLibraryFlags(config, linkLanguage, target);
break;
case cmStateEnums::MODULE_LIBRARY:
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
@@ -1397,8 +1487,8 @@ void cmLocalGenerator::GetTargetFlags(
if (linkLanguage != "Swift") {
sharedLibFlags = cmStrCat(
this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
- if (!buildType.empty()) {
- std::string build = cmStrCat(libraryLinkVariable, '_', buildType);
+ if (!configUpper.empty()) {
+ std::string build = cmStrCat(libraryLinkVariable, '_', configUpper);
sharedLibFlags += this->Makefile->GetSafeDefinition(build);
sharedLibFlags += " ";
}
@@ -1406,14 +1496,14 @@ void cmLocalGenerator::GetTargetFlags(
!(this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"))) {
std::vector<cmSourceFile*> sources;
- target->GetSourceFiles(sources, buildType);
+ target->GetSourceFiles(sources, config);
std::string defFlag =
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
for (cmSourceFile* sf : sources) {
if (sf->GetExtension() == "def") {
sharedLibFlags += defFlag;
- sharedLibFlags += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL);
+ sharedLibFlags +=
+ this->ConvertToOutputFormat(sf->ResolveFullPath(), SHELL);
sharedLibFlags += " ";
}
}
@@ -1425,9 +1515,9 @@ void cmLocalGenerator::GetTargetFlags(
sharedLibFlags += targetLinkFlags;
sharedLibFlags += " ";
}
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
targetLinkFlags =
- target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+ target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
if (targetLinkFlags) {
sharedLibFlags += targetLinkFlags;
sharedLibFlags += " ";
@@ -1452,9 +1542,9 @@ void cmLocalGenerator::GetTargetFlags(
if (linkLanguage != "Swift") {
exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
exeFlags += " ";
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType));
+ cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
exeFlags += " ";
}
if (linkLanguage.empty()) {
@@ -1481,7 +1571,7 @@ void cmLocalGenerator::GetTargetFlags(
}
}
- this->AddLanguageFlagsForLinking(flags, target, linkLanguage, buildType);
+ this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
if (pcli) {
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
@@ -1506,9 +1596,9 @@ void cmLocalGenerator::GetTargetFlags(
exeFlags += targetLinkFlags;
exeFlags += " ";
}
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
targetLinkFlags =
- target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+ target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
if (targetLinkFlags) {
exeFlags += targetLinkFlags;
exeFlags += " ";
@@ -1541,16 +1631,17 @@ void cmLocalGenerator::GetTargetFlags(
void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
std::string const& config,
std::string const& lang,
- std::string& flags)
+ std::string& flags,
+ std::string const& arch)
{
std::vector<BT<std::string>> tmpFlags =
- this->GetTargetCompileFlags(target, config, lang);
+ this->GetTargetCompileFlags(target, config, lang, arch);
this->AppendFlags(flags, tmpFlags);
}
std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
cmGeneratorTarget* target, std::string const& config,
- std::string const& lang)
+ std::string const& lang, std::string const& arch)
{
std::vector<BT<std::string>> flags;
std::string compileFlags;
@@ -1564,7 +1655,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
this->AppendFeatureOptions(compileFlags, lang, "IPO");
}
- this->AddArchitectureFlags(compileFlags, target, lang, config);
+ this->AddArchitectureFlags(compileFlags, target, lang, config, arch);
if (lang == "Fortran") {
this->AppendFlags(compileFlags,
@@ -1753,10 +1844,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
"CMAKE_POLICY_WARNING_CMP0065")) {
std::ostringstream w;
/* clang-format off */
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
- "For compatibility with older versions of CMake, "
- "additional flags may be added to export symbols on all "
- "executables regardless of their ENABLE_EXPORTS property.";
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
+ "For compatibility with older versions of CMake, "
+ "additional flags may be added to export symbols on all "
+ "executables regardless of their ENABLE_EXPORTS property.";
/* clang-format on */
this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
@@ -1812,7 +1903,8 @@ bool cmLocalGenerator::AllAppleArchSysrootsAreTheSame(
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
cmGeneratorTarget const* target,
const std::string& lang,
- const std::string& config)
+ const std::string& config,
+ const std::string& filterArch)
{
// Only add Apple specific flags on Apple platforms
if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
@@ -1821,8 +1913,10 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
if (!archs.empty() && !lang.empty() &&
(lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
for (std::string const& arch : archs) {
- flags += " -arch ";
- flags += arch;
+ if (filterArch.empty() || filterArch == arch) {
+ flags += " -arch ";
+ flags += arch;
+ }
}
}
@@ -1841,10 +1935,12 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
if (cmIsOff(archSysroot)) {
continue;
}
- flags += " -Xarch_" + arch + " ";
- // Combine sysroot flag and path to work with -Xarch
- std::string arch_sysroot = sysrootFlag + archSysroot;
- flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+ if (filterArch.empty() || filterArch == arch) {
+ flags += " -Xarch_" + arch + " ";
+ // Combine sysroot flag and path to work with -Xarch
+ std::string arch_sysroot = sysrootFlag + archSysroot;
+ flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+ }
}
} else if (sysroot && *sysroot) {
flags += " ";
@@ -1887,6 +1983,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
this->AppendFlags(flags, "-swift-version " + std::string(v));
}
}
+ } else if (lang == "CUDA") {
+ target->AddCUDAArchitectureFlags(flags);
}
// Add MSVC runtime library flags. This is activated by the presence
@@ -1973,7 +2071,6 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
if (name.empty()) {
return false;
}
-
if (cmSystemTools::GetFilenameLastExtension(name) == ".exe") {
name = cmSystemTools::GetFilenameWithoutLastExtension(name);
}
@@ -2013,11 +2110,9 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
case cmStateEnums::OBJECT_LIBRARY:
// An object library has no single file on which to depend.
// This was listed to get the target-level dependency.
- return false;
case cmStateEnums::INTERFACE_LIBRARY:
// An interface library has no file on which to depend.
// This was listed to get the target-level dependency.
- return false;
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
@@ -2434,7 +2529,9 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
void cmLocalGenerator::AppendFlags(std::string& flags,
const std::string& newFlags) const
{
- if (!newFlags.empty()) {
+ bool allSpaces = std::all_of(newFlags.begin(), newFlags.end(), cmIsSpace);
+
+ if (!newFlags.empty() && !allSpaces) {
if (!flags.empty()) {
flags += " ";
}
@@ -2481,146 +2578,177 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
continue;
}
- const std::string pchSource = target->GetPchSource(config, lang);
- const std::string pchHeader = target->GetPchHeader(config, lang);
-
- if (pchSource.empty() || pchHeader.empty()) {
- continue;
+ std::vector<std::string> architectures;
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ target->GetAppleArchs(config, architectures);
}
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ } else {
+ std::string useMultiArchPch;
+ for (const std::string& arch : architectures) {
+ const std::string pchHeader =
+ target->GetPchHeader(config, lang, arch);
+ if (!pchHeader.empty()) {
+ useMultiArchPch = cmStrCat(useMultiArchPch, ";-Xarch_", arch,
+ ";-include", pchHeader);
+ }
+ }
- const std::string pchExtension =
- this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
-
- if (pchExtension.empty()) {
- continue;
+ if (!useMultiArchPch.empty()) {
+ target->Target->SetProperty(
+ cmStrCat(lang, "_COMPILE_OPTIONS_USE_PCH"), useMultiArchPch);
+ }
}
- const char* pchReuseFrom =
- target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ for (const std::string& arch : architectures) {
+ const std::string pchSource = target->GetPchSource(config, lang, arch);
+ const std::string pchHeader = target->GetPchHeader(config, lang, arch);
- auto pch_sf = this->Makefile->GetOrCreateSource(
- pchSource, false, cmSourceFileLocationKind::Known);
+ if (pchSource.empty() || pchHeader.empty()) {
+ continue;
+ }
- if (!this->GetGlobalGenerator()->IsXcode()) {
- if (!pchReuseFrom) {
- target->AddSource(pchSource, true);
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+ if (pchExtension.empty()) {
+ continue;
}
- const std::string pchFile = target->GetPchFile(config, lang);
+ const char* pchReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- // Exclude the pch files from linking
- if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
- if (!pchReuseFrom) {
- pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
- } else {
- auto reuseTarget =
- this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
- if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!pchReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
- const std::string pdb_prefix =
- this->GetGlobalGenerator()->IsMultiConfig()
- ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
- : "";
+ const std::string pchFile = target->GetPchFile(config, lang, arch);
- const std::string target_compile_pdb_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/");
+ // Exclude the pch files from linking
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ if (!pchReuseFrom) {
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
- const std::string copy_script =
- cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
- cmGeneratedFileStream file(copy_script);
+ if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
- file << "# CMake generated file\n";
- for (auto extension : { ".pdb", ".idb" }) {
- const std::string from_file =
- cmStrCat(reuseTarget->GetLocalGenerator()
- ->GetCurrentBinaryDirectory(),
- "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
- pchReuseFrom, extension);
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig()
+ ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+ : "";
- const std::string to_dir = cmStrCat(
+ const std::string target_compile_pdb_dir = cmStrCat(
target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", target->GetName(), ".dir/${PDB_PREFIX}");
+ "/", target->GetName(), ".dir/");
- const std::string to_file =
- cmStrCat(to_dir, pchReuseFrom, extension);
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
- std::string dest_file = to_file;
+ file << "# CMake generated file\n";
+ for (auto extension : { ".pdb", ".idb" }) {
+ const std::string from_file =
+ cmStrCat(reuseTarget->GetLocalGenerator()
+ ->GetCurrentBinaryDirectory(),
+ "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
+ pchReuseFrom, extension);
- const std::string prefix = target->GetSafeProperty("PREFIX");
- if (!prefix.empty()) {
- dest_file =
- cmStrCat(to_dir, prefix, pchReuseFrom, extension);
- }
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", target->GetName(), ".dir/${PDB_PREFIX}");
+
+ const std::string to_file =
+ cmStrCat(to_dir, pchReuseFrom, extension);
+
+ std::string dest_file = to_file;
+
+ const std::string prefix = target->GetSafeProperty("PREFIX");
+ if (!prefix.empty()) {
+ dest_file =
+ cmStrCat(to_dir, prefix, pchReuseFrom, extension);
+ }
- file << "if (EXISTS \"" << from_file << "\" AND \""
- << from_file << "\" IS_NEWER_THAN \"" << dest_file
- << "\")\n";
- file << " file(COPY \"" << from_file << "\""
- << " DESTINATION \"" << to_dir << "\")\n";
- if (!prefix.empty()) {
- file << " file(REMOVE \"" << dest_file << "\")\n";
- file << " file(RENAME \"" << to_file << "\" \"" << dest_file
+ file << "if (EXISTS \"" << from_file << "\" AND \""
+ << from_file << "\" IS_NEWER_THAN \"" << dest_file
<< "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ if (!prefix.empty()) {
+ file << " file(REMOVE \"" << dest_file << "\")\n";
+ file << " file(RENAME \"" << to_file << "\" \""
+ << dest_file << "\")\n";
+ }
+ file << "endif()\n";
}
- file << "endif()\n";
- }
- cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
- { cmSystemTools::GetCMakeCommand(),
- cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
-
- const std::string no_main_dependency;
- const std::vector<std::string> no_deps;
- const char* no_message = "";
- const char* no_current_dir = nullptr;
- std::vector<std::string> no_byproducts;
-
- std::vector<std::string> outputs;
- outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
- pchReuseFrom, ".pdb"));
-
- if (this->GetGlobalGenerator()->IsVisualStudio()) {
- this->AddCustomCommandToTarget(
- target->GetName(), outputs, no_deps, commandLines,
- cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
- } else {
- cmImplicitDependsList no_implicit_depends;
- cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
- outputs, no_byproducts, no_deps, no_main_dependency,
- no_implicit_depends, commandLines, no_message,
- no_current_dir);
-
- if (copy_rule) {
- target->AddSource(copy_rule->ResolveFullPath());
+ bool stdPipesUTF8 = true;
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(),
+ cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P",
+ copy_script });
+
+ const std::string no_main_dependency;
+ const std::vector<std::string> no_deps;
+ const char* no_message = "";
+ const char* no_current_dir = nullptr;
+ std::vector<std::string> no_byproducts;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
+ pchReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ this->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmCustomCommandType::PRE_BUILD, no_message, no_current_dir,
+ true, false, "", "", false,
+ cmObjectLibraryCommands::Reject, stdPipesUTF8);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
+ outputs, no_byproducts, no_deps, no_main_dependency,
+ no_implicit_depends, commandLines, no_message,
+ no_current_dir, false, true, false, false, "", "",
+ stdPipesUTF8);
+
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
}
- }
- target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- target_compile_pdb_dir);
- }
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir);
+ }
- std::string pchSourceObj =
- reuseTarget->GetPchFileObject(config, lang);
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang, arch);
- // Link to the pch object file
- target->Target->AppendProperty(
- "LINK_FLAGS",
- cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
- true);
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ "LINK_FLAGS",
+ cmStrCat(" ",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+ true);
+ }
+ } else {
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
}
- } else {
- pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
- }
- // Add pchHeader to source files, which will
- // be grouped as "Precompile Header File"
- auto pchHeader_sf = this->Makefile->GetOrCreateSource(
- pchHeader, false, cmSourceFileLocationKind::Known);
- std::string err;
- pchHeader_sf->ResolveFullPath(&err);
- target->AddSource(pchHeader);
+ // Add pchHeader to source files, which will
+ // be grouped as "Precompile Header File"
+ auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+ pchHeader, false, cmSourceFileLocationKind::Known);
+ std::string err;
+ pchHeader_sf->ResolveFullPath(&err);
+ target->AddSource(pchHeader);
+ }
}
}
}
@@ -2948,11 +3076,11 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
// command line without any escapes. However we still have to
// get the '$' and '#' characters through WMake as '$$' and
// '$#'.
- for (const char* c = define.c_str(); *c; ++c) {
- if (*c == '$' || *c == '#') {
+ for (char c : define) {
+ if (c == '$' || c == '#') {
def += '$';
}
- def += *c;
+ def += c;
}
} else {
// Make the definition appear properly on the command line. Use
@@ -2996,8 +3124,8 @@ const char* cmLocalGenerator::GetFeature(const std::string& feature,
}
cmStateSnapshot snp = this->StateSnapshot;
while (snp.IsValid()) {
- if (const char* value = snp.GetDirectory().GetProperty(featureName)) {
- return value;
+ if (cmProp value = snp.GetDirectory().GetProperty(featureName)) {
+ return value->c_str();
}
snp = snp.GetBuildsystemDirectoryParent();
}
@@ -3302,11 +3430,12 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
// Select a nice-looking reference to the source file to construct
// the object file name.
std::string objectName;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if ((relSource && !relBinary) || (subSource && !subBinary)) {
objectName = relFromSource;
- } else if ((relBinary && !relSource) || (subBinary && !subSource)) {
- objectName = relFromBinary;
- } else if (relFromBinary.length() < relFromSource.length()) {
+ } else if ((relBinary && !relSource) || (subBinary && !subSource) ||
+ relFromBinary.length() < relFromSource.length()) {
objectName = relFromBinary;
} else {
objectName = relFromSource;
@@ -3324,12 +3453,12 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
// Ensure that for the CMakeFiles/<target>.dir/generated_source_file
// we don't end up having:
// CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
- const char* unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
- const char* pchExtension = source.GetProperty("PCH_EXTENSION");
+ cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
+ cmProp psExtension = source.GetProperty("PCH_EXTENSION");
const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
- if (unitySourceFile || pchExtension || isPchObject) {
- if (pchExtension) {
- customOutputExtension = pchExtension;
+ if (unitySourceFile || psExtension || isPchObject) {
+ if (psExtension) {
+ customOutputExtension = psExtension->c_str();
}
cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
@@ -3465,7 +3594,6 @@ bool cmLocalGenerator::NeedBackwardsCompatibility_2_4()
break;
case cmPolicies::NEW:
// New behavior is to ignore the variable.
- return false;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// This will never be the case because the only way to require
@@ -3645,7 +3773,7 @@ cmSourceFile* AddCustomCommand(
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
cmMakefile* mf = lg.GetMakefile();
@@ -3707,7 +3835,8 @@ cmSourceFile* AddCustomCommand(
}
std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
- outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir);
+ outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir,
+ stdPipesUTF8);
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
cc->SetImplicitDepends(implicit_depends);
@@ -3734,7 +3863,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile,
const std::string& job_pool,
- bool command_expand_lists)
+ bool command_expand_lists, bool stdPipesUTF8)
{
cmMakefile* mf = lg.GetMakefile();
@@ -3744,7 +3873,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
// 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,
- comment, workingDir);
+ comment, workingDir, stdPipesUTF8);
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
cc.SetUsesTerminal(uses_terminal);
@@ -3775,7 +3904,7 @@ cmSourceFile* AddCustomCommandToOutput(
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
// Always create the output sources and mark them generated.
CreateGeneratedSources(lg, outputs, origin, lfbt);
@@ -3784,7 +3913,7 @@ cmSourceFile* AddCustomCommandToOutput(
return AddCustomCommand(
lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends,
commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
}
void AppendCustomCommandToOutput(cmLocalGenerator& lg,
@@ -3820,7 +3949,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
const cmCustomCommandLines& commandLines,
bool escapeOldStyle, const char* comment,
bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
// Always create the byproduct sources and mark them generated.
CreateGeneratedSource(lg, force.Name, origin, lfbt);
@@ -3837,7 +3966,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency,
no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false,
escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"",
- job_pool);
+ job_pool, stdPipesUTF8);
if (rule) {
lg.GetMakefile()->AddTargetByproducts(target, byproducts);
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a459384..1492304 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -105,8 +105,8 @@ public:
void AddArchitectureFlags(std::string& flags,
cmGeneratorTarget const* target,
- const std::string& lang,
- const std::string& config);
+ const std::string& lang, const std::string& config,
+ const std::string& filterArch = std::string());
void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
const std::string& lang, const std::string& config);
@@ -297,7 +297,8 @@ public:
const char* comment, const char* workingDir, bool escapeOldStyle = true,
bool uses_terminal = false, const std::string& depfile = "",
const std::string& job_pool = "", bool command_expand_lists = false,
- cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
+ cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject,
+ bool stdPipesUTF8 = false);
/**
* Add a custom command to a source file.
@@ -308,7 +309,8 @@ public:
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
@@ -318,7 +320,8 @@ public:
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
/**
* Add a utility to the build. A utility target is a command that is run
@@ -330,7 +333,8 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
const char* comment = nullptr, bool uses_terminal = false,
- bool command_expand_lists = false, const std::string& job_pool = "");
+ bool command_expand_lists = false, const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
std::string GetProjectName() const;
@@ -417,6 +421,11 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
+ void GetDeviceLinkFlags(cmLinkLineComputer* linkLineComputer,
+ const std::string& config, std::string& linkLibs,
+ std::string& linkFlags, std::string& frameworkPath,
+ std::string& linkPath, cmGeneratorTarget* target);
+
void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
const std::string& config, std::string& linkLibs,
std::string& flags, std::string& linkFlags,
@@ -435,10 +444,11 @@ public:
std::string const& lang) const;
void GetTargetCompileFlags(cmGeneratorTarget* target,
std::string const& config,
- std::string const& lang, std::string& flags);
- std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target,
- std::string const& config,
- std::string const& lang);
+ std::string const& lang, std::string& flags,
+ std::string const& arch = std::string());
+ std::vector<BT<std::string>> GetTargetCompileFlags(
+ cmGeneratorTarget* target, std::string const& config,
+ std::string const& lang, std::string const& arch = std::string());
std::string GetFrameworkFlags(std::string const& l,
std::string const& config,
@@ -549,7 +559,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile,
const std::string& job_pool,
- bool command_expand_lists);
+ bool command_expand_lists, bool stdPipesUTF8);
cmSourceFile* AddCustomCommandToOutput(
cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
@@ -560,7 +570,7 @@ cmSourceFile* AddCustomCommandToOutput(
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool);
+ const std::string& job_pool, bool stdPipesUTF8);
void AppendCustomCommandToOutput(cmLocalGenerator& lg,
const cmListFileBacktrace& lfbt,
@@ -577,7 +587,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
const cmCustomCommandLines& commandLines,
bool escapeOldStyle, const char* comment,
bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool);
+ const std::string& job_pool, bool stdPipesUTF8);
}
#endif
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index be1dd0d..d1944a4 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -144,8 +144,9 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
bool forceFullPaths)
{
if (forceFullPaths) {
- return this->ConvertToOutputFormat(cmSystemTools::CollapseFullPath(path),
- format);
+ return this->ConvertToOutputFormat(
+ cmSystemTools::CollapseFullPath(path, this->GetCurrentBinaryDirectory()),
+ format);
}
return this->ConvertToOutputFormat(
this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), path),
@@ -206,9 +207,8 @@ void cmLocalNinjaGenerator::WriteBuildFileTop()
void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Project: " << this->GetProjectName() << std::endl
- << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ")
- << std::endl;
+ os << "# Project: " << this->GetProjectName() << '\n'
+ << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ") << '\n';
cmGlobalNinjaGenerator::WriteDivider(os);
}
@@ -235,8 +235,7 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
cmGlobalNinjaGenerator::WriteComment(
os, "Minimal version of Ninja required by this file");
- os << "ninja_required_version = " << requiredVersion << std::endl
- << std::endl;
+ os << "ninja_required_version = " << requiredVersion << "\n\n";
}
void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable(
@@ -251,23 +250,22 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- const char* jobpools =
+ cmProp jobpools =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS");
if (!jobpools) {
- jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS");
+ jobpools = this->GetMakefile()->GetDef("CMAKE_JOB_POOLS");
}
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools = cmExpandedList(jobpools);
+ std::vector<std::string> pools = cmExpandedList(*jobpools);
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
if (eq != std::string::npos &&
sscanf(pool.c_str() + eq, "=%u", &jobs) == 1) {
- os << "pool " << pool.substr(0, eq) << std::endl;
- os << " depth = " << jobs << std::endl;
- os << std::endl;
+ os << "pool " << pool.substr(0, eq) << "\n depth = " << jobs
+ << "\n\n";
} else {
cmSystemTools::Error("Invalid pool defined by property 'JOB_POOLS': " +
pool);
@@ -279,8 +277,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Include auxiliary files.\n"
- << "\n";
+ os << "# Include auxiliary files.\n\n";
cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
std::string const ninjaCommonFile =
ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE);
@@ -293,8 +290,7 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Include auxiliary files.\n"
- << "\n";
+ os << "# Include auxiliary files.\n\n";
cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
std::string const ninjaRulesFile =
ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE);
@@ -307,14 +303,14 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Write statements declared in CMakeLists.txt:" << std::endl
+ os << "# Write statements declared in CMakeLists.txt:\n"
<< "# " << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")
- << std::endl;
+ << '\n';
if (this->IsRootMakefile()) {
- os << "# Which is the root file." << std::endl;
+ os << "# Which is the root file.\n";
}
cmGlobalNinjaGenerator::WriteDivider(os);
- os << std::endl;
+ os << '\n';
}
void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
@@ -632,10 +628,9 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
std::string cmLocalNinjaGenerator::MakeCustomLauncher(
cmCustomCommandGenerator const& ccg)
{
- const char* property_value =
- this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
+ cmProp property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
- if (!property_value || !*property_value) {
+ if (!property_value || property_value->empty()) {
return std::string();
}
@@ -657,7 +652,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
this->CreateRulePlaceholderExpander());
- std::string launcher = property_value;
+ std::string launcher = *property_value;
rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
if (!launcher.empty()) {
launcher += " ";
@@ -668,11 +663,11 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
{
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
std::vector<std::string> cleanFiles;
{
- cmExpandList(cmGeneratorExpression::Evaluate(prop_value, this, config),
+ cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, this, config),
cleanFiles);
}
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 24a6351..aa8912e 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -48,37 +48,6 @@
# include "cmDependsJava.h"
#endif
-// Escape special characters in Makefile dependency lines
-class cmMakeSafe
-{
-public:
- cmMakeSafe(const char* s)
- : Data(s)
- {
- }
- cmMakeSafe(std::string const& s)
- : Data(s.c_str())
- {
- }
-
-private:
- const char* Data;
- friend std::ostream& operator<<(std::ostream& os, cmMakeSafe const& self)
- {
- for (const char* c = self.Data; *c; ++c) {
- switch (*c) {
- case '=':
- os << "$(EQUALS)";
- break;
- default:
- os << *c;
- break;
- }
- }
- return os;
- }
-};
-
// Helper function used below.
static std::string cmSplitExtension(std::string const& in, std::string& base)
{
@@ -498,6 +467,14 @@ const std::string& cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
return this->HomeRelativeOutputPath;
}
+std::string cmLocalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ return gg->ConvertToMakefilePath(path);
+}
+
void cmLocalUnixMakefileGenerator3::WriteMakeRule(
std::ostream& os, const char* comment, const std::string& target,
const std::vector<std::string>& depends,
@@ -528,7 +505,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
}
// Construct the left hand side of the rule.
- std::string tgt = cmSystemTools::ConvertToOutputPath(
+ std::string tgt = this->ConvertToMakefilePath(
this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target));
const char* space = "";
@@ -542,30 +519,30 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
if (symbolic) {
if (const char* sym =
this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) {
- os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
+ os << tgt << space << ": " << sym << "\n";
}
}
// Write the rule.
if (depends.empty()) {
// No dependencies. The commands will always run.
- os << cmMakeSafe(tgt) << space << ":\n";
+ os << tgt << space << ":\n";
} else {
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists even on older make implementations.
std::string binDir = this->GetBinaryDirectory();
for (std::string const& depend : depends) {
- replace = depend;
- replace = cmSystemTools::ConvertToOutputPath(
- this->MaybeConvertToRelativePath(binDir, replace));
- os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
+ os << tgt << space << ": "
+ << this->ConvertToMakefilePath(
+ this->MaybeConvertToRelativePath(binDir, depend))
+ << '\n';
}
}
// Write the list of commands.
os << cmWrap("\t", commands, "", "\n") << "\n";
if (symbolic && !this->IsWatcomWMake()) {
- os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
+ os << ".PHONY : " << tgt << "\n";
}
os << "\n";
// Add the output to the local help if requested.
@@ -623,8 +600,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
this->MaybeConvertWatcomShellCommand(cmSystemTools::GetCMakeCommand());
if (cmakeShellCommand.empty()) {
cmakeShellCommand = this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
- cmOutputConverter::SHELL);
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
}
/* clang-format off */
@@ -648,16 +624,14 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
<< "# The top-level source directory on which CMake was run.\n"
<< "CMAKE_SOURCE_DIR = "
<< this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(this->GetSourceDirectory()),
- cmOutputConverter::SHELL)
+ this->GetSourceDirectory(), cmOutputConverter::SHELL)
<< "\n"
<< "\n";
makefileStream
<< "# The top-level build directory on which CMake was run.\n"
<< "CMAKE_BINARY_DIR = "
<< this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(this->GetBinaryDirectory()),
- cmOutputConverter::SHELL)
+ this->GetBinaryDirectory(), cmOutputConverter::SHELL)
<< "\n"
<< "\n";
/* clang-format on */
@@ -978,7 +952,8 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// Expand rule variables referenced in the given launcher command.
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = target->GetName().c_str();
- vars.CMTargetType = cmState::GetTargetTypeName(target->GetType());
+ vars.CMTargetType =
+ cmState::GetTargetTypeName(target->GetType()).c_str();
std::string output;
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
@@ -1057,10 +1032,9 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
cleanfile += filename;
}
cleanfile += ".cmake";
- std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
- cmsys::ofstream fout(cleanfilePath.c_str());
+ cmsys::ofstream fout(cleanfile.c_str());
if (!fout) {
- cmSystemTools::Error("Could not create " + cleanfilePath);
+ cmSystemTools::Error("Could not create " + cleanfile);
}
if (!files.empty()) {
fout << "file(REMOVE_RECURSE\n";
@@ -1102,10 +1076,10 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
{
std::vector<std::string> cleanFiles;
// Look for additional files registered for cleaning in this directory.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this,
+ *prop_value, this,
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
cleanFiles);
}
@@ -1120,10 +1094,9 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake");
// Write clean script
{
- std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
- cmsys::ofstream fout(cleanfilePath.c_str());
+ cmsys::ofstream fout(cleanfile.c_str());
if (!fout) {
- cmSystemTools::Error("Could not create " + cleanfilePath);
+ cmSystemTools::Error("Could not create " + cleanfile);
return;
}
fout << "file(REMOVE_RECURSE\n";
@@ -1194,9 +1167,8 @@ void cmLocalUnixMakefileGenerator3::AppendEcho(
color_name);
if (progress) {
cmd += "--progress-dir=";
- cmd += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress->Dir),
- cmOutputConverter::SHELL);
+ cmd += this->ConvertToOutputFormat(progress->Dir,
+ cmOutputConverter::SHELL);
cmd += " ";
cmd += "--progress-num=";
cmd += progress->Arg;
@@ -1331,10 +1303,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
int result;
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
if (verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
- << internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
}
needRescanDependInfo = true;
}
@@ -1351,10 +1322,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
result < 0) {
if (verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \""
- << internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
}
needRescanDirInfo = true;
}
@@ -1520,11 +1490,9 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
if (cmSystemTools::FileExists(dependee) &&
!cmSystemTools::FileExists(depender)) {
if (verbose) {
- std::ostringstream msg;
- msg << "Deleting primary custom command output \"" << dependee
- << "\" because another output \"" << depender
- << "\" does not exist." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat(
+ "Deleting primary custom command output \"", dependee,
+ "\" because another output \"", depender, "\" does not exist.\n"));
}
cmSystemTools::RemoveFile(dependee);
}
@@ -1636,15 +1604,14 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
- progCmd << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+ progCmd << this->ConvertToOutputFormat(progressDir,
+ cmOutputConverter::SHELL);
std::string progressFile = "/CMakeFiles/progress.marks";
std::string progressFileNameFull = this->ConvertToFullPath(progressFile);
progCmd << " "
- << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressFileNameFull),
- cmOutputConverter::SHELL);
+ << this->ConvertToOutputFormat(progressFileNameFull,
+ cmOutputConverter::SHELL);
commands.push_back(progCmd.str());
}
std::string mf2Dir = "CMakeFiles/Makefile2";
@@ -1654,8 +1621,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+ progCmd << this->ConvertToOutputFormat(progressDir,
+ cmOutputConverter::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
@@ -1788,7 +1755,7 @@ private:
const std::string& testDir)
{
// First check if the test directory "starts with" the base directory:
- if (testDir.find(baseDir) != 0) {
+ if (!cmHasPrefix(testDir, baseDir)) {
return false;
}
// If it does, then check that it's either the same string, or that the
@@ -1899,9 +1866,9 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
// 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 (const char* xform =
+ if (cmProp xform =
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(xform, transformRules);
+ cmExpandList(*xform, transformRules);
}
if (const char* xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
@@ -1972,7 +1939,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
{
os << "#======================================"
- << "=======================================\n";
+ "=======================================\n";
}
void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
@@ -1980,7 +1947,7 @@ void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
{
// Write the given string to the stream with escaping to get it back
// into CMake through the lexical scanner.
- os << "\"";
+ os << '"';
for (char c : s) {
if (c == '\\') {
os << "\\\\";
@@ -1990,7 +1957,7 @@ void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
os << c;
}
}
- os << "\"";
+ os << '"';
}
std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 68eeb29..2b07952 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -46,6 +46,12 @@ public:
// local generators StartOutputDirectory
const std::string& GetHomeRelativeOutputPath();
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// Write out a make rule
void WriteMakeRule(std::ostream& os, const char* comment,
const std::string& target,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 9aa3991..95c798b 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio7Generator.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include <windows.h>
#include <ctype.h> // for isspace
@@ -18,6 +21,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmake.h"
@@ -52,14 +56,11 @@ extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(
cmGlobalGenerator* gg, cmMakefile* mf)
: cmLocalVisualStudioGenerator(gg, mf)
+ , Internal(cm::make_unique<cmLocalVisualStudio7GeneratorInternals>(this))
{
- this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
}
-cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
-{
- delete this->Internal;
-}
+cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator() = default;
void cmLocalVisualStudio7Generator::AddHelperCommands()
{
@@ -226,7 +227,6 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
std::string makefileIn =
cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
- makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
if (file->GetCustomCommand()) {
return file;
@@ -252,15 +252,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
std::string argB = cmStrCat("-B", this->GetBinaryDirectory());
std::string stampName =
cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp");
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commandLines =
cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB,
"--check-stamp-file", stampName });
std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
const char* no_working_directory = nullptr;
- std::string fullpathStampName = cmSystemTools::CollapseFullPath(stampName);
- this->AddCustomCommandToOutput(fullpathStampName, listFiles, makefileIn,
- commandLines, comment.c_str(),
- no_working_directory, true, false);
+ this->AddCustomCommandToOutput(
+ stampName, listFiles, makefileIn, commandLines, comment.c_str(),
+ no_working_directory, true, false, false, false, "", "", stdPipesUTF8);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
// Finalize the source file path now since we're adding this after
// the generator validated all project-named sources.
@@ -1006,9 +1006,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
}
std::string libflags;
- this->GetStaticLibraryFlags(libflags, configTypeUpper,
- target->GetLinkerLanguage(configName),
- target);
+ this->GetStaticLibraryFlags(
+ libflags, configName, target->GetLinkerLanguage(configName), target);
if (!libflags.empty()) {
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
}
@@ -1448,14 +1447,15 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
needfc = true;
}
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf.GetProperty(COMPILE_FLAGS)) {
- fc.CompileFlags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ if (cmProp cflags = sf.GetProperty(COMPILE_FLAGS)) {
+ fc.CompileFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
needfc = true;
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = sf.GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = sf.GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- fc.CompileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ fc.CompileFlags,
+ genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
needfc = true;
}
// Add precompile headers compile options.
@@ -1476,7 +1476,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
if (lg->FortranProject) {
switch (cmOutputConverter::GetFortranFormat(
- sf.GetProperty("Fortran_FORMAT"))) {
+ sf.GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
fc.CompileFlags = "-fixed " + fc.CompileFlags;
needfc = true;
@@ -1490,31 +1490,30 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
}
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
- fc.CompileDefs = genexInterpreter.Evaluate(cdefs, COMPILE_DEFINITIONS);
+ if (cmProp cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
+ fc.CompileDefs = genexInterpreter.Evaluate(*cdefs, COMPILE_DEFINITIONS);
needfc = true;
}
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ if (cmProp ccdefs = sf.GetProperty(defPropName)) {
fc.CompileDefsConfig =
- genexInterpreter.Evaluate(ccdefs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*ccdefs, COMPILE_DEFINITIONS);
needfc = true;
}
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
- fc.IncludeDirs = genexInterpreter.Evaluate(cincs, INCLUDE_DIRECTORIES);
+ if (cmProp cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
+ fc.IncludeDirs = genexInterpreter.Evaluate(*cincs, INCLUDE_DIRECTORIES);
needfc = true;
}
// Check for extra object-file dependencies.
- if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(deps);
+ if (cmProp deps = sf.GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> depends = cmExpandedList(*deps);
const char* sep = "";
- for (std::vector<std::string>::iterator j = depends.begin();
- j != depends.end(); ++j) {
+ for (const std::string& d : depends) {
fc.AdditionalDeps += sep;
- fc.AdditionalDeps += lg->ConvertToXMLOutputPath(*j);
+ fc.AdditionalDeps += lg->ConvertToXMLOutputPath(d);
sep = ";";
needfc = true;
}
@@ -1524,7 +1523,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
- !cmContains(acs.Configs, ci) ||
+ !cm::contains(acs.Configs, ci) ||
(gt->GetPropertyAsBool("UNITY_BUILD") &&
sf.GetProperty("UNITY_SOURCE_FILE") &&
!sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
@@ -2010,7 +2009,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFooter(
fout << "\t<Globals>\n";
for (std::string const& key : target->GetPropertyKeys()) {
- if (key.find("VS_GLOBAL_") == 0) {
+ if (cmHasLiteralPrefix(key, "VS_GLOBAL_")) {
std::string name = key.substr(10);
if (!name.empty()) {
/* clang-format off */
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 745766c..8b9b8ad 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -48,6 +49,10 @@ public:
virtual ~cmLocalVisualStudio7Generator();
+ cmLocalVisualStudio7Generator(const cmLocalVisualStudio7Generator&) = delete;
+ const cmLocalVisualStudio7Generator& operator=(
+ const cmLocalVisualStudio7Generator&) = delete;
+
void AddHelperCommands() override;
/**
@@ -144,7 +149,7 @@ private:
bool FortranProject;
bool WindowsCEProject;
- cmLocalVisualStudio7GeneratorInternals* Internal;
+ std::unique_ptr<cmLocalVisualStudio7GeneratorInternals> Internal;
};
#endif
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 8d50898..ebd4f96 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -102,10 +102,12 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
std::vector<std::string> no_output;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commands = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
pcc.reset(new cmCustomCommand(no_output, no_byproducts, no_depends, commands,
- cmListFileBacktrace(), nullptr, nullptr));
+ cmListFileBacktrace(), nullptr, nullptr,
+ stdPipesUTF8));
pcc->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true);
return pcc;
@@ -154,8 +156,7 @@ std::string cmLocalVisualStudioGenerator::ConstructScript(
script += newline;
newline = newline_text;
script += "cd ";
- script += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(workingDirectory), SHELL);
+ script += this->ConvertToOutputFormat(workingDirectory, SHELL);
script += check_error;
// Change the working drive.
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index 6cbed36..53112e0 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -79,14 +79,14 @@ public:
// A load_command and its associated data
struct RawLoadCommand
{
- uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
+ uint32_t type(const cmMachOHeaderAndLoadCommands& m) const
{
if (this->LoadCommand.size() < sizeof(load_command)) {
return 0;
}
const load_command* cmd =
reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
- return m->swap(cmd->cmd);
+ return m.swap(cmd->cmd);
}
std::vector<char> LoadCommand;
};
@@ -186,8 +186,11 @@ class cmMachOInternal
{
public:
cmMachOInternal(const char* fname);
+ cmMachOInternal(const cmMachOInternal&) = delete;
~cmMachOInternal();
+ cmMachOInternal& operator=(const cmMachOInternal&) = delete;
+
// read a Mach-O file
bool read_mach_o(uint32_t file_offset);
@@ -202,7 +205,7 @@ public:
std::string ErrorMessage;
// the list of Mach-O's
- std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
+ std::vector<std::unique_ptr<cmMachOHeaderAndLoadCommands>> MachOList;
};
cmMachOInternal::cmMachOInternal(const char* fname)
@@ -260,12 +263,7 @@ cmMachOInternal::cmMachOInternal(const char* fname)
}
}
-cmMachOInternal::~cmMachOInternal()
-{
- for (auto& i : this->MachOList) {
- delete i;
- }
-}
+cmMachOInternal::~cmMachOInternal() = default;
bool cmMachOInternal::read_mach_o(uint32_t file_offset)
{
@@ -280,25 +278,25 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset)
return false;
}
- cmMachOHeaderAndLoadCommands* f = nullptr;
+ std::unique_ptr<cmMachOHeaderAndLoadCommands> f;
if (magic == MH_CIGAM || magic == MH_MAGIC) {
bool swap = false;
if (magic == MH_CIGAM) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
+ f = cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header>>(swap);
} else if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) {
bool swap = false;
if (magic == MH_CIGAM_64) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
+ f =
+ cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header_64>>(swap);
}
if (f && f->read_mach_o(this->Fin)) {
- this->MachOList.push_back(f);
+ this->MachOList.push_back(std::move(f));
} else {
- delete f;
this->ErrorMessage = "Failed to read Mach-O header.";
return false;
}
@@ -333,11 +331,12 @@ bool cmMachO::GetInstallName(std::string& install_name)
}
// grab the first Mach-O and get the install name from that one
- cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
+ std::unique_ptr<cmMachOHeaderAndLoadCommands>& macho =
+ this->Internal->MachOList[0];
for (size_t i = 0; i < macho->load_commands().size(); i++) {
const cmMachOHeaderAndLoadCommands::RawLoadCommand& cmd =
macho->load_commands()[i];
- uint32_t lc_cmd = cmd.type(macho);
+ uint32_t lc_cmd = cmd.type(*macho);
if (lc_cmd == LC_ID_DYLIB || lc_cmd == LC_LOAD_WEAK_DYLIB ||
lc_cmd == LC_LOAD_DYLIB) {
if (sizeof(dylib_command) < cmd.LoadCommand.size()) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 18689fa..028b0f5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -24,9 +24,9 @@
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
+#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -61,6 +61,7 @@
#include "cmake.h"
#ifndef CMAKE_BOOTSTRAP
+# include "cmMakefileProfilingData.h"
# include "cmVariableWatch.h"
#endif
@@ -373,19 +374,30 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
class cmMakefileCall
{
public:
- cmMakefileCall(cmMakefile* mf, cmCommandContext const& cc,
+ cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff,
cmExecutionStatus& status)
: Makefile(mf)
{
cmListFileContext const& lfc = cmListFileContext::FromCommandContext(
- cc, this->Makefile->StateSnapshot.GetExecutionListFile());
+ lff, this->Makefile->StateSnapshot.GetExecutionListFile());
this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc);
++this->Makefile->RecursionDepth;
this->Makefile->ExecutionStatusStack.push_back(&status);
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
+ lfc);
+ }
+#endif
}
~cmMakefileCall()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
+ }
+#endif
this->Makefile->ExecutionStatusStack.pop_back();
--this->Makefile->RecursionDepth;
this->Makefile->Backtrace = this->Makefile->Backtrace.Pop();
@@ -685,6 +697,27 @@ bool cmMakefile::ReadListFile(const std::string& filename)
return true;
}
+bool cmMakefile::ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName)
+{
+ std::string filenametoread = cmSystemTools::CollapseFullPath(
+ virtualFileName, this->GetCurrentSourceDirectory());
+
+ ListFileScope scope(this, filenametoread);
+
+ cmListFile listFile;
+ if (!listFile.ParseString(content.c_str(), virtualFileName.c_str(),
+ this->GetMessenger(), this->Backtrace)) {
+ return false;
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ scope.Quiet();
+ }
+ return true;
+}
+
void cmMakefile::ReadListFile(cmListFile const& listFile,
std::string const& filenametoread)
{
@@ -988,7 +1021,7 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
const cmCustomCommandLines& commandLines, cmCustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile, const std::string& job_pool,
- bool command_expand_lists)
+ bool command_expand_lists, bool stdPipesUTF8)
{
cmTarget* t = this->GetCustomCommandTarget(
target, cmObjectLibraryCommands::Reject, this->Backtrace);
@@ -1006,14 +1039,15 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
// Dispatch command creation to allow generator expressions in outputs.
- this->AddGeneratorAction([=](cmLocalGenerator& lg,
- const cmListFileBacktrace& lfbt) {
- BacktraceGuard guard(this->Backtrace, lfbt);
- detail::AddCustomCommandToTarget(
- lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends, commandLines,
- type, GetCStrOrNull(commentStr), GetCStrOrNull(workingStr),
- escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists);
- });
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AddCustomCommandToTarget(
+ lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends,
+ commandLines, type, GetCStrOrNull(commentStr),
+ GetCStrOrNull(workingStr), escapeOldStyle, uses_terminal, depfile,
+ job_pool, command_expand_lists, stdPipesUTF8);
+ });
return t;
}
@@ -1024,14 +1058,14 @@ void cmMakefile::AddCustomCommandToOutput(
const char* comment, const char* workingDir,
const CommandSourceCallback& callback, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
std::vector<std::string> no_byproducts;
cmImplicitDependsList no_implicit_depends;
this->AddCustomCommandToOutput(
{ output }, no_byproducts, depends, main_dependency, no_implicit_depends,
commandLines, comment, workingDir, callback, replace, escapeOldStyle,
- uses_terminal, command_expand_lists, depfile, job_pool);
+ uses_terminal, command_expand_lists, depfile, job_pool, stdPipesUTF8);
}
void cmMakefile::AddCustomCommandToOutput(
@@ -1042,7 +1076,7 @@ void cmMakefile::AddCustomCommandToOutput(
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, const CommandSourceCallback& callback, bool replace,
bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
- const std::string& depfile, const std::string& job_pool)
+ const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
{
// Make sure there is at least one output.
if (outputs.empty()) {
@@ -1064,18 +1098,19 @@ void cmMakefile::AddCustomCommandToOutput(
cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
// Dispatch command creation to allow generator expressions in outputs.
- this->AddGeneratorAction([=](cmLocalGenerator& lg,
- const cmListFileBacktrace& lfbt) {
- BacktraceGuard guard(this->Backtrace, lfbt);
- cmSourceFile* sf = detail::AddCustomCommandToOutput(
- lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
- main_dependency, implicit_depends, commandLines,
- GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
- escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool);
- if (callback && sf) {
- callback(sf);
- }
- });
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ cmSourceFile* sf = detail::AddCustomCommandToOutput(
+ lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
+ main_dependency, implicit_depends, commandLines,
+ GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
+ escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool,
+ stdPipesUTF8);
+ if (callback && sf) {
+ callback(sf);
+ }
+ });
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1191,7 +1226,7 @@ cmTarget* cmMakefile::AddUtilityCommand(
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
const char* comment, bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
cmTarget* target = this->AddNewUtilityTarget(utilityName, excludeFromAll);
@@ -1220,7 +1255,7 @@ cmTarget* cmMakefile::AddUtilityCommand(
force, GetCStrOrNull(workingStr), byproducts,
depends, commandLines, escapeOldStyle,
GetCStrOrNull(commentStr), uses_terminal,
- command_expand_lists, job_pool);
+ command_expand_lists, job_pool, stdPipesUTF8);
});
return target;
@@ -1358,9 +1393,9 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
const char* define = def.c_str() + 2;
if (remove) {
- if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
+ if (cmProp cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(cdefs);
+ std::vector<std::string> defs = cmExpandedList(*cdefs);
// Recompose the list without the definition.
auto defEnd = std::remove(defs.begin(), defs.end(), define);
@@ -1389,29 +1424,32 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
// Include transform property. There is no per-config version.
{
const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
- this->SetProperty(prop, parent->GetProperty(prop));
+ cmProp p = parent->GetProperty(prop);
+ this->SetProperty(prop, p ? p->c_str() : nullptr);
}
// compile definitions property and per-config versions
cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
- this->SetProperty("COMPILE_DEFINITIONS",
- parent->GetProperty("COMPILE_DEFINITIONS"));
+ cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
+ this->SetProperty("COMPILE_DEFINITIONS", p ? p->c_str() : nullptr);
std::vector<std::string> configs;
this->GetConfigurations(configs);
for (std::string const& config : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- const char* prop = parent->GetProperty(defPropName);
- this->SetProperty(defPropName, prop);
+ cmProp prop = parent->GetProperty(defPropName);
+ this->SetProperty(defPropName, prop ? prop->c_str() : nullptr);
}
}
// labels
- this->SetProperty("LABELS", parent->GetProperty("LABELS"));
+ cmProp p = parent->GetProperty("LABELS");
+ this->SetProperty("LABELS", p ? p->c_str() : nullptr);
// link libraries
- this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
+ p = parent->GetProperty("LINK_LIBRARIES");
+ this->SetProperty("LINK_LIBRARIES", p ? p->c_str() : nullptr);
// the initial project name
this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -1606,7 +1644,7 @@ void cmMakefile::Configure()
allowedCommands.insert("message");
isProblem = false;
for (cmListFileFunction const& func : listFile.Functions) {
- if (!cmContains(allowedCommands, func.Name.Lower)) {
+ if (!cm::contains(allowedCommands, func.Name.Lower)) {
isProblem = true;
break;
}
@@ -1973,8 +2011,8 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
default:;
}
- if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+ if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
@@ -2418,14 +2456,14 @@ void cmMakefile::ExpandVariablesCMP0019()
}
std::ostringstream w;
- const char* includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
- if (mightExpandVariablesCMP0019(includeDirs)) {
- std::string dirs = includeDirs;
+ cmProp includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
+ if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+ std::string dirs = *includeDirs;
this->ExpandVariablesInString(dirs, true, true);
- if (pol == cmPolicies::WARN && dirs != includeDirs) {
+ if (pol == cmPolicies::WARN && dirs != *includeDirs) {
/* clang-format off */
w << "Evaluated directory INCLUDE_DIRECTORIES\n"
- << " " << includeDirs << "\n"
+ << " " << *includeDirs << "\n"
<< "as\n"
<< " " << dirs << "\n";
/* clang-format on */
@@ -2441,13 +2479,13 @@ void cmMakefile::ExpandVariablesCMP0019()
continue;
}
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
- if (mightExpandVariablesCMP0019(includeDirs)) {
- std::string dirs = includeDirs;
+ if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+ std::string dirs = *includeDirs;
this->ExpandVariablesInString(dirs, true, true);
- if (pol == cmPolicies::WARN && dirs != includeDirs) {
+ if (pol == cmPolicies::WARN && dirs != *includeDirs) {
/* clang-format off */
w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
- << " " << includeDirs << "\n"
+ << " " << *includeDirs << "\n"
<< "as\n"
<< " " << dirs << "\n";
/* clang-format on */
@@ -2456,10 +2494,10 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
- if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
- if (mightExpandVariablesCMP0019(linkDirsProp)) {
- std::string d = linkDirsProp;
- std::string orig = linkDirsProp;
+ if (cmProp linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
+ if (mightExpandVariablesCMP0019(linkDirsProp->c_str())) {
+ std::string d = *linkDirsProp;
+ const std::string orig = d;
this->ExpandVariablesInString(d, true, true);
if (pol == cmPolicies::WARN && d != orig) {
/* clang-format off */
@@ -2472,20 +2510,17 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
- if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+ if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
std::string libName = *l;
- if (libName == "optimized") {
- ++l;
- libName = *l;
- } else if (libName == "debug") {
+ if (libName == "optimized"_s || libName == "debug"_s) {
++l;
libName = *l;
}
if (mightExpandVariablesCMP0019(libName.c_str())) {
- std::string orig = libName;
+ const std::string orig = libName;
this->ExpandVariablesInString(libName, true, true);
if (pol == cmPolicies::WARN && libName != orig) {
/* clang-format off */
@@ -2589,7 +2624,7 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const
};
for (auto const& entry : sdkDatabase) {
- if (sdkRoot.find(entry.name) == 0 ||
+ if (cmHasPrefix(sdkRoot, entry.name) ||
sdkRoot.find(std::string("/") + entry.name) != std::string::npos) {
return entry.sdk;
}
@@ -2998,7 +3033,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
openstack.pop_back();
result.append(last, in - last);
std::string const& lookup = result.substr(var.loc);
- const char* value = nullptr;
+ cmProp value = nullptr;
std::string varresult;
std::string svalue;
switch (var.domain) {
@@ -3006,12 +3041,12 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
if (filename && lookup == lineVar) {
varresult = std::to_string(line);
} else {
- value = this->GetDefinition(lookup);
+ value = this->GetDef(lookup);
}
break;
case ENVIRONMENT:
if (cmSystemTools::GetEnv(lookup, svalue)) {
- value = svalue.c_str();
+ value = &svalue;
}
break;
case CACHE:
@@ -3021,9 +3056,9 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
// Get the string we're meant to append to.
if (value) {
if (escapeQuotes) {
- varresult = cmEscapeQuotes(value);
+ varresult = cmEscapeQuotes(*value);
} else {
- varresult = value;
+ varresult = *value;
}
} else if (!this->SuppressSideEffects) {
this->MaybeWarnUninitialized(lookup, filename);
@@ -4051,7 +4086,7 @@ void cmMakefile::AppendProperty(const std::string& prop,
this->Backtrace);
}
-const char* cmMakefile::GetProperty(const std::string& prop) const
+cmProp cmMakefile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
static std::string output;
@@ -4064,20 +4099,21 @@ const char* cmMakefile::GetProperty(const std::string& prop) const
return pair.first;
});
output = cmJoin(keys, ";");
- return output.c_str();
+ return &output;
}
return this->StateSnapshot.GetDirectory().GetProperty(prop);
}
-const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const
+cmProp cmMakefile::GetProperty(const std::string& prop, bool chain) const
{
return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
}
bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
std::vector<std::string> cmMakefile::GetPropertyKeys() const
@@ -4129,8 +4165,8 @@ void cmMakefile::GetTests(const std::string& config,
void cmMakefile::AddCMakeDependFilesFromUser()
{
std::vector<std::string> deps;
- if (const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
- cmExpandList(deps_str, deps);
+ if (cmProp deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
+ cmExpandList(*deps_str, deps);
}
for (std::string const& dep : deps) {
if (cmSystemTools::FileIsFullPath(dep)) {
@@ -4257,7 +4293,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
bool cmMakefile::IsAlias(const std::string& name) const
{
- if (cmContains(this->AliasTargets, name)) {
+ if (cm::contains(this->AliasTargets, name)) {
return true;
}
return this->GetGlobalGenerator()->IsAlias(name);
@@ -4498,7 +4534,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::CMP0069 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0071 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4627,7 +4663,7 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
}
std::vector<std::string> availableFeatures = cmExpandedList(features);
- if (!cmContains(availableFeatures, feature)) {
+ if (!cm::contains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
<< " compiler\n\""
@@ -4763,8 +4799,8 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const
{
- const char* defaultCStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ cmProp defaultCStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
@@ -4775,11 +4811,11 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
return true;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*defaultCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat("The CMAKE_", lang,
"_STANDARD_DEFAULT variable contains an "
"invalid value: \"",
- defaultCStandard, "\".");
+ *defaultCStandard, "\".");
this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4790,24 +4826,23 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCStandard) {
existingCStandard = defaultCStandard;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCStandard, "\".");
+ "\" contained an invalid value: \"", *existingCStandard, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
const char* const* existingCIt = existingCStandard
? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard))
+ cmStrCmp(*existingCStandard))
: cm::cend(C_STANDARDS);
if (needC11 && existingCStandard &&
@@ -4858,8 +4893,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const
{
- const char* defaultCxxStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ cmProp defaultCxxStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCxxStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
@@ -4870,10 +4905,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
return true;
}
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
+ cmStrCmp(*defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
const std::string e =
cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
- "invalid value: \"", defaultCxxStandard, "\".");
+ "invalid value: \"", *defaultCxxStandard, "\".");
this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4886,7 +4921,7 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard =
+ cmProp existingCxxStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCxxStandard) {
existingCxxStandard = defaultCxxStandard;
@@ -4894,11 +4929,11 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
const char* const* existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCxxStandard));
+ cmStrCmp(*existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ "\" contained an invalid value: \"", *existingCxxStandard, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4925,27 +4960,27 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
if (const char* propCxx98 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx98);
- needCxx98 = cmContains(props, feature);
+ needCxx98 = cm::contains(props, feature);
}
if (const char* propCxx11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx11);
- needCxx11 = cmContains(props, feature);
+ needCxx11 = cm::contains(props, feature);
}
if (const char* propCxx14 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx14);
- needCxx14 = cmContains(props, feature);
+ needCxx14 = cm::contains(props, feature);
}
if (const char* propCxx17 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx17);
- needCxx17 = cmContains(props, feature);
+ needCxx17 = cm::contains(props, feature);
}
if (const char* propCxx20 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx20);
- needCxx20 = cmContains(props, feature);
+ needCxx20 = cm::contains(props, feature);
}
}
@@ -4963,12 +4998,12 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard =
+ cmProp existingCxxStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCxxStandard == nullptr) {
- const char* defaultCxxStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
- if (defaultCxxStandard && *defaultCxxStandard) {
+ cmProp defaultCxxStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCxxStandard && !defaultCxxStandard->empty()) {
existingCxxStandard = defaultCxxStandard;
}
}
@@ -4976,11 +5011,11 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
if (existingCxxStandard) {
existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCxxStandard));
+ cmStrCmp(*existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ "\" contained an invalid value: \"", *existingCxxStandard, "\".");
if (error) {
*error = e;
} else {
@@ -5016,8 +5051,8 @@ bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const
{
- const char* defaultCudaStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ cmProp defaultCudaStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCudaStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
@@ -5028,11 +5063,11 @@ bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
return true;
}
if (std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
- cmStrCmp(defaultCudaStandard)) ==
+ cmStrCmp(*defaultCudaStandard)) ==
cm::cend(CUDA_STANDARDS)) {
const std::string e =
cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
- "invalid value: \"", defaultCudaStandard, "\".");
+ "invalid value: \"", *defaultCudaStandard, "\".");
this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -5045,7 +5080,7 @@ bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
needCuda14, needCuda17, needCuda20);
- const char* existingCudaStandard =
+ cmProp existingCudaStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCudaStandard) {
existingCudaStandard = defaultCudaStandard;
@@ -5053,11 +5088,11 @@ bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
const char* const* existingCudaLevel =
std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
- cmStrCmp(existingCudaStandard));
+ cmStrCmp(*existingCudaStandard));
if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCudaStandard, "\".");
+ "\" contained an invalid value: \"", *existingCudaStandard, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -5084,27 +5119,27 @@ void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
if (const char* propCuda03 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda03);
- needCuda03 = cmContains(props, feature);
+ needCuda03 = cm::contains(props, feature);
}
if (const char* propCuda11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda11);
- needCuda11 = cmContains(props, feature);
+ needCuda11 = cm::contains(props, feature);
}
if (const char* propCuda14 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda14);
- needCuda14 = cmContains(props, feature);
+ needCuda14 = cm::contains(props, feature);
}
if (const char* propCuda17 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda17);
- needCuda17 = cmContains(props, feature);
+ needCuda17 = cm::contains(props, feature);
}
if (const char* propCuda20 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda20);
- needCuda20 = cmContains(props, feature);
+ needCuda20 = cm::contains(props, feature);
}
}
@@ -5122,12 +5157,12 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
needCuda14, needCuda17, needCuda20);
- const char* existingCudaStandard =
+ cmProp existingCudaStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCudaStandard == nullptr) {
- const char* defaultCudaStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
- if (defaultCudaStandard && *defaultCudaStandard) {
+ cmProp defaultCudaStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCudaStandard && !defaultCudaStandard->empty()) {
existingCudaStandard = defaultCudaStandard;
}
}
@@ -5135,11 +5170,11 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
if (existingCudaStandard) {
existingCudaLevel =
std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
- cmStrCmp(existingCudaStandard));
+ cmStrCmp(*existingCudaStandard));
if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCudaStandard, "\".");
+ "\" contained an invalid value: \"", *existingCudaStandard, "\".");
if (error) {
*error = e;
} else {
@@ -5178,17 +5213,17 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
if (const char* propC90 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC90);
- needC90 = cmContains(props, feature);
+ needC90 = cm::contains(props, feature);
}
if (const char* propC99 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC99);
- needC99 = cmContains(props, feature);
+ needC99 = cm::contains(props, feature);
}
if (const char* propC11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC11);
- needC11 = cmContains(props, feature);
+ needC11 = cm::contains(props, feature);
}
}
@@ -5203,21 +5238,20 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCStandard == nullptr) {
- const char* defaultCStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
- if (defaultCStandard && *defaultCStandard) {
+ cmProp defaultCStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCStandard && !defaultCStandard->empty()) {
existingCStandard = defaultCStandard;
}
}
if (existingCStandard) {
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCStandard, "\".");
+ "\" contained an invalid value: \"", *existingCStandard, "\".");
if (error) {
*error = e;
} else {
@@ -5229,7 +5263,7 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
const char* const* existingCIt = existingCStandard
? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard))
+ cmStrCmp(*existingCStandard))
: cm::cend(C_STANDARDS);
bool setC90 = needC90 && !existingCStandard;
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d918abe..04a1f2d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -58,6 +58,8 @@ class cmTestGenerator;
class cmVariableWatch;
class cmake;
+using cmProp = const std::string*;
+
/** Flag if byproducts shall also be considered. */
enum class cmSourceOutputKind
{
@@ -117,6 +119,9 @@ public:
bool ReadListFile(const std::string& filename);
+ bool ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName);
+
bool ReadDependentFile(const std::string& filename,
bool noPolicyScope = true);
@@ -183,7 +188,8 @@ public:
const cmCustomCommandLines& commandLines, cmCustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle = true,
bool uses_terminal = false, const std::string& depfile = "",
- const std::string& job_pool = "", bool command_expand_lists = false);
+ const std::string& job_pool = "", bool command_expand_lists = false,
+ bool stdPipesUTF8 = false);
/**
* Called for each file with custom command.
@@ -200,7 +206,8 @@ public:
const char* workingDir, const CommandSourceCallback& callback = nullptr,
bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
void AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
@@ -211,7 +218,8 @@ public:
const char* workingDir, const CommandSourceCallback& callback = nullptr,
bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -279,7 +287,8 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
const char* comment = nullptr, bool uses_terminal = false,
- bool command_expand_lists = false, const std::string& job_pool = "");
+ bool command_expand_lists = false, const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
/**
* Add a subdirectory to the build.
@@ -314,6 +323,12 @@ public:
void AddCacheDefinition(const std::string& name, const char* value,
const char* doc, cmStateEnums::CacheEntryType type,
bool force = false);
+ void AddCacheDefinition(const std::string& name, const std::string& value,
+ const char* doc, cmStateEnums::CacheEntryType type,
+ bool force = false)
+ {
+ AddCacheDefinition(name, value.c_str(), doc, type, force);
+ }
/**
* Remove a variable definition from the build. This is not valid
@@ -408,7 +423,8 @@ public:
}
const char* GetIncludeRegularExpression() const
{
- return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+ cmProp p = this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+ return p ? p->c_str() : nullptr;
}
/**
@@ -786,8 +802,8 @@ public:
void SetProperty(const std::string& prop, const char* value);
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetProperty(const std::string& prop) const;
- const char* GetProperty(const std::string& prop, bool chain) const;
+ cmProp GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 0471a45..e15b016 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -122,31 +122,15 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
}
// Build a list of compiler flags and linker flags.
- std::string flags;
+ std::string langFlags;
std::string linkFlags;
- // Add flags to create an executable.
- // Add symbol export flags if necessary.
- if (this->GeneratorTarget->IsExecutableWithExports()) {
- std::string export_flag_var =
- cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG");
- this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetSafeDefinition(export_flag_var));
- }
-
- this->LocalGenerator->AppendFlags(linkFlags,
- this->LocalGenerator->GetLinkLibsCMP0065(
- linkLanguage, *this->GeneratorTarget));
-
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
- flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
-
- this->LocalGenerator->AddArchitectureFlags(
- flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Add target-specific linker flags.
- this->GetTargetLinkFlags(linkFlags, linkLanguage);
+ // Add device-specific linker flags.
+ this->GetDeviceLinkFlags(linkFlags, linkLanguage);
// Construct a list of files associated with this executable that
// may need to be cleaned.
@@ -226,7 +210,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
vars.ObjectDir = objectDir.c_str();
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
- vars.Flags = flags.c_str();
+ vars.LanguageCompileFlags = langFlags.c_str();
vars.LinkFlags = linkFlags.c_str();
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
@@ -547,7 +531,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index d3f3a4f..2d360e6 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -141,8 +141,7 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
std::string extraFlags;
this->LocalGenerator->GetStaticLibraryFlags(
- extraFlags, cmSystemTools::UpperCase(this->GetConfigName()), linkLanguage,
- this->GeneratorTarget);
+ extraFlags, this->GetConfigName(), linkLanguage, this->GeneratorTarget);
this->WriteLibraryRules(linkRuleVar, extraFlags, false);
}
@@ -250,9 +249,14 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
+ // Add language-specific flags.
+ std::string langFlags;
+ this->LocalGenerator->AddLanguageFlagsForLinking(
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+
// Create set of linking flags.
std::string linkFlags;
- this->GetTargetLinkFlags(linkFlags, linkLanguage);
+ this->GetDeviceLinkFlags(linkFlags, linkLanguage);
// Get the name of the device object to generate.
std::string const targetOutputReal =
@@ -345,16 +349,10 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
+ vars.LanguageCompileFlags = langFlags.c_str();
vars.LinkFlags = linkFlags.c_str();
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
- // Add language-specific flags.
- std::string langFlags;
- this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
-
- vars.LanguageCompileFlags = langFlags.c_str();
-
std::string launcher;
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
@@ -756,7 +754,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
new file mode 100644
index 0000000..adf4eee
--- /dev/null
+++ b/Source/cmMakefileProfilingData.cxx
@@ -0,0 +1,114 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmMakefileProfilingData.h"
+
+#include <chrono>
+#include <stdexcept>
+#include <vector>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/SystemInformation.hxx"
+
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
+
+#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmMakefileProfilingData::cmMakefileProfilingData(
+ const std::string& profileStream)
+{
+ std::ios::openmode omode = std::ios::out | std::ios::trunc;
+ this->ProfileStream.open(profileStream.c_str(), omode);
+ Json::StreamWriterBuilder wbuilder;
+ this->JsonWriter =
+ std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
+ if (!this->ProfileStream.good()) {
+ throw std::runtime_error(std::string("Unable to open: ") + profileStream);
+ }
+
+ this->ProfileStream << "[";
+};
+
+cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
+{
+ if (this->ProfileStream.good()) {
+ try {
+ this->ProfileStream << "]";
+ this->ProfileStream.close();
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+ }
+}
+
+void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
+ cmListFileContext const& lfc)
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ if (this->ProfileStream.tellp() > 1) {
+ this->ProfileStream << ",";
+ }
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "B";
+ v["name"] = lff.Name.Original;
+ v["cat"] = "cmake";
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ Json::Value argsValue;
+ if (!lff.Arguments.empty()) {
+ std::string args;
+ for (const auto& a : lff.Arguments) {
+ args += (args.empty() ? "" : " ") + a.Value;
+ }
+ argsValue["functionArgs"] = args;
+ }
+ argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
+ v["args"] = argsValue;
+
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output: ", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
+
+void cmMakefileProfilingData::StopEntry()
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ this->ProfileStream << ",";
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "E";
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output:", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
new file mode 100644
index 0000000..1babd97
--- /dev/null
+++ b/Source/cmMakefileProfilingData.h
@@ -0,0 +1,29 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmMakefileProfilingData_h
+#define cmMakefileProfilingData_h
+#include <memory>
+#include <string>
+
+#include "cmsys/FStream.hxx"
+
+namespace Json {
+class StreamWriter;
+}
+
+class cmListFileContext;
+struct cmListFileFunction;
+
+class cmMakefileProfilingData
+{
+public:
+ cmMakefileProfilingData(const std::string&);
+ ~cmMakefileProfilingData() noexcept;
+ void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+ void StopEntry();
+
+private:
+ cmsys::ofstream ProfileStream;
+ std::unique_ptr<Json::StreamWriter> JsonWriter;
+};
+#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index d7e2de6..b21946c 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include <cassert>
#include <cstdio>
#include <sstream>
+#include <unordered_map>
#include <utility>
#include <cm/memory>
@@ -46,9 +47,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
this->LocalGenerator->GetGlobalGenerator());
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
this->NoRuleMessages = false;
- if (const char* ruleStatus =
- cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
- this->NoRuleMessages = cmIsOff(ruleStatus);
+ if (cmProp ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
+ this->NoRuleMessages = cmIsOff(*ruleStatus);
}
MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
}
@@ -87,6 +87,18 @@ std::string cmMakefileTargetGenerator::GetConfigName()
return configNames.front();
}
+void cmMakefileTargetGenerator::GetDeviceLinkFlags(
+ std::string& linkFlags, const std::string& linkLanguage)
+{
+ cmGeneratorTarget::DeviceLinkSetter setter(*this->GetGeneratorTarget());
+
+ std::vector<std::string> linkOpts;
+ this->GeneratorTarget->GetLinkOptions(linkOpts, this->GetConfigName(),
+ linkLanguage);
+ // LINK_OPTIONS are escaped.
+ this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+}
+
void cmMakefileTargetGenerator::GetTargetLinkFlags(
std::string& flags, const std::string& linkLanguage)
{
@@ -155,7 +167,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// Evaluates generator expressions and expands prop_value
auto evaluatedFiles =
- [this](const char* prop_value) -> std::vector<std::string> {
+ [this](const std::string& prop_value) -> std::vector<std::string> {
std::vector<std::string> files;
cmExpandList(cmGeneratorExpression::Evaluate(
prop_value, this->LocalGenerator, this->GetConfigName(),
@@ -165,9 +177,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
};
// Look for additional files registered for cleaning in this directory.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(prop_value);
+ std::vector<std::string> const files = evaluatedFiles(*prop_value);
this->CleanFiles.insert(files.begin(), files.end());
}
@@ -184,8 +196,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
// add custom commands to the clean rules?
- const char* clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
- bool clean = cmIsOff(clean_no_custom);
+ cmProp clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
+ bool clean = clean_no_custom ? cmIsOff(*clean_no_custom) : true;
// First generate the object rule files. Save a list of all object
// files for this target.
@@ -300,8 +312,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
- << "# This may be replaced when dependencies are built."
- << std::endl;
+ << "# This may be replaced when dependencies are built.\n";
}
// Open the flags file. This should be copy-if-different because the
@@ -342,17 +353,32 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
<< "\n";
}
+ bool const escapeOctothorpe = this->GlobalGenerator->CanEscapeOctothorpe();
+
for (std::string const& language : languages) {
- std::string flags = this->GetFlags(language, this->GetConfigName());
std::string defines = this->GetDefines(language, this->GetConfigName());
std::string includes = this->GetIncludes(language, this->GetConfigName());
- // Escape comment characters so they do not terminate assignment.
- cmSystemTools::ReplaceString(flags, "#", "\\#");
- cmSystemTools::ReplaceString(defines, "#", "\\#");
- cmSystemTools::ReplaceString(includes, "#", "\\#");
- *this->FlagFileStream << language << "_FLAGS = " << flags << "\n\n";
+ if (escapeOctothorpe) {
+ // Escape comment characters so they do not terminate assignment.
+ cmSystemTools::ReplaceString(defines, "#", "\\#");
+ cmSystemTools::ReplaceString(includes, "#", "\\#");
+ }
*this->FlagFileStream << language << "_DEFINES = " << defines << "\n\n";
*this->FlagFileStream << language << "_INCLUDES = " << includes << "\n\n";
+
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(this->GetConfigName(), architectures);
+ architectures.emplace_back();
+
+ for (const std::string& arch : architectures) {
+ std::string flags =
+ this->GetFlags(language, this->GetConfigName(), arch);
+ if (escapeOctothorpe) {
+ cmSystemTools::ReplaceString(flags, "#", "\\#");
+ }
+ *this->FlagFileStream << language << "_FLAGS" << arch << " = " << flags
+ << "\n\n";
+ }
}
}
@@ -465,17 +491,37 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string configUpper = cmSystemTools::UpperCase(config);
// Add precompile headers dependencies
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(config, lang);
- if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- std::string const& pchHeader =
- this->GeneratorTarget->GetPchHeader(config, lang);
- depends.push_back(pchHeader);
- if (source.GetFullPath() != pchSource) {
- depends.push_back(this->GeneratorTarget->GetPchFile(config, lang));
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::string filterArch;
+ std::unordered_map<std::string, std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, lang, arch);
+ if (pchSource == source.GetFullPath()) {
+ filterArch = arch;
+ }
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
+
+ if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ for (const std::string& arch : architectures) {
+ std::string const& pchHeader =
+ this->GeneratorTarget->GetPchHeader(config, lang, arch);
+ depends.push_back(pchHeader);
+ if (pchSources.find(source.GetFullPath()) == pchSources.end()) {
+ 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);
}
std::string relativeObj =
@@ -486,7 +532,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string flags;
// Add language-specific flags.
- std::string langFlags = cmStrCat("$(", lang, "_FLAGS)");
+ std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
this->LocalGenerator->AppendFlags(flags, langFlags);
cmGeneratorExpressionInterpreter genexInterpreter(
@@ -499,9 +545,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add flags from source file properties.
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source.GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) {
const std::string& evaluatedFlags =
- genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
*this->FlagFileStream << "# Custom flags: " << relativeObj
<< "_FLAGS = " << evaluatedFlags << "\n"
@@ -509,9 +555,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source.GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source.GetProperty(COMPILE_OPTIONS)) {
const std::string& evaluatedOptions =
- genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS);
+ genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS);
this->LocalGenerator->AppendCompileOptions(flags, evaluatedOptions);
*this->FlagFileStream << "# Custom options: " << relativeObj
<< "_OPTIONS = " << evaluatedOptions << "\n"
@@ -519,11 +565,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Add precompile headers compile options.
- if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (source.GetFullPath() == pchSource) {
- pchOptions =
- this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+ auto pchIt = pchSources.find(source.GetFullPath());
+ if (pchIt != pchSources.end()) {
+ pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+ config, lang, pchIt->second);
} else {
pchOptions =
this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
@@ -542,9 +589,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
this->LocalGenerator->AppendIncludeDirectories(includes, evaluatedIncludes,
source);
*this->FlagFileStream << "# Custom include directories: " << relativeObj
@@ -558,18 +605,18 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add source-specific preprocessor definitions.
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
const std::string& evaluatedDefs =
- genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS);
this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj
<< "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* config_compile_defs = source.GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source.GetProperty(defPropName)) {
const std::string& evaluatedDefs =
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS);
this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_"
<< configUpper << " = " << evaluatedDefs << "\n"
@@ -639,7 +686,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = lang.c_str();
vars.Target = targetOutPathReal.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -716,8 +763,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCommand, vars);
- std::string workingDirectory = cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentBinaryDirectory());
+ std::string workingDirectory =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
this->GetFlags(lang, this->GetConfigName()));
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
@@ -847,9 +894,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Check for extra outputs created by the compilation.
std::vector<std::string> outputs(1, relativeObj);
- if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
+ if (cmProp extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
// Register these as extra files to clean.
- cmExpandList(extra_outputs_str, outputs);
+ cmExpandList(*extra_outputs_str, outputs);
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
@@ -1129,8 +1176,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// translation table for the dependency scanning process.
depCmd << "cd "
<< (this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetBinaryDirectory()),
+ this->LocalGenerator->GetBinaryDirectory(),
cmOutputConverter::SHELL))
<< " && ";
#endif
@@ -1146,23 +1192,19 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
<< this->GlobalGenerator->GetName() << "\" "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetSourceDirectory()),
+ this->LocalGenerator->GetSourceDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentSourceDirectory()),
+ this->LocalGenerator->GetCurrentSourceDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetBinaryDirectory()),
+ this->LocalGenerator->GetBinaryDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentBinaryDirectory()),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
@@ -1205,8 +1247,8 @@ void cmMakefileTargetGenerator::WriteObjectDependRules(
// Create the list of dependencies known at cmake time. These are
// shared between the object file and dependency scanning rule.
depends.push_back(source.GetFullPath());
- if (const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
- cmExpandList(objectDeps, depends);
+ if (cmProp objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
+ cmExpandList(*objectDeps, depends);
}
}
@@ -1250,8 +1292,10 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
// Setup implicit dependency scanning.
for (auto const& idi : ccg.GetCC().GetImplicitDepends()) {
- std::string objFullPath = cmSystemTools::CollapseFullPath(outputs[0]);
- std::string srcFullPath = cmSystemTools::CollapseFullPath(idi.second);
+ std::string objFullPath = cmSystemTools::CollapseFullPath(
+ outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
+ std::string srcFullPath = cmSystemTools::CollapseFullPath(
+ idi.second, this->LocalGenerator->GetCurrentBinaryDirectory());
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, idi.first,
objFullPath, srcFullPath);
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index ec6b314..f38f862 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -60,6 +60,8 @@ public:
std::string GetConfigName();
protected:
+ void GetDeviceLinkFlags(std::string& linkFlags,
+ const std::string& linkLanguage);
void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
// create the file and directory etc
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 885703f..49e8af9 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -156,23 +156,25 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
const std::string& config) const
{
- return this->TargetLinkLanguage(config) + "_" +
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
- "_LINKER__" +
+ return cmStrCat(
+ this->TargetLinkLanguage(config), "_",
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+ "_LINKER__",
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName()) +
- "_" + config;
+ this->GetGeneratorTarget()->GetName()),
+ "_", config);
}
std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
const std::string& config) const
{
- return this->TargetLinkLanguage(config) + "_" +
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
- "_DEVICE_LINKER__" +
+ return cmStrCat(
+ this->TargetLinkLanguage(config), "_",
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+ "_DEVICE_LINKER__",
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName()) +
- "_" + config;
+ this->GetGeneratorTarget()->GetName()),
+ "_", config);
}
struct cmNinjaRemoveNoOpCommands
@@ -191,7 +193,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
+ .c_str();
vars.Language = "CUDA";
@@ -230,11 +233,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
vars.LinkFlags = "$LINK_FLAGS";
vars.Manifests = "$MANIFESTS";
- std::string langFlags;
- if (this->GetGeneratorTarget()->GetType() != cmStateEnums::EXECUTABLE) {
- langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS";
- vars.LanguageCompileFlags = langFlags.c_str();
- }
+ vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS";
std::string launcher;
const char* val = this->GetLocalGenerator()->GetRuleLauncher(
@@ -282,7 +281,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
cmNinjaRule rule(std::move(linkRuleName));
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
- vars.CMTargetType = cmState::GetTargetTypeName(targetType);
+ vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
std::string lang = this->TargetLinkLanguage(config);
vars.Language = config.c_str();
@@ -587,8 +586,6 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
return;
}
- // Now we can do device linking
-
// First and very important step is to make sure while inside this
// step our link language is set to CUDA
std::string cudaLinkLanguage = "CUDA";
@@ -674,9 +671,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
- localGen.GetTargetFlags(
- linkLineComputer.get(), config, vars["LINK_LIBRARIES"], vars["FLAGS"],
- vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
+ localGen.GetDeviceLinkFlags(linkLineComputer.get(), config,
+ vars["LINK_LIBRARIES"], vars["LINK_FLAGS"],
+ frameworkPath, linkPath, genTarget);
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
@@ -686,22 +683,12 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
vars["LINK_PATH"] = frameworkPath + linkPath;
- // Compute architecture specific link flags. Yes, these go into a different
- // variable for executables, probably due to a mistake made when duplicating
- // code between the Makefile executable and library generators.
- if (targetType == cmStateEnums::EXECUTABLE) {
- std::string t = vars["FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
- vars["FLAGS"] = t;
- } else {
- std::string t = vars["ARCH_FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
- vars["ARCH_FLAGS"] = t;
- t.clear();
- localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
- config);
- vars["LANGUAGE_COMPILE_FLAGS"] = t;
- }
+ // Compute language specific link flags.
+ std::string langFlags;
+ localGen.AddLanguageFlagsForLinking(langFlags, genTarget, cudaLinkLanguage,
+ config);
+ vars["LANGUAGE_COMPILE_FLAGS"] = langFlags;
+
auto const tgtNames = this->TargetNames(config);
if (genTarget->HasSOName(config)) {
vars["SONAME_FLAG"] =
@@ -812,8 +799,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
} else if (gt->IsFrameworkOnApple()) {
// Create the library framework.
+
+ cmOSXBundleGenerator::SkipParts bundleSkipParts;
+ if (globalGen->GetName() == "Ninja Multi-Config") {
+ const auto postFix = this->GeneratorTarget->GetFilePostfix(config);
+ // Skip creating Info.plist when there are multiple configurations, and
+ // the current configuration has a postfix. The non-postfix configuration
+ // Info.plist can be used by all the other configurations.
+ if (!postFix.empty()) {
+ bundleSkipParts.infoPlist = true;
+ }
+ }
+
this->OSXBundleGenerator->CreateFramework(
- tgtNames.Output, gt->GetDirectory(config), config);
+ tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
} else if (gt->IsCFBundleOnApple()) {
// Create the core foundation bundle.
this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 486ed8d..701c44f 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -7,6 +7,8 @@
#include <iterator>
#include <map>
#include <ostream>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <cm/memory>
@@ -94,17 +96,19 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
const std::string& lang, const std::string& config) const
{
- return lang + "_COMPILER__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
- "_" + config;
+ return cmStrCat(
+ lang, "_COMPILER__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
std::string const& lang, const std::string& config) const
{
- return lang + "_PREPROCESS__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
- "_" + config;
+ return cmStrCat(
+ lang, "_PREPROCESS__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
@@ -129,9 +133,10 @@ bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
const std::string& lang, const std::string& config) const
{
- return lang + "_DYNDEP__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
- "_" + config;
+ return cmStrCat(
+ lang, "_DYNDEP__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
@@ -154,7 +159,26 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
cmSourceFile const* source, const std::string& language,
const std::string& config)
{
- std::string flags = this->GetFlags(language, config);
+ std::vector<std::string> architectures;
+ std::unordered_map<std::string, std::string> pchSources;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::string filterArch;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, language, arch);
+ if (pchSource == source->GetFullPath()) {
+ filterArch = arch;
+ }
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
+
+ std::string flags = this->GetFlags(language, config, filterArch);
// Add Fortran format flags.
if (language == "Fortran") {
@@ -166,26 +190,24 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
this->LocalGenerator, config, this->GeneratorTarget, language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
this->LocalGenerator->AppendFlags(
- flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
this->LocalGenerator->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
// Add precompile headers compile options.
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(config, language);
-
- if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (source->GetFullPath() == pchSource) {
- pchOptions =
- this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
+ auto pchIt = pchSources.find(source->GetFullPath());
+ if (pchIt != pchSources.end()) {
+ pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+ config, language, pchIt->second);
} else {
pchOptions =
this->GeneratorTarget->GetPchUseCompileOptions(config, language);
@@ -219,8 +241,8 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
{
- std::string const& deptype =
- this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+ std::string const& deptype = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_NINJA_DEPTYPE_", lang));
if (deptype == "msvc") {
return true;
}
@@ -259,17 +281,17 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
}
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
this->LocalGenerator->AppendDefines(
- defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
}
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
this->LocalGenerator->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
}
std::string definesString = this->GetDefines(language, config);
@@ -287,9 +309,9 @@ std::string cmNinjaTargetGenerator::ComputeIncludes(
this->LocalGenerator, config, this->GeneratorTarget, language);
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
this->LocalGenerator->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*source);
}
@@ -355,13 +377,12 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += this->GetGlobalGenerator()->ConfigDirectory(config);
- path += "/";
- path += objectName;
+ path += cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', objectName);
return path;
}
@@ -389,16 +410,15 @@ std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
this->GetGlobalGenerator()->GetLanguageOutputExtension(*source);
assert(objName.size() >= objExt.size());
std::string const ppName =
- objName.substr(0, objName.size() - objExt.size()) + "-pp." + ppExt;
+ cmStrCat(objName.substr(0, objName.size() - objExt.size()), "-pp.", ppExt);
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += this->GetGlobalGenerator()->ConfigDirectory(config);
- path += "/";
- path += ppName;
+ path +=
+ cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', ppName);
return path;
}
@@ -407,13 +427,11 @@ std::string cmNinjaTargetGenerator::GetDyndepFilePath(
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += this->GetGlobalGenerator()->ConfigDirectory(config);
- path += "/";
- path += lang;
- path += ".dd";
+ path += cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang, ".dd");
return path;
}
@@ -442,8 +460,7 @@ std::string cmNinjaTargetGenerator::GetTargetFilePath(
if (path.empty() || path == ".") {
return name;
}
- path += "/";
- path += name;
+ path += cmStrCat('/', name);
return path;
}
@@ -497,7 +514,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
vars.Language = lang.c_str();
vars.Source = "$in";
vars.Object = "$out";
@@ -522,7 +539,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
bool const lang_supports_response = lang != "RC";
if (lang_supports_response && this->ForceResponseFile()) {
std::string const responseFlagVar =
- "CMAKE_" + lang + "_RESPONSE_FILE_FLAG";
+ cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_FLAG");
responseFlag = this->Makefile->GetSafeDefinition(responseFlagVar);
if (responseFlag.empty() && lang != "CUDA") {
responseFlag = "@";
@@ -587,7 +604,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
rule.RspFile = "$RSP_FILE";
rule.RspContent =
cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
- ppFlags = responseFlag + rule.RspFile;
+ ppFlags = cmStrCat(responseFlag, rule.RspFile);
ppVars.Defines = "";
ppVars.Includes = "";
}
@@ -658,7 +675,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
rule.RspFile = "$RSP_FILE";
rule.RspContent =
cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags);
- flags = responseFlag + rule.RspFile;
+ flags = cmStrCat(responseFlag, rule.RspFile);
vars.Defines = "";
vars.Includes = "";
}
@@ -671,7 +688,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
rule.DepType = "msvc";
rule.DepFile.clear();
flags += " /showIncludes";
- } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
+ } 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.
if (!mf->GetIsSourceFileTryCompile()) {
@@ -688,14 +705,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
} else {
rule.DepType = "gcc";
rule.DepFile = "$DEP_FILE";
- const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+ 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>",
mf->GetDefinition("CMAKE_C_COMPILER"));
- flags += " " + depfileFlags;
+ flags += cmStrCat(' ', depfileFlags);
}
}
@@ -718,7 +735,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
} else {
- const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
+ const std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
}
@@ -728,7 +745,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
if (!compileCmds.empty() &&
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
lang == "OBJC" || lang == "OBJCXX")) {
- std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+ std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
if (clauncher && *clauncher) {
compilerLauncher = clauncher;
@@ -737,13 +754,13 @@ 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 = lang + "_INCLUDE_WHAT_YOU_USE";
+ std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
- std::string const tidy_prop = lang + "_CLANG_TIDY";
+ std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
- std::string const cpplint_prop = lang + "_CPPLINT";
+ std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
- std::string const cppcheck_prop = lang + "_CPPCHECK";
+ std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
(cppcheck && *cppcheck)) {
@@ -751,18 +768,19 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
if (!compilerLauncher.empty()) {
// In __run_co_compile case the launcher command is supplied
// via --launcher=<maybe-list> and consumed
- run_iwyu += " --launcher=";
- run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
+ run_iwyu +=
+ cmStrCat(" --launcher=",
+ this->LocalGenerator->EscapeForShell(compilerLauncher));
compilerLauncher.clear();
}
if (iwyu && *iwyu) {
- run_iwyu += " --iwyu=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu);
+ run_iwyu += cmStrCat(" --iwyu=",
+ this->GetLocalGenerator()->EscapeForShell(iwyu));
}
if (tidy && *tidy) {
run_iwyu += " --tidy=";
const char* driverMode = this->Makefile->GetDefinition(
- "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
+ cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
if (!(driverMode && *driverMode)) {
driverMode = lang == "C" ? "gcc" : "g++";
}
@@ -770,12 +788,12 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
if (cpplint && *cpplint) {
- run_iwyu += " --cpplint=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint);
+ run_iwyu += cmStrCat(
+ " --cpplint=", this->GetLocalGenerator()->EscapeForShell(cpplint));
}
if (cppcheck && *cppcheck) {
- run_iwyu += " --cppcheck=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cppcheck);
+ run_iwyu += cmStrCat(
+ " --cppcheck=", this->GetLocalGenerator()->EscapeForShell(cppcheck));
}
if ((tidy && *tidy) || (cpplint && *cpplint) ||
(cppcheck && *cppcheck)) {
@@ -797,7 +815,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCmds.front().insert(0, cmJoin(args, " ") + " ");
+ compileCmds.front().insert(0, cmStrCat(cmJoin(args, " "), ' '));
}
if (!compileCmds.empty()) {
@@ -872,7 +890,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
{
cmNinjaBuild build("phony");
- build.Comment = "Order-only phony target for " + this->GetTargetName();
+ build.Comment =
+ cmStrCat("Order-only phony target for ", this->GetTargetName());
build.Outputs.push_back(this->OrderDependsTargetForTarget(config));
cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
@@ -960,9 +979,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
return name;
}
- return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
- config + "/" + target->GetName() +
- ".swiftdeps");
+ return this->ConvertToNinjaPath(
+ cmStrCat(target->GetSupportDirectory(), '/', config, '/',
+ target->GetName(), ".swiftdeps"));
}();
// build the global target dependencies
@@ -994,7 +1013,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string cmakeVarLang = cmStrCat("CMAKE_", language);
// build response file name
- std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_FLAG";
+ std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG");
const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
@@ -1019,14 +1038,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (!replaceExt) {
// use original code
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileName + ".d", cmOutputConverter::SHELL);
+ cmStrCat(objectFileName, ".d"), cmOutputConverter::SHELL);
} else {
// Replace the original source file extension with the
// depend file extension.
- std::string dependFileName =
- cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
+ std::string dependFileName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileDir + "/" + dependFileName, cmOutputConverter::SHELL);
+ cmStrCat(objectFileDir, '/', dependFileName),
+ cmOutputConverter::SHELL);
}
}
@@ -1049,17 +1069,35 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// Add precompile headers dependencies
std::vector<std::string> depList;
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(config, language);
- if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
- if (source->GetFullPath() != pchSource) {
- depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::unordered_set<std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, language, arch);
+
+ if (!pchSource.empty()) {
+ pchSources.insert(pchSource);
+ }
+ }
+
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ for (const std::string& arch : architectures) {
+ depList.push_back(
+ this->GeneratorTarget->GetPchHeader(config, language, arch));
+ if (pchSources.find(source->GetFullPath()) == pchSources.end()) {
+ depList.push_back(
+ this->GeneratorTarget->GetPchFile(config, language, arch));
+ }
}
}
- if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDepList = cmExpandedList(objectDeps);
+ if (cmProp objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> objDepList = cmExpandedList(*objectDeps);
std::copy(objDepList.begin(), objDepList.end(),
std::back_inserter(depList));
}
@@ -1101,7 +1139,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
ppBuild.Outputs.push_back(ppFileName);
- ppBuild.RspFile = ppFileName + ".rsp";
+ ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
bool const compilePP = this->UsePreprocessedSource(language);
bool const compilePPWithDefines =
@@ -1130,7 +1168,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// In case compilation requires flags that are incompatible with
// preprocessing, include them here.
std::string const& postFlag = this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_POSTPROCESS_FLAG");
+ cmStrCat("CMAKE_", language, "_POSTPROCESS_FLAG"));
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
}
@@ -1158,13 +1196,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
sourceDirectory, this->GeneratorTarget, language, false, false,
config);
- vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+ vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
}
// Explicit preprocessing always uses a depfile.
ppBuild.Variables["DEP_FILE"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileName + ".pp.d", cmOutputConverter::SHELL);
+ cmStrCat(objectFileName, ".pp.d"), cmOutputConverter::SHELL);
if (compilePP) {
// The actual compilation does not need a depfile because it
// depends on the already-preprocessed source.
@@ -1177,7 +1215,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
ppBuild.Variables["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = objectFileName + ".ddi";
+ std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
ppBuild.ImplicitOuts.push_back(ddiFile);
if (firstForConfig) {
@@ -1207,8 +1245,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
vars);
- if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- if (source->GetFullPath() == pchSource) {
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ auto pchIt = pchSources.find(source->GetFullPath());
+ if (pchIt != pchSources.end()) {
this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
this->GetGeneratorTarget(), vars);
}
@@ -1216,7 +1255,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->SetMsvcTargetPdbVariable(vars, config);
- objBuild.RspFile = objectFileName + ".rsp";
+ objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
if (language == "Swift") {
this->EmitSwiftDependencyInfo(source, config);
@@ -1225,10 +1264,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
objBuild, commandLineLengthLimit);
}
- if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
+ if (cmProp objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
cmNinjaBuild build("phony");
build.Comment = "Additional output files.";
- build.Outputs = cmExpandedList(objectOutputs);
+ build.Outputs = cmExpandedList(*objectOutputs);
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
@@ -1242,8 +1281,8 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
{
Json::Value tdi(Json::objectValue);
tdi["language"] = lang;
- tdi["compiler-id"] =
- this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
+ tdi["compiler-id"] = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
if (lang == "Fortran") {
std::string mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
@@ -1292,16 +1331,16 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
std::string const objectFilePath =
this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
- if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return name;
+ if (cmProp name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return *name;
}
- return objectFilePath + ".swiftdeps";
+ return cmStrCat(objectFilePath, ".swiftdeps");
}();
std::string const swiftDiaPath = [source, objectFilePath]() -> std::string {
- if (const char* name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
- return name;
+ if (cmProp name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
+ return *name;
}
- return objectFilePath + ".dia";
+ return cmStrCat(objectFilePath, ".dia");
}();
std::string const makeDepsPath = [this, source, config]() -> std::string {
cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
@@ -1311,12 +1350,13 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
cmSystemTools::GetFilenamePath(objectFileName);
if (this->Makefile->IsOn("CMAKE_Swift_DEPFLE_EXTNSION_REPLACE")) {
- std::string dependFileName =
- cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
- return local->ConvertToOutputFormat(objectFileDir + "/" + dependFileName,
- cmOutputConverter::SHELL);
+ std::string dependFileName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
+ return local->ConvertToOutputFormat(
+ cmStrCat(objectFileDir, '/', dependFileName),
+ cmOutputConverter::SHELL);
}
- return local->ConvertToOutputFormat(objectFileName + ".d",
+ return local->ConvertToOutputFormat(cmStrCat(objectFileName, ".d"),
cmOutputConverter::SHELL);
}();
@@ -1381,7 +1421,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
} else {
- const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT";
+ const std::string cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 382b563..7eea4b2 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -56,9 +56,9 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
outpath = out;
}
-void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
- const std::string& outpath,
- const std::string& config)
+void cmOSXBundleGenerator::CreateFramework(
+ const std::string& targetName, const std::string& outpath,
+ const std::string& config, const cmOSXBundleGenerator::SkipParts& skipParts)
{
if (this->MustSkip()) {
return;
@@ -77,16 +77,18 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
std::string frameworkVersion = this->GT->GetFrameworkVersion();
- // Configure the Info.plist file
- std::string plist = newoutpath;
- if (!this->Makefile->PlatformIsAppleEmbedded()) {
- // Put the Info.plist file into the Resources directory.
- this->MacContentFolders->insert("Resources");
- plist += "/Resources";
- }
- plist += "/Info.plist";
std::string name = cmSystemTools::GetFilenameName(targetName);
- this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+ if (!skipParts.infoPlist) {
+ // Configure the Info.plist file
+ std::string plist = newoutpath;
+ if (!this->Makefile->PlatformIsAppleEmbedded()) {
+ // Put the Info.plist file into the Resources directory.
+ this->MacContentFolders->insert("Resources");
+ plist += "/Resources";
+ }
+ plist += "/Info.plist";
+ this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+ }
// Generate Versions directory only for MacOSX frameworks
if (this->Makefile->PlatformIsAppleEmbedded()) {
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 232be48..5bf1d98 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -19,6 +19,15 @@ class cmOSXBundleGenerator
public:
cmOSXBundleGenerator(cmGeneratorTarget* target);
+ struct SkipParts
+ {
+ SkipParts()
+ : infoPlist(false)
+ {
+ }
+ bool infoPlist; // NOLINT(modernize-use-default-member-init)
+ };
+
// create an app bundle at a given root, and return
// the directory within the bundle that contains the executable
void CreateAppBundle(const std::string& targetName, std::string& root,
@@ -26,7 +35,8 @@ public:
// create a framework at a given root
void CreateFramework(const std::string& targetName, const std::string& root,
- const std::string& config);
+ const std::string& config,
+ const SkipParts& skipParts = SkipParts());
// create a cf bundle at a given root
void CreateCFBundle(const std::string& targetName, const std::string& root,
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 22e59ac..a9adf99 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -52,7 +52,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
// See if a cache variable with this name already exists
// If so just make sure the doc state is correct
cmState* state = status.GetMakefile().GetState();
- const char* existingValue = state->GetCacheEntryValue(args[0]);
+ cmProp existingValue = state->GetCacheEntryValue(args[0]);
if (existingValue &&
(state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
@@ -60,7 +60,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
}
// Nothing in the cache so add it
- std::string initialValue = existingValue ? existingValue : "Off";
+ std::string initialValue = existingValue ? *existingValue : "Off";
if (args.size() == 3) {
initialValue = args[2];
}
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 1c6fad1..68bf3af 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -26,7 +26,7 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
// already exists, we can use a short-path to reference it without a
// space.
if (this->GetState()->UseWindowsShell() &&
- remote.find(' ') != std::string::npos &&
+ remote.find_first_of(" #") != std::string::npos &&
cmSystemTools::FileExists(remote)) {
std::string tmp;
if (cmSystemTools::GetShortPath(remote, tmp)) {
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 147f97f..b18c205 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -20,6 +20,8 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
+using cmProp = const std::string*;
+
namespace {
/** \class cmDependInformation
* \brief Store dependency information for a single source file.
@@ -117,14 +119,13 @@ public:
std::set<std::string> uniqueIncludes;
std::vector<std::string> orderedAndUniqueIncludes;
for (auto const& target : this->Makefile->GetTargets()) {
- const char* incDirProp =
- target.second.GetProperty("INCLUDE_DIRECTORIES");
+ cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
}
std::string incDirs = cmGeneratorExpression::Preprocess(
- incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+ *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
std::vector<std::string> includes = cmExpandedList(incDirs);
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5c8bc98..dea3f8a 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -72,6 +72,7 @@ static const char* idToVersion(cmPolicies::PolicyID id)
#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH) \
case cmPolicies::ID: \
return #V_MAJOR "." #V_MINOR "." #V_PATCH;
+ // NOLINTNEXTLINE(bugprone-branch-clone)
CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
case cmPolicies::CMPCOUNT:
@@ -90,6 +91,7 @@ static bool isPolicyNewerThan(cmPolicies::PolicyID id, unsigned int majorV,
(majorV == (V_MAJOR) && minorV + 1 < (V_MINOR) + 1) || \
(majorV == (V_MAJOR) && minorV == (V_MINOR) && \
patchV + 1 < (V_PATCH) + 1));
+ // NOLINTNEXTLINE(bugprone-branch-clone)
CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
case cmPolicies::CMPCOUNT:
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 1366ff0..4abfa1f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -305,7 +305,18 @@ class cmMakefile;
17, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0102, \
"mark_as_advanced() does nothing if a cache entry does not exist.", \
- 3, 17, 0, cmPolicies::WARN)
+ 3, 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0103, \
+ "Multiple export() with same FILE without APPEND is not allowed.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0104, \
+ "CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty " \
+ "CUDA_ARCHITECTURES not allowed.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0105, "Device link step uses the link options.", 3, 18, \
+ 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -335,7 +346,9 @@ class cmMakefile;
F(CMP0081) \
F(CMP0083) \
F(CMP0095) \
- F(CMP0099)
+ F(CMP0099) \
+ F(CMP0104) \
+ F(CMP0105)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
index e80ea5c..0fb4ff7 100644
--- a/Source/cmProcessOutput.cxx
+++ b/Source/cmProcessOutput.cxx
@@ -4,7 +4,10 @@
#include "cmProcessOutput.h"
#if defined(_WIN32)
+# include <cm/memory>
+
# include <windows.h>
+
unsigned int cmProcessOutput::defaultCodepage =
KWSYS_ENCODING_DEFAULT_CODEPAGE;
#endif
@@ -143,9 +146,9 @@ bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
bool success = false;
const int wlength =
MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), NULL, 0);
- wchar_t* wdata = new wchar_t[wlength];
- int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), wdata,
- wlength);
+ auto wdata = cm::make_unique<wchar_t[]>(wlength);
+ int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()),
+ wdata.get(), wlength);
if (r > 0) {
if (lastChar) {
*lastChar = 0;
@@ -154,18 +157,16 @@ bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
*lastChar = wdata[wlength - 1];
}
}
- int length = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, NULL,
- 0, NULL, NULL);
- char* data = new char[length];
- r = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, data, length,
- NULL, NULL);
+ int length = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+ NULL, 0, NULL, NULL);
+ auto data = cm::make_unique<char[]>(length);
+ r = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+ data.get(), length, NULL, NULL);
if (r > 0) {
- decoded = std::string(data, length);
+ decoded = std::string(data.get(), length);
success = true;
}
- delete[] data;
}
- delete[] wdata;
return success;
}
#endif
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index a25fd42..2ec66d9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -47,10 +47,10 @@ bool cmProjectCommand(std::vector<std::string> const& args,
mf.SetProjectName(projectName);
mf.AddCacheDefinition(projectName + "_BINARY_DIR",
- mf.GetCurrentBinaryDirectory().c_str(),
+ mf.GetCurrentBinaryDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
- mf.GetCurrentSourceDirectory().c_str(),
+ mf.GetCurrentSourceDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
@@ -66,7 +66,7 @@ bool cmProjectCommand(std::vector<std::string> const& args,
// will work.
if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
- mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(),
+ mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
"Value Computed by CMake", cmStateEnums::STATIC);
}
@@ -379,7 +379,7 @@ static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
// CMakeLists.txt file, then go with the last one.
if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
mf.AddDefinition(name, value);
- mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake",
+ mf.AddCacheDefinition(name, value, "Value Computed by CMake",
cmStateEnums::STATIC);
}
}
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 6a3174c..c8efaf6 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -2,19 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinition.h"
-void cmPropertyDefinition::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* shortDescription,
- const char* fullDescription,
- bool chain)
+#include <utility>
+
+cmPropertyDefinition::cmPropertyDefinition(std::string name,
+ cmProperty::ScopeType scope,
+ std::string shortDescription,
+ std::string fullDescription,
+ bool chain)
+ : Name(std::move(name))
+ , ShortDescription(std::move(shortDescription))
+ , FullDescription(std::move(fullDescription))
+ , Scope(scope)
+ , Chained(chain)
{
- this->Name = name;
- this->Scope = scope;
- this->Chained = chain;
- if (shortDescription) {
- this->ShortDescription = shortDescription;
- }
- if (fullDescription) {
- this->FullDescription = fullDescription;
- }
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 0d68c32..d2e4467 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -21,13 +21,10 @@
class cmPropertyDefinition
{
public:
- /// Define this property
- void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained);
-
- /// Default constructor
- cmPropertyDefinition() { this->Chained = false; }
+ /// Constructor
+ cmPropertyDefinition(std::string name, cmProperty::ScopeType scope,
+ std::string ShortDescription,
+ std::string FullDescription, bool chained = false);
/// Is the property chained?
bool IsChained() const { return this->Chained; }
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index f752ed7..614d5a4 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -2,20 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinitionMap.h"
+#include <tuple>
#include <utility>
-void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription,
- bool chain)
+void cmPropertyDefinitionMap::DefineProperty(
+ const std::string& name, cmProperty::ScopeType scope,
+ const std::string& ShortDescription, const std::string& FullDescription,
+ bool chain)
{
auto it = this->find(name);
- cmPropertyDefinition* prop;
if (it == this->end()) {
- prop = &(*this)[name];
- prop->DefineProperty(name, scope, ShortDescription, FullDescription,
- chain);
+ // try_emplace() since C++17
+ this->emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(name, scope, ShortDescription,
+ FullDescription, chain));
}
}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 8ec7910..2ae6efb 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -17,8 +17,8 @@ class cmPropertyDefinitionMap
public:
// define the property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain);
// has a named property been defined
bool IsPropertyDefined(const std::string& name) const;
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index d4b3552..f22f36d 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -42,13 +42,11 @@ void cmPropertyMap::RemoveProperty(const std::string& name)
Map_.erase(name);
}
-const char* cmPropertyMap::GetPropertyValue(const std::string& name) const
+cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
{
- {
- auto it = Map_.find(name);
- if (it != Map_.end()) {
- return it->second.c_str();
- }
+ auto it = Map_.find(name);
+ if (it != Map_.end()) {
+ return &it->second;
}
return nullptr;
}
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index bea4372..40ac356 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -10,6 +10,8 @@
#include <utility>
#include <vector>
+using cmProp = const std::string*;
+
/** \class cmPropertyMap
* \brief String property map.
*/
@@ -31,7 +33,7 @@ public:
bool asString = false);
//! Get the property value
- const char* GetPropertyValue(const std::string& name) const;
+ cmProp GetPropertyValue(const std::string& name) const;
//! Remove the property @a name from the map
void RemoveProperty(const std::string& name);
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index cc4df8f..48c4b10 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -39,7 +39,8 @@ bool cmQTWrapCPPCommand(std::vector<std::string> const& args,
cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
if (curr) {
- sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
+ cmProp p = curr->GetProperty("ABSTRACT");
+ sf->SetProperty("ABSTRACT", p ? p->c_str() : nullptr);
}
// Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index d5891c4..57fcd2d 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -13,7 +13,6 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
@@ -55,7 +54,7 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Test if this is a value option and change the existing value
- if (!optName.empty() && cmContains(valueOpts, optName)) {
+ if (!optName.empty() && cm::contains(valueOpts, optName)) {
const auto existItNext(existIt + 1);
const auto fitNext(fit + 1);
if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 7a6cb42..18b135d 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -164,10 +164,10 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
// Set FOLDER property in the target
{
- char const* folder =
+ cmProp folder =
makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
if (folder != nullptr) {
- target->SetProperty("FOLDER", folder);
+ target->SetProperty("FOLDER", *folder);
}
}
}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 629367d..b0a7c30 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -16,13 +16,13 @@
#include <cm/algorithm>
#include <cm/iterator>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/SystemInformation.hxx"
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
@@ -339,15 +339,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Targets FOLDER
{
- const char* folder =
+ cmProp prop =
this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
- if (folder == nullptr) {
- folder = this->Makefile->GetState()->GetGlobalProperty(
+ if (prop == nullptr) {
+ prop = this->Makefile->GetState()->GetGlobalProperty(
"AUTOGEN_TARGETS_FOLDER");
}
+ const char* folder;
// Inherit FOLDER property from target (#13688)
- if (folder == nullptr) {
+ if (prop == nullptr) {
folder = this->GenTarget->GetProperty("FOLDER");
+ } else {
+ folder = prop->c_str();
}
if (folder != nullptr) {
this->TargetsFolder = folder;
@@ -847,7 +850,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
this->Makefile->GetSource(fullPath, locationKind);
if (sf != nullptr) {
// Check if we know about this header already
- if (cmContains(this->AutogenTarget.Headers, sf)) {
+ if (cm::contains(this->AutogenTarget.Headers, sf)) {
continue;
}
// We only accept not-GENERATED files that do exist.
@@ -895,14 +898,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
cmSystemTools::LowerCase(sf->GetExtension());
if (cm->IsHeaderExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Headers, sf.get())) {
+ if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsSourceExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Sources, sf.get())) {
+ if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUSource(std::move(muf));
@@ -1094,6 +1097,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// of fiddling with the include directories
std::vector<std::string> configs;
this->GlobalGen->GetQtAutoGenConfigs(configs);
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commandLines;
for (auto const& config : configs) {
commandLines.push_back(cmMakeCommandLine(
@@ -1138,7 +1142,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
const std::vector<std::string> no_deps;
cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
this->Makefile->GetBacktrace(), autogenComment.c_str(),
- this->Dir.Work.c_str());
+ this->Dir.Work.c_str(), stdPipesUTF8);
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
this->GenTarget->Target->AddPreBuildCommand(std::move(cc));
@@ -1208,7 +1212,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false,
/*escapeOldStyle=*/false,
/*uses_terminal=*/false,
- /*command_expand_lists=*/false, this->AutogenTarget.DepFile);
+ /*command_expand_lists=*/false, this->AutogenTarget.DepFile, "",
+ stdPipesUTF8);
// Alter variables for the autogen target which now merely wraps the
// custom command
@@ -1279,6 +1284,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccDepends.push_back(qrc.QrcFile);
ccDepends.push_back(qrc.InfoFile);
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commandLines;
if (this->MultiConfig) {
// Build for all configurations
@@ -1307,7 +1313,8 @@ bool cmQtAutoGenInitializer::InitRccTargets()
cmTarget* autoRccTarget = this->LocalGen->AddUtilityCommand(
ccName, true, this->Dir.Work.c_str(), ccOutput, ccDepends,
- commandLines, false, ccComment.c_str());
+ commandLines, false, ccComment.c_str(), false, false, "",
+ stdPipesUTF8);
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
@@ -1347,7 +1354,8 @@ bool cmQtAutoGenInitializer::InitRccTargets()
this->LocalGen->AddCustomCommandToOutput(
ccOutput, ccByproducts, ccDepends, no_main_dependency,
no_implicit_depends, commandLines, ccComment.c_str(),
- this->Dir.Work.c_str());
+ this->Dir.Work.c_str(), false, true, false, false, "", "",
+ stdPipesUTF8);
}
// Reconfigure when .qrc file changes
this->Makefile->AddCMakeDependFile(qrc.QrcFile);
@@ -1604,10 +1612,9 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
};
for (std::string const& prop : props) {
- const char* propName =
- this->Makefile->GetState()->GetGlobalProperty(prop);
- if ((propName != nullptr) && (*propName != '\0')) {
- groupName = propName;
+ cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop);
+ if (propName && !propName->empty()) {
+ groupName = *propName;
property = prop;
break;
}
@@ -1668,6 +1675,13 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
}
return 0u;
};
+ auto toUInt2 = [](cmProp input) -> unsigned int {
+ unsigned long tmp = 0;
+ if (input != nullptr && cmStrToULong(*input, &tmp)) {
+ return static_cast<unsigned int>(tmp);
+ }
+ return 0u;
+ };
// Initialize return value to a default
std::pair<IntegerVersion, unsigned int> res(
@@ -1689,9 +1703,9 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
knownQtVersions.reserve(keys.size() * 2);
// Adds a version to the result (nullptr safe)
- auto addVersion = [&knownQtVersions, &toUInt](const char* major,
- const char* minor) {
- cmQtAutoGen::IntegerVersion ver(toUInt(major), toUInt(minor));
+ auto addVersion = [&knownQtVersions, &toUInt2](cmProp major,
+ cmProp minor) {
+ cmQtAutoGen::IntegerVersion ver(toUInt2(major), toUInt2(minor));
if (ver.Major != 0) {
knownQtVersions.emplace_back(ver);
}
@@ -1699,8 +1713,8 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
// Read versions from variables
for (auto const& keyPair : keys) {
- addVersion(target->Makefile->GetDefinition(std::string(keyPair.first)),
- target->Makefile->GetDefinition(std::string(keyPair.second)));
+ addVersion(target->Makefile->GetDef(std::string(keyPair.first)),
+ target->Makefile->GetDef(std::string(keyPair.second)));
}
// Read versions from directory properties
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 893bd6b..36dd627 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -700,27 +700,27 @@ bool cmQtAutoMocUicT::ParseCacheT::WriteToFile(std::string const& fileName)
if (!ofs) {
return false;
}
- ofs << "# Generated by CMake. Changes will be overwritten." << std::endl;
+ ofs << "# Generated by CMake. Changes will be overwritten.\n";
for (auto const& pair : Map_) {
- ofs << pair.first << std::endl;
+ ofs << pair.first << '\n';
FileT const& file = *pair.second;
if (!file.Moc.Macro.empty()) {
- ofs << " mmc:" << file.Moc.Macro << std::endl;
+ ofs << " mmc:" << file.Moc.Macro << '\n';
}
for (IncludeKeyT const& item : file.Moc.Include.Underscore) {
- ofs << " miu:" << item.Key << std::endl;
+ ofs << " miu:" << item.Key << '\n';
}
for (IncludeKeyT const& item : file.Moc.Include.Dot) {
- ofs << " mid:" << item.Key << std::endl;
+ ofs << " mid:" << item.Key << '\n';
}
for (std::string const& item : file.Moc.Depends) {
- ofs << " mdp:" << item << std::endl;
+ ofs << " mdp:" << item << '\n';
}
for (IncludeKeyT const& item : file.Uic.Include) {
- ofs << " uic:" << item.Key << std::endl;
+ ofs << " uic:" << item.Key << '\n';
}
for (std::string const& item : file.Uic.Depends) {
- ofs << " udp:" << item << std::endl;
+ ofs << " udp:" << item << '\n';
}
}
return ofs.Close();
@@ -2211,9 +2211,9 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
" for writing."));
return;
}
- ofs << BaseConst().DepFileRuleName << ": \\" << std::endl;
+ ofs << BaseConst().DepFileRuleName << ": \\\n";
for (const std::string& file : dependencies) {
- ofs << '\t' << escapeDependencyPath(file) << " \\" << std::endl;
+ ofs << '\t' << escapeDependencyPath(file) << " \\\n";
if (!ofs.good()) {
LogError(GenT::GEN,
cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
@@ -2224,8 +2224,7 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
// 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)
- << std::endl;
+ ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) << '\n';
}
void cmQtAutoMocUicT::JobFinishT::Process()
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 7f4abf9..26e93bb 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -89,7 +89,8 @@ void cmRST::ProcessModule(std::istream& is)
this->ProcessLine(line);
} else {
if (line[0] != '#') {
- this->ProcessLine(line.substr(0, pos));
+ line.resize(pos);
+ this->ProcessLine(line);
}
rst.clear();
this->Reset();
@@ -102,8 +103,9 @@ void cmRST::ProcessModule(std::istream& is)
this->ProcessLine("");
continue;
}
- if (line.substr(0, 2) == "# ") {
- this->ProcessLine(line.substr(2));
+ if (cmHasLiteralPrefix(line, "# ")) {
+ line.erase(0, 2);
+ this->ProcessLine(line);
continue;
}
rst.clear();
@@ -164,6 +166,8 @@ void cmRST::ProcessLine(std::string const& line)
this->Markup =
(line.find_first_not_of(" \t", 2) == std::string::npos ? MarkupEmpty
: MarkupNormal);
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if (this->CMakeDirective.find(line)) {
// Output cmake domain directives and their content normally.
this->NormalLine(line);
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 5ab1b3a..254131b 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -236,8 +236,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
}
if (variable == "CMAKE_COMMAND") {
return outputConverter->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
- cmOutputConverter::SHELL);
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
}
auto compIt = this->Compilers.find(variable);
@@ -334,7 +333,17 @@ void cmRulePlaceholderExpander::ExpandRuleVariables(
std::string replace =
this->ExpandRuleVariable(outputConverter, var, replaceValues);
expandedInput += s.substr(pos, start - pos);
+
+ // Prevent consecutive whitespace in the output if the rule variable
+ // expands to an empty string.
+ bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
+ end + 1 < s.size() && s[end + 1] == ' ';
+ if (consecutive) {
+ expandedInput.pop_back();
+ }
+
expandedInput += replace;
+
// move to next one
start = s.find('<', start + var.size() + 2);
pos = end + 1;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 7a987c2..0781d29 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -39,7 +39,7 @@ static void AddVisualStudioPath(std::vector<std::string>& paths,
std::string vsloc;
bool found = false;
# ifndef CMAKE_BOOTSTRAP
- if (gg->GetName().find(prefix) == 0) {
+ if (cmHasPrefix(gg->GetName(), prefix)) {
cmGlobalVisualStudioVersionedGenerator* vsgen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
if (vsgen->GetVSInstance(vsloc)) {
@@ -218,6 +218,9 @@ bool cmRuntimeDependencyArchive::GetGetRuntimeDependenciesCommand(
// First see if it was supplied by the user
std::string toolCommand = this->GetMakefile()->GetSafeDefinition(
"CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND");
+ if (toolCommand.empty() && search == "objdump") {
+ toolCommand = this->GetMakefile()->GetSafeDefinition("CMAKE_OBJDUMP");
+ }
if (!toolCommand.empty()) {
cmExpandList(toolCommand, command);
return true;
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 52bde7c..cfe3087 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -39,6 +39,8 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
if (doing == DoingVariable) {
var = arg;
doing = DoingMode;
+ // This will always clone one of the other blocks.
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (doing == DoingMode && arg == "NATIVE_COMMAND") {
#ifdef _WIN32
mode = ModeWindows;
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 3b2e5f3..434fb68 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -59,16 +59,12 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental)
, SupportExperimental(supportExperimental)
{
// Register supported protocols:
- this->RegisterProtocol(new cmServerProtocol1);
+ this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
}
cmServer::~cmServer()
{
Close();
-
- for (cmServerProtocol* p : this->SupportedProtocols) {
- delete p;
- }
}
void cmServer::ProcessRequest(cmConnection* connection,
@@ -117,22 +113,22 @@ void cmServer::ProcessRequest(cmConnection* connection,
}
}
-void cmServer::RegisterProtocol(cmServerProtocol* protocol)
+void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
{
if (protocol->IsExperimental() && !this->SupportExperimental) {
- delete protocol;
+ 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](cmServerProtocol* p) {
- return p->ProtocolVersion() == version;
- });
+ 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(protocol);
+ this->SupportedProtocols.push_back(std::move(protocol));
}
}
@@ -297,19 +293,20 @@ void cmServer::WriteJsonObject(cmConnection* connection,
}
cmServerProtocol* cmServer::FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor)
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor)
{
cmServerProtocol* bestMatch = nullptr;
- for (auto protocol : protocols) {
+ for (const auto& protocol : protocols) {
auto version = protocol->ProtocolVersion();
if (major != version.first) {
continue;
}
if (minor == version.second) {
- return protocol;
+ return protocol.get();
}
if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
- bestMatch = protocol;
+ bestMatch = protocol.get();
}
}
return minor < 0 ? bestMatch : nullptr;
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 3d7027b..ec40738 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -103,7 +103,7 @@ public:
cmFileMonitor* FileMonitor() const;
private:
- void RegisterProtocol(cmServerProtocol* protocol);
+ void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
// Callbacks from cmServerConnection:
@@ -149,12 +149,13 @@ private:
const DebugInfo* debug) const;
static cmServerProtocol* FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor);
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor);
const bool SupportExperimental;
cmServerProtocol* Protocol = nullptr;
- std::vector<cmServerProtocol*> SupportedProtocols;
+ std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
friend class cmServerProtocol;
friend class cmServerRequest;
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 1d4ea01..10e6317 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -10,10 +10,10 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cm_uv.h"
-#include "cmAlgorithms.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileMonitor.h"
#include "cmGlobalGenerator.h"
@@ -182,7 +182,7 @@ static bool getOrTestHomeDirectory(cmState* state, std::string& value,
std::string* errorMessage)
{
const std::string cachedValue =
- std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"));
+ *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (value.empty()) {
value = cachedValue;
return true;
@@ -205,9 +205,7 @@ static bool getOrTestValue(cmState* state, const std::string& key,
const std::string& keyDescription,
std::string* errorMessage)
{
- const char* entry = state->GetCacheEntryValue(key);
- const std::string cachedValue =
- entry == nullptr ? std::string() : std::string(entry);
+ const std::string cachedValue = state->GetSafeCacheEntryValue(key);
if (value.empty()) {
value = cachedValue;
}
@@ -435,7 +433,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
keys = allKeys;
} else {
for (auto const& i : keys) {
- if (!cmContains(allKeys, i)) {
+ if (!cm::contains(allKeys, i)) {
return request.ReportError("Key \"" + i + "\" not found in cache.");
}
}
@@ -452,7 +450,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
bool haveProperties = false;
for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
haveProperties = true;
- props[prop] = state->GetCacheEntryProperty(key, prop);
+ props[prop] = *state->GetCacheEntryProperty(key, prop);
}
if (haveProperties) {
entry[kPROPERTIES_KEY] = props;
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 5e2a146..5c55427 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -135,7 +135,7 @@ bool cmSetCommand(std::vector<std::string> const& args,
// see if this is already in the cache
cmState* state = status.GetMakefile().GetState();
- const char* existingValue = state->GetCacheEntryValue(variable);
+ cmProp existingValue = state->GetCacheEntryValue(variable);
if (existingValue &&
(state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
// if the set is trying to CACHE the value but the value
@@ -149,8 +149,8 @@ bool cmSetCommand(std::vector<std::string> const& args,
// if it is meant to be in the cache then define it in the cache
if (cache) {
- status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
- type, force);
+ status.GetMakefile().AddCacheDefinition(variable, value, docstring, type,
+ force);
} else {
// add the definition
status.GetMakefile().AddDefinition(variable, value);
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 3705727..4dbbbd7 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -235,14 +235,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
if (!names.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = *names.begin();
- if (!cmSystemTools::FileIsFullPath(dir)) {
- dir = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
- *names.begin());
- }
-
- // The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir);
+ std::string dir = cmSystemTools::CollapseFullPath(
+ *names.begin(), status.GetMakefile().GetCurrentSourceDirectory());
mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
if (!mf) {
@@ -307,7 +301,7 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
if (remove) {
target->SetProperty(propertyName, nullptr);
} else {
- target->SetProperty(propertyName, propertyValue.c_str());
+ target->SetProperty(propertyName, propertyValue);
}
}
@@ -438,7 +432,7 @@ bool HandleCacheMode(cmExecutionStatus& status,
for (std::string const& name : names) {
// Get the source file.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- const char* existingValue = cm->GetState()->GetCacheEntryValue(name);
+ cmProp existingValue = cm->GetState()->GetCacheEntryValue(name);
if (existingValue) {
if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
propertyValue, appendAsString, appendMode,
@@ -460,16 +454,15 @@ bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
cmState* state = makefile.GetState();
if (remove) {
state->RemoveCacheEntryProperty(cacheKey, propertyName);
}
if (appendMode) {
- state->AppendCacheEntryProperty(cacheKey, propertyName, value,
+ state->AppendCacheEntryProperty(cacheKey, propertyName, propertyValue,
appendAsString);
} else {
- state->SetCacheEntryProperty(cacheKey, propertyName, value);
+ state->SetCacheEntryProperty(cacheKey, propertyName, propertyValue);
}
return true;
@@ -505,13 +498,13 @@ bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
if (remove) {
file->RemoveProperty(propertyName);
} else if (appendMode) {
- file->AppendProperty(&makefile, propertyName, value, appendAsString);
+ file->AppendProperty(&makefile, propertyName, propertyValue,
+ appendAsString);
} else {
- file->SetProperty(&makefile, propertyName, value);
+ file->SetProperty(&makefile, propertyName, propertyValue);
}
return true;
}
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index d47f121..b2d905e 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -72,8 +72,7 @@ bool cmSiteNameCommand(std::vector<std::string> const& args,
}
#endif
status.GetMakefile().AddCacheDefinition(
- args[0], siteName.c_str(),
- "Name of the computer/site where compile is being run",
+ args[0], siteName, "Name of the computer/site where compile is being run",
cmStateEnums::STRING);
return true;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index fd9cacd..f525439 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -48,9 +48,9 @@ std::string cmSourceFile::GetObjectLibrary() const
std::string const& cmSourceFile::GetOrDetermineLanguage()
{
// If the language was set explicitly by the user then use it.
- if (const char* lang = this->GetProperty(propLANGUAGE)) {
+ if (cmProp lang = this->GetProperty(propLANGUAGE)) {
// Assign to member in order to return a reference.
- this->Language = lang;
+ this->Language = *lang;
return this->Language;
}
@@ -81,8 +81,8 @@ std::string const& cmSourceFile::GetOrDetermineLanguage()
std::string cmSourceFile::GetLanguage() const
{
// If the language was set explicitly by the user then use it.
- if (const char* lang = this->GetProperty(propLANGUAGE)) {
- return lang;
+ if (cmProp lang = this->GetProperty(propLANGUAGE)) {
+ return *lang;
}
// Use the language determined from the file extension.
@@ -317,17 +317,18 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
}
// Perform the normal property lookup.
- return this->GetProperty(prop);
+ cmProp p = this->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
-const char* cmSourceFile::GetProperty(const std::string& prop) const
+cmProp cmSourceFile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
if (prop == propLOCATION) {
if (this->FullPath.empty()) {
return nullptr;
}
- return this->FullPath.c_str();
+ return &this->FullPath;
}
// Check for the properties with backtraces.
@@ -338,7 +339,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->IncludeDirectories, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_OPTIONS) {
@@ -348,7 +349,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileOptions, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_DEFINITIONS) {
@@ -358,10 +359,10 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileDefinitions, ";");
- return output.c_str();
+ return &output;
}
- const char* retVal = this->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
cmMakefile const* mf = this->Location.GetMakefile();
const bool chain =
@@ -369,6 +370,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
if (chain) {
return mf->GetProperty(prop, chain);
}
+ return nullptr;
}
return retVal;
@@ -376,16 +378,17 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
{
- const char* ret = this->GetProperty(prop);
+ cmProp ret = this->GetProperty(prop);
if (!ret) {
return "";
}
- return ret;
+ return ret->c_str();
}
bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
void cmSourceFile::SetProperties(cmPropertyMap properties)
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index e22829f..e527069 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -17,6 +17,8 @@
class cmMakefile;
+using cmProp = const std::string*;
+
/** \class cmSourceFile
* \brief Represent a class loaded from a makefile.
*
@@ -45,7 +47,7 @@ public:
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
const char* GetSafeProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 5f807b8..e852c05 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -4,6 +4,8 @@
#include <cassert>
+#include <cm/string_view>
+
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -152,7 +154,7 @@ bool cmSourceFileLocation::MatchesAmbiguousExtension(
// Only a fixed set of extensions will be tried to match a file on
// disk. One of these must match if loc refers to this source file.
- std::string const& ext = this->Name.substr(loc.Name.size() + 1);
+ auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
cmMakefile const* mf = this->Makefile;
auto cm = mf->GetCMakeInstance();
return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 8c3ec9f..155068cb 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include <cm/memory>
+
#include "cmStringAlgorithms.h"
class cmSourceGroupInternals
@@ -16,7 +18,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
const char* parentName)
: Name(std::move(name))
{
- this->Internal = new cmSourceGroupInternals;
+ this->Internal = cm::make_unique<cmSourceGroupInternals>();
this->SetGroupRegex(regex);
if (parentName) {
this->FullName = cmStrCat(parentName, '\\');
@@ -24,10 +26,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
this->FullName += this->Name;
}
-cmSourceGroup::~cmSourceGroup()
-{
- delete this->Internal;
-}
+cmSourceGroup::~cmSourceGroup() = default;
cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
{
@@ -36,7 +35,7 @@ cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
this->GroupRegex = r.GroupRegex;
this->GroupFiles = r.GroupFiles;
this->SourceFiles = r.SourceFiles;
- this->Internal = new cmSourceGroupInternals(*r.Internal);
+ this->Internal = cm::make_unique<cmSourceGroupInternals>(*r.Internal);
}
cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r)
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 581dc5d..623cded 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -122,7 +123,7 @@ private:
*/
std::vector<const cmSourceFile*> SourceFiles;
- cmSourceGroupInternals* Internal;
+ std::unique_ptr<cmSourceGroupInternals> Internal;
};
#endif
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index cc62952..bb75a14 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -7,7 +7,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceGroup.h"
@@ -30,18 +31,6 @@ std::vector<std::string> tokenizePath(const std::string& path)
return cmTokenize(path, "\\/");
}
-std::string getFullFilePath(const std::string& currentPath,
- const std::string& path)
-{
- std::string fullPath = path;
-
- if (!cmSystemTools::FileIsFullPath(path)) {
- fullPath = cmStrCat(currentPath, '/', path);
- }
-
- return cmSystemTools::CollapseFullPath(fullPath);
-}
-
std::set<std::string> getSourceGroupFilesPaths(
const std::string& root, const std::vector<std::string>& files)
{
@@ -124,7 +113,8 @@ bool addFilesToItsSourceGroups(const std::string& root,
errorMsg = "Could not create source group for file: " + sgFilesPath;
return false;
}
- const std::string fullPath = getFullFilePath(root, sgFilesPath);
+ const std::string fullPath =
+ cmSystemTools::CollapseFullPath(sgFilesPath, root);
sg->AddGroupFile(fullPath);
}
}
@@ -147,7 +137,7 @@ ExpectedOptions getExpectedOptions()
bool isExpectedOption(const std::string& argument,
const ExpectedOptions& expectedOptions)
{
- return cmContains(expectedOptions, argument);
+ return cm::contains(expectedOptions, argument);
}
void parseArguments(const std::vector<std::string>& args,
@@ -255,10 +245,8 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
parsedArguments[kFilesOptionName];
for (auto const& filesArg : filesArguments) {
std::string src = filesArg;
- if (!cmSystemTools::FileIsFullPath(src)) {
- src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg);
- }
- src = cmSystemTools::CollapseFullPath(src);
+ src =
+ cmSystemTools::CollapseFullPath(src, mf.GetCurrentSourceDirectory());
sg->AddGroupFile(src);
}
}
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index 13f7622..55d23c1 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -3,6 +3,19 @@
#ifndef cmStandardLexer_h
#define cmStandardLexer_h
+#if !defined(_WIN32) && !defined(__sun)
+/* POSIX APIs are needed */
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__sun) && defined(__GNUC__) && !defined(__cplusplus)
+/* C sources: for fileno and strdup */
+# define _XOPEN_SOURCE 600
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+/* For isascii */
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmsys/Configure.h" // IWYU pragma: keep
/* Disable some warnings. */
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 9fc7615..2e748d3 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -26,6 +26,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
+using cmProp = const std::string*;
+
cmState::cmState()
{
this->CacheManager = cm::make_unique<cmCacheManager>();
@@ -34,30 +36,44 @@ cmState::cmState()
cmState::~cmState() = default;
-const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
-{
+const std::string& cmState::GetTargetTypeName(
+ cmStateEnums::TargetType targetType)
+{
+#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(STATIC_LIBRARY);
+ MAKE_STATIC_PROP(MODULE_LIBRARY);
+ MAKE_STATIC_PROP(SHARED_LIBRARY);
+ MAKE_STATIC_PROP(OBJECT_LIBRARY);
+ MAKE_STATIC_PROP(EXECUTABLE);
+ MAKE_STATIC_PROP(UTILITY);
+ MAKE_STATIC_PROP(GLOBAL_TARGET);
+ MAKE_STATIC_PROP(INTERFACE_LIBRARY);
+ MAKE_STATIC_PROP(UNKNOWN_LIBRARY);
+ static const std::string propEmpty;
+#undef MAKE_STATIC_PROP
+
switch (targetType) {
case cmStateEnums::STATIC_LIBRARY:
- return "STATIC_LIBRARY";
+ return propSTATIC_LIBRARY;
case cmStateEnums::MODULE_LIBRARY:
- return "MODULE_LIBRARY";
+ return propMODULE_LIBRARY;
case cmStateEnums::SHARED_LIBRARY:
- return "SHARED_LIBRARY";
+ return propSHARED_LIBRARY;
case cmStateEnums::OBJECT_LIBRARY:
- return "OBJECT_LIBRARY";
+ return propOBJECT_LIBRARY;
case cmStateEnums::EXECUTABLE:
- return "EXECUTABLE";
+ return propEXECUTABLE;
case cmStateEnums::UTILITY:
- return "UTILITY";
+ return propUTILITY;
case cmStateEnums::GLOBAL_TARGET:
- return "GLOBAL_TARGET";
+ return propGLOBAL_TARGET;
case cmStateEnums::INTERFACE_LIBRARY:
- return "INTERFACE_LIBRARY";
+ return propINTERFACE_LIBRARY;
case cmStateEnums::UNKNOWN_LIBRARY:
- return "UNKNOWN_LIBRARY";
+ return propUNKNOWN_LIBRARY;
}
assert(false && "Unexpected target type");
- return nullptr;
+ return propEmpty;
}
static const std::array<std::string, 7> cmCacheEntryTypes = {
@@ -123,32 +139,20 @@ bool cmState::DeleteCache(const std::string& path)
std::vector<std::string> cmState::GetCacheEntryKeys() const
{
- std::vector<std::string> definitions;
- definitions.reserve(this->CacheManager->GetSize());
- cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
- for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
- definitions.push_back(cit.GetName());
- }
- return definitions;
+ return this->CacheManager->GetCacheEntryKeys();
}
-const char* cmState::GetCacheEntryValue(std::string const& key) const
+cmProp cmState::GetCacheEntryValue(std::string const& key) const
{
- cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
- if (!e) {
- return nullptr;
- }
- return e->Value.c_str();
+ return this->CacheManager->GetCacheEntryValue(key);
}
std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
{
- std::string retval;
- auto val = this->GetCacheEntryValue(key);
- if (val) {
- retval = val;
+ if (cmProp val = this->GetCacheEntryValue(key)) {
+ return *val;
}
- return retval;
+ return std::string();
}
const std::string* cmState::GetInitializedCacheValue(
@@ -160,8 +164,7 @@ const std::string* cmState::GetInitializedCacheValue(
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
std::string const& key) const
{
- cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
- return it.GetType();
+ return this->CacheManager->GetCacheEntryType(key);
}
void cmState::SetCacheEntryValue(std::string const& key,
@@ -174,40 +177,32 @@ void cmState::SetCacheEntryProperty(std::string const& key,
std::string const& propertyName,
std::string const& value)
{
- cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
- it.SetProperty(propertyName, value.c_str());
+ this->CacheManager->SetCacheEntryProperty(key, propertyName, value);
}
void cmState::SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName,
bool value)
{
- cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
- it.SetProperty(propertyName, value);
+ this->CacheManager->SetCacheEntryBoolProperty(key, propertyName, value);
}
std::vector<std::string> cmState::GetCacheEntryPropertyList(
const std::string& key)
{
- cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
- return it.GetPropertyList();
+ return this->CacheManager->GetCacheEntryPropertyList(key);
}
-const char* cmState::GetCacheEntryProperty(std::string const& key,
- std::string const& propertyName)
+cmProp cmState::GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName)
{
- cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
- if (!it.PropertyExists(propertyName)) {
- return nullptr;
- }
- return it.GetProperty(propertyName);
+ return this->CacheManager->GetCacheEntryProperty(key, propertyName);
}
bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName)
{
- return this->CacheManager->GetCacheIterator(key).GetPropertyAsBool(
- propertyName);
+ return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName);
}
void cmState::AddCacheEntry(const std::string& key, const char* value,
@@ -259,14 +254,13 @@ void cmState::AppendCacheEntryProperty(const std::string& key,
const std::string& property,
const std::string& value, bool asString)
{
- this->CacheManager->GetCacheIterator(key).AppendProperty(property, value,
- asString);
+ this->CacheManager->AppendCacheEntryProperty(key, property, value, asString);
}
void cmState::RemoveCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
- this->CacheManager->GetCacheIterator(key).SetProperty(propertyName, nullptr);
+ this->CacheManager->RemoveCacheEntryProperty(key, propertyName);
}
cmStateSnapshot cmState::Reset()
@@ -335,8 +329,8 @@ cmStateSnapshot cmState::Reset()
void cmState::DefineProperty(const std::string& name,
cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained)
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chained)
{
this->PropertyDefinitions[scope].DefineProperty(
name, scope, ShortDescription, FullDescription, chained);
@@ -573,7 +567,7 @@ void cmState::AppendGlobalProperty(const std::string& prop,
this->GlobalProperties.AppendProperty(prop, value, asString);
}
-const char* cmState::GetGlobalProperty(const std::string& prop)
+cmProp cmState::GetGlobalProperty(const std::string& prop)
{
if (prop == "CACHE_VARIABLES") {
std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
@@ -597,31 +591,49 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
}
#define STRING_LIST_ELEMENT(F) ";" #F
if (prop == "CMAKE_C_KNOWN_FEATURES") {
- return &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C90_KNOWN_FEATURES") {
- return &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C99_KNOWN_FEATURES") {
- return &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C11_KNOWN_FEATURES") {
- return &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
- return &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
- return &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
- return &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
- return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
- return &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
#undef STRING_LIST_ELEMENT
@@ -630,7 +642,8 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
- return cmIsOn(this->GetGlobalProperty(prop));
+ cmProp p = this->GetGlobalProperty(prop);
+ return p && cmIsOn(*p);
}
void cmState::SetSourceDirectory(std::string const& sourceDirectory)
diff --git a/Source/cmState.h b/Source/cmState.h
index 6ee2b0c..e3fbfdc 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -30,6 +30,8 @@ class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
+using cmProp = const std::string*;
+
class cmState
{
friend class cmStateSnapshot;
@@ -51,7 +53,8 @@ public:
CPack,
};
- static const char* GetTargetTypeName(cmStateEnums::TargetType targetType);
+ static const std::string& GetTargetTypeName(
+ cmStateEnums::TargetType targetType);
cmStateSnapshot CreateBaseSnapshot();
cmStateSnapshot CreateBuildsystemDirectorySnapshot(
@@ -87,7 +90,7 @@ public:
bool DeleteCache(const std::string& path);
std::vector<std::string> GetCacheEntryKeys() const;
- const char* GetCacheEntryValue(std::string const& key) const;
+ cmProp GetCacheEntryValue(std::string const& key) const;
std::string GetSafeCacheEntryValue(std::string const& key) const;
const std::string* GetInitializedCacheValue(std::string const& key) const;
cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const;
@@ -102,8 +105,8 @@ public:
void SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName, bool value);
std::vector<std::string> GetCacheEntryPropertyList(std::string const& key);
- const char* GetCacheEntryProperty(std::string const& key,
- std::string const& propertyName);
+ cmProp GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName);
bool GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName);
void AppendCacheEntryProperty(std::string const& key,
@@ -121,8 +124,8 @@ public:
cmStateSnapshot Reset();
// Define a property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain = false);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain = false);
// get property definition
cmPropertyDefinition const* GetPropertyDefinition(
@@ -171,7 +174,7 @@ public:
void SetGlobalProperty(const std::string& prop, const char* value);
void AppendGlobalProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetGlobalProperty(const std::string& prop);
+ cmProp GetGlobalProperty(const std::string& prop);
bool GetGlobalPropertyAsBool(const std::string& prop);
std::string const& GetSourceDirectory() const;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 4f003ed..a4fe663 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -548,32 +548,31 @@ void cmStateDirectory::AppendProperty(const std::string& prop,
this->DirectoryState->Properties.AppendProperty(prop, value, asString);
}
-const char* cmStateDirectory::GetProperty(const std::string& prop) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop) const
{
const bool chain =
this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY);
return this->GetProperty(prop, chain);
}
-const char* cmStateDirectory::GetProperty(const std::string& prop,
- bool chain) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
{
static std::string output;
output.clear();
if (prop == "PARENT_DIRECTORY") {
cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
if (parent.IsValid()) {
- return parent.GetDirectory().GetCurrentSource().c_str();
+ return &parent.GetDirectory().GetCurrentSource();
}
- return "";
+ return &output;
}
if (prop == kBINARY_DIR) {
output = this->GetCurrentBinary();
- return output.c_str();
+ return &output;
}
if (prop == kSOURCE_DIR) {
output = this->GetCurrentSource();
- return output.c_str();
+ return &output;
}
if (prop == kSUBDIRECTORIES) {
std::vector<std::string> child_dirs;
@@ -584,11 +583,11 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
}
output = cmJoin(child_dirs, ";");
- return output.c_str();
+ return &output;
}
if (prop == kBUILDSYSTEM_TARGETS) {
output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
- return output.c_str();
+ return &output;
}
if (prop == "LISTFILE_STACK") {
@@ -600,41 +599,41 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
}
std::reverse(listFiles.begin(), listFiles.end());
output = cmJoin(listFiles, ";");
- return output.c_str();
+ return &output;
}
if (prop == "CACHE_VARIABLES") {
output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "VARIABLES") {
std::vector<std::string> res = this->Snapshot_.ClosureKeys();
cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
output = cmJoin(res, ";");
- return output.c_str();
+ return &output;
}
if (prop == "INCLUDE_DIRECTORIES") {
output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "COMPILE_OPTIONS") {
output = cmJoin(this->GetCompileOptionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "COMPILE_DEFINITIONS") {
output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "LINK_OPTIONS") {
output = cmJoin(this->GetLinkOptionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "LINK_DIRECTORIES") {
output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
- return output.c_str();
+ return &output;
}
- const char* retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
if (!retVal && chain) {
cmStateSnapshot parentSnapshot =
this->Snapshot_.GetBuildsystemDirectoryParent();
@@ -649,7 +648,8 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 53a2d54..8144160 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -16,6 +16,8 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
+using cmProp = const std::string*;
+
class cmStateDirectory
{
cmStateDirectory(
@@ -86,8 +88,8 @@ public:
cmListFileBacktrace const& lfbt);
void AppendProperty(const std::string& prop, const std::string& value,
bool asString, cmListFileBacktrace const& lfbt);
- const char* GetProperty(const std::string& prop) const;
- const char* GetProperty(const std::string& prop, bool chain) const;
+ cmProp GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 832e74e..d79df6f 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -411,11 +411,12 @@ void cmStateSnapshot::InitializeFromParent()
this->Position->BuildSystemDirectory->LinkDirectoriesBacktraces,
this->Position->LinkDirectoriesPosition);
- const char* include_regex =
+ cmProp include_regex =
parent->BuildSystemDirectory->Properties.GetPropertyValue(
"INCLUDE_REGULAR_EXPRESSION");
this->Position->BuildSystemDirectory->Properties.SetProperty(
- "INCLUDE_REGULAR_EXPRESSION", include_regex);
+ "INCLUDE_REGULAR_EXPRESSION",
+ include_regex ? include_regex->c_str() : nullptr);
}
cmState* cmStateSnapshot::GetState() const
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 0e405de..a5ecca7 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -87,7 +87,7 @@ void cmExpandLists(InputIt first, InputIt last,
std::vector<std::string>& argsOut)
{
for (; first != last; ++first) {
- ExpandList(*first, argsOut);
+ cmExpandList(*first, argsOut);
}
}
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9212195..7662204 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -124,6 +124,27 @@ bool HandleAsciiCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleHexCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() != 3) {
+ status.SetError("Incorrect number of arguments");
+ return false;
+ }
+ auto const& instr = args[1];
+ auto const& outvar = args[2];
+ std::string output(instr.size() * 2, ' ');
+
+ std::string::size_type hexIndex = 0;
+ for (auto const& c : instr) {
+ sprintf(&output[hexIndex], "%.2x", static_cast<unsigned char>(c) & 0xFF);
+ hexIndex += 2;
+ }
+
+ status.GetMakefile().AddDefinition(outvar, output);
+ return true;
+}
+
bool HandleConfigureCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -936,6 +957,7 @@ bool cmStringCommand(std::vector<std::string> const& args,
{ "TOUPPER"_s, HandleToUpperCommand },
{ "COMPARE"_s, HandleCompareCommand },
{ "ASCII"_s, HandleAsciiCommand },
+ { "HEX"_s, HandleHexCommand },
{ "CONFIGURE"_s, HandleConfigureCommand },
{ "LENGTH"_s, HandleLengthCommand },
{ "APPEND"_s, HandleAppendCommand },
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9127c50..23b099a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1,5 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmSystemTools.h"
#include <cmext/algorithm>
@@ -25,6 +35,9 @@
#endif
#if !defined(CMAKE_BOOTSTRAP)
+# if defined(_WIN32)
+# include <cm/memory>
+# endif
# include "cmCryptoHash.h"
#endif
@@ -908,7 +921,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
std::string thumbprint;
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
- BYTE* certData = NULL;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = NULL;
PCCERT_CONTEXT certContext = NULL;
@@ -920,12 +932,12 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) {
DWORD fileSize = GetFileSize(certFile, NULL);
if (fileSize != INVALID_FILE_SIZE) {
- certData = new BYTE[fileSize];
+ auto certData = cm::make_unique<BYTE[]>(fileSize);
if (certData != NULL) {
DWORD dwRead = 0;
- if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) {
+ if (ReadFile(certFile, certData.get(), fileSize, &dwRead, NULL)) {
cryptBlob.cbData = fileSize;
- cryptBlob.pbData = certData;
+ cryptBlob.pbData = certData.get();
// Verify that this is a valid cert
if (PFXIsPFXBlob(&cryptBlob)) {
@@ -961,7 +973,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
}
}
}
- delete[] certData;
}
}
CloseHandle(certFile);
@@ -1054,8 +1065,7 @@ bool cmSystemTools::SimpleGlob(const std::string& glob,
if (type < 0 && !cmSystemTools::FileIsDirectory(fname)) {
continue;
}
- if (sfname.size() >= ppath.size() &&
- sfname.substr(0, ppath.size()) == ppath) {
+ if (cmHasPrefix(sfname, ppath)) {
files.push_back(fname);
res = true;
}
@@ -1311,6 +1321,7 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format);
+ a.Open();
a.SetMTime(mtime);
a.SetVerbose(verbose);
bool tarCreatedSuccessfully = true;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1ad9fd1..955a5cc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -78,7 +78,7 @@ const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>(
}
template <>
-const char* cmTargetPropertyComputer::GetSources<cmTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmTarget>(
cmTarget const* tgt, cmMessenger* messenger,
cmListFileBacktrace const& context)
{
@@ -156,7 +156,7 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>(
}
static std::string srcs;
srcs = ss.str();
- return srcs.c_str();
+ return &srcs;
}
class cmTargetInternals
@@ -303,6 +303,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("PDB_OUTPUT_DIRECTORY");
initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
initProp("FRAMEWORK");
+ initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
initProp("Fortran_FORMAT");
initProp("Fortran_MODULE_DIRECTORY");
initProp("Fortran_COMPILER_LAUNCHER");
@@ -362,6 +363,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("CUDA_SEPARABLE_COMPILATION");
initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
initProp("CUDA_RUNTIME_LIBRARY");
+ initProp("CUDA_ARCHITECTURES");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("Swift_LANGUAGE_VERSION");
@@ -370,6 +372,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("DISABLE_PRECOMPILE_HEADERS");
initProp("UNITY_BUILD");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+ initPropValue("PCH_WARN_INVALID", "ON");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -438,6 +441,13 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
initProp(property);
}
+
+ if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
+ std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+ cmSystemTools::UpperCase(configName));
+ initProp(property);
+ }
}
}
@@ -883,7 +893,7 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
cmListFileContext lfc = cmd.second;
lfc.FilePath = cmDir.ConvertToRelPathIfNotContained(
impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
- s << " * " << lfc << std::endl;
+ s << " * " << lfc << '\n';
}
}
}
@@ -1002,7 +1012,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
dependencies += ";";
dependencies += lib;
dependencies += ";";
- mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
+ mf.AddCacheDefinition(targetEntry, dependencies,
"Dependencies for the target", cmStateEnums::STATIC);
}
}
@@ -1295,8 +1305,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
cmStrCat(reusedFrom, ".dir/"));
- this->SetProperty("COMPILE_PDB_NAME",
- reusedTarget->GetProperty("COMPILE_PDB_NAME"));
+ cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
+ this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
this->AddUtility(reusedFrom, false, impl->Makefile);
} else {
impl->Properties.SetProperty(prop, value);
@@ -1500,7 +1510,7 @@ void cmTarget::InsertPrecompileHeader(std::string const& entry,
}
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
- const char* value,
+ const std::string& value,
cmMakefile* context,
bool imported)
{
@@ -1538,7 +1548,7 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
context->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
-static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
+static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const std::string& value,
cmMakefile* context)
{
// Look for link-type keywords in the value.
@@ -1583,18 +1593,18 @@ void cmTarget::CheckProperty(const std::string& prop,
{
// Certain properties need checking.
if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
}
}
if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
}
}
if (prop == "INTERFACE_LINK_LIBRARIES") {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckINTERFACE_LINK_LIBRARIES(*value, context);
}
}
if (prop == "IMPORTED_GLOBAL") {
@@ -1604,14 +1614,14 @@ void cmTarget::CheckProperty(const std::string& prop,
}
}
-const char* cmTarget::GetComputedProperty(
- const std::string& prop, cmMessenger* messenger,
- cmListFileBacktrace const& context) const
+cmProp cmTarget::GetComputedProperty(const std::string& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context) const
{
return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context);
}
-const char* cmTarget::GetProperty(const std::string& prop) const
+cmProp cmTarget::GetProperty(const std::string& prop) const
{
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
MAKE_STATIC_PROP(LINK_LIBRARIES);
@@ -1630,6 +1640,8 @@ const char* cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(BINARY_DIR);
MAKE_STATIC_PROP(SOURCE_DIR);
MAKE_STATIC_PROP(SOURCES);
+ MAKE_STATIC_PROP(FALSE);
+ MAKE_STATIC_PROP(TRUE);
#undef MAKE_STATIC_PROP
static std::unordered_set<std::string> const specialProps{
propLINK_LIBRARIES,
@@ -1657,11 +1669,11 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkImplementationPropertyEntries, ";");
- return output.c_str();
+ return &output;
}
// the type property returns what type the target is
if (prop == propTYPE) {
- return cmState::GetTargetTypeName(this->GetType());
+ return &cmState::GetTargetTypeName(this->GetType());
}
if (prop == propINCLUDE_DIRECTORIES) {
if (impl->IncludeDirectoriesEntries.empty()) {
@@ -1670,7 +1682,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->IncludeDirectoriesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_FEATURES) {
if (impl->CompileFeaturesEntries.empty()) {
@@ -1679,7 +1691,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileFeaturesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_OPTIONS) {
if (impl->CompileOptionsEntries.empty()) {
@@ -1688,7 +1700,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileOptionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_DEFINITIONS) {
if (impl->CompileDefinitionsEntries.empty()) {
@@ -1697,7 +1709,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileDefinitionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propLINK_OPTIONS) {
if (impl->LinkOptionsEntries.empty()) {
@@ -1706,7 +1718,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkOptionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propLINK_DIRECTORIES) {
if (impl->LinkDirectoriesEntries.empty()) {
@@ -1716,7 +1728,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkDirectoriesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
if (impl->Utilities.empty()) {
@@ -1732,7 +1744,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
return item.Value.first;
});
output = cmJoin(utilities, ";");
- return output.c_str();
+ return &output;
}
if (prop == propPRECOMPILE_HEADERS) {
if (impl->PrecompileHeadersEntries.empty()) {
@@ -1741,32 +1753,30 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->PrecompileHeadersEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propIMPORTED) {
- return this->IsImported() ? "TRUE" : "FALSE";
+ return this->IsImported() ? &propTRUE : &propFALSE;
}
if (prop == propIMPORTED_GLOBAL) {
- return this->IsImportedGloballyVisible() ? "TRUE" : "FALSE";
+ return this->IsImportedGloballyVisible() ? &propTRUE : &propFALSE;
}
if (prop == propNAME) {
- return this->GetName().c_str();
+ return &this->GetName();
}
if (prop == propBINARY_DIR) {
- return impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentBinary()
- .c_str();
+ return &impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentBinary();
}
if (prop == propSOURCE_DIR) {
- return impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentSource()
- .c_str();
+ return &impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentSource();
}
}
- const char* retVal = impl->Properties.GetPropertyValue(prop);
+ cmProp retVal = impl->Properties.GetPropertyValue(prop);
if (!retVal) {
const bool chain =
impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET);
@@ -1774,22 +1784,24 @@ const char* cmTarget::GetProperty(const std::string& prop) const
return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
prop, chain);
}
+ return nullptr;
}
return retVal;
}
const char* cmTarget::GetSafeProperty(const std::string& prop) const
{
- const char* ret = this->GetProperty(prop);
+ cmProp ret = this->GetProperty(prop);
if (!ret) {
return "";
}
- return ret;
+ return ret->c_str();
}
bool cmTarget::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
cmPropertyMap const& cmTarget::GetProperties() const
@@ -1918,38 +1930,37 @@ std::string cmTarget::ImportedGetFullPath(
std::string result;
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
- this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+ this->GetMappedConfig(desired_config, loc, imp, suffix)) {
switch (artifact) {
case cmStateEnums::RuntimeBinaryArtifact:
if (loc) {
- result = loc;
+ result = *loc;
} else {
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
- if (const char* config_location = this->GetProperty(impProp)) {
- result = config_location;
- } else if (const char* location =
+ if (cmProp config_location = this->GetProperty(impProp)) {
+ result = *config_location;
+ } else if (cmProp location =
this->GetProperty("IMPORTED_LOCATION")) {
- result = location;
+ result = *location;
}
}
break;
case cmStateEnums::ImportLibraryArtifact:
if (imp) {
- result = imp;
+ result = *imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- if (const char* config_implib = this->GetProperty(impProp)) {
- result = config_implib;
- } else if (const char* implib =
- this->GetProperty("IMPORTED_IMPLIB")) {
- result = implib;
+ if (cmProp config_implib = this->GetProperty(impProp)) {
+ result = *config_implib;
+ } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+ result = *implib;
}
}
break;
@@ -1992,9 +2003,8 @@ bool cmTargetInternals::CheckImportedLibName(std::string const& prop,
return true;
}
-bool cmTarget::GetMappedConfig(std::string const& desired_config,
- const char** loc, const char** imp,
- std::string& suffix) const
+bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc,
+ cmProp& imp, std::string& suffix) const
{
std::string config_upper;
if (!desired_config.empty()) {
@@ -2016,8 +2026,8 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
std::vector<std::string> mappedConfigs;
{
std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
- if (const char* mapValue = this->GetProperty(mapProp)) {
- cmExpandList(mapValue, mappedConfigs, true);
+ if (cmProp mapValue = this->GetProperty(mapProp)) {
+ cmExpandList(*mapValue, mappedConfigs, true);
}
}
@@ -2031,30 +2041,30 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// If a mapping was found, check its configurations.
for (auto mci = mappedConfigs.begin();
- !*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
+ !loc && !imp && mci != mappedConfigs.end(); ++mci) {
// Look for this configuration.
if (mci->empty()) {
// An empty string in the mapping has a special meaning:
// look up the config-less properties.
- *loc = this->GetProperty(locPropBase);
+ loc = this->GetProperty(locPropBase);
if (allowImp) {
- *imp = this->GetProperty("IMPORTED_IMPLIB");
+ imp = this->GetProperty("IMPORTED_IMPLIB");
}
// If it was found, set the suffix.
- if (*loc || *imp) {
+ if (loc || imp) {
suffix.clear();
}
} else {
std::string mcUpper = cmSystemTools::UpperCase(*mci);
std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
// If it was found, use it for all properties below.
- if (*loc || *imp) {
+ if (loc || imp) {
suffix = cmStrCat('_', mcUpper);
}
}
@@ -2063,59 +2073,59 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// If we needed to find one of the mapped configurations but did not
// then the target location is not found. The project does not want
// any other configuration.
- if (!mappedConfigs.empty() && !*loc && !*imp) {
+ if (!mappedConfigs.empty() && !loc && !imp) {
// Interface libraries are always available because their
- // library name is optional so it is okay to leave *loc empty.
+ // library name is optional so it is okay to leave loc empty.
return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
// If we have not yet found it then there are no mapped
// configurations. Look for an exact-match.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
std::string locProp = cmStrCat(locPropBase, suffix);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
}
// If we have not yet found it then there are no mapped
// configurations and no exact match.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
// The suffix computed above is not useful.
suffix.clear();
// Look for a configuration-less location. This may be set by
// manually-written code.
- *loc = this->GetProperty(locPropBase);
+ loc = this->GetProperty(locPropBase);
if (allowImp) {
- *imp = this->GetProperty("IMPORTED_IMPLIB");
+ imp = this->GetProperty("IMPORTED_IMPLIB");
}
}
// If we have not yet found it then the project is willing to try
// any available configuration.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
std::vector<std::string> availableConfigs;
- if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
- cmExpandList(iconfigs, availableConfigs);
+ if (cmProp iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
+ cmExpandList(*iconfigs, availableConfigs);
}
for (auto aci = availableConfigs.begin();
- !*loc && !*imp && aci != availableConfigs.end(); ++aci) {
+ !loc && !imp && aci != availableConfigs.end(); ++aci) {
suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci));
std::string locProp = cmStrCat(locPropBase, suffix);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
}
}
// If we have not yet found it then the target location is not available.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
// Interface libraries are always available because their
- // library name is optional so it is okay to leave *loc empty.
+ // library name is optional so it is okay to leave loc empty.
return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 286933b..ddc3b9b 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -28,6 +28,8 @@ class cmPropertyMap;
class cmSourceFile;
class cmTargetInternals;
+using cmProp = const std::string*;
+
/** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile.
*
@@ -170,14 +172,13 @@ public:
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
const char* GetSafeProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
void CheckProperty(const std::string& prop, cmMakefile* context) const;
- const char* GetComputedProperty(const std::string& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context) const;
+ cmProp GetComputedProperty(const std::string& prop, cmMessenger* messenger,
+ cmListFileBacktrace const& context) const;
//! Get all properties
cmPropertyMap const& GetProperties() const;
@@ -191,8 +192,8 @@ public:
bool IsImportedGloballyVisible() const;
bool IsPerConfig() const;
- bool GetMappedConfig(std::string const& desired_config, const char** loc,
- const char** imp, std::string& suffix) const;
+ bool GetMappedConfig(std::string const& desired_config, cmProp& loc,
+ cmProp& imp, std::string& suffix) const;
//! Return whether this target is an executable with symbol exports enabled.
bool IsExecutableWithExports() const;
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 0de8d6d..6325837 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -9,6 +9,8 @@
#include "cmTarget.h"
#include "cmake.h"
+using cmProp = const std::string*;
+
cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status)
: Makefile(&status.GetMakefile())
, Status(status)
@@ -157,9 +159,9 @@ void cmTargetPropCommandBase::HandleInterfaceContent(
{
if (prepend) {
const std::string propName = std::string("INTERFACE_") + this->Property;
- const char* propValue = tgt->GetProperty(propName);
- const std::string totalContent = this->Join(content) +
- (propValue ? std::string(";") + propValue : std::string());
+ cmProp propValue = tgt->GetProperty(propName);
+ const std::string totalContent =
+ this->Join(content) + (propValue ? (";" + *propValue) : std::string());
tgt->SetProperty(propName, totalContent);
} else {
tgt->AppendProperty("INTERFACE_" + this->Property, this->Join(content));
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index df34f18..5387e00 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -14,15 +14,17 @@
class cmMessenger;
+using cmProp = const std::string*;
+
class cmTargetPropertyComputer
{
public:
template <typename Target>
- static const char* GetProperty(Target const* tgt, const std::string& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context)
+ static cmProp GetProperty(Target const* tgt, const std::string& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context)
{
- if (const char* loc = GetLocation(tgt, prop, messenger, context)) {
+ if (cmProp loc = GetLocation(tgt, prop, messenger, context)) {
return loc;
}
if (cmSystemTools::GetFatalErrorOccured()) {
@@ -52,9 +54,9 @@ private:
std::string const& config);
template <typename Target>
- static const char* GetLocation(Target const* tgt, std::string const& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context)
+ static cmProp GetLocation(Target const* tgt, std::string const& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context)
{
// Watch for special "computed" properties that are dependent on
@@ -71,7 +73,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocationForBuild(tgt).c_str();
+ return &ComputeLocationForBuild(tgt);
}
// Support "LOCATION_<CONFIG>".
@@ -82,7 +84,7 @@ private:
return nullptr;
}
std::string configName = prop.substr(9);
- return ComputeLocation(tgt, configName).c_str();
+ return &ComputeLocation(tgt, configName);
}
// Support "<CONFIG>_LOCATION".
@@ -95,7 +97,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocation(tgt, configName).c_str();
+ return &ComputeLocation(tgt, configName);
}
}
}
@@ -103,8 +105,8 @@ private:
}
template <typename Target>
- static const char* GetSources(Target const* tgt, cmMessenger* messenger,
- cmListFileBacktrace const& context);
+ static cmProp GetSources(Target const* tgt, cmMessenger* messenger,
+ cmListFileBacktrace const& context);
};
#endif
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index 3b731cc..a26bef3 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -34,15 +34,18 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
const char* cmTest::GetProperty(const std::string& prop) const
{
- const char* retVal = this->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
const bool chain =
this->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TEST);
if (chain) {
- return this->Makefile->GetProperty(prop, chain);
+ if (cmProp p = this->Makefile->GetProperty(prop, chain)) {
+ return p->c_str();
+ }
}
+ return nullptr;
}
- return retVal;
+ return retVal->c_str();
}
bool cmTest::GetPropertyAsBool(const std::string& prop) const
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 333d4d5..1142dbd 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -134,7 +134,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
ge.Parse(i.second)->Evaluate(this->LG, config));
}
this->GenerateInternalProperties(os);
- os << ")" << std::endl;
+ os << ")\n";
}
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
@@ -176,9 +176,9 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
}
fout << c;
}
- fout << "\"";
+ fout << '"';
}
- fout << ")" << std::endl;
+ fout << ")\n";
// Output properties for the test.
fout << indent << "set_tests_properties(" << this->Test->GetName()
@@ -188,7 +188,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
<< cmOutputConverter::EscapeForCMake(i.second);
}
this->GenerateInternalProperties(fout);
- fout << ")" << std::endl;
+ fout << ")\n";
}
void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
@@ -213,7 +213,7 @@ void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
prependTripleSeparator = true;
}
- os << "\"";
+ os << '"';
}
std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments(
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 390fd16..13f73dc 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -1,5 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmTimestamp.h"
#include <cstdlib>
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 0e8e986..329b3b9 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -242,8 +242,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment.c_str(), cmStateEnums::STRING);
cmState* state = this->Makefile->GetState();
- const char* existingValue =
- state->GetCacheEntryValue(this->RunResultVariable);
+ cmProp existingValue = state->GetCacheEntryValue(this->RunResultVariable);
if (existingValue) {
state->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1");
}
@@ -265,7 +264,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(),
cmStateEnums::STRING);
cmState* state = this->Makefile->GetState();
- const char* existing = state->GetCacheEntryValue(internalRunOutputName);
+ cmProp existing = state->GetCacheEntryValue(internalRunOutputName);
if (existing) {
state->SetCacheEntryProperty(internalRunOutputName, "ADVANCED", "1");
}
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index a43165c..5865a19 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -102,15 +102,15 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args,
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- status.GetMakefile().AddCacheDefinition(
- cacheEntry, utilityExecutable.c_str(), "Path to an internal program.",
- cmStateEnums::FILEPATH);
+ status.GetMakefile().AddCacheDefinition(cacheEntry, utilityExecutable,
+ "Path to an internal program.",
+ cmStateEnums::FILEPATH);
// add a value into the cache that maps from the
// full path to the name of the project
cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
- status.GetMakefile().AddCacheDefinition(
- utilityExecutable, utilityName.c_str(), "Executable to project name.",
- cmStateEnums::INTERNAL);
+ status.GetMakefile().AddCacheDefinition(utilityExecutable, utilityName,
+ "Executable to project name.",
+ cmStateEnums::INTERNAL);
return true;
}
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 35b9a1d..ecae16d 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -42,7 +42,7 @@ void cmVariableWatchCommandVariableAccessed(const std::string& variable,
/// Ultra bad!!
cmMakefile* makefile = const_cast<cmMakefile*>(mf);
- std::string stack = makefile->GetProperty("LISTFILE_STACK");
+ std::string stack = *mf->GetProperty("LISTFILE_STACK");
if (!data->Command.empty()) {
cmListFileFunction newLFF;
const char* const currentListFile =
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8da113e..930db41 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -6,11 +6,12 @@
#include <set>
#include <cm/memory>
+#include <cm/string_view>
#include <cm/vector>
+#include <cmext/algorithm>
#include "windows.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -22,6 +23,7 @@
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVisualStudioGeneratorOptions.h"
@@ -61,10 +63,10 @@ struct cmVisualStudio10TargetGenerator::Elem
this->StartElement();
}
Elem(const Elem&) = delete;
- Elem(Elem& par, const std::string& tag)
+ Elem(Elem& par, cm::string_view tag)
: S(par.S)
, Indent(par.Indent + 1)
- , Tag(tag)
+ , Tag(std::string(tag))
{
par.SetHasElements();
this->StartElement();
@@ -78,22 +80,22 @@ struct cmVisualStudio10TargetGenerator::Elem
}
std::ostream& WriteString(const char* line);
void StartElement() { this->WriteString("<") << this->Tag; }
- void Element(const std::string& tag, const std::string& val)
+ void Element(cm::string_view tag, std::string val)
{
- Elem(*this, tag).Content(val);
+ Elem(*this, tag).Content(std::move(val));
}
- Elem& Attribute(const char* an, const std::string& av)
+ Elem& Attribute(const char* an, std::string av)
{
- this->S << " " << an << "=\"" << cmVS10EscapeAttr(av) << "\"";
+ this->S << " " << an << "=\"" << cmVS10EscapeAttr(std::move(av)) << "\"";
return *this;
}
- void Content(const std::string& val)
+ void Content(std::string val)
{
if (!this->HasContent) {
this->S << ">";
this->HasContent = true;
}
- this->S << cmVS10EscapeXML(val);
+ this->S << cmVS10EscapeXML(std::move(val));
}
~Elem()
{
@@ -556,10 +558,11 @@ void cmVisualStudio10TargetGenerator::Generate()
std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
for (std::string const& keyIt : keys) {
- static const char* prefix = "VS_GLOBAL_";
- if (keyIt.find(prefix) != 0)
+ static const cm::string_view prefix = "VS_GLOBAL_";
+ if (!cmHasPrefix(keyIt, prefix))
continue;
- std::string globalKey = keyIt.substr(strlen(prefix));
+ cm::string_view globalKey =
+ cm::string_view(keyIt).substr(prefix.length());
// Skip invalid or separately-handled properties.
if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
@@ -790,21 +793,14 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
for (std::string const& ri : packageReferences) {
size_t versionIndex = ri.find_last_of('_');
if (versionIndex != std::string::npos) {
- WritePackageReference(e1, ri.substr(0, versionIndex),
- ri.substr(versionIndex + 1));
+ Elem e2(e1, "PackageReference");
+ e2.Attribute("Include", ri.substr(0, versionIndex));
+ e2.Attribute("Version", ri.substr(versionIndex + 1));
}
}
}
}
-void cmVisualStudio10TargetGenerator::WritePackageReference(
- Elem& e1, std::string const& ref, std::string const& version)
-{
- Elem e2(e1, "PackageReference");
- e2.Attribute("Include", ref);
- e2.Attribute("Version", version);
-}
-
void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
{
std::vector<std::string> references;
@@ -814,17 +810,15 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
}
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (auto const& i : props.GetList()) {
- if (i.first.find("VS_DOTNET_REFERENCE_") == 0) {
- std::string name = i.first.substr(20);
- if (!name.empty()) {
- std::string path = i.second;
- if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
- }
- ConvertToWindowsSlash(path);
- this->DotNetHintReferences[""].push_back(
- DotNetHintReference(name, path));
+ static const cm::string_view vsDnRef = "VS_DOTNET_REFERENCE_";
+ if (cmHasPrefix(i.first, vsDnRef)) {
+ std::string path = i.second;
+ if (!cmsys::SystemTools::FileIsFullPath(path)) {
+ path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
}
+ ConvertToWindowsSlash(path);
+ this->DotNetHintReferences[""].emplace_back(
+ DotNetHintReference(i.first.substr(vsDnRef.length()), path));
}
}
if (!references.empty() || !this->DotNetHintReferences.empty()) {
@@ -837,7 +831,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
cmsys::SystemTools::GetFilenameWithoutLastExtension(ri);
std::string path = ri;
ConvertToWindowsSlash(path);
- this->DotNetHintReferences[""].push_back(
+ this->DotNetHintReferences[""].emplace_back(
DotNetHintReference(name, path));
} else {
this->WriteDotNetReference(e1, ri, "", "");
@@ -883,11 +877,10 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
{
- const char* imports =
+ cmProp imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit =
- cmExpandedList(std::string(imports), false);
+ std::vector<std::string> argsSplit = cmExpandedList(*imports, false);
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -910,12 +903,8 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
CustomTags tags;
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (const auto& i : props.GetList()) {
- if (i.first.find(refPropFullPrefix) == 0) {
- std::string refTag = i.first.substr(refPropFullPrefix.length());
- std::string refVal = i.second;
- if (!refTag.empty() && !refVal.empty()) {
- tags[refTag] = refVal;
- }
+ if (cmHasPrefix(i.first, refPropFullPrefix) && !i.second.empty()) {
+ tags[i.first.substr(refPropFullPrefix.length())] = i.second;
}
}
for (auto const& tag : tags) {
@@ -952,7 +941,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
// subdirectory
// of the .csproj file, we have to use relative pathnames, otherwise
// visual studio does not show the file in the IDE. Sorry.
- if (obj.find(srcDir) == 0) {
+ if (cmHasPrefix(obj, srcDir)) {
obj = this->ConvertPath(obj, true);
ConvertToWindowsSlash(obj);
useRelativePath = true;
@@ -981,17 +970,11 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
// If the resource was NOT added using a relative path (which should
// be the default), we have to provide a link here
if (!useRelativePath) {
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
+ std::string link = this->GetCSharpSourceLink(oi);
+ if (link.empty()) {
link = cmsys::SystemTools::GetFilenameName(obj);
}
- if (!link.empty()) {
- e2.Element("Link", link);
- }
+ e2.Element("Link", link);
}
// Determine if this is a generated resource from a .Designer.cs file
std::string designerResource =
@@ -1000,15 +983,15 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
".Designer.cs";
if (cmsys::SystemTools::FileExists(designerResource)) {
std::string generator = "PublicResXFileCodeGenerator";
- if (const char* g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
- generator = g;
+ if (cmProp g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
+ generator = *g;
}
if (!generator.empty()) {
e2.Element("Generator", generator);
- if (designerResource.find(srcDir) == 0) {
- designerResource = designerResource.substr(srcDir.length() + 1);
- } else if (designerResource.find(binDir) == 0) {
- designerResource = designerResource.substr(binDir.length() + 1);
+ if (cmHasPrefix(designerResource, srcDir)) {
+ designerResource.erase(0, srcDir.length());
+ } else if (cmHasPrefix(designerResource, binDir)) {
+ designerResource.erase(0, binDir.length());
} else {
designerResource =
cmsys::SystemTools::GetFilenameName(designerResource);
@@ -1019,11 +1002,12 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
}
const cmPropertyMap& props = oi->GetProperties();
for (const std::string& p : props.GetKeys()) {
- static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.find(propNamePrefix) == 0) {
- std::string tagName = p.substr(propNamePrefix.length());
+ static const cm::string_view propNamePrefix = "VS_CSHARP_";
+ if (cmHasPrefix(p, propNamePrefix)) {
+ cm::string_view tagName =
+ cm::string_view(p).substr(propNamePrefix.length());
if (!tagName.empty()) {
- std::string value = props.GetPropertyValue(p);
+ const std::string& value = *props.GetPropertyValue(p);
if (!value.empty()) {
e2.Element(tagName, value);
}
@@ -1043,10 +1027,10 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
Elem e1(e0, "ItemGroup");
for (cmSourceFile const* oi : xamlObjs) {
std::string obj = oi->GetFullPath();
- const char* xamlType;
- const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
+ std::string xamlType;
+ cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
if (xamlTypeProperty) {
- xamlType = xamlTypeProperty;
+ xamlType = *xamlTypeProperty;
} else {
xamlType = "Page";
}
@@ -1054,25 +1038,6 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
Elem e2(e1, xamlType);
this->WriteSource(e2, oi);
e2.SetHasElements();
- if (this->ProjectType == csproj && !this->InSourceBuild) {
- // add <Link> tag to written XAML source if necessary
- const std::string& srcDir =
- this->Makefile->GetCurrentSourceDirectory();
- const std::string& binDir =
- this->Makefile->GetCurrentBinaryDirectory();
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
- link = cmsys::SystemTools::GetFilenameName(obj);
- }
- if (!link.empty()) {
- ConvertToWindowsSlash(link);
- e2.Element("Link", link);
- }
- }
e2.Element("SubType", "Designer");
}
}
@@ -1439,16 +1404,14 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
this->WriteSource(*spe2, source);
spe2->SetHasElements();
+ if (command.GetStdPipesUTF8()) {
+ this->WriteStdOutEncodingUtf8(*spe2);
+ }
} else {
Elem e1(e0, "ItemGroup");
Elem e2(e1, "None");
- std::string link;
- this->GetCSharpSourceLink(source, link);
this->WriteSource(e2, source);
e2.SetHasElements();
- if (!link.empty()) {
- e2.Element("Link", link);
- }
}
for (std::string const& c : this->Configurations) {
cmCustomCommandGenerator ccg(command, c, lg);
@@ -1779,25 +1742,70 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1,
if (this->IsResxHeader(fileName)) {
e2.Element("FileType", "CppForm");
} else if (this->IsXamlHeader(fileName)) {
- std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
- e2.Element("DependentUpon", xamlFileName);
+ e2.Element("DependentUpon",
+ fileName.substr(0, fileName.find_last_of(".")));
}
}
+void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
+ const std::string& settingsPropertyValue, ConfigToSettings& toolSettings)
+{
+ if (!settingsPropertyValue.empty()) {
+ cmGeneratorExpression ge;
+
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(settingsPropertyValue);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ std::vector<std::string> settings = cmExpandedList(evaluated);
+ for (const std::string& setting : settings) {
+ const std::string::size_type assignment = setting.find('=');
+ if (assignment != std::string::npos) {
+ const std::string propName = setting.substr(0, assignment);
+ const std::string propValue = setting.substr(assignment + 1);
+
+ if (!propValue.empty()) {
+ toolSettings[config][propName] = propValue;
+ }
+ }
+ }
+ }
+ }
+}
+
+bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs(
+ const ConfigToSettings& toolSettings, const std::string& propName)
+{
+ std::string firstPropValue = "";
+ for (const auto& configToSettings : toolSettings) {
+ const std::unordered_map<std::string, std::string>& settings =
+ configToSettings.second;
+
+ if (firstPropValue.empty()) {
+ if (settings.find(propName) != settings.end()) {
+ firstPropValue = settings.find(propName)->second;
+ }
+ }
+
+ if (settings.find(propName) == settings.end()) {
+ return false;
+ }
+
+ if (settings.find(propName)->second != firstPropValue) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
cmSourceFile const* sf)
{
bool toolHasSettings = false;
const char* tool = "None";
- std::string shaderType;
- std::string shaderEntryPoint;
- std::string shaderModel;
- std::string shaderAdditionalFlags;
- std::string shaderDisableOptimizations;
- std::string shaderEnableDebug;
- std::string shaderObjectFileName;
- std::string outputHeaderFile;
- std::string variableName;
std::string settingsGenerator;
std::string settingsLastGenOutput;
std::string sourceLink;
@@ -1805,76 +1813,84 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
std::string copyToOutDir;
std::string includeInVsix;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
- if (this->ProjectType == csproj) {
- // EVERY extra source file must have a <Link>, otherwise it might not
- // be visible in Visual Studio at all. The path relative to current
- // source- or binary-dir is used within the link, if the file is
- // in none of these paths, it is added with the plain filename without
- // any path. This means the file will show up at root-level of the csproj
- // (where CMakeLists.txt etc. are).
- if (!this->InSourceBuild) {
- toolHasSettings = true;
- std::string fullFileName = sf->GetFullPath();
- std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
- std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
- if (fullFileName.find(binDir) != std::string::npos) {
- sourceLink.clear();
- } else if (fullFileName.find(srcDir) != std::string::npos) {
- sourceLink = fullFileName.substr(srcDir.length() + 1);
- } else {
- // fallback: add plain filename without any path
- sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName);
- }
- if (!sourceLink.empty()) {
- ConvertToWindowsSlash(sourceLink);
- }
- }
+ ConfigToSettings toolSettings;
+ for (const auto& config : this->Configurations) {
+ toolSettings[config];
+ }
+
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ toolHasSettings = true;
}
if (ext == "hlsl") {
tool = "FXCompile";
// Figure out the type of shader compiler to use.
- if (const char* st = sf->GetProperty("VS_SHADER_TYPE")) {
- shaderType = st;
- toolHasSettings = true;
+ if (cmProp st = sf->GetProperty("VS_SHADER_TYPE")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ShaderType"] = *st;
+ }
}
// Figure out which entry point to use if any
- if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
- shaderEntryPoint = se;
- toolHasSettings = true;
+ if (cmProp se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["EntryPointName"] = *se;
+ }
}
// Figure out which shader model to use if any
- if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) {
- shaderModel = sm;
- toolHasSettings = true;
+ if (cmProp sm = sf->GetProperty("VS_SHADER_MODEL")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ShaderModel"] = *sm;
+ }
}
// Figure out which output header file to use if any
- if (const char* ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
- outputHeaderFile = ohf;
- toolHasSettings = true;
+ if (cmProp ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["HeaderFileOutput"] = *ohf;
+ }
}
// Figure out which variable name to use if any
- if (const char* vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
- variableName = vn;
- toolHasSettings = true;
+ if (cmProp vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["VariableName"] = *vn;
+ }
}
// Figure out if there's any additional flags to use
- if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS")) {
- shaderAdditionalFlags = saf;
- toolHasSettings = true;
+ if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["AdditionalOptions"] = *saf;
+ }
}
// Figure out if debug information should be generated
- if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
- shaderEnableDebug = sed;
- toolHasSettings = true;
+ if (cmProp sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["EnableDebuggingInformation"] =
+ cmIsOn(evaluated) ? "true" : "false";
+ }
+ }
}
// Figure out if optimizations should be disabled
- if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
- shaderDisableOptimizations = sdo;
- toolHasSettings = true;
+ if (cmProp sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["DisableOptimizations"] =
+ cmIsOn(evaluated) ? "true" : "false";
+ }
+ }
}
- if (const char* sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
- shaderObjectFileName = sofn;
- toolHasSettings = true;
+ if (cmProp sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ObjectFileOutput"] = *sofn;
+ }
}
} else if (ext == "jpg" || ext == "png") {
tool = "Image";
@@ -1894,9 +1910,9 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
} else if (ext == "vsixmanifest") {
subType = "Designer";
}
- if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
+ if (cmProp c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
tool = "Content";
- copyToOutDir = c;
+ copyToOutDir = *c;
toolHasSettings = true;
}
if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) {
@@ -1923,32 +1939,79 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
}
- const char* toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
- if (toolOverride && *toolOverride) {
- tool = toolOverride;
+ cmProp toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
+ if (toolOverride && !toolOverride->empty()) {
+ tool = toolOverride->c_str();
}
std::string deployContent;
std::string deployLocation;
if (this->GlobalGenerator->TargetsWindowsPhone() ||
this->GlobalGenerator->TargetsWindowsStore()) {
- const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
- if (content && *content) {
+ cmProp content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
+ if (content && !content->empty()) {
toolHasSettings = true;
- deployContent = content;
+ deployContent = *content;
- const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
- if (location && *location) {
- deployLocation = location;
+ cmProp location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
+ if (location && !location->empty()) {
+ deployLocation = *location;
}
}
}
+ if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) {
+ cmProp toolTargetProperty = this->GeneratorTarget->Target->GetProperty(
+ "VS_SOURCE_SETTINGS_" + std::string(tool));
+ ConfigToSettings toolTargetSettings;
+ if (toolTargetProperty) {
+ ParseSettingsProperty(*toolTargetProperty, toolTargetSettings);
+ }
+
+ ParsedToolTargetSettings[tool] = toolTargetSettings;
+ }
+
+ for (const auto& configToSetting : ParsedToolTargetSettings[tool]) {
+ for (const auto& setting : configToSetting.second) {
+ toolSettings[configToSetting.first][setting.first] = setting.second;
+ }
+ }
+
+ if (cmProp p = sf->GetProperty("VS_SETTINGS")) {
+ ParseSettingsProperty(*p, toolSettings);
+ }
+
+ if (!toolSettings.empty()) {
+ toolHasSettings = true;
+ }
+
Elem e2(e1, tool);
this->WriteSource(e2, sf);
if (toolHasSettings) {
e2.SetHasElements();
+ std::vector<std::string> writtenSettings;
+ for (const auto& configSettings : toolSettings) {
+ for (const auto& setting : configSettings.second) {
+
+ if (std::find(writtenSettings.begin(), writtenSettings.end(),
+ setting.first) != writtenSettings.end()) {
+ continue;
+ }
+
+ if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) {
+ e2.Element(setting.first, setting.second);
+ writtenSettings.push_back(setting.first);
+ } else {
+ e2.WritePlatformConfigTag(setting.first,
+ "'$(Configuration)|$(Platform)'=='" +
+ configSettings.first + "|" +
+ this->Platform + "'",
+ setting.second);
+ }
+ }
+ }
+
if (!deployContent.empty()) {
cmGeneratorExpression ge;
std::unique_ptr<cmCompiledGeneratorExpression> cge =
@@ -1974,82 +2037,13 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
}
}
- if (!shaderType.empty()) {
- e2.Element("ShaderType", shaderType);
- }
- if (!shaderEntryPoint.empty()) {
- e2.Element("EntryPointName", shaderEntryPoint);
- }
- if (!shaderModel.empty()) {
- e2.Element("ShaderModel", shaderModel);
- }
- if (!outputHeaderFile.empty()) {
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- e2.WritePlatformConfigTag("HeaderFileOutput",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- outputHeaderFile);
- }
- }
- if (!variableName.empty()) {
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- e2.WritePlatformConfigTag("VariableName",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- variableName);
- }
- }
- if (!shaderEnableDebug.empty()) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(shaderEnableDebug);
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- const std::string& enableDebug =
- cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
- if (!enableDebug.empty()) {
- e2.WritePlatformConfigTag("EnableDebuggingInformation",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- cmIsOn(enableDebug) ? "true" : "false");
- }
- }
- }
- if (!shaderDisableOptimizations.empty()) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(shaderDisableOptimizations);
-
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- const std::string& disableOptimizations =
- cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
- if (!disableOptimizations.empty()) {
- e2.WritePlatformConfigTag(
- "DisableOptimizations",
- "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] +
- "|" + this->Platform + "'",
- (cmIsOn(disableOptimizations) ? "true" : "false"));
- }
- }
- }
- if (!shaderObjectFileName.empty()) {
- e2.Element("ObjectFileOutput", shaderObjectFileName);
- }
- if (!shaderAdditionalFlags.empty()) {
- e2.Element("AdditionalOptions", shaderAdditionalFlags);
- }
if (!settingsGenerator.empty()) {
e2.Element("Generator", settingsGenerator);
}
if (!settingsLastGenOutput.empty()) {
e2.Element("LastGenOutput", settingsLastGenOutput);
}
- if (!sourceLink.empty()) {
- e2.Element("Link", sourceLink);
- }
if (!subType.empty()) {
e2.Element("SubType", subType);
}
@@ -2102,6 +2096,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
ConvertToWindowsSlash(sourceFile);
e2.Attribute("Include", sourceFile);
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ // For out of source projects we have to provide a link (if not specified
+ // via property) for every source file (besides .cs files) otherwise they
+ // will not be visible in VS at all.
+ // First we check if the file is in a source group, then we check if the
+ // file path is relative to current source- or binary-dir, otherwise it is
+ // added with the plain filename without any path. This means the file will
+ // show up at root-level of the csproj (where CMakeLists.txt etc. are).
+ std::string link = this->GetCSharpSourceLink(sf);
+ if (link.empty())
+ link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
+ e2.Element("Link", link);
+ }
+
ToolSource toolSource = { sf, forceRelative };
this->Tools[e2.Tag].push_back(toolSource);
}
@@ -2245,7 +2253,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
e2.Attribute("CustomUnityFile", "true");
std::string unityDir = cmSystemTools::GetFilenamePath(
- si.Source->GetProperty("UNITY_SOURCE_FILE"));
+ *si.Source->GetProperty("UNITY_SOURCE_FILE"));
e2.Attribute("UnityFilesDirectory", unityDir);
} else {
// Visual Studio versions prior to 2017 15.8 do not know about unity
@@ -2290,25 +2298,25 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
bool configDependentDefines = false;
std::string includes;
bool configDependentIncludes = false;
- if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
+ if (cmProp cflags = sf.GetProperty("COMPILE_FLAGS")) {
configDependentFlags =
- cmGeneratorExpression::Find(cflags) != std::string::npos;
- flags += cflags;
+ cmGeneratorExpression::Find(*cflags) != std::string::npos;
+ flags += *cflags;
}
- if (const char* coptions = sf.GetProperty("COMPILE_OPTIONS")) {
+ if (cmProp coptions = sf.GetProperty("COMPILE_OPTIONS")) {
configDependentOptions =
- cmGeneratorExpression::Find(coptions) != std::string::npos;
- options += coptions;
+ cmGeneratorExpression::Find(*coptions) != std::string::npos;
+ options += *coptions;
}
- if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
+ if (cmProp cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
configDependentDefines =
- cmGeneratorExpression::Find(cdefs) != std::string::npos;
- defines += cdefs;
+ cmGeneratorExpression::Find(*cdefs) != std::string::npos;
+ defines += *cdefs;
}
- if (const char* cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
+ if (cmProp cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
configDependentIncludes =
- cmGeneratorExpression::Find(cincludes) != std::string::npos;
- includes += cincludes;
+ cmGeneratorExpression::Find(*cincludes) != std::string::npos;
+ includes += *cincludes;
}
std::string lang =
this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
@@ -2347,13 +2355,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configDefines = defines;
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ if (cmProp ccdefs = sf.GetProperty(defPropName)) {
if (!configDefines.empty()) {
configDefines += ";";
}
configDependentDefines |=
- cmGeneratorExpression::Find(ccdefs) != std::string::npos;
- configDefines += ccdefs;
+ cmGeneratorExpression::Find(*ccdefs) != std::string::npos;
+ configDefines += *ccdefs;
}
// Add precompile headers compile options.
@@ -2454,19 +2462,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
if (this->IsXamlSource(source->GetFullPath())) {
const std::string& fileName = source->GetFullPath();
- std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
- e2.Element("DependentUpon", xamlFileName);
+ e2.Element("DependentUpon",
+ fileName.substr(0, fileName.find_last_of(".")));
}
if (this->ProjectType == csproj) {
std::string f = source->GetFullPath();
using CsPropMap = std::map<std::string, std::string>;
CsPropMap sourceFileTags;
- // set <Link> tag if necessary
- std::string link;
- this->GetCSharpSourceLink(source, link);
- if (!link.empty()) {
- sourceFileTags["Link"] = link;
- }
this->GetCSharpSourceProperties(&sf, sourceFileTags);
// write source file specific tags
if (!sourceFileTags.empty()) {
@@ -2716,7 +2718,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string langForClCompile;
if (this->ProjectType == csproj) {
langForClCompile = "CSharp";
- } else if (cmContains(clLangs, linkLanguage)) {
+ } else if (cm::contains(clLangs, linkLanguage)) {
langForClCompile = linkLanguage;
} else {
std::set<std::string> languages;
@@ -3182,6 +3184,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable());
Options& cudaLinkOptions = *pOptions;
+ cmGeneratorTarget::DeviceLinkSetter setter(*this->GeneratorTarget);
+
// Determine if we need to do a device link
const bool doDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, configName);
@@ -3189,12 +3193,20 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
cudaLinkOptions.AddFlag("PerformDeviceLink",
doDeviceLinking ? "true" : "false");
- // Suppress deprecation warnings for default GPU targets during device link.
- if (cmSystemTools::VersionCompareGreaterEq(
- this->GlobalGenerator->GetPlatformToolsetCudaString(), "8.0")) {
- cudaLinkOptions.AppendFlagString("AdditionalOptions",
- "-Wno-deprecated-gpu-targets");
- }
+ // Add extra flags for device linking
+ cudaLinkOptions.AppendFlagString(
+ "AdditionalOptions",
+ this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_FLAGS"));
+ cudaLinkOptions.AppendFlagString(
+ "AdditionalOptions",
+ this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS"));
+
+ std::vector<std::string> linkOpts;
+ std::string linkFlags;
+ this->GeneratorTarget->GetLinkOptions(linkOpts, configName, "CUDA");
+ // LINK_OPTIONS are escaped.
+ this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+ cudaLinkOptions.AppendFlagString("AdditionalOptions", linkFlags);
// For static libraries that have device linking enabled compute
// the libraries
@@ -3412,9 +3424,8 @@ void cmVisualStudio10TargetGenerator::WriteLibOptions(
this->GeneratorTarget->GetLinkClosure(config)->LinkerLanguage;
std::string libflags;
- this->LocalGenerator->GetStaticLibraryFlags(
- libflags, cmSystemTools::UpperCase(config), linkLanguage,
- this->GeneratorTarget);
+ this->LocalGenerator->GetStaticLibraryFlags(libflags, config, linkLanguage,
+ this->GeneratorTarget);
if (!libflags.empty()) {
Elem e2(e1, "Lib");
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
@@ -3650,7 +3661,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec, config);
- if (cmContains(linkClosure->Languages, "CUDA") &&
+ if (cm::contains(linkClosure->Languages, "CUDA") &&
this->CudaOptions[config] != nullptr) {
this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
}
@@ -3924,7 +3935,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
{
for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) {
if (cmSystemTools::ComparePath(targetsFile, i.File)) {
- if (!cmContains(i.Configs, config)) {
+ if (!cm::contains(i.Configs, config)) {
i.Configs.push_back(config);
}
return;
@@ -4052,6 +4063,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
std::string script;
const char* pre = "";
std::string comment;
+ bool stdPipesUTF8 = false;
for (cmCustomCommand const& cc : commands) {
cmCustomCommandGenerator ccg(cc, configName, lg);
if (!ccg.HasOnlyEmptyCommandLines()) {
@@ -4060,11 +4072,16 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
script += pre;
pre = "\n";
script += lg->ConstructScript(ccg);
+
+ stdPipesUTF8 = stdPipesUTF8 || cc.GetStdPipesUTF8();
}
}
comment = cmVS10EscapeComment(comment);
if (this->ProjectType != csproj) {
Elem e2(e1, name);
+ if (stdPipesUTF8) {
+ this->WriteStdOutEncodingUtf8(e2);
+ }
e2.Element("Message", comment);
e2.Element("Command", script);
} else {
@@ -4845,11 +4862,11 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties(
if (this->ProjectType == csproj) {
const cmPropertyMap& props = sf->GetProperties();
for (const std::string& p : props.GetKeys()) {
- static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.find(propNamePrefix) == 0) {
+ static const cm::string_view propNamePrefix = "VS_CSHARP_";
+ if (cmHasPrefix(p, propNamePrefix)) {
std::string tagName = p.substr(propNamePrefix.length());
if (!tagName.empty()) {
- const std::string val = props.GetPropertyValue(p);
+ const std::string& val = *props.GetPropertyValue(p);
if (!val.empty()) {
tags[tagName] = val;
} else {
@@ -4869,24 +4886,34 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties(
}
}
-void cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
- cmSourceFile const* sf, std::string& link)
+std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
+ cmSourceFile const* source)
{
- std::string const& sourceFilePath = sf->GetFullPath();
- std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory();
-
- if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) {
- const std::string& stripFromPath =
- this->Makefile->GetCurrentSourceDirectory();
- if (sourceFilePath.find(stripFromPath) == 0) {
- if (const char* l = sf->GetProperty("VS_CSHARP_Link")) {
- link = l;
- } else {
- link = sourceFilePath.substr(stripFromPath.length() + 1);
- }
- ConvertToWindowsSlash(link);
- }
- }
+ // For out of source files, we first check if a matching source group
+ // for this file exists, otherwise we check if the path relative to current
+ // source- or binary-dir is used within the link and return that
+ std::string link;
+ std::string const& fullFileName = source->GetFullPath();
+ std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory();
+ std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory();
+ // unfortunately we have to copy the source groups, because
+ // FindSourceGroup uses a regex which is modifying the group
+ std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+ cmSourceGroup* sourceGroup =
+ this->Makefile->FindSourceGroup(fullFileName, sourceGroups);
+ if (sourceGroup && !sourceGroup->GetFullName().empty()) {
+ link = sourceGroup->GetFullName() + "/" +
+ cmsys::SystemTools::GetFilenameName(fullFileName);
+ } else if (cmHasPrefix(fullFileName, srcDir)) {
+ link = fullFileName.substr(srcDir.length() + 1);
+ } else if (cmHasPrefix(fullFileName, binDir)) {
+ link = fullFileName.substr(binDir.length() + 1);
+ } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) {
+ link = *l;
+ }
+
+ ConvertToWindowsSlash(link);
+ return link;
}
std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
@@ -4899,3 +4926,8 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
return path;
}
+
+void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
+{
+ e1.Element("StdOutEncoding", "UTF-8");
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 30027c9..e3782f4 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -10,6 +10,7 @@
#include <memory>
#include <set>
#include <string>
+#include <unordered_map>
#include <vector>
class cmComputeLinkInformation;
@@ -73,8 +74,6 @@ private:
std::vector<size_t> const& exclude_configs);
void WriteAllSources(Elem& e0);
void WritePackageReferences(Elem& e0);
- void WritePackageReference(Elem& e1, std::string const& ref,
- std::string const& version);
void WriteDotNetReferences(Elem& e0);
void WriteDotNetReference(Elem& e1, std::string const& ref,
std::string const& hint,
@@ -183,7 +182,9 @@ private:
std::map<std::string, std::string>& tags);
void WriteCSharpSourceProperties(
Elem& e2, const std::map<std::string, std::string>& tags);
- void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link);
+ std::string GetCSharpSourceLink(cmSourceFile const* source);
+
+ void WriteStdOutEncodingUtf8(Elem& e1);
private:
friend class cmVS10GeneratorOptions;
@@ -236,6 +237,15 @@ private:
using ToolSourceMap = std::map<std::string, ToolSources>;
ToolSourceMap Tools;
+
+ using ConfigToSettings =
+ std::unordered_map<std::string,
+ std::unordered_map<std::string, std::string>>;
+ std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings;
+ bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
+ const std::string& propName);
+ void ParseSettingsProperty(const std::string& settingsPropertyValue,
+ ConfigToSettings& toolSettings);
std::string GetCMakeFilePath(const char* name) const;
};
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 4533e9b..d7822b1 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -517,7 +517,7 @@ bool cmVisualStudioSlnParser::ParseMultiValueTag(const std::string& line,
State& state)
{
size_t idxEqualSign = line.find('=');
- const std::string& fullTag = line.substr(0, idxEqualSign);
+ auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
if (!this->ParseTag(fullTag, parsedLine, state))
return false;
if (idxEqualSign != line.npos) {
@@ -560,7 +560,7 @@ bool cmVisualStudioSlnParser::ParseSingleValueTag(const std::string& line,
State& state)
{
size_t idxEqualSign = line.find('=');
- const std::string& fullTag = line.substr(0, idxEqualSign);
+ auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
if (!this->ParseTag(fullTag, parsedLine, state))
return false;
if (idxEqualSign != line.npos) {
@@ -586,17 +586,17 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line,
return true;
}
-bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag,
+bool cmVisualStudioSlnParser::ParseTag(cm::string_view fullTag,
ParsedLine& parsedLine, State& state)
{
size_t idxLeftParen = fullTag.find('(');
- if (idxLeftParen == fullTag.npos) {
+ if (idxLeftParen == cm::string_view::npos) {
parsedLine.SetTag(cmTrimWhitespace(fullTag));
return true;
}
parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen)));
size_t idxRightParen = fullTag.rfind(')');
- if (idxRightParen == fullTag.npos) {
+ if (idxRightParen == cm::string_view::npos) {
this->LastResult.SetError(ResultErrorInputStructure,
state.GetCurrentLine());
return false;
diff --git a/Source/cmVisualStudioSlnParser.h b/Source/cmVisualStudioSlnParser.h
index 6c05633..4557cdb 100644
--- a/Source/cmVisualStudioSlnParser.h
+++ b/Source/cmVisualStudioSlnParser.h
@@ -9,6 +9,8 @@
#include <iosfwd>
#include <string>
+#include <cm/string_view>
+
#include <stddef.h>
class cmSlnData;
@@ -97,8 +99,7 @@ protected:
bool ParseKeyValuePair(const std::string& line, ParsedLine& parsedLine,
State& state);
- bool ParseTag(const std::string& fullTag, ParsedLine& parsedLine,
- State& state);
+ bool ParseTag(cm::string_view fullTag, ParsedLine& parsedLine, State& state);
bool ParseValue(const std::string& value, ParsedLine& parsedLine);
};
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index d4a164d..4c7576d 100644
--- a/Source/cmWorkingDirectory.h
+++ b/Source/cmWorkingDirectory.h
@@ -37,6 +37,8 @@ public:
*/
int GetLastResult() const { return ResultCode; }
+ std::string const& GetOldDirectory() const { return this->OldDir; }
+
private:
std::string OldDir;
int ResultCode;
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 34e21b2..666ba87 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -72,7 +72,7 @@ bool cmWriteFileCommand(std::vector<std::string> const& args,
status.SetError(error);
return false;
}
- file << message << std::endl;
+ file << message << '\n';
file.close();
if (mode && !writable) {
cmSystemTools::SetPermissions(fileName.c_str(), mode);
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index a9bb2ef..6b133a9 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -30,11 +30,12 @@ void cmXCode21Object::PrintComment(std::ostream& out)
out << " */";
}
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
- std::ostream& out, PBXType t)
+void cmXCode21Object::PrintList(
+ std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out,
+ PBXType t)
{
bool hasOne = false;
- for (auto obj : v) {
+ for (const auto& obj : v) {
if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
hasOne = true;
break;
@@ -44,7 +45,7 @@ void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
return;
}
out << "\n/* Begin " << PBXTypeNames[t] << " section */\n";
- for (auto obj : v) {
+ for (const auto& obj : v) {
if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
obj->Print(out);
}
@@ -52,8 +53,8 @@ void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
out << "/* End " << PBXTypeNames[t] << " section */\n";
}
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
- std::ostream& out)
+void cmXCode21Object::PrintList(
+ std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out)
{
cmXCodeObject::Indent(1, out);
out << "objects = {\n";
diff --git a/Source/cmXCode21Object.h b/Source/cmXCode21Object.h
index 8e4b80f..76fad23 100644
--- a/Source/cmXCode21Object.h
+++ b/Source/cmXCode21Object.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <vector>
#include "cmXCodeObject.h"
@@ -15,8 +16,9 @@ class cmXCode21Object : public cmXCodeObject
public:
cmXCode21Object(PBXType ptype, Type type);
void PrintComment(std::ostream&) override;
- static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out,
- PBXType t);
- static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out);
+ static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+ std::ostream& out, PBXType t);
+ static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+ std::ostream& out);
};
#endif
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index d9be3d2..24ecaa2 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -12,7 +12,7 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
class cmGeneratorTarget;
@@ -82,10 +82,13 @@ public:
void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
- bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); }
+ bool HasObject(cmXCodeObject* o) const
+ {
+ return cm::contains(this->List, o);
+ }
void AddUniqueObject(cmXCodeObject* value)
{
- if (!cmContains(this->List, value)) {
+ if (!cm::contains(this->List, value)) {
this->List.push_back(value);
}
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index b34c2f6..1b437e9 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -427,7 +429,7 @@ std::string cmXCodeScheme::FindConfiguration(const std::string& name)
// Try to find the desired configuration by name,
// and if it's not found return first from the list
//
- if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) {
+ if (!cm::contains(this->ConfigList, name) && !this->ConfigList.empty()) {
return this->ConfigList[0];
}
diff --git a/Source/cm_get_date.c b/Source/cm_get_date.c
index 4bef803..49f5577 100644
--- a/Source/cm_get_date.c
+++ b/Source/cm_get_date.c
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cm_get_date.h"
+// FIXME: This suppresses use of localtime_r because archive_getdate.c
+// depends the rest of libarchive's checks for that.
+#define CM_GET_DATE
+
#define __archive_get_date cm_get_date
#include "../Utilities/cmlibarchive/libarchive/archive_getdate.c"
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a99d9a6..c619e1e 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -9,6 +9,7 @@
#include <initializer_list>
#include <iostream>
#include <sstream>
+#include <stdexcept>
#include <utility>
#include <cm/memory>
@@ -23,9 +24,9 @@
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -39,6 +40,9 @@
#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#if !defined(CMAKE_BOOTSTRAP)
+# include "cmMakefileProfilingData.h"
+#endif
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -288,7 +292,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
bool findPackageMode = false;
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-D", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-D")) {
std::string entry = arg.substr(2);
if (entry.empty()) {
++i;
@@ -377,7 +381,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
// -Wno-error=<name>
this->DiagLevels[name] = std::min(this->DiagLevels[name], DIAG_WARN);
}
- } else if (arg.find("-U", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-U")) {
std::string entryPattern = arg.substr(2);
if (entryPattern.empty()) {
++i;
@@ -407,7 +411,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
for (std::string const& currentEntry : entriesToDelete) {
this->State->RemoveCacheEntry(currentEntry);
}
- } else if (arg.find("-C", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-C")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -422,7 +426,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
// Resolve script path specified on command line relative to $PWD.
path = cmSystemTools::CollapseFullPath(path);
this->ReadListFile(args, path);
- } else if (arg.find("-P", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-P")) {
i++;
if (i >= args.size()) {
cmSystemTools::Error("-P must be followed by a file name.");
@@ -441,7 +445,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
this->SetHomeOutputDirectory(
cmSystemTools::GetCurrentWorkingDirectory());
this->ReadListFile(args, path);
- } else if (arg.find("--find-package", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--find-package")) {
findPackageMode = true;
}
}
@@ -520,11 +524,11 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
if (!quiet) {
printf("%s not found.\n", packageName.c_str());
}
- } else if (mode == "EXIST") {
+ } else if (mode == "EXIST"_s) {
if (!quiet) {
printf("%s found.\n", packageName.c_str());
}
- } else if (mode == "COMPILE") {
+ } else if (mode == "COMPILE"_s) {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
std::vector<std::string> includeDirs = cmExpandedList(includes);
@@ -535,7 +539,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
- } else if (mode == "LINK") {
+ } else if (mode == "LINK"_s) {
const char* targetName = "dummy";
std::vector<std::string> srcs;
cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
@@ -613,9 +617,13 @@ void cmake::SetArgs(const std::vector<std::string>& args)
{
bool haveToolset = false;
bool havePlatform = false;
+#if !defined(CMAKE_BOOTSTRAP)
+ std::string profilingFormat;
+ std::string profilingOutput;
+#endif
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-H") || cmHasLiteralPrefix(arg, "-S")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -633,9 +641,11 @@ void cmake::SetArgs(const std::vector<std::string>& args)
path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
this->SetHomeDirectory(path);
- } else if (arg.find("-O", 0) == 0) {
+ // 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 (arg.find("-B", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-B")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -654,54 +664,43 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmSystemTools::ConvertToUnixSlashes(path);
this->SetHomeOutputDirectory(path);
} else if ((i < args.size() - 2) &&
- (arg.find("--check-build-system", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-build-system")) {
this->CheckBuildSystemArgument = args[++i];
this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
} else if ((i < args.size() - 1) &&
- (arg.find("--check-stamp-file", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-stamp-file")) {
this->CheckStampFile = args[++i];
} else if ((i < args.size() - 1) &&
- (arg.find("--check-stamp-list", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-stamp-list")) {
this->CheckStampList = args[++i];
- } else if (arg == "--regenerate-during-build") {
+ } else if (arg == "--regenerate-during-build"_s) {
this->RegenerateDuringBuild = true;
}
#if defined(CMAKE_HAVE_VS_GENERATORS)
else if ((i < args.size() - 1) &&
- (arg.find("--vs-solution-file", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--vs-solution-file")) {
this->VSSolutionFile = args[++i];
}
#endif
- else if (arg.find("-D", 0) == 0) {
- // skip for now
- // in case '-D var=val' is given, also skip the next
- // in case '-Dvar=val' is given, don't skip the next
- if (arg.size() == 2) {
- ++i;
- }
- } else if (arg.find("-U", 0) == 0) {
- // skip for now
- // in case '-U var' is given, also skip the next
- // in case '-Uvar' is given, don't skip the next
- if (arg.size() == 2) {
- ++i;
- }
- } else if (arg.find("-C", 0) == 0) {
+ else if (cmHasLiteralPrefix(arg, "-D") || cmHasLiteralPrefix(arg, "-U") ||
+ cmHasLiteralPrefix(arg, "-C")) {
// skip for now
- // in case '-C path' is given, also skip the next
- // in case '-Cpath' is given, don't skip the next
+ // 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;
}
- } else if (arg.find("-P", 0) == 0) {
+ // 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 (arg.find("--find-package", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--find-package")) {
// skip for now
i++;
- } else if (arg.find("-W", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-W")) {
// skip for now
- } else if (arg.find("--graphviz=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--graphviz=")) {
std::string path = arg.substr(strlen("--graphviz="));
path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
@@ -710,13 +709,13 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmSystemTools::Error("No file specified for --graphviz");
return;
}
- } else if (arg.find("--debug-trycompile", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--debug-trycompile")) {
std::cout << "debug trycompile on\n";
this->DebugTryCompileOn();
- } else if (arg.find("--debug-output", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--debug-output")) {
std::cout << "Running with debug output on.\n";
this->SetDebugOutputOn(true);
- } else if (arg.find("--log-level=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--log-level=")) {
const auto logLevel =
StringToLogLevel(arg.substr(sizeof("--log-level=") - 1));
if (logLevel == LogLevel::LOG_UNDEFINED) {
@@ -725,7 +724,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetLogLevel(logLevel);
this->LogLevelWasSetViaCLI = true;
- } else if (arg.find("--loglevel=", 0) == 0) {
+ } 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
@@ -737,16 +736,16 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetLogLevel(logLevel);
this->LogLevelWasSetViaCLI = true;
- } else if (arg == "--log-context") {
+ } else if (arg == "--log-context"_s) {
this->SetShowLogContext(true);
- } else if (arg.find("--debug-find", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--debug-find")) {
std::cout << "Running with debug output on for the `find` commands.\n";
this->SetDebugFindOutputOn(true);
- } else if (arg.find("--trace-expand", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace-expand")) {
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(true);
- } else if (arg.find("--trace-format=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace-format=")) {
this->SetTrace(true);
const auto traceFormat =
StringToTraceFormat(arg.substr(strlen("--trace-format=")));
@@ -756,35 +755,35 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetTraceFormat(traceFormat);
- } else if (arg.find("--trace-source=", 0) == 0) {
+ } 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 (arg.find("--trace-redirect=", 0) == 0) {
+ } 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 (arg.find("--trace", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace")) {
std::cout << "Running with trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(false);
- } else if (arg.find("--warn-uninitialized", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--warn-uninitialized")) {
std::cout << "Warn about uninitialized values.\n";
this->SetWarnUninitialized(true);
- } else if (arg.find("--warn-unused-vars", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--warn-unused-vars")) {
std::cout << "Finding unused variables.\n";
this->SetWarnUnused(true);
- } else if (arg.find("--no-warn-unused-cli", 0) == 0) {
+ } 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 (arg.find("--check-system-vars", 0) == 0) {
+ } 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 (arg.find("-A", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-A")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -800,7 +799,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetGeneratorPlatform(value);
havePlatform = true;
- } else if (arg.find("-T", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-T")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -816,7 +815,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetGeneratorToolset(value);
haveToolset = true;
- } else if (arg.find("-G", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-G")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -840,6 +839,20 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetGlobalGenerator(std::move(gen));
+#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);
+ cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error("No path specified for --profiling-output");
+ }
+#endif
}
// no option assume it is the path to the source or an existing build
else {
@@ -857,6 +870,29 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
}
+#if !defined(CMAKE_BOOTSTRAP)
+ if (!profilingOutput.empty() || !profilingFormat.empty()) {
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error(
+ "--profiling-format specified but no --profiling-output!");
+ return;
+ }
+ if (profilingFormat == "google-trace"_s) {
+ try {
+ this->ProfilingOutput =
+ cm::make_unique<cmMakefileProfilingData>(profilingOutput);
+ } catch (std::runtime_error& e) {
+ cmSystemTools::Error(
+ cmStrCat("Could not start profiling: ", e.what()));
+ return;
+ }
+ } else {
+ cmSystemTools::Error("Invalid format specified for --profiling-format");
+ return;
+ }
+ }
+#endif
+
const bool haveSourceDir = !this->GetHomeDirectory().empty();
const bool haveBinaryDir = !this->GetHomeOutputDirectory().empty();
@@ -992,9 +1028,9 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
- if (name == "cmakecache.txt") {
+ if (name == "cmakecache.txt"_s) {
cachePath = cmSystemTools::GetFilenamePath(fullPath);
- } else if (name == "cmakelists.txt") {
+ } else if (name == "cmakelists.txt"_s) {
listPath = cmSystemTools::GetFilenamePath(fullPath);
}
} else {
@@ -1003,7 +1039,7 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
- if (name == "cmakecache.txt" || name == "cmakelists.txt") {
+ if (name == "cmakecache.txt"_s || name == "cmakelists.txt"_s) {
argIsFile = true;
listPath = cmSystemTools::GetFilenamePath(fullPath);
} else {
@@ -1014,11 +1050,11 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
// If there is a CMakeCache.txt file, use its settings.
if (!cachePath.empty()) {
if (this->LoadCache(cachePath)) {
- const char* existingValue =
+ cmProp existingValue =
this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (existingValue) {
this->SetHomeOutputDirectory(cachePath);
- this->SetHomeDirectory(existingValue);
+ this->SetHomeDirectory(*existingValue);
return;
}
}
@@ -1361,12 +1397,12 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
i++;
save.value = *i;
warning << *i << "\n";
- const char* existingValue = this->State->GetCacheEntryValue(save.key);
+ cmProp existingValue = this->State->GetCacheEntryValue(save.key);
if (existingValue) {
save.type = this->State->GetCacheEntryType(save.key);
- if (const char* help =
+ if (cmProp help =
this->State->GetCacheEntryProperty(save.key, "HELPSTRING")) {
- save.help = help;
+ save.help = *help;
}
}
saved.push_back(std::move(save));
@@ -1411,9 +1447,9 @@ int cmake::Configure()
if (this->DiagLevels.count("dev") == 1) {
bool setDeprecatedVariables = false;
- const char* cachedWarnDeprecated =
+ cmProp cachedWarnDeprecated =
this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
- const char* cachedErrorDeprecated =
+ cmProp cachedErrorDeprecated =
this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
// don't overwrite deprecated warning setting from a previous invocation
@@ -1452,23 +1488,23 @@ int cmake::Configure()
// Cache variables may have already been set by a previous invocation,
// so we cannot rely on command line options alone. Always ensure our
// messenger is in sync with the cache.
- const char* value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
- this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
+ cmProp value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+ this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(*value));
value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
- this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
+ this->Messenger->SetDeprecatedWarningsAsErrors(value && cmIsOn(*value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
+ this->Messenger->SetSuppressDevWarnings(value && cmIsOn(*value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
- this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
+ this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value));
int ret = this->ActualConfigure();
- const char* delCacheVars =
+ cmProp delCacheVars =
this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
- if (delCacheVars && delCacheVars[0] != 0) {
- return this->HandleDeleteCacheVariables(delCacheVars);
+ if (delCacheVars && !delCacheVars->empty()) {
+ return this->HandleDeleteCacheVariables(*delCacheVars);
}
return ret;
}
@@ -1891,13 +1927,13 @@ void cmake::AddCacheEntry(const std::string& key, const char* value,
cmStateEnums::CacheEntryType(type));
this->UnwatchUnusedCli(key);
- if (key == "CMAKE_WARN_DEPRECATED") {
+ if (key == "CMAKE_WARN_DEPRECATED"_s) {
this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
- } else if (key == "CMAKE_ERROR_DEPRECATED") {
+ } else if (key == "CMAKE_ERROR_DEPRECATED"_s) {
this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
- } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") {
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS"_s) {
this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
- } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") {
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS"_s) {
this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
}
}
@@ -1933,9 +1969,10 @@ std::string cmake::StripExtension(const std::string& file) const
{
auto dotpos = file.rfind('.');
if (dotpos != std::string::npos) {
- auto ext = file.substr(dotpos + 1);
#if defined(_WIN32) || defined(__APPLE__)
- ext = cmSystemTools::LowerCase(ext);
+ auto ext = cmSystemTools::LowerCase(file.substr(dotpos + 1));
+#else
+ auto ext = cm::string_view(file).substr(dotpos + 1);
#endif
if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
return file.substr(0, dotpos);
@@ -2383,7 +2420,7 @@ void cmake::AppendProperty(const std::string& prop, const std::string& value,
this->State->AppendGlobalProperty(prop, value, asString);
}
-const char* cmake::GetProperty(const std::string& prop)
+cmProp cmake::GetProperty(const std::string& prop)
{
return this->State->GetGlobalProperty(prop);
}
@@ -2435,7 +2472,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
bool writeToStdout = true;
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-G", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-G")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -2624,10 +2661,10 @@ void cmake::IssueMessage(MessageType t, std::string const& text,
std::vector<std::string> cmake::GetDebugConfigs()
{
std::vector<std::string> configs;
- if (const char* config_list =
+ if (cmProp config_list =
this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
// Expand the specified list and convert to upper-case.
- cmExpandList(config_list, configs);
+ cmExpandList(*config_list, configs);
std::transform(configs.begin(), configs.end(), configs.begin(),
cmSystemTools::UpperCase);
}
@@ -2657,59 +2694,58 @@ int cmake::Build(int jobs, const std::string& dir,
std::cerr << "Error: could not load cache\n";
return 1;
}
- const char* cachedGenerator =
- this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp cachedGenerator = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
if (!cachedGenerator) {
std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return 1;
}
- auto gen = this->CreateGlobalGenerator(cachedGenerator);
+ auto gen = this->CreateGlobalGenerator(*cachedGenerator);
if (!gen) {
- std::cerr << "Error: could create CMAKE_GENERATOR \"" << cachedGenerator
+ std::cerr << "Error: could create CMAKE_GENERATOR \"" << *cachedGenerator
<< "\"\n";
return 1;
}
this->SetGlobalGenerator(std::move(gen));
- const char* cachedGeneratorInstance =
+ cmProp cachedGeneratorInstance =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE");
if (cachedGeneratorInstance) {
cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
- if (!this->GlobalGenerator->SetGeneratorInstance(cachedGeneratorInstance,
+ if (!this->GlobalGenerator->SetGeneratorInstance(*cachedGeneratorInstance,
&mf)) {
return 1;
}
}
- const char* cachedGeneratorPlatform =
+ cmProp cachedGeneratorPlatform =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
if (cachedGeneratorPlatform) {
cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
- if (!this->GlobalGenerator->SetGeneratorPlatform(cachedGeneratorPlatform,
+ if (!this->GlobalGenerator->SetGeneratorPlatform(*cachedGeneratorPlatform,
&mf)) {
return 1;
}
}
- const char* cachedGeneratorToolset =
+ cmProp cachedGeneratorToolset =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
if (cachedGeneratorToolset) {
cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
- if (!this->GlobalGenerator->SetGeneratorToolset(cachedGeneratorToolset,
+ if (!this->GlobalGenerator->SetGeneratorToolset(*cachedGeneratorToolset,
true, &mf)) {
return 1;
}
}
std::string output;
std::string projName;
- const char* cachedProjectName =
+ cmProp cachedProjectName =
this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
if (!cachedProjectName) {
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
return 1;
}
- projName = cachedProjectName;
+ projName = *cachedProjectName;
- const char* cachedVerbose =
+ cmProp cachedVerbose =
this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
- if (cmIsOn(cachedVerbose)) {
+ if (cachedVerbose && cmIsOn(*cachedVerbose)) {
verbose = true;
}
@@ -2793,7 +2829,7 @@ bool cmake::Open(const std::string& dir, bool dryRun)
std::cerr << "Error: could not load cache\n";
return false;
}
- const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
if (!genName) {
std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return false;
@@ -2802,7 +2838,7 @@ bool cmake::Open(const std::string& dir, bool dryRun)
this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string fullName =
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- genName, extraGenName ? *extraGenName : "");
+ *genName, extraGenName ? *extraGenName : "");
std::unique_ptr<cmGlobalGenerator> gen =
this->CreateGlobalGenerator(fullName);
@@ -2812,21 +2848,21 @@ bool cmake::Open(const std::string& dir, bool dryRun)
return false;
}
- const char* cachedProjectName =
+ cmProp cachedProjectName =
this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
if (!cachedProjectName) {
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
return false;
}
- return gen->Open(dir, cachedProjectName, dryRun);
+ return gen->Open(dir, *cachedProjectName, dryRun);
}
void cmake::WatchUnusedCli(const std::string& var)
{
#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
- if (!cmContains(this->UsedCliVariables, var)) {
+ if (!cm::contains(this->UsedCliVariables, var)) {
this->UsedCliVariables[var] = false;
}
#endif
@@ -2953,3 +2989,15 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b)
" and functions.",
cmStateEnums::INTERNAL);
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+cmMakefileProfilingData& cmake::GetProfilingOutput()
+{
+ return *(this->ProfilingOutput);
+}
+
+bool cmake::IsProfilingEnabled() const
+{
+ return static_cast<bool>(this->ProfilingOutput);
+}
+#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index 35425ec..cfcd264 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -16,6 +16,8 @@
#include <utility>
#include <vector>
+#include <cm/string_view>
+
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
@@ -34,6 +36,9 @@ class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
+#if !defined(CMAKE_BOOTSTRAP)
+class cmMakefileProfilingData;
+#endif
class cmMessenger;
class cmVariableWatch;
struct cmDocumentationEntry;
@@ -135,13 +140,13 @@ public:
struct FileExtensions
{
- bool Test(std::string const& ext) const
+ bool Test(cm::string_view ext) const
{
return (this->unordered.find(ext) != this->unordered.end());
}
std::vector<std::string> ordered;
- std::unordered_set<std::string> unordered;
+ std::unordered_set<cm::string_view> unordered;
};
using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
@@ -263,7 +268,7 @@ public:
return this->SourceFileExtensions.ordered;
}
- bool IsSourceExtension(const std::string& ext) const
+ bool IsSourceExtension(cm::string_view ext) const
{
return this->SourceFileExtensions.Test(ext);
}
@@ -273,7 +278,7 @@ public:
return this->HeaderFileExtensions.ordered;
}
- bool IsHeaderExtension(const std::string& ext) const
+ bool IsHeaderExtension(cm::string_view ext) const
{
return this->HeaderFileExtensions.Test(ext);
}
@@ -283,7 +288,7 @@ public:
return this->CudaFileExtensions.ordered;
}
- bool IsCudaExtension(const std::string& ext) const
+ bool IsCudaExtension(cm::string_view ext) const
{
return this->CudaFileExtensions.Test(ext);
}
@@ -293,7 +298,7 @@ public:
return this->FortranFileExtensions.ordered;
}
- bool IsFortranExtension(const std::string& ext) const
+ bool IsFortranExtension(cm::string_view ext) const
{
return this->FortranFileExtensions.Test(ext);
}
@@ -361,7 +366,7 @@ public:
void SetProperty(const std::string& prop, const char* value);
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetProperty(const std::string& prop);
+ cmProp GetProperty(const std::string& prop);
bool GetPropertyAsBool(const std::string& prop);
//! Get or create an cmInstalledFile instance and return a pointer to it
@@ -549,6 +554,11 @@ public:
bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
+#if !defined(CMAKE_BOOTSTRAP)
+ cmMakefileProfilingData& GetProfilingOutput();
+ bool IsProfilingEnabled() const;
+#endif
+
protected:
void RunCheckForUnusedVariables();
int HandleDeleteCacheVariables(const std::string& var);
@@ -657,6 +667,10 @@ private:
void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+
+#if !defined(CMAKE_BOOTSTRAP)
+ std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
+#endif
};
#define CMAKE_STANDARD_OPTIONS_TABLE \
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 494d5d9..84d0538 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -93,6 +93,12 @@ const char* cmDocumentationOptions[][2] = {
{ "--check-system-vars",
"Find problems with variable usage in system "
"files." },
+# if !defined(CMAKE_BOOTSTRAP)
+ { "--profiling-format=<fmt>", "Output data for profiling CMake scripts." },
+ { "--profiling-output=<file>",
+ "Select an output path for the profiling data enabled through "
+ "--profiling-format." },
+# endif
{ nullptr, nullptr }
};
@@ -286,16 +292,16 @@ int do_cmake(int ac, char const* const* av)
cmStateEnums::CacheEntryType t = cm.GetState()->GetCacheEntryType(k);
if (t != cmStateEnums::INTERNAL && t != cmStateEnums::STATIC &&
t != cmStateEnums::UNINITIALIZED) {
- const char* advancedProp =
+ cmProp advancedProp =
cm.GetState()->GetCacheEntryProperty(k, "ADVANCED");
if (list_all_cached || !advancedProp) {
if (list_help) {
- std::cout << "// "
- << cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING")
- << std::endl;
+ cmProp help =
+ cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING");
+ std::cout << "// " << (help ? *help : "") << std::endl;
}
std::cout << k << ":" << cmState::CacheEntryTypeToString(t) << "="
- << cm.GetState()->GetCacheEntryValue(k) << std::endl;
+ << cm.GetState()->GetSafeCacheEntryValue(k) << std::endl;
if (list_help) {
std::cout << std::endl;
}
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index caf6453..5c27ac1 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -25,6 +25,7 @@
#include "cmsys/Encoding.hxx"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// We don't want any wildcard expansion.
@@ -63,7 +64,7 @@ static void usage(const char* msg)
msg);
}
-static std::string trimLeadingSpace(const std::string& cmdline)
+static cm::string_view trimLeadingSpace(cm::string_view cmdline)
{
int i = 0;
for (; cmdline[i] == ' '; ++i)
@@ -81,34 +82,30 @@ static void replaceAll(std::string& str, const std::string& search,
}
}
-bool startsWith(const std::string& str, const std::string& what)
-{
- return str.compare(0, what.size(), what) == 0;
-}
-
// Strips one argument from the cmdline and returns it. "surrounding quotes"
// are removed from the argument if there were any.
static std::string getArg(std::string& cmdline)
{
- std::string ret;
bool in_quoted = false;
unsigned int i = 0;
- cmdline = trimLeadingSpace(cmdline);
+ cm::string_view cmdview = trimLeadingSpace(cmdline);
+ size_t spaceCnt = cmdline.size() - cmdview.size();
for (;; ++i) {
- if (i >= cmdline.size())
+ if (i >= cmdview.size())
usage("Couldn't parse arguments.");
- if (!in_quoted && cmdline[i] == ' ')
+ if (!in_quoted && cmdview[i] == ' ')
break; // "a b" "x y"
- if (cmdline[i] == '"')
+ if (cmdview[i] == '"')
in_quoted = !in_quoted;
}
- ret = cmdline.substr(0, i);
- if (ret[0] == '"' && ret[i - 1] == '"')
- ret = ret.substr(1, ret.size() - 2);
- cmdline = cmdline.substr(i);
+ cmdview = cmdview.substr(0, i);
+ if (cmdview[0] == '"' && cmdview[i - 1] == '"')
+ cmdview = cmdview.substr(1, i - 2);
+ std::string ret(cmdview);
+ cmdline.erase(0, spaceCnt + i);
return ret;
}
@@ -127,7 +124,7 @@ static void parseCommandLine(LPWSTR wincmdline, std::string& lang,
prefix = getArg(cmdline);
clpath = getArg(cmdline);
binpath = getArg(cmdline);
- rest = trimLeadingSpace(cmdline);
+ rest = std::string(trimLeadingSpace(cmdline));
}
// Not all backslashes need to be escaped in a depfile, but it's easier that
@@ -169,8 +166,8 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
// build.ninja file. Therefore we need to canonicalize the path to use
// backward slashes and relativize the path to the build directory.
replaceAll(tmp, "/", "\\");
- if (startsWith(tmp, cwd))
- tmp = tmp.substr(cwd.size());
+ if (cmHasPrefix(tmp, cwd))
+ tmp.erase(0, cwd.size());
escapePath(tmp);
fprintf(out, "%s \\\n", tmp.c_str());
}
@@ -194,7 +191,7 @@ std::string replace(const std::string& str, const std::string& what,
return replaced.replace(pos, what.size(), replacement);
}
-static int process(const std::string& srcfilename, const std::string& dfile,
+static int process(cm::string_view srcfilename, const std::string& dfile,
const std::string& objfile, const std::string& prefix,
const std::string& cmd, const std::string& dir = "",
bool quiet = false)
@@ -221,13 +218,14 @@ static int process(const std::string& srcfilename, const std::string& dfile,
std::vector<std::string> includes;
bool isFirstLine = true; // cl prints always first the source filename
while (std::getline(ss, line)) {
- if (startsWith(line, prefix)) {
- std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str());
+ cm::string_view inc(line);
+ if (cmHasPrefix(inc, prefix)) {
+ inc = trimLeadingSpace(inc.substr(prefix.size()));
if (inc.back() == '\r') // blech, stupid \r\n
inc = inc.substr(0, inc.size() - 1);
- includes.push_back(inc);
+ includes.emplace_back(std::string(inc));
} else {
- if (!isFirstLine || !startsWith(line, srcfilename)) {
+ if (!isFirstLine || !cmHasPrefix(inc, srcfilename)) {
if (!quiet || exit_code != 0) {
fprintf(stdout, "%s\n", line.c_str());
}
@@ -258,14 +256,10 @@ int main()
cl, binpath, rest);
// needed to suppress filename output of msvc tools
- std::string srcfilename;
- {
- std::string::size_type pos = srcfile.rfind('\\');
- if (pos == std::string::npos) {
- srcfilename = srcfile;
- } else {
- srcfilename = srcfile.substr(pos + 1);
- }
+ cm::string_view srcfilename(srcfile);
+ std::string::size_type pos = srcfile.rfind('\\');
+ if (pos != std::string::npos) {
+ srcfilename = srcfilename.substr(pos + 1);
}
std::string nol = " /nologo ";
@@ -286,7 +280,7 @@ int main()
// call cl in object dir so the .i is generated there
std::string objdir;
{
- std::string::size_type pos = objfile.rfind("\\");
+ pos = objfile.rfind("\\");
if (pos != std::string::npos) {
objdir = objfile.substr(0, pos);
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 2b8ea24..a8e07e4 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -8,7 +8,6 @@
#include "cm_uv.h"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -90,6 +89,7 @@ void CMakeCommandUsage(const char* program)
<< "Available commands: \n"
<< " capabilities - Report capabilities built into cmake "
"in JSON format\n"
+ << " cat <files>... - concat the files and print them to the standard output\n"
<< " chdir dir cmd [args...] - run command in a given directory\n"
<< " compare_files [--ignore-eol] file1 file2\n"
<< " - check if file1 is same as file2\n"
@@ -180,6 +180,13 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
+static void cmCatFile(const std::string& fileToAppend)
+{
+ cmsys::ifstream source(fileToAppend.c_str(),
+ (std::ios::binary | std::ios::in));
+ std::cout << source.rdbuf();
+}
+
static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
{
if (cmSystemTools::FileIsSymlink(dir)) {
@@ -678,7 +685,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
} else if (!a.empty() && a[0] == '-') {
// Environment variable and command names cannot start in '-',
// so this must be an unknown option.
- std::cerr << "cmake -E env: unknown option '" << a << "'"
+ std::cerr << "cmake -E env: unknown option '" << a << '\''
<< std::endl;
return 1;
} else if (a.find('=') != std::string::npos) {
@@ -927,6 +934,33 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
}
+ // Command to concat files into one
+ if (args[1] == "cat" && args.size() >= 3) {
+ int return_value = 0;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (cmHasLiteralPrefix(arg, "-")) {
+ if (arg != "--") {
+ cmSystemTools::Error(arg + ": option not handled");
+ return_value = 1;
+ }
+ } else if (!cmSystemTools::TestFileAccess(arg,
+ cmsys::TEST_FILE_READ) &&
+ cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
+ cmSystemTools::Error(arg + ": permission denied (ignoring)");
+ return_value = 1;
+ } else if (cmSystemTools::FileIsDirectory(arg)) {
+ cmSystemTools::Error(arg + ": is a directory (ignoring)");
+ return_value = 1;
+ } else if (!cmSystemTools::FileExists(arg)) {
+ cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
+ return_value = 1;
+ } else {
+ cmCatFile(arg);
+ }
+ }
+ return return_value;
+ }
+
// Command to change directory and run a program.
if (args[1] == "chdir" && args.size() >= 4) {
std::string const& directory = args[2];
@@ -1054,8 +1088,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
homeOutDir = args[5];
startOutDir = args[6];
depInfo = args[7];
- if (args.size() >= 9 && args[8].length() >= 8 &&
- args[8].substr(0, 8) == "--color=") {
+ if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) {
// Enable or disable color based on the switch value.
color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
}
@@ -1186,7 +1219,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
}
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
- if (!cmContains(knownFormats, format)) {
+ if (!cm::contains(knownFormats, format)) {
cmSystemTools::Error("Unknown -E tar --format= argument: " +
format);
return 1;
@@ -1304,7 +1337,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
} else if (arg == "--debug") {
pipe.clear();
isDebug = true;
- } else if (arg.substr(0, pipePrefix.size()) == pipePrefix) {
+ } else if (cmHasPrefix(arg, pipePrefix)) {
isDebug = false;
pipe = arg.substr(pipePrefix.size());
if (pipe.empty()) {
@@ -1511,7 +1544,7 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
bool newline = true;
std::string progressDir;
for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (arg.find("--switch=") == 0) {
+ if (cmHasLiteralPrefix(arg, "--switch=")) {
// Enable or disable color based on the switch value.
std::string value = arg.substr(9);
if (!value.empty()) {
@@ -1566,7 +1599,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
// args[3] == --verbose=?
bool verbose = false;
if (args.size() >= 4) {
- if (args[3].find("--verbose=") == 0) {
+ if (cmHasLiteralPrefix(args[3], "--verbose=")) {
if (!cmIsOff(args[3].substr(10))) {
verbose = true;
}
@@ -1654,11 +1687,13 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
cmVisualStudioWCEPlatformParser parser(name.c_str());
parser.ParseVersion(version);
if (parser.Found()) {
- std::cout << "@echo off" << std::endl;
- std::cout << "echo Environment Selection: " << name << std::endl;
- std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
- std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() << std::endl;
- std::cout << "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+ /* clang-format off */
+ std::cout << "@echo off\n"
+ "echo Environment Selection: " << name << "\n"
+ "set PATH=" << parser.GetPathDirectories() << "\n"
+ "set INCLUDE=" << parser.GetIncludeDirectories() << "\n"
+ "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+ /* clang-format on */
return 0;
}
#else
@@ -1845,7 +1880,7 @@ int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
std::vector<std::string> expandedArgs;
for (std::string const& i : args) {
// check for nmake temporary files
- if (i[0] == '@' && i.find("@CMakeFiles") != 0) {
+ if (i[0] == '@' && !cmHasLiteralPrefix(i, "@CMakeFiles")) {
cmsys::ifstream fin(i.substr(1).c_str());
std::string line;
while (cmSystemTools::GetLineFromStream(fin, line)) {
@@ -1971,9 +2006,8 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
// Parse the link command to extract information we need.
for (; arg != argEnd; ++arg) {
- if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0) {
- this->Incremental = true;
- } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
+ if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
this->Incremental = true;
} else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) {
this->LinkGeneratesManifest = false;
@@ -2083,12 +2117,18 @@ int cmVSLink::LinkIncremental()
}
// If we have not previously generated a manifest file,
- // generate an empty one so the resource compiler succeeds.
+ // generate a manifest file so the resource compiler succeeds.
if (!cmSystemTools::FileExists(this->ManifestFile)) {
if (this->Verbose) {
std::cout << "Create empty: " << this->ManifestFile << "\n";
}
- cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+ if (this->UserManifests.empty()) {
+ // generate an empty manifest because there are no user provided
+ // manifest files.
+ cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+ } else {
+ this->RunMT("/out:" + this->ManifestFile, false);
+ }
}
// Compile the resource file.
@@ -2156,7 +2196,10 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
mtCommand.emplace_back("/nologo");
mtCommand.emplace_back("/manifest");
- if (this->LinkGeneratesManifest) {
+
+ // add the linker generated manifest if the file exists.
+ if (this->LinkGeneratesManifest &&
+ cmSystemTools::FileExists(this->LinkerManifestFile)) {
mtCommand.push_back(this->LinkerManifestFile);
}
cm::append(mtCommand, this->UserManifests);
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index fbdf75a..3b5bf8c 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -35,6 +35,7 @@ static const char* cmDocumentationOptions[][2] = {
{ "--output-on-failure",
"Output anything outputted by the test program "
"if the test should fail." },
+ { "--stop-on-failure", "Stop running the tests after one has failed." },
{ "--test-output-size-passed <size>",
"Limit the output for passed tests "
"to <size> bytes" },
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
index bf876f2..4265018 100644
--- a/Source/kwsys/Base64.c
+++ b/Source/kwsys/Base64.c
@@ -130,7 +130,10 @@ size_t kwsysBase64_Encode(const unsigned char* input, size_t length,
/* Decode 4 bytes into a 3 byte string. */
int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest)
{
- unsigned char d0, d1, d2, d3;
+ unsigned char d0;
+ unsigned char d1;
+ unsigned char d2;
+ unsigned char d3;
d0 = kwsysBase64DecodeChar(src[0]);
d1 = kwsysBase64DecodeChar(src[1]);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 09bcdb9..d8f7e57 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -11,9 +11,9 @@
# be used. All classes are disabled by default. The CMake listfile
# above this one configures the library as follows:
#
-# SET(KWSYS_NAMESPACE foosys)
-# SET(KWSYS_USE_Directory 1) # Enable Directory class.
-# SUBDIRS(kwsys)
+# set(KWSYS_NAMESPACE foosys)
+# set(KWSYS_USE_Directory 1) # Enable Directory class.
+# add_subdirectory(kwsys)
#
# Optional settings are as follows:
#
@@ -39,8 +39,8 @@
#
# Example:
#
-# SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
-# INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+# set(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
+# include_directories(${PROJECT_BINARY_DIR})
#
# KWSYS_CXX_STANDARD = A value for CMAKE_CXX_STANDARD within KWSys.
# Set to empty string to use no default value.
@@ -65,11 +65,11 @@
#
# Example:
#
-# SET(KWSYS_INSTALL_BIN_DIR bin)
-# SET(KWSYS_INSTALL_LIB_DIR lib)
-# SET(KWSYS_INSTALL_INCLUDE_DIR include)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
+# set(KWSYS_INSTALL_BIN_DIR bin)
+# set(KWSYS_INSTALL_LIB_DIR lib)
+# set(KWSYS_INSTALL_INCLUDE_DIR include)
+# set(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
+# set(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
# Once configured, kwsys should be used as follows from C or C++ code:
#
@@ -86,33 +86,33 @@
# any outside mailing list and no documentation of the change will be
# written.
-CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
-FOREACH(p
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+foreach(p
CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
CMP0063 # CMake 3.3, Honor visibility properties for all target types.
CMP0067 # CMake 3.8, Honor language standard in try_compile source-file signature.
CMP0069 # CMake 3.9, INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
)
- IF(POLICY ${p})
- CMAKE_POLICY(SET ${p} NEW)
- ENDIF()
-ENDFOREACH()
+ if(POLICY ${p})
+ cmake_policy(SET ${p} NEW)
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# If a namespace is not specified, use "kwsys" and enable testing.
# This should be the case only when kwsys is not included inside
# another project and is being tested.
-IF(NOT KWSYS_NAMESPACE)
- SET(KWSYS_NAMESPACE "kwsys")
- SET(KWSYS_STANDALONE 1)
-ENDIF()
+if(NOT KWSYS_NAMESPACE)
+ set(KWSYS_NAMESPACE "kwsys")
+ set(KWSYS_STANDALONE 1)
+endif()
#-----------------------------------------------------------------------------
# The project name is that of the specified namespace.
-PROJECT(${KWSYS_NAMESPACE})
+project(${KWSYS_NAMESPACE})
# Tell CMake how to follow dependencies of sources in this directory.
-SET_PROPERTY(DIRECTORY
+set_property(DIRECTORY
PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
"KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>"
)
@@ -131,229 +131,229 @@ elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD)
endif()
# Select library components.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- SET(KWSYS_ENABLE_C 1)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ set(KWSYS_ENABLE_C 1)
# Enable all components.
- SET(KWSYS_USE_Base64 1)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_DynamicLoader 1)
- SET(KWSYS_USE_Encoding 1)
- SET(KWSYS_USE_Glob 1)
- SET(KWSYS_USE_MD5 1)
- SET(KWSYS_USE_Process 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_CommandLineArguments 1)
- SET(KWSYS_USE_Terminal 1)
- SET(KWSYS_USE_IOStream 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_String 1)
- SET(KWSYS_USE_SystemInformation 1)
- SET(KWSYS_USE_ConsoleBuf 1)
-ENDIF()
+ set(KWSYS_USE_Base64 1)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_DynamicLoader 1)
+ set(KWSYS_USE_Encoding 1)
+ set(KWSYS_USE_Glob 1)
+ set(KWSYS_USE_MD5 1)
+ set(KWSYS_USE_Process 1)
+ set(KWSYS_USE_RegularExpression 1)
+ set(KWSYS_USE_System 1)
+ set(KWSYS_USE_SystemTools 1)
+ set(KWSYS_USE_CommandLineArguments 1)
+ set(KWSYS_USE_Terminal 1)
+ set(KWSYS_USE_IOStream 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_String 1)
+ set(KWSYS_USE_SystemInformation 1)
+ set(KWSYS_USE_ConsoleBuf 1)
+endif()
# Enforce component dependencies.
-IF(KWSYS_USE_SystemTools)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Glob)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Process)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_USE_Process 1)
-ENDIF()
-IF(KWSYS_USE_System)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Directory)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_DynamicLoader)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_FStream)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_ConsoleBuf)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
+if(KWSYS_USE_SystemTools)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Glob)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_SystemTools 1)
+ set(KWSYS_USE_RegularExpression 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Process)
+ set(KWSYS_USE_System 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_SystemInformation)
+ set(KWSYS_USE_Process 1)
+endif()
+if(KWSYS_USE_System)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Directory)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_DynamicLoader)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_FStream)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_ConsoleBuf)
+ set(KWSYS_USE_Encoding 1)
+endif()
# Specify default 8 bit encoding for Windows
-IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
- SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
-ENDIF()
+if(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
+ set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
+endif()
# Enable testing if building standalone.
-IF(KWSYS_STANDALONE)
- INCLUDE(Dart)
- MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
- IF(BUILD_TESTING)
- ENABLE_TESTING()
- ENDIF()
-ENDIF()
+if(KWSYS_STANDALONE)
+ include(Dart)
+ mark_as_advanced(BUILD_TESTING DART_ROOT TCL_TCLSH)
+ if(BUILD_TESTING)
+ enable_testing()
+ endif()
+endif()
# Choose default shared/static build if not specified.
-IF(NOT DEFINED KWSYS_BUILD_SHARED)
- SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
-ENDIF()
+if(NOT DEFINED KWSYS_BUILD_SHARED)
+ set(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
+endif()
# Include helper macros.
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
-INCLUDE(CheckTypeSize)
+include(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
+include(CheckTypeSize)
# Do full dependency headers.
-INCLUDE_REGULAR_EXPRESSION("^.*$")
+include_regular_expression("^.*$")
# Use new KWSYS_INSTALL_*_DIR variable names to control installation.
# Take defaults from the old names. Note that there was no old name
# for the bin dir, so we take the old lib dir name so DLLs will be
# installed in a compatible way for old code.
-IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
+if(NOT KWSYS_INSTALL_INCLUDE_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
"${KWSYS_HEADER_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_LIB_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
+endif()
+if(NOT KWSYS_INSTALL_LIB_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_BIN_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
+endif()
+if(NOT KWSYS_INSTALL_BIN_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
+endif()
# Setup header install rules.
-SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
-IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
+set(KWSYS_INSTALL_INCLUDE_OPTIONS)
+if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
-ENDIF()
+endif()
# Setup library install rules.
-SET(KWSYS_INSTALL_LIBRARY_RULE)
-SET(KWSYS_INSTALL_NAMELINK_RULE)
-IF(KWSYS_INSTALL_LIB_DIR)
- IF(KWSYS_INSTALL_EXPORT_NAME)
- LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
- ENDIF()
+set(KWSYS_INSTALL_LIBRARY_RULE)
+set(KWSYS_INSTALL_NAMELINK_RULE)
+if(KWSYS_INSTALL_LIB_DIR)
+ if(KWSYS_INSTALL_EXPORT_NAME)
+ list(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
+ endif()
# Install the shared library to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_SKIP
)
# Assign the shared library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+ endif()
+ if(KWSYS_BUILD_SHARED)
+ set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_ONLY
)
# Assign the namelink to the development component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Install the archive to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR}
)
# Assign the archive to the development component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
- ENDIF()
-ENDIF()
-IF(KWSYS_INSTALL_BIN_DIR)
+ endif()
+endif()
+if(KWSYS_INSTALL_BIN_DIR)
# Install the runtime library to the bin directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR}
)
# Assign the runtime library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
-ENDIF()
+ endif()
+endif()
# Do not support old KWSYS_*a_INSTALL_DIR variable names.
-SET(KWSYS_HEADER_INSTALL_DIR)
-SET(KWSYS_LIBRARY_INSTALL_DIR)
+set(KWSYS_HEADER_INSTALL_DIR)
+set(KWSYS_LIBRARY_INSTALL_DIR)
# Generated source files will need this header.
-STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
+string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
KWSYS_IN_SOURCE_BUILD)
-IF(NOT KWSYS_IN_SOURCE_BUILD)
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
+if(NOT KWSYS_IN_SOURCE_BUILD)
+ configure_file(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE)
-ENDIF()
+endif()
# Select plugin module file name convention.
-IF(NOT KWSYS_DynamicLoader_PREFIX)
- SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
-ENDIF()
-IF(NOT KWSYS_DynamicLoader_SUFFIX)
- SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
-ENDIF()
+if(NOT KWSYS_DynamicLoader_PREFIX)
+ set(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
+endif()
+if(NOT KWSYS_DynamicLoader_SUFFIX)
+ set(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
+endif()
#-----------------------------------------------------------------------------
# We require ANSI support from the C compiler. Add any needed flags.
-IF(CMAKE_ANSI_CFLAGS)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-ENDIF()
+if(CMAKE_ANSI_CFLAGS)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+endif()
#-----------------------------------------------------------------------------
# Adjust compiler flags for some platforms.
-IF(NOT CMAKE_COMPILER_IS_GNUCXX)
- IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
- STRING(REGEX MATCH "-timplicit_local"
+if(NOT CMAKE_COMPILER_IS_GNUCXX)
+ if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ string(REGEX MATCH "-timplicit_local"
KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}")
- STRING(REGEX MATCH "-no_implicit_include"
+ string(REGEX MATCH "-no_implicit_include"
KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}")
- IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
- ENDIF()
- IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
- SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
- IF(CMAKE_CXX_COMPILER_ID MATCHES "HP")
+ if(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
+ endif()
+ if(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "HP-UX")
+ set(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "HP")
# it is known that version 3.85 fails and 6.25 works without these flags
- IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
# use new C++ library and improved template support
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
- ENDIF()
- ENDIF()
- ENDIF()
-ENDIF()
-IF(KWSYS_STANDALONE)
- IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
- IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
- ELSE()
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
- ENDIF()
- ENDIF()
-ENDIF()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
+ endif()
+ endif()
+ endif()
+endif()
+if(KWSYS_STANDALONE)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+ endif()
+ endif()
+endif()
#-----------------------------------------------------------------------------
# Configure the standard library header wrappers based on compiler's
@@ -365,75 +365,75 @@ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG
"Checking whether C++ compiler has 'long long'" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64
"Checking whether C++ compiler has '__int64'" DIRECT)
-IF(KWSYS_CXX_HAS___INT64)
+if(KWSYS_CXX_HAS___INT64)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64
"Checking whether long and __int64 are the same type" DIRECT)
- IF(KWSYS_CXX_HAS_LONG_LONG)
+ if(KWSYS_CXX_HAS_LONG_LONG)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
"Checking whether long long and __int64 are the same type" DIRECT)
- ENDIF()
-ENDIF()
+ endif()
+endif()
# Enable the "long long" type if it is available. It is standard in
# C99 and C++03 but not in earlier standards.
-IF(KWSYS_CXX_HAS_LONG_LONG)
- SET(KWSYS_USE_LONG_LONG 1)
-ELSE()
- SET(KWSYS_USE_LONG_LONG 0)
-ENDIF()
+if(KWSYS_CXX_HAS_LONG_LONG)
+ set(KWSYS_USE_LONG_LONG 1)
+else()
+ set(KWSYS_USE_LONG_LONG 0)
+endif()
# Enable the "__int64" type if it is available and unique. It is not
# standard.
-SET(KWSYS_USE___INT64 0)
-IF(KWSYS_CXX_HAS___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
- SET(KWSYS_USE___INT64 1)
- ENDIF()
- ENDIF()
-ENDIF()
-
-IF(KWSYS_USE_Encoding)
+set(KWSYS_USE___INT64 0)
+if(KWSYS_CXX_HAS___INT64)
+ if(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
+ if(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
+ set(KWSYS_USE___INT64 1)
+ endif()
+ endif()
+endif()
+
+if(KWSYS_USE_Encoding)
# Look for type size helper macros.
KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
"Checking whether wstring is available" DIRECT)
-ENDIF()
+endif()
-IF(KWSYS_USE_IOStream)
+if(KWSYS_USE_IOStream)
# Determine whether iostreams support long long.
- IF(KWSYS_CXX_HAS_LONG_LONG)
+ if(KWSYS_CXX_HAS_LONG_LONG)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
"Checking if istream supports long long" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
"Checking if ostream supports long long" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
- SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
- ENDIF()
- IF(KWSYS_CXX_HAS___INT64)
+ else()
+ set(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
+ set(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
+ endif()
+ if(KWSYS_CXX_HAS___INT64)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
"Checking if istream supports __int64" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
"Checking if ostream supports __int64" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
- SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
- ENDIF()
-ENDIF()
-
-IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
- SET(KWSYS_NAME_IS_KWSYS 1)
-ELSE()
- SET(KWSYS_NAME_IS_KWSYS 0)
-ENDIF()
-
-IF(KWSYS_BUILD_SHARED)
- SET(KWSYS_BUILD_SHARED 1)
- SET(KWSYS_LIBRARY_TYPE SHARED)
-ELSE()
- SET(KWSYS_BUILD_SHARED 0)
- SET(KWSYS_LIBRARY_TYPE STATIC)
-ENDIF()
+ else()
+ set(KWSYS_IOS_HAS_ISTREAM___INT64 0)
+ set(KWSYS_IOS_HAS_OSTREAM___INT64 0)
+ endif()
+endif()
+
+if(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ set(KWSYS_NAME_IS_KWSYS 1)
+else()
+ set(KWSYS_NAME_IS_KWSYS 0)
+endif()
+
+if(KWSYS_BUILD_SHARED)
+ set(KWSYS_BUILD_SHARED 1)
+ set(KWSYS_LIBRARY_TYPE SHARED)
+else()
+ set(KWSYS_BUILD_SHARED 0)
+ set(KWSYS_LIBRARY_TYPE STATIC)
+endif()
if(NOT DEFINED KWSYS_BUILD_PIC)
set(KWSYS_BUILD_PIC 0)
@@ -446,32 +446,32 @@ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
"Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
"Checking whether C compiler has ssize_t in unistd.h" DIRECT)
-IF(KWSYS_USE_Process)
+if(KWSYS_USE_Process)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
"Checking whether C compiler has clock_gettime" DIRECT)
-ENDIF()
+endif()
-SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
+set_source_files_properties(ProcessUNIX.c System.c PROPERTIES
COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}"
)
-IF(DEFINED KWSYS_PROCESS_USE_SELECT)
- GET_PROPERTY(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
- SET_PROPERTY(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
-ENDIF()
-
-IF(KWSYS_USE_DynamicLoader)
- GET_PROPERTY(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
- IF(KWSYS_SUPPORTS_SHARED_LIBS)
- SET(KWSYS_SUPPORTS_SHARED_LIBS 1)
- ELSE()
- SET(KWSYS_SUPPORTS_SHARED_LIBS 0)
- ENDIF()
- SET_PROPERTY(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+if(DEFINED KWSYS_PROCESS_USE_SELECT)
+ get_property(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
+ set_property(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
+endif()
+
+if(KWSYS_USE_DynamicLoader)
+ get_property(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+ if(KWSYS_SUPPORTS_SHARED_LIBS)
+ set(KWSYS_SUPPORTS_SHARED_LIBS 1)
+ else()
+ set(KWSYS_SUPPORTS_SHARED_LIBS 0)
+ endif()
+ set_property(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_SUPPORTS_SHARED_LIBS=${KWSYS_SUPPORTS_SHARED_LIBS})
-ENDIF()
+endif()
-IF(KWSYS_USE_SystemTools)
+if(KWSYS_USE_SystemTools)
if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP)
set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1)
endif ()
@@ -494,7 +494,7 @@ IF(KWSYS_USE_SystemTools)
"Checking whether CXX compiler struct stat has st_mtim member" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
"Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT)
- SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}
@@ -503,623 +503,623 @@ IF(KWSYS_USE_SystemTools)
KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
)
- IF(NOT WIN32)
- IF(KWSYS_STANDALONE)
- OPTION(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
- ENDIF()
- IF(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
- SET_PROPERTY(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ if(NOT WIN32)
+ if(KWSYS_STANDALONE)
+ option(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
+ endif()
+ if(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+ set_property(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES
)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Disable getpwnam for static linux builds since it depends on shared glibc
- GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
- IF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
- SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ get_property(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+ if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
+ set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
HAVE_GETPWNAM=0
)
- ENDIF()
-ENDIF()
+ endif()
+endif()
-IF(KWSYS_USE_SystemInformation)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+if(KWSYS_USE_SystemInformation)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
- IF(NOT CYGWIN)
- INCLUDE(CheckIncludeFiles)
+ if(NOT CYGWIN)
+ include(CheckIncludeFiles)
CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
- IF(KWSYS_SYS_HAS_IFADDRS_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_IFADDRS_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1)
- ENDIF()
- ENDIF()
- IF(WIN32)
- INCLUDE(CheckSymbolExists)
- SET(CMAKE_REQUIRED_LIBRARIES Psapi)
+ endif()
+ endif()
+ if(WIN32)
+ include(CheckSymbolExists)
+ set(CMAKE_REQUIRED_LIBRARIES psapi)
CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI)
- UNSET(CMAKE_REQUIRED_LIBRARIES)
- IF(KWSYS_SYS_HAS_PSAPI)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ if(KWSYS_SYS_HAS_PSAPI)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1)
- IF(MSVC70 OR MSVC71)
+ if(MSVC70 OR MSVC71)
# Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
+ endif()
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "HP-UX")
CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
- IF(KWSYS_SYS_HAS_MPCTL_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_MPCTL_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "BSD")
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "BSD")
CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
- IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_MACHINE_CPU_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
"Checking whether CXX compiler has rlimit64" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
- IF(KWSYS_CXX_HAS_RLIMIT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+ if(KWSYS_CXX_HAS_RLIMIT64)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
"Checking whether CXX compiler has atol" DIRECT)
- IF(KWSYS_CXX_HAS_ATOL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_ATOL)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
"Checking whether CXX compiler has atoll" DIRECT)
- IF(KWSYS_CXX_HAS_ATOLL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_ATOLL)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
"Checking whether CXX compiler has _atoi64" DIRECT)
- IF(KWSYS_CXX_HAS__ATOI64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS__ATOI64)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
- ENDIF()
- IF(UNIX)
- INCLUDE(CheckIncludeFileCXX)
+ endif()
+ if(UNIX)
+ include(CheckIncludeFileCXX)
# check for simple stack trace
# usually it's in libc but on FreeBSD
# it's in libexecinfo
- FIND_LIBRARY(EXECINFO_LIB "execinfo")
- MARK_AS_ADVANCED(EXECINFO_LIB)
- IF (NOT EXECINFO_LIB)
- SET(EXECINFO_LIB "")
- ENDIF()
+ find_library(EXECINFO_LIB "execinfo")
+ mark_as_advanced(EXECINFO_LIB)
+ if (NOT EXECINFO_LIB)
+ set(EXECINFO_LIB "")
+ endif()
CHECK_INCLUDE_FILE_CXX("execinfo.h" KWSYS_CXX_HAS_EXECINFOH)
- IF (KWSYS_CXX_HAS_EXECINFOH)
+ if (KWSYS_CXX_HAS_EXECINFOH)
# we have the backtrace header check if it
# can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BACKTRACE
"Checking whether backtrace works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_BACKTRACE)
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+ if (KWSYS_CXX_HAS_BACKTRACE)
# backtrace is supported by this system and compiler.
# now check for the more advanced capabilities.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE=1)
# check for symbol lookup using dladdr
CHECK_INCLUDE_FILE_CXX("dlfcn.h" KWSYS_CXX_HAS_DLFCNH)
- IF (KWSYS_CXX_HAS_DLFCNH)
+ if (KWSYS_CXX_HAS_DLFCNH)
# we have symbol lookup libraries and headers
# check if they can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_DLADDR
"Checking whether dladdr works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_DLADDR)
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+ if (KWSYS_CXX_HAS_DLADDR)
# symbol lookup is supported by this system
# and compiler.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# c++ demangling support
# check for cxxabi headers
CHECK_INCLUDE_FILE_CXX("cxxabi.h" KWSYS_CXX_HAS_CXXABIH)
- IF (KWSYS_CXX_HAS_CXXABIH)
+ if (KWSYS_CXX_HAS_CXXABIH)
# check if cxxabi can be used with this
# system and compiler.
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CXXABI
"Checking whether cxxabi works with this C++ compiler" DIRECT)
- IF (KWSYS_CXX_HAS_CXXABI)
+ if (KWSYS_CXX_HAS_CXXABI)
# c++ demangle using cxxabi is supported with
# this system and compiler
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# basic backtrace works better with release build
# don't bother with advanced features for release
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS_DEBUG KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS_RELWITHDEBINFO KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(BORLAND)
+ endif()
+ endif()
+ endif()
+ if(BORLAND)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
"Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_BORLAND_ASM)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
"Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(KWSYS_USE___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ endif()
+ endif()
+ if(KWSYS_USE___INT64)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
- ENDIF()
- IF(KWSYS_USE_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_USE_LONG_LONG)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_IOS_HAS_OSTREAM___INT64)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_BUILD_SHARED)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
- ENDIF()
+ endif()
- IF(UNIX AND NOT CYGWIN)
+ if(UNIX AND NOT CYGWIN)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
"Checking whether CXX compiler has getloadavg" DIRECT)
- IF(KWSYS_CXX_HAS_GETLOADAVG)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_GETLOADAVG)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
- ENDIF()
- ENDIF()
-ENDIF()
+ endif()
+ endif()
+endif()
-IF(KWSYS_USE_FStream)
+if(KWSYS_USE_FStream)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H
"Checking whether <ext/stdio_filebuf.h> is available" DIRECT)
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Choose a directory for the generated headers.
-IF(NOT KWSYS_HEADER_ROOT)
- SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
-ENDIF()
-SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
-INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
+if(NOT KWSYS_HEADER_ROOT)
+ set(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
+endif()
+set(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
+include_directories(${KWSYS_HEADER_ROOT})
#-----------------------------------------------------------------------------
-IF(KWSYS_INSTALL_DOC_DIR)
+if(KWSYS_INSTALL_DOC_DIR)
# Assign the license to the runtime component since it must be
# distributed with binary forms of this software.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
+ endif()
# Install the license under the documentation directory.
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_LICENSE_OPTIONS})
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Build a list of classes and headers we need to implement the
# selected components. Initialize with required components.
-SET(KWSYS_CLASSES)
-SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String)
+set(KWSYS_CLASSES)
+set(KWSYS_H_FILES Configure SharedForward)
+set(KWSYS_HXX_FILES Configure String)
-IF(NOT CMake_SOURCE_DIR)
- SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
+if(NOT CMake_SOURCE_DIR)
+ set(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
hashtable hash_fun hash_map hash_set
)
-ENDIF()
+endif()
# Add selected C++ classes.
-SET(cppclasses
+set(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
-FOREACH(cpp ${cppclasses})
- IF(KWSYS_USE_${cpp})
+foreach(cpp ${cppclasses})
+ if(KWSYS_USE_${cpp})
# Use the corresponding class.
- SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
+ set(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
# Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+ if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+ include(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+ endif()
+ endif()
+endforeach()
# Add selected C components.
-FOREACH(c
+foreach(c
Process Base64 Encoding MD5 Terminal System String
)
- IF(KWSYS_USE_${c})
+ if(KWSYS_USE_${c})
# Use the corresponding header file.
- SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
+ set(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
# Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+ if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+ include(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+ endif()
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# Build a list of sources for the library based on components that are
# included.
-SET(KWSYS_C_SRCS)
-SET(KWSYS_CXX_SRCS)
+set(KWSYS_C_SRCS)
+set(KWSYS_CXX_SRCS)
# Add the proper sources for this platform's Process implementation.
-IF(KWSYS_USE_Process)
- IF(NOT UNIX)
+if(KWSYS_USE_Process)
+ if(NOT UNIX)
# Use the Windows implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
- ELSE()
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
+ else()
# Use the UNIX implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
- ENDIF()
-ENDIF()
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
+ endif()
+endif()
# Add selected C sources.
-FOREACH(c Base64 Encoding MD5 Terminal System String)
- IF(KWSYS_USE_${c})
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
- LIST(APPEND KWSYS_C_SRCS ${c}C.c)
- ELSE()
- LIST(APPEND KWSYS_C_SRCS ${c}.c)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+foreach(c Base64 Encoding MD5 Terminal System String)
+ if(KWSYS_USE_${c})
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
+ list(APPEND KWSYS_C_SRCS ${c}C.c)
+ else()
+ list(APPEND KWSYS_C_SRCS ${c}.c)
+ endif()
+ endif()
+endforeach()
# Configure headers of C++ classes and construct the list of sources.
-FOREACH(c ${KWSYS_CLASSES})
+foreach(c ${KWSYS_CLASSES})
# Add this source to the list of source files for the library.
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
- ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx)
- ENDIF()
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
+ list(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
+ elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
+ list(APPEND KWSYS_CXX_SRCS ${c}.cxx)
+ endif()
# Configure the header for this class.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
+ configure_file(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
@ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
+ set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
# Configure C headers.
-FOREACH(h ${KWSYS_H_FILES})
+foreach(h ${KWSYS_H_FILES})
# Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
+ configure_file(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
@ONLY IMMEDIATE)
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${h}.h
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
# Configure other C++ headers.
-FOREACH(h ${KWSYS_HXX_FILES})
+foreach(h ${KWSYS_HXX_FILES})
# Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
+ configure_file(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
@ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
+ set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# Add the library with the configured name and list of sources.
-IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
- IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
- SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
- SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
- SET(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
- SET(KWSYS_LINK_DEPENDENCY INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_OBJECT} OBJECT
+if(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+ if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+ set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
+ set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
+ set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
+ set(KWSYS_LINK_DEPENDENCY INTERFACE)
+ add_library(${KWSYS_TARGET_OBJECT} OBJECT
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
- IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
- SET_PROPERTY(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
+ if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+ set_property(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
- ENDIF()
- ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_LINK} INTERFACE)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_LINK} INTERFACE
+ endif()
+ add_library(${KWSYS_TARGET_INTERFACE} INTERFACE)
+ add_library(${KWSYS_TARGET_LINK} INTERFACE)
+ target_link_libraries(${KWSYS_TARGET_LINK} INTERFACE
${KWSYS_TARGET_INTERFACE})
- TARGET_SOURCES(${KWSYS_TARGET_LINK} INTERFACE
+ target_sources(${KWSYS_TARGET_LINK} INTERFACE
$<TARGET_OBJECTS:${KWSYS_TARGET_OBJECT}>)
target_compile_features(${KWSYS_TARGET_OBJECT} PRIVATE ${KWSYS_CXX_COMPILE_FEATURES})
target_compile_features(${KWSYS_TARGET_INTERFACE} INTERFACE ${KWSYS_CXX_COMPILE_FEATURES})
- ELSE()
- SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
+ else()
+ set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_LINK})
- SET(KWSYS_LINK_DEPENDENCY PUBLIC)
- ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+ set(KWSYS_LINK_DEPENDENCY PUBLIC)
+ add_library(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
target_compile_features(${KWSYS_TARGET_INTERFACE} PUBLIC ${KWSYS_CXX_COMPILE_FEATURES})
- ENDIF()
+ endif()
if (KWSYS_ALIAS_TARGET)
add_library(${KWSYS_ALIAS_TARGET} ALIAS ${KWSYS_TARGET_INTERFACE})
endif ()
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_OBJECT} PROPERTIES
+ set_target_properties(${KWSYS_TARGET_OBJECT} PROPERTIES
C_CLANG_TIDY ""
CXX_CLANG_TIDY ""
C_INCLUDE_WHAT_YOU_USE ""
CXX_INCLUDE_WHAT_YOU_USE ""
LABELS "${KWSYS_LABELS_LIB}")
- IF(KWSYS_USE_DynamicLoader)
- IF(UNIX)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ if(KWSYS_USE_DynamicLoader)
+ if(UNIX)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${CMAKE_DL_LIBS})
- ENDIF()
- ENDIF()
+ endif()
+ endif()
- IF(KWSYS_USE_SystemInformation)
- IF(WIN32)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
+ if(KWSYS_USE_SystemInformation)
+ if(WIN32)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
# link in dbghelp.dll for symbol lookup if MSVC 1800 or later
# Note that the dbghelp runtime is part of MS Windows OS
- IF(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
- ENDIF()
- IF(KWSYS_SYS_HAS_PSAPI)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
- Psapi)
- ENDIF()
- ELSEIF(UNIX)
- IF (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
+ if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
+ endif()
+ if(KWSYS_SYS_HAS_PSAPI)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ psapi)
+ endif()
+ elseif(UNIX)
+ if (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
# backtrace on FreeBSD is not in libc
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${EXECINFO_LIB})
- ENDIF()
- IF (KWSYS_CXX_HAS_DLADDR)
+ endif()
+ if (KWSYS_CXX_HAS_DLADDR)
# for symbol lookup using dladdr
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${CMAKE_DL_LIBS})
- ENDIF()
- IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
socket)
- ENDIF()
- ENDIF()
- ENDIF()
+ endif()
+ endif()
+ endif()
# Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_CXX)
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_INTERFACE} PROPERTIES
+ if(KWSYS_PROPERTIES_CXX)
+ set_target_properties(${KWSYS_TARGET_INTERFACE} PROPERTIES
${KWSYS_PROPERTIES_CXX})
- ENDIF()
+ endif()
# Set up include usage requirement
- IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+ if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+ target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
$<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
$<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
- ENDIF()
- IF(KWSYS_INSTALL_NAMELINK_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
- ENDIF()
-ENDIF()
+ if(KWSYS_INSTALL_LIBRARY_RULE)
+ install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
+ endif()
+ if(KWSYS_INSTALL_NAMELINK_RULE)
+ install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
+ endif()
+endif()
# Add a C-only library if requested.
-IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
- IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
- SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
- SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
- SET(KWSYS_TARGET_C_INSTALL
+if(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+ if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+ set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
+ set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
+ set(KWSYS_TARGET_C_INSTALL
${KWSYS_TARGET_C_INTERFACE} ${KWSYS_TARGET_C_LINK})
- SET(KWSYS_LINK_DEPENDENCY INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
- IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
- SET_PROPERTY(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
+ set(KWSYS_LINK_DEPENDENCY INTERFACE)
+ add_library(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
+ if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+ set_property(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
- ENDIF()
- ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_C_LINK} INTERFACE)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_C_LINK} INTERFACE
+ endif()
+ add_library(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
+ add_library(${KWSYS_TARGET_C_LINK} INTERFACE)
+ target_link_libraries(${KWSYS_TARGET_C_LINK} INTERFACE
${KWSYS_TARGET_C_INTERFACE})
- TARGET_SOURCES(${KWSYS_TARGET_C_LINK} INTERFACE
+ target_sources(${KWSYS_TARGET_C_LINK} INTERFACE
$<TARGET_OBJECTS:${KWSYS_TARGET_C_OBJECT}>)
- ELSE()
- SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
- SET(KWSYS_LINK_DEPENDENCY PUBLIC)
- ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+ else()
+ set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
+ set(KWSYS_LINK_DEPENDENCY PUBLIC)
+ add_library(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
${KWSYS_C_SRCS})
- ENDIF()
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_OBJECT} PROPERTIES
+ endif()
+ set_target_properties(${KWSYS_TARGET_C_OBJECT} PROPERTIES
LABELS "${KWSYS_LABELS_LIB}")
# Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_C)
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
+ if(KWSYS_PROPERTIES_C)
+ set_target_properties(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
${KWSYS_PROPERTIES_C})
- ENDIF()
+ endif()
# Set up include usage requirement
- IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+ if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+ target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
$<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
$<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_C_INSTALL})
- ENDIF()
-ENDIF()
+ if(KWSYS_INSTALL_LIBRARY_RULE)
+ install(TARGETS ${KWSYS_TARGET_C_INSTALL})
+ endif()
+endif()
# For building kwsys itself, we use a macro defined on the command
# line to configure the namespace in the C and C++ source files.
-ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
+add_definitions("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
# Disable deprecation warnings for standard C functions.
-IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
+if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))))
- ADD_DEFINITIONS(
+ add_definitions(
-D_CRT_NONSTDC_NO_DEPRECATE
-D_CRT_SECURE_NO_DEPRECATE
-D_CRT_SECURE_NO_WARNINGS
-D_SCL_SECURE_NO_DEPRECATE
)
-ENDIF()
+endif()
-IF(WIN32)
+if(WIN32)
# Help enforce the use of wide Windows apis.
- ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
-ENDIF()
+ add_definitions(-DUNICODE -D_UNICODE)
+endif()
-IF(KWSYS_USE_String)
+if(KWSYS_USE_String)
# Activate code in "String.c". See the comment in the source.
- SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
+ set_source_files_properties(String.c PROPERTIES
COMPILE_FLAGS "-DKWSYS_STRING_C")
-ENDIF()
+endif()
-IF(KWSYS_USE_Encoding)
+if(KWSYS_USE_Encoding)
# Set default 8 bit encoding in "EndcodingC.c".
- SET_PROPERTY(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ set_property(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Setup testing if not being built as part of another project.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- IF(BUILD_TESTING)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ if(BUILD_TESTING)
# Compute the location of executables.
- SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- IF(EXECUTABLE_OUTPUT_PATH)
- SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
- ENDIF()
+ set(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(EXEC_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+ endif()
# C tests
- SET(KWSYS_C_TESTS
+ set(KWSYS_C_TESTS
testEncode.c
testTerminal.c
)
- IF(KWSYS_STANDALONE)
- SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
- ENDIF()
- CREATE_TEST_SOURCELIST(
+ if(KWSYS_STANDALONE)
+ set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
+ endif()
+ create_test_sourcelist(
KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c
${KWSYS_C_TESTS}
)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
- FOREACH(testfile ${KWSYS_C_TESTS})
+ add_executable(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
+ foreach(testfile ${KWSYS_C_TESTS})
get_filename_component(test "${testfile}" NAME_WE)
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
+ add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
+ set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ endforeach()
# C++ tests
- IF(NOT WATCOM AND NOT CMake_SOURCE_DIR)
- SET(KWSYS_CXX_TESTS
+ if(NOT WATCOM AND NOT CMake_SOURCE_DIR)
+ set(KWSYS_CXX_TESTS
testHashSTL.cxx
)
- ENDIF()
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConfigure.cxx
testSystemTools.cxx
testCommandLineArguments.cxx
testCommandLineArguments1.cxx
testDirectory.cxx
)
- IF(KWSYS_STL_HAS_WSTRING)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ if(KWSYS_STL_HAS_WSTRING)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testEncoding.cxx
)
- ENDIF()
- IF(KWSYS_USE_FStream)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ if(KWSYS_USE_FStream)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testFStream.cxx
)
- ENDIF()
- IF(KWSYS_USE_ConsoleBuf)
- ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_TARGET_LINK})
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ if(KWSYS_USE_ConsoleBuf)
+ add_executable(testConsoleBufChild testConsoleBufChild.cxx)
+ set_property(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
+ set_property(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
+ set_property(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(testConsoleBufChild ${KWSYS_TARGET_LINK})
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf.cxx
)
- IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506")
set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
- ENDIF()
- SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ endif()
+ set_property(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
- ENDIF()
- IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
- ENDIF()
- IF(KWSYS_USE_DynamicLoader)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
+ endif()
+ if(KWSYS_USE_SystemInformation)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
+ endif()
+ if(KWSYS_USE_DynamicLoader)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
# If kwsys contains the DynamicLoader, need extra library
- ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
+ add_library(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
+ set_property(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
+ add_dependencies(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
if (WIN32)
# Windows tests supported flags.
@@ -1134,33 +1134,33 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
add_dependencies(${KWSYS_NAMESPACE}TestDynloadUse ${KWSYS_TARGET_INTERFACE})
target_link_libraries(${KWSYS_NAMESPACE}TestDynloadUse PRIVATE ${KWSYS_NAMESPACE}TestDynloadImpl)
endif ()
- ENDIF()
- CREATE_TEST_SOURCELIST(
+ endif()
+ create_test_sourcelist(
KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
${KWSYS_CXX_TESTS}
)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
-
- SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- CONFIGURE_FILE(
+ add_executable(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
+
+ set(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ configure_file(
${PROJECT_SOURCE_DIR}/testSystemTools.h.in
${PROJECT_BINARY_DIR}/testSystemTools.h)
- INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+ include_directories(${PROJECT_BINARY_DIR})
- IF(CTEST_TEST_KWSYS)
- CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
+ if(CTEST_TEST_KWSYS)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- ENDIF()
+ set_directory_properties(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
+ endif()
- SET(KWSYS_TEST_ARGS_testCommandLineArguments
+ set(KWSYS_TEST_ARGS_testCommandLineArguments
--another-bool-variable
--long3=opt
--set-bool-arg1
@@ -1179,7 +1179,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-C=test
--long2 hello
)
- SET(KWSYS_TEST_ARGS_testCommandLineArguments1
+ set(KWSYS_TEST_ARGS_testCommandLineArguments1
--ignored
-n 24
--second-ignored
@@ -1188,73 +1188,71 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-p
some junk at the end
)
- FOREACH(testfile ${KWSYS_CXX_TESTS})
+ foreach(testfile ${KWSYS_CXX_TESTS})
get_filename_component(test "${testfile}" NAME_WE)
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
+ add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
+ set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ endforeach()
# Process tests.
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
- IF(NOT CYGWIN)
- SET(KWSYS_TEST_PROCESS_7 7)
- ENDIF()
- FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
- ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
- SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
- ENDFOREACH()
-
- SET(testProcess_COMPILE_FLAGS "")
+ add_executable(${KWSYS_NAMESPACE}TestProcess testProcess.c)
+ set_property(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
+ #set(KWSYS_TEST_PROCESS_7 7) # uncomment to run timing-sensitive test locally
+ foreach(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
+ add_test(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
+ set_property(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ set_tests_properties(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
+ endforeach()
+
+ set(testProcess_COMPILE_FLAGS "")
# Some Apple compilers produce bad optimizations in this source.
- IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
- ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ if(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "XL")
# Tell IBM XL not to warn about our test infinite loop
- IF(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
+ if(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
AND CMAKE_C_COMPILER_VERSION VERSION_LESS "16.1.0"
AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1")
# v13.1.[1-6] on Linux ppc64le is clang based and does not accept
# the -qsuppress option, so just suppress all warnings.
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
- ELSE()
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
- ENDIF()
- ENDIF()
- IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
- ENDIF()
- SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
+ else()
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
+ endif()
+ endif()
+ if(CMAKE_C_FLAGS MATCHES "-fsanitize=")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
+ endif()
+ set_property(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
# Test SharedForward
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
+ configure_file(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward
+ add_executable(${KWSYS_NAMESPACE}TestSharedForward
${PROJECT_BINARY_DIR}/testSharedForward.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
- ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
- SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ add_dependencies(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
+ add_test(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
+ set_property(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
# Configure some test properties.
- IF(KWSYS_STANDALONE)
+ if(KWSYS_STANDALONE)
# We expect test to fail
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
- GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
- MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
- ENDIF()
+ set_tests_properties(kwsys.testFail PROPERTIES WILL_FAIL ON)
+ get_test_property(kwsys.testFail WILL_FAIL wfv)
+ set_tests_properties(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
+ message(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
+ endif()
# Set up ctest custom configuration file.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+ configure_file(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
# Suppress known consistent failures on buggy systems.
- IF(KWSYS_TEST_BOGUS_FAILURES)
- SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
- ENDIF()
+ if(KWSYS_TEST_BOGUS_FAILURES)
+ set_tests_properties(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
+ endif()
- ENDIF()
-ENDIF()
+ endif()
+endif()
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 3fd1955..a2ed874 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -66,26 +66,21 @@ class CommandLineArgumentsMapOfStrucs
class CommandLineArgumentsInternal
{
public:
- CommandLineArgumentsInternal()
- : UnknownArgumentCallback{ nullptr }
- , ClientData{ nullptr }
- , LastArgument{ 0 }
- {
- }
+ CommandLineArgumentsInternal() = default;
- typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
- typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
- typedef kwsys::String String;
- typedef CommandLineArgumentsSetOfStrings SetOfStrings;
+ using VectorOfStrings = CommandLineArgumentsVectorOfStrings;
+ using CallbacksMap = CommandLineArgumentsMapOfStrucs;
+ using String = kwsys::String;
+ using SetOfStrings = CommandLineArgumentsSetOfStrings;
VectorOfStrings Argv;
String Argv0;
CallbacksMap Callbacks;
- CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
- void* ClientData;
+ CommandLineArguments::ErrorCallbackType UnknownArgumentCallback{ nullptr };
+ void* ClientData{ nullptr };
- VectorOfStrings::size_type LastArgument;
+ VectorOfStrings::size_type LastArgument{ 0 };
VectorOfStrings UnusedArguments;
};
@@ -424,8 +419,7 @@ void CommandLineArguments::SetUnknownArgumentCallback(
const char* CommandLineArguments::GetHelp(const char* arg)
{
- CommandLineArguments::Internal::CallbacksMap::iterator it =
- this->Internals->Callbacks.find(arg);
+ auto it = this->Internals->Callbacks.find(arg);
if (it == this->Internals->Callbacks.end()) {
return nullptr;
}
@@ -434,8 +428,7 @@ const char* CommandLineArguments::GetHelp(const char* arg)
// one point to if this one is pointing to another argument.
CommandLineArgumentsCallbackStructure* cs = &(it->second);
for (;;) {
- CommandLineArguments::Internal::CallbacksMap::iterator hit =
- this->Internals->Callbacks.find(cs->Help);
+ auto hit = this->Internals->Callbacks.find(cs->Help);
if (hit == this->Internals->Callbacks.end()) {
break;
}
@@ -470,9 +463,8 @@ void CommandLineArguments::GenerateHelp()
// Collapse all arguments into the map of vectors of all arguments that do
// the same thing.
CommandLineArguments::Internal::CallbacksMap::iterator it;
- typedef std::map<CommandLineArguments::Internal::String,
- CommandLineArguments::Internal::SetOfStrings>
- MapArgs;
+ using MapArgs = std::map<CommandLineArguments::Internal::String,
+ CommandLineArguments::Internal::SetOfStrings>;
MapArgs mp;
MapArgs::iterator mpit, smpit;
for (it = this->Internals->Callbacks.begin();
@@ -709,7 +701,7 @@ bool CommandLineArguments::PopulateVariable(
if (cs->Callback) {
if (!cs->Callback(cs->Argument, value, cs->CallData)) {
this->Internals->LastArgument--;
- return 0;
+ return false;
}
}
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to "
@@ -759,10 +751,10 @@ bool CommandLineArguments::PopulateVariable(
std::cerr << "Got unknown variable type: \"" << cs->VariableType
<< "\"" << std::endl;
this->Internals->LastArgument--;
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index e379182..d640948 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -35,6 +35,18 @@ Directory::Directory()
this->Internal = new DirectoryInternals;
}
+Directory::Directory(Directory&& other)
+{
+ this->Internal = other.Internal;
+ other.Internal = nullptr;
+}
+
+Directory& Directory::operator=(Directory&& other)
+{
+ std::swap(this->Internal, other.Internal);
+ return *this;
+}
+
Directory::~Directory()
{
delete this->Internal;
@@ -204,15 +216,15 @@ bool Directory::Load(const std::string& name)
DIR* dir = opendir(name.c_str());
if (!dir) {
- return 0;
+ return false;
}
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
- this->Internal->Files.push_back(d->d_name);
+ this->Internal->Files.emplace_back(d->d_name);
}
this->Internal->Path = name;
closedir(dir);
- return 1;
+ return true;
}
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index ad8c51b..9b0f4c3 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -23,6 +23,11 @@ class @KWSYS_NAMESPACE@_EXPORT Directory
{
public:
Directory();
+ Directory(Directory&& other);
+ Directory(const Directory&) = delete;
+ Directory& operator=(const Directory&) = delete;
+ Directory& operator=(Directory&& other);
+ bool operator==(const Directory&) = delete;
~Directory();
/**
@@ -62,10 +67,7 @@ public:
private:
// Private implementation details.
DirectoryInternals* Internal;
-
- Directory(const Directory&); // Not implemented.
- void operator=(const Directory&); // Not implemented.
-}; // End Class: Directory
+}; // End Class: Directory
} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/ExtraTest.cmake.in b/Source/kwsys/ExtraTest.cmake.in
index e8c0a1c..4cec9e2 100644
--- a/Source/kwsys/ExtraTest.cmake.in
+++ b/Source/kwsys/ExtraTest.cmake.in
@@ -1 +1 @@
-MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
+message("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 34bb0d0..8e30f92 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -385,10 +385,9 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
}
if (skip > 0) {
- expr = expr.substr(skip);
+ expr.erase(0, skip);
}
- cexpr = "";
for (cc = 0; cc < expr.size(); cc++) {
int ch = expr[cc];
if (ch == '/') {
@@ -415,8 +414,7 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
void Glob::AddExpression(const std::string& expr)
{
- this->Internals->Expressions.push_back(
- kwsys::RegularExpression(this->PatternToRegex(expr)));
+ this->Internals->Expressions.emplace_back(this->PatternToRegex(expr));
}
void Glob::SetRelative(const char* dir)
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
index 97cf9ba..fb18a5b 100644
--- a/Source/kwsys/MD5.c
+++ b/Source/kwsys/MD5.c
@@ -171,8 +171,10 @@ typedef struct md5_state_s
static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
{
- md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
- d = pms->abcd[3];
+ md5_word_t a = pms->abcd[0];
+ md5_word_t b = pms->abcd[1];
+ md5_word_t c = pms->abcd[2];
+ md5_word_t d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
@@ -227,9 +229,10 @@ static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
# else
# define xbuf X /* (static only) */
# endif
- for (i = 0; i < 16; ++i, xp += 4)
+ for (i = 0; i < 16; ++i, xp += 4) {
xbuf[i] =
(md5_word_t)(xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24));
+ }
}
#endif
}
@@ -367,34 +370,39 @@ static void md5_append(md5_state_t* pms, const md5_byte_t* data, size_t nbytes)
size_t offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
- if (nbytes <= 0)
+ if (nbytes <= 0) {
return;
+ }
/* Update the message length. */
pms->count[1] += (md5_word_t)(nbytes >> 29);
pms->count[0] += nbits;
- if (pms->count[0] < nbits)
+ if (pms->count[0] < nbits) {
pms->count[1]++;
+ }
/* Process an initial partial block. */
if (offset) {
size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
+ if (offset + copy < 64) {
return;
+ }
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
+ for (; left >= 64; p += 64, left -= 64) {
md5_process(pms, p);
+ }
/* Process a final partial block. */
- if (left)
+ if (left) {
memcpy(pms->buf, p, left);
+ }
}
/* Finish the message and return the digest. */
@@ -409,14 +417,16 @@ static void md5_finish(md5_state_t* pms, md5_byte_t digest[16])
int i;
/* Save the length before padding. */
- for (i = 0; i < 8; ++i)
+ for (i = 0; i < 8; ++i) {
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ }
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
+ for (i = 0; i < 16; ++i) {
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+ }
}
#if defined(__clang__) && !defined(__INTEL_COMPILER)
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 73ea9db..9f2162b 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -180,8 +180,8 @@ kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe,
* write end of the pipe will be closed in the parent process and the
* read end will be closed in the child process.
*/
-kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
- kwsysProcess_Pipe_Handle p[2]);
+kwsysEXPORT void kwsysProcess_SetPipeNative(
+ kwsysProcess* cp, int pipe, const kwsysProcess_Pipe_Handle p[2]);
/**
* Get/Set a possibly platform-specific option. Possible options are:
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index f65690b..cc45529 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -152,10 +152,11 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
static void kwsysProcessDestroy(kwsysProcess* cp);
static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+ const double* userTimeout,
kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
+ const double* userTimeout,
kwsysProcessTimeNative* timeoutLength,
int zeroIsExpired);
static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
@@ -431,8 +432,8 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
char const* const* c = command;
kwsysProcess_ptrdiff_t n = 0;
kwsysProcess_ptrdiff_t i = 0;
- while (*c++)
- ;
+ while (*c++) {
+ }
n = c - command - 1;
newCommands[cp->NumberOfCommands] =
(char**)malloc((size_t)(n + 1) * sizeof(char*));
@@ -571,7 +572,7 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared)
}
}
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, const int p[2])
{
int* pPipeNative = 0;
@@ -684,7 +685,8 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
if (!cp) {
return "Process management structure could not be allocated";
- } else if (cp->State == kwsysProcess_State_Error) {
+ }
+ if (cp->State == kwsysProcess_State_Error) {
return cp->ErrorMessage;
}
return "Success";
@@ -694,7 +696,8 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
{
if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) {
return "GetExceptionString called with NULL process management structure";
- } else if (cp->State == kwsysProcess_State_Exception) {
+ }
+ if (cp->State == kwsysProcess_State_Exception) {
return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString;
}
return "No exception";
@@ -786,8 +789,8 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Some platforms specify that the chdir call may be
interrupted. Repeat the call until it finishes. */
- while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR))
- ;
+ while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR)) {
+ }
if (r < 0) {
kwsysProcessCleanup(cp, 1);
return;
@@ -1013,8 +1016,8 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if (cp->RealWorkingDirectory) {
/* Some platforms specify that the chdir call may be
interrupted. Repeat the call until it finishes. */
- while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
- ;
+ while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+ }
free(cp->RealWorkingDirectory);
cp->RealWorkingDirectory = 0;
}
@@ -1099,22 +1102,22 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
if (wd.PipeId) {
/* Data are ready on a pipe. */
return wd.PipeId;
- } else if (wd.Expired) {
+ }
+ if (wd.Expired) {
/* A timeout has expired. */
if (wd.User) {
/* The user timeout has expired. It has no time left. */
return kwsysProcess_Pipe_Timeout;
- } else {
- /* The process timeout has expired. Kill the children now. */
- kwsysProcess_Kill(cp);
- cp->Killed = 0;
- cp->TimeoutExpired = 1;
- return kwsysProcess_Pipe_None;
}
- } else {
- /* No pipes are left open. */
+
+ /* The process timeout has expired. Kill the children now. */
+ kwsysProcess_Kill(cp);
+ cp->Killed = 0;
+ cp->TimeoutExpired = 1;
return kwsysProcess_Pipe_None;
}
+ /* No pipes are left open. */
+ return kwsysProcess_Pipe_None;
}
static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
@@ -1144,8 +1147,8 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
read until the operation is not interrupted. */
while (((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
KWSYSPE_PIPE_BUFFER_SIZE)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (n > 0) {
/* We have data on this pipe. */
if (i == KWSYSPE_PIPE_SIGNAL) {
@@ -1183,7 +1186,7 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
/* Make sure the set is empty (it should always be empty here
anyway). */
- FD_ZERO(&cp->PipeSet);
+ FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
/* Setup a timeout if required. */
if (wd->TimeoutTime.tv_sec < 0) {
@@ -1218,15 +1221,16 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
/* Run select to block until data are available. Repeat call
until it is not interrupted. */
while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Check result of select. */
if (numReady == 0) {
/* Select's timeout expired. */
wd->Expired = 1;
return 1;
- } else if (numReady < 0) {
+ }
+ if (numReady < 0) {
/* Select returned an error. Leave the error description in the
pipe buffer. */
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
@@ -1366,11 +1370,13 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited;
cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[prPipe].ExitValue =
+ // NOLINTNEXTLINE(google-readability-casting)
(int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode);
} else if (WIFSIGNALED(cp->ProcessResults[prPipe].ExitCode)) {
/* The child received an unhandled signal. */
cp->ProcessResults[prPipe].State = kwsysProcess_State_Exception;
kwsysProcessSetExitExceptionByIndex(
+ // NOLINTNEXTLINE(google-readability-casting)
cp, (int)WTERMSIG(cp->ProcessResults[prPipe].ExitCode), prPipe);
} else {
/* Error getting the child return code. */
@@ -1449,8 +1455,8 @@ void kwsysProcess_Kill(kwsysProcess* cp)
/* Reap the child. Keep trying until the call is not
interrupted. */
- while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR))
- ;
+ while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR)) {
+ }
}
}
@@ -1501,7 +1507,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->PipesLeft = 0;
cp->CommandsLeft = 0;
#if KWSYSPE_USE_SELECT
- FD_ZERO(&cp->PipeSet);
+ FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
#endif
cp->State = kwsysProcess_State_Starting;
cp->Killed = 0;
@@ -1590,16 +1596,16 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
/* Reap the child. Keep trying until the call is not
interrupted. */
while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
}
}
/* Restore the working directory. */
if (cp->RealWorkingDirectory) {
- while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
- ;
+ while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+ }
}
}
@@ -1635,8 +1641,8 @@ static void kwsysProcessCleanupDescriptor(int* pfd)
if (pfd && *pfd > 2) {
/* Keep trying to close until it is not interrupted by a
* signal. */
- while ((close(*pfd) < 0) && (errno == EINTR))
- ;
+ while ((close(*pfd) < 0) && (errno == EINTR)) {
+ }
*pfd = -1;
}
}
@@ -1661,8 +1667,8 @@ static void kwsysProcessClosePipes(kwsysProcess* cp)
read until the operation is not interrupted. */
while ((read(cp->PipeReadEnds[i], cp->PipeBuffer,
KWSYSPE_PIPE_BUFFER_SIZE) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
#endif
@@ -1689,7 +1695,8 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
kwsysProcessCreateInformation* si)
{
- sigset_t mask, old_mask;
+ sigset_t mask;
+ sigset_t old_mask;
int pgidPipe[2];
char tmp;
ssize_t readRes;
@@ -1817,8 +1824,8 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Make sure the child is in the process group before we proceed. This
avoids race conditions with calls to the kill function that we make for
signalling process groups. */
- while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0)
- ;
+ while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0) {
+ }
if (readRes < 0) {
sigprocmask(SIG_SETMASK, &old_mask, 0);
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
@@ -1846,8 +1853,8 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Keep trying to read until the operation is not interrupted. */
while (((n = read(si->ErrorPipe[0], cp->ErrorMessage + total,
(size_t)(KWSYSPE_PIPE_BUFFER_SIZE - total))) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (n > 0) {
total += n;
}
@@ -1872,7 +1879,8 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
int i;
/* Temporarily disable signals that access ForkPIDs. We don't want them to
read a reaped PID, and writes to ForkPIDs are not atomic. */
- sigset_t mask, old_mask;
+ sigset_t mask;
+ sigset_t old_mask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
@@ -1885,8 +1893,8 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
int result;
while (((result = waitpid(cp->ForkPIDs[i], &cp->CommandExitCodes[i],
WNOHANG)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (result > 0) {
/* This child has termianted. */
cp->ForkPIDs[i] = 0;
@@ -1959,7 +1967,8 @@ static int kwsysProcessSetupOutputPipeNative(int* p, int des[2])
/* Get the time at which either the process or user timeout will
expire. Returns 1 if the user timeout is first, and 0 otherwise. */
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+ const double* userTimeout,
kwsysProcessTime* timeoutTime)
{
/* The first time this is called, we need to calculate the time at
@@ -1991,35 +2000,33 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
/* Get the length of time before the given timeout time arrives.
Returns 1 if the time has already arrived, and 0 otherwise. */
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
+ const double* userTimeout,
kwsysProcessTimeNative* timeoutLength,
int zeroIsExpired)
{
if (timeoutTime->tv_sec < 0) {
/* No timeout time has been requested. */
return 0;
- } else {
- /* Calculate the remaining time. */
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime timeLeft =
- kwsysProcessTimeSubtract(*timeoutTime, currentTime);
- if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
- /* Caller has explicitly requested a zero timeout. */
- timeLeft.tv_sec = 0;
- timeLeft.tv_usec = 0;
- }
+ }
+ /* Calculate the remaining time. */
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime timeLeft =
+ kwsysProcessTimeSubtract(*timeoutTime, currentTime);
+ if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
+ /* Caller has explicitly requested a zero timeout. */
+ timeLeft.tv_sec = 0;
+ timeLeft.tv_usec = 0;
+ }
- if (timeLeft.tv_sec < 0 ||
- (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
- /* Timeout has already expired. */
- return 1;
- } else {
- /* There is some time left. */
- timeoutLength->tv_sec = timeLeft.tv_sec;
- timeoutLength->tv_usec = timeLeft.tv_usec;
- return 0;
- }
+ if (timeLeft.tv_sec < 0 ||
+ (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
+ /* Timeout has already expired. */
+ return 1;
}
+ /* There is some time left. */
+ timeoutLength->tv_sec = timeLeft.tv_sec;
+ timeoutLength->tv_usec = timeLeft.tv_usec;
+ return 0;
}
static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
@@ -2424,41 +2431,39 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
if (middle_pid < 0) {
/* Fork failed. Return as if we were not detaching. */
return middle_pid;
- } else if (middle_pid == 0) {
+ }
+ if (middle_pid == 0) {
/* This is the intermediate process. Create the real child. */
pid_t child_pid = fork();
if (child_pid == 0) {
/* This is the real child process. There is nothing to do here. */
return 0;
- } else {
- /* Use the error pipe to report the pid to the real parent. */
- while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR))
- ;
-
- /* Exit without cleanup. The parent holds all resources. */
- kwsysProcessExit();
- return 0; /* Never reached, but avoids SunCC warning. */
}
- } else {
- /* This is the original parent process. The intermediate
- process will use the error pipe to report the pid of the
- detached child. */
- pid_t child_pid;
- int status;
- while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR))
- ;
+ /* Use the error pipe to report the pid to the real parent. */
+ while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR)) {
+ }
- /* Wait for the intermediate process to exit and clean it up. */
- while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR))
- ;
- return child_pid;
+ /* Exit without cleanup. The parent holds all resources. */
+ kwsysProcessExit();
+ return 0; /* Never reached, but avoids SunCC warning. */
}
- } else {
- /* Not creating a detached process. Use normal fork. */
- return fork();
+ /* This is the original parent process. The intermediate
+ process will use the error pipe to report the pid of the
+ detached child. */
+ pid_t child_pid;
+ int status;
+ while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR)) {
+ }
+
+ /* Wait for the intermediate process to exit and clean it up. */
+ while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR)) {
+ }
+ return child_pid;
}
+ /* Not creating a detached process. Use normal fork. */
+ return fork();
}
#endif
@@ -2563,7 +2568,8 @@ static void kwsysProcessKill(pid_t process_id)
/* Make sure the process started and provided a valid header. */
if (ps && fscanf(ps, "%*[^\n]\n") != EOF) {
/* Look for processes whose parent is the process being killed. */
- int pid, ppid;
+ int pid;
+ int ppid;
while (fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2) {
if (ppid == process_id) {
/* Recursively kill this child and its children. */
@@ -2725,8 +2731,8 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
sigemptyset(&newSigAction.sa_mask);
while ((sigaction(SIGCHLD, &newSigAction,
&kwsysProcessesOldSigChldAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Install our handler for SIGINT / SIGTERM. Repeat call until
it is not interrupted. */
@@ -2734,15 +2740,15 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
sigaddset(&newSigAction.sa_mask, SIGTERM);
while ((sigaction(SIGINT, &newSigAction,
&kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
sigemptyset(&newSigAction.sa_mask);
sigaddset(&newSigAction.sa_mask, SIGINT);
while ((sigaction(SIGTERM, &newSigAction,
&kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
}
@@ -2773,14 +2779,14 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
/* Restore the signal handlers. Repeat call until it is not
interrupted. */
while ((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
while ((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
while ((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Free the table of process pointers since it is now empty.
This is safe because the signal handler has been removed. */
@@ -2806,7 +2812,10 @@ static void kwsysProcessesSignalHandler(int signum
#endif
)
{
- int i, j, procStatus, old_errno = errno;
+ int i;
+ int j;
+ int procStatus;
+ int old_errno = errno;
#if KWSYSPE_USE_SIGINFO
(void)info;
(void)ucontext;
@@ -2863,8 +2872,8 @@ static void kwsysProcessesSignalHandler(int signum
memset(&defSigAction, 0, sizeof(defSigAction));
defSigAction.sa_handler = SIG_DFL;
sigemptyset(&defSigAction.sa_mask);
- while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR))
- ;
+ while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR)) {
+ }
/* Unmask the signal. */
sigemptyset(&unblockSet);
sigaddset(&unblockSet, signum);
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 68c5218..56bbd20 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -761,7 +761,7 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
}
}
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, const HANDLE p[2])
{
HANDLE* pPipeNative = 0;
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index d43cc6f..dbfd2fd 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -22,7 +22,7 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t;
typedef int kwsysSystem_ptrdiff_t;
#endif
-static int kwsysSystem__AppendByte(char* local, char** begin, char** end,
+static int kwsysSystem__AppendByte(const char* local, char** begin, char** end,
int* size, char c)
{
/* Allocate space for the character. */
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 6ec6e48..ba9fa67 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -132,7 +132,7 @@ typedef int siginfo_t;
# endif
# endif
# if defined(KWSYS_CXX_HAS_RLIMIT64)
-typedef struct rlimit64 ResourceLimitType;
+using ResourceLimitType = struct rlimit64;
# define GetResourceLimit getrlimit64
# else
typedef struct rlimit ResourceLimitType;
@@ -204,7 +204,8 @@ typedef struct rlimit ResourceLimitType;
# define USE_ASM_INSTRUCTIONS 0
#endif
-#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__)
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__) && \
+ !defined(_M_ARM64)
# include <intrin.h>
# define USE_CPUID_INTRINSICS 1
#else
@@ -303,34 +304,34 @@ T min(T a, T b)
}
extern "C" {
-typedef void (*SigAction)(int, siginfo_t*, void*);
+using SigAction = void (*)(int, siginfo_t*, void*);
}
// Define SystemInformationImplementation class
-typedef void (*DELAY_FUNC)(unsigned int uiMS);
+using DELAY_FUNC = void (*)(unsigned int);
class SystemInformationImplementation
{
public:
- typedef SystemInformation::LongLong LongLong;
+ using LongLong = SystemInformation::LongLong;
SystemInformationImplementation();
- ~SystemInformationImplementation();
+ ~SystemInformationImplementation() = default;
- const char* GetVendorString();
+ const char* GetVendorString() const;
const char* GetVendorID();
- std::string GetTypeID();
- std::string GetFamilyID();
- std::string GetModelID();
- std::string GetModelName();
- std::string GetSteppingCode();
- const char* GetExtendedProcessorName();
- const char* GetProcessorSerialNumber();
- int GetProcessorCacheSize();
- unsigned int GetLogicalProcessorsPerPhysical();
- float GetProcessorClockFrequency();
- int GetProcessorAPICID();
- int GetProcessorCacheXSize(long int);
- bool DoesCPUSupportFeature(long int);
+ std::string GetTypeID() const;
+ std::string GetFamilyID() const;
+ std::string GetModelID() const;
+ std::string GetModelName() const;
+ std::string GetSteppingCode() const;
+ const char* GetExtendedProcessorName() const;
+ const char* GetProcessorSerialNumber() const;
+ int GetProcessorCacheSize() const;
+ unsigned int GetLogicalProcessorsPerPhysical() const;
+ float GetProcessorClockFrequency() const;
+ int GetProcessorAPICID() const;
+ int GetProcessorCacheXSize(long int) const;
+ bool DoesCPUSupportFeature(long int) const;
const char* GetOSName();
const char* GetHostname();
@@ -339,24 +340,24 @@ public:
const char* GetOSVersion();
const char* GetOSPlatform();
- bool Is64Bits();
+ bool Is64Bits() const;
- unsigned int GetNumberOfLogicalCPU(); // per physical cpu
- unsigned int GetNumberOfPhysicalCPU();
+ unsigned int GetNumberOfLogicalCPU() const; // per physical cpu
+ unsigned int GetNumberOfPhysicalCPU() const;
bool DoesCPUSupportCPUID();
// Retrieve memory information in MiB.
- size_t GetTotalVirtualMemory();
- size_t GetAvailableVirtualMemory();
- size_t GetTotalPhysicalMemory();
- size_t GetAvailablePhysicalMemory();
+ size_t GetTotalVirtualMemory() const;
+ size_t GetAvailableVirtualMemory() const;
+ size_t GetTotalPhysicalMemory() const;
+ size_t GetAvailablePhysicalMemory() const;
LongLong GetProcessId();
// Retrieve memory information in KiB.
LongLong GetHostMemoryTotal();
- LongLong GetHostMemoryAvailable(const char* envVarName);
+ LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName);
LongLong GetHostMemoryUsed();
LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName,
@@ -377,60 +378,103 @@ public:
void RunMemoryCheck();
public:
- typedef struct tagID
+ using ID = struct tagID
+
{
+
int Type;
+
int Family;
+
int Model;
+
int Revision;
+
int ExtendedFamily;
+
int ExtendedModel;
+
std::string ProcessorName;
+
std::string Vendor;
+
std::string SerialNumber;
+
std::string ModelName;
- } ID;
+ };
+
+ using CPUPowerManagement = struct tagCPUPowerManagement
- typedef struct tagCPUPowerManagement
{
+
bool HasVoltageID;
+
bool HasFrequencyID;
+
bool HasTempSenseDiode;
- } CPUPowerManagement;
+ };
+
+ using CPUExtendedFeatures = struct tagCPUExtendedFeatures
- typedef struct tagCPUExtendedFeatures
{
+
bool Has3DNow;
+
bool Has3DNowPlus;
+
bool SupportsMP;
+
bool HasMMXPlus;
+
bool HasSSEMMX;
+
unsigned int LogicalProcessorsPerPhysical;
+
int APIC_ID;
+
CPUPowerManagement PowerManagement;
- } CPUExtendedFeatures;
+ };
+
+ using CPUFeatures = struct CPUtagFeatures
- typedef struct CPUtagFeatures
{
+
bool HasFPU;
+
bool HasTSC;
+
bool HasMMX;
+
bool HasSSE;
+
bool HasSSEFP;
+
bool HasSSE2;
+
bool HasIA64;
+
bool HasAPIC;
+
bool HasCMOV;
+
bool HasMTRR;
+
bool HasACPI;
+
bool HasSerial;
+
bool HasThermal;
+
int CPUSpeed;
+
int L1CacheSize;
+
int L2CacheSize;
+
int L3CacheSize;
+
CPUExtendedFeatures ExtendedFeatures;
- } CPUFeatures;
+ };
enum Manufacturer
{
@@ -476,7 +520,7 @@ protected:
void CPUCountWindows(); // For windows
unsigned char GetAPICId(); // For windows
- bool IsSMTSupported();
+ bool IsSMTSupported() const;
static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
@@ -885,7 +929,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines)
*pBuf = '\0';
pBuf += 1;
}
- lines.push_back(buf);
+ lines.emplace_back(buf);
++nRead;
}
if (ferror(file)) {
@@ -899,7 +943,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines)
int LoadLines(const char* fileName, std::vector<std::string>& lines)
{
FILE* file = fopen(fileName, "r");
- if (file == 0) {
+ if (file == nullptr) {
return 0;
}
int nRead = LoadLines(file, lines);
@@ -1324,7 +1368,7 @@ std::string SymbolProperties::GetFileName(const std::string& path) const
if (!this->ReportPath) {
size_t at = file.rfind("/");
if (at != std::string::npos) {
- file = file.substr(at + 1);
+ file.erase(0, at + 1);
}
}
return file;
@@ -1464,10 +1508,6 @@ SystemInformationImplementation::SystemInformationImplementation()
this->OSIs64Bit = (sizeof(void*) == 8);
}
-SystemInformationImplementation::~SystemInformationImplementation()
-{
-}
-
void SystemInformationImplementation::RunCPUCheck()
{
#ifdef _WIN32
@@ -1564,7 +1604,7 @@ void SystemInformationImplementation::RunMemoryCheck()
}
/** Get the vendor string */
-const char* SystemInformationImplementation::GetVendorString()
+const char* SystemInformationImplementation::GetVendorString() const
{
return this->ChipID.Vendor.c_str();
}
@@ -1760,7 +1800,7 @@ const char* SystemInformationImplementation::GetVendorID()
}
/** Return the type ID of the CPU */
-std::string SystemInformationImplementation::GetTypeID()
+std::string SystemInformationImplementation::GetTypeID() const
{
std::ostringstream str;
str << this->ChipID.Type;
@@ -1768,7 +1808,7 @@ std::string SystemInformationImplementation::GetTypeID()
}
/** Return the family of the CPU present */
-std::string SystemInformationImplementation::GetFamilyID()
+std::string SystemInformationImplementation::GetFamilyID() const
{
std::ostringstream str;
str << this->ChipID.Family;
@@ -1776,7 +1816,7 @@ std::string SystemInformationImplementation::GetFamilyID()
}
// Return the model of CPU present */
-std::string SystemInformationImplementation::GetModelID()
+std::string SystemInformationImplementation::GetModelID() const
{
std::ostringstream str;
str << this->ChipID.Model;
@@ -1784,13 +1824,13 @@ std::string SystemInformationImplementation::GetModelID()
}
// Return the model name of CPU present */
-std::string SystemInformationImplementation::GetModelName()
+std::string SystemInformationImplementation::GetModelName() const
{
return this->ChipID.ModelName;
}
/** Return the stepping code of the CPU present. */
-std::string SystemInformationImplementation::GetSteppingCode()
+std::string SystemInformationImplementation::GetSteppingCode() const
{
std::ostringstream str;
str << this->ChipID.Revision;
@@ -1798,44 +1838,46 @@ std::string SystemInformationImplementation::GetSteppingCode()
}
/** Return the stepping code of the CPU present. */
-const char* SystemInformationImplementation::GetExtendedProcessorName()
+const char* SystemInformationImplementation::GetExtendedProcessorName() const
{
return this->ChipID.ProcessorName.c_str();
}
/** Return the serial number of the processor
* in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */
-const char* SystemInformationImplementation::GetProcessorSerialNumber()
+const char* SystemInformationImplementation::GetProcessorSerialNumber() const
{
return this->ChipID.SerialNumber.c_str();
}
/** Return the logical processors per physical */
unsigned int SystemInformationImplementation::GetLogicalProcessorsPerPhysical()
+ const
{
return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical;
}
/** Return the processor clock frequency. */
-float SystemInformationImplementation::GetProcessorClockFrequency()
+float SystemInformationImplementation::GetProcessorClockFrequency() const
{
return this->CPUSpeedInMHz;
}
/** Return the APIC ID. */
-int SystemInformationImplementation::GetProcessorAPICID()
+int SystemInformationImplementation::GetProcessorAPICID() const
{
return this->Features.ExtendedFeatures.APIC_ID;
}
/** Return the L1 cache size. */
-int SystemInformationImplementation::GetProcessorCacheSize()
+int SystemInformationImplementation::GetProcessorCacheSize() const
{
return this->Features.L1CacheSize;
}
/** Return the chosen cache size. */
-int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
+int SystemInformationImplementation::GetProcessorCacheXSize(
+ long int dwCacheID) const
{
switch (dwCacheID) {
case SystemInformation::CPU_FEATURE_L1CACHE:
@@ -1848,7 +1890,8 @@ int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
return -1;
}
-bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature)
+bool SystemInformationImplementation::DoesCPUSupportFeature(
+ long int dwFeature) const
{
bool bHasFeature = false;
@@ -2128,7 +2171,7 @@ void SystemInformationImplementation::FindManufacturer(
this->ChipManufacturer = HP; // Hewlett-Packard
else if (this->ChipID.Vendor == "Motorola")
this->ChipManufacturer = Motorola; // Motorola Microelectronics
- else if (family.substr(0, 7) == "PA-RISC")
+ else if (family.compare(0, 7, "PA-RISC") == 0)
this->ChipManufacturer = HP; // Hewlett-Packard
else
this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer
@@ -2843,7 +2886,7 @@ static void SystemInformationStripLeadingSpace(std::string& str)
// post-process the name.
std::string::size_type pos = str.find_first_not_of(" ");
if (pos != std::string::npos) {
- str = str.substr(pos);
+ str.erase(0, pos);
}
}
#endif
@@ -3358,7 +3401,9 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
return this->ExtractValueFromCpuInfoFile(buffer, word, pos2);
}
}
- return buffer.substr(pos + 2, pos2 - pos - 2);
+ buffer.erase(0, pos + 2);
+ buffer.resize(pos2 - pos - 2);
+ return buffer;
}
}
this->CurrentPositionInFile = std::string::npos;
@@ -3409,7 +3454,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// We want to record the total number of cores in this->NumberOfPhysicalCPU
// (checking only the first proc)
std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores");
- unsigned int NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
+ auto NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u);
this->NumberOfPhysicalCPU =
NumberOfCoresPerSocket * (unsigned int)NumberOfSockets;
@@ -3441,7 +3486,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// Linux Sparc: CPU speed is in Hz and encoded in hexadecimal
CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "Cpu0ClkTck");
this->CPUSpeedInMHz =
- static_cast<float>(strtoull(CPUSpeed.c_str(), 0, 16)) / 1000000.0f;
+ static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 16)) / 1000000.0f;
}
#endif
@@ -3502,13 +3547,12 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
cachename.push_back("D-cache"); // e.g. PA-RISC
this->Features.L1CacheSize = 0;
- for (size_t index = 0; index < cachename.size(); index++) {
- std::string cacheSize =
- this->ExtractValueFromCpuInfoFile(buffer, cachename[index]);
+ for (auto& index : cachename) {
+ std::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer, index);
if (!cacheSize.empty()) {
pos = cacheSize.find(" KB");
if (pos != std::string::npos) {
- cacheSize = cacheSize.substr(0, pos);
+ cacheSize.resize(pos);
}
this->Features.L1CacheSize += atoi(cacheSize.c_str());
}
@@ -4249,24 +4293,24 @@ bool SystemInformationImplementation::QueryMemory()
}
/** */
-size_t SystemInformationImplementation::GetTotalVirtualMemory()
+size_t SystemInformationImplementation::GetTotalVirtualMemory() const
{
return this->TotalVirtualMemory;
}
/** */
-size_t SystemInformationImplementation::GetAvailableVirtualMemory()
+size_t SystemInformationImplementation::GetAvailableVirtualMemory() const
{
return this->AvailableVirtualMemory;
}
-size_t SystemInformationImplementation::GetTotalPhysicalMemory()
+size_t SystemInformationImplementation::GetTotalPhysicalMemory() const
{
return this->TotalPhysicalMemory;
}
/** */
-size_t SystemInformationImplementation::GetAvailablePhysicalMemory()
+size_t SystemInformationImplementation::GetAvailablePhysicalMemory() const
{
return this->AvailablePhysicalMemory;
}
@@ -4279,9 +4323,15 @@ SystemInformationImplementation::GetCyclesDifference(DELAY_FUNC DelayFunction,
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
unsigned __int64 stamp1, stamp2;
+# ifdef _M_ARM64
+ stamp1 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+ DelayFunction(uiParameter);
+ stamp2 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+# else
stamp1 = __rdtsc();
DelayFunction(uiParameter);
stamp2 = __rdtsc();
+# endif
return stamp2 - stamp1;
#elif USE_ASM_INSTRUCTIONS
@@ -4350,7 +4400,7 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
}
/** Works only for windows */
-bool SystemInformationImplementation::IsSMTSupported()
+bool SystemInformationImplementation::IsSMTSupported() const
{
return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1;
}
@@ -4432,13 +4482,13 @@ void SystemInformationImplementation::CPUCountWindows()
}
/** Return the number of logical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU() const
{
return this->NumberOfLogicalCPU;
}
/** Return the number of physical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU() const
{
return this->NumberOfPhysicalCPU;
}
@@ -4733,14 +4783,15 @@ std::string SystemInformationImplementation::ParseValueFromKStat(
}
pos = command.find(' ', pos + 1);
}
- args_string.push_back(command.substr(start + 1, command.size() - start - 1));
+ command.erase(0, start + 1);
+ args_string.push_back(command);
std::vector<const char*> args;
args.reserve(3 + args_string.size());
args.push_back("kstat");
args.push_back("-p");
- for (size_t i = 0; i < args_string.size(); ++i) {
- args.push_back(args_string[i].c_str());
+ for (auto& i : args_string) {
+ args.push_back(i.c_str());
}
args.push_back(nullptr);
@@ -4922,7 +4973,9 @@ bool SystemInformationImplementation::QueryQNXMemory()
while (buffer[pos] == ' ')
pos++;
- this->TotalPhysicalMemory = atoi(buffer.substr(pos, pos2 - pos).c_str());
+ buffer.erase(0, pos);
+ buffer.resize(pos2);
+ this->TotalPhysicalMemory = atoi(buffer.c_str());
return true;
#endif
return false;
@@ -5459,7 +5512,7 @@ void SystemInformationImplementation::TrimNewline(std::string& output)
}
/** Return true if the machine is 64 bits */
-bool SystemInformationImplementation::Is64Bits()
+bool SystemInformationImplementation::Is64Bits() const
{
return this->OSIs64Bit;
}
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index d27081b..3a6ceec 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -123,9 +123,9 @@ extern char** environ;
#define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)"
#define VTK_URL_REGEX \
- "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/" \
+ "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]*)(:([0-9]+))?/" \
"(.+)?"
-
+#define VTK_URL_BYTE_REGEX "%[0-9a-fA-F][0-9a-fA-F]"
#ifdef _MSC_VER
# include <sys/utime.h>
#else
@@ -221,11 +221,17 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
#ifdef KWSYS_WINDOWS_DIRS
# include <wctype.h>
+# ifdef _MSC_VER
+typedef KWSYS_NAMESPACE::SystemTools::mode_t mode_t;
+# endif
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
{
- return _wmkdir(
- KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+ int ret =
+ _wmkdir(KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+ if (ret == 0 && mode)
+ KWSYS_NAMESPACE::SystemTools::SetPermissions(dir, *mode);
+ return ret;
}
inline int Rmdir(const std::string& dir)
{
@@ -295,9 +301,9 @@ inline void Realpath(const std::string& path, std::string& resolved_path,
# include <fcntl.h>
# include <unistd.h>
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
{
- return mkdir(dir.c_str(), 00777);
+ return mkdir(dir.c_str(), mode ? *mode : 00777);
}
inline int Rmdir(const std::string& dir)
{
@@ -350,7 +356,7 @@ extern int putenv(char* __string) __THROW;
namespace KWSYS_NAMESPACE {
-double SystemTools::GetTime(void)
+double SystemTools::GetTime()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
FILETIME ft;
@@ -368,7 +374,7 @@ double SystemTools::GetTime(void)
#if defined(_WIN32)
typedef wchar_t envchar;
#else
-typedef char envchar;
+using envchar = char;
#endif
/* Order by environment key only (VAR from VAR=VALUE). */
@@ -421,7 +427,7 @@ public:
const envchar* Release(const envchar* env)
{
const envchar* old = nullptr;
- iterator i = this->find(env);
+ auto i = this->find(env);
if (i != this->end()) {
old = *i;
this->erase(i);
@@ -452,7 +458,7 @@ struct SystemToolsPathCaseCmp
class SystemToolsStatic
{
public:
- typedef std::map<std::string, std::string> StringMap;
+ using StringMap = std::map<std::string, std::string>;
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
/**
* Path translation table from dir to refdir
@@ -488,10 +494,13 @@ public:
*/
static std::string FindName(
const std::string& name,
- const std::vector<std::string>& path = std::vector<std::string>(),
+ const std::vector<std::string>& userPaths = std::vector<std::string>(),
bool no_system_path = false);
};
+// Do NOT initialize. Default initialization to zero is necessary.
+static SystemToolsStatic* SystemToolsStatics;
+
#ifdef _WIN32
std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
{
@@ -566,7 +575,7 @@ std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p)
{
// Check to see if actual case has already been called
// for this path, and the result is stored in the PathCaseMap
- auto& pcm = SystemTools::Statics->PathCaseMap;
+ auto& pcm = SystemToolsStatics->PathCaseMap;
{
auto itr = pcm.find(p);
if (itr != pcm.end()) {
@@ -613,8 +622,7 @@ void SystemTools::GetPath(std::vector<std::string>& path, const char* env)
done = true;
}
}
- for (std::vector<std::string>::iterator i = path.begin() + old_size;
- i != path.end(); ++i) {
+ for (auto i = path.begin() + old_size; i != path.end(); ++i) {
SystemTools::ConvertToUnixSlashes(*i);
}
}
@@ -624,7 +632,7 @@ const char* SystemToolsStatic::GetEnvBuffered(const char* key)
{
std::string env;
if (SystemTools::GetEnv(key, env)) {
- std::string& menv = SystemTools::Statics->EnvMap[key];
+ std::string& menv = SystemToolsStatics->EnvMap[key];
if (menv != env) {
menv = std::move(env);
}
@@ -913,16 +921,17 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
std::string::size_type pos = 0;
std::string topdir;
while ((pos = dir.find('/', pos)) != std::string::npos) {
- topdir = dir.substr(0, pos);
+ // all underlying functions use C strings, so temporarily
+ // end the string here
+ dir[pos] = '\0';
- if (Mkdir(topdir) == 0 && mode != nullptr) {
- SystemTools::SetPermissions(topdir, *mode);
- }
+ Mkdir(dir, mode);
+ dir[pos] = '/';
++pos;
}
topdir = dir;
- if (Mkdir(topdir) != 0) {
+ if (Mkdir(topdir, mode) != 0) {
// There is a bug in the Borland Run time library which makes MKDIR
// return EACCES when it should return EEXISTS
// if it is some other error besides directory exists
@@ -934,8 +943,6 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
) {
return false;
}
- } else if (mode != nullptr) {
- SystemTools::SetPermissions(topdir, *mode);
}
return true;
@@ -1011,38 +1018,40 @@ void SystemToolsStatic::ReplaceString(std::string& source, const char* replace,
# define KWSYS_ST_KEY_WOW64_64KEY 0x0100
# endif
-static bool SystemToolsParseRegistryKey(const std::string& key,
- HKEY& primaryKey, std::string& second,
- std::string& valuename)
+static bool hasPrefix(const std::string& s, const char* pattern,
+ std::string::size_type spos)
{
- std::string primary = key;
+ size_t plen = strlen(pattern);
+ if (spos != plen)
+ return false;
+ return s.compare(0, plen, pattern) == 0;
+}
- size_t start = primary.find('\\');
+static bool SystemToolsParseRegistryKey(const std::string& key,
+ HKEY& primaryKey, std::wstring& second,
+ std::string* valuename)
+{
+ size_t start = key.find('\\');
if (start == std::string::npos) {
return false;
}
- size_t valuenamepos = primary.find(';');
- if (valuenamepos != std::string::npos) {
- valuename = primary.substr(valuenamepos + 1);
+ size_t valuenamepos = key.find(';');
+ if (valuenamepos != std::string::npos && valuename) {
+ *valuename = key.substr(valuenamepos + 1);
}
- second = primary.substr(start + 1, valuenamepos - start - 1);
- primary = primary.substr(0, start);
+ second = Encoding::ToWide(key.substr(start + 1, valuenamepos - start - 1));
- if (primary == "HKEY_CURRENT_USER") {
+ if (hasPrefix(key, "HKEY_CURRENT_USER", start)) {
primaryKey = HKEY_CURRENT_USER;
- }
- if (primary == "HKEY_CURRENT_CONFIG") {
+ } else if (hasPrefix(key, "HKEY_CURRENT_CONFIG", start)) {
primaryKey = HKEY_CURRENT_CONFIG;
- }
- if (primary == "HKEY_CLASSES_ROOT") {
+ } else if (hasPrefix(key, "HKEY_CLASSES_ROOT", start)) {
primaryKey = HKEY_CLASSES_ROOT;
- }
- if (primary == "HKEY_LOCAL_MACHINE") {
+ } else if (hasPrefix(key, "HKEY_LOCAL_MACHINE", start)) {
primaryKey = HKEY_LOCAL_MACHINE;
- }
- if (primary == "HKEY_USERS") {
+ } else if (hasPrefix(key, "HKEY_USERS", start)) {
primaryKey = HKEY_USERS;
}
@@ -1074,14 +1083,13 @@ bool SystemTools::GetRegistrySubKeys(const std::string& key,
KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
- std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ std::wstring second;
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, nullptr)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1121,14 +1129,14 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value,
{
bool valueset = false;
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1175,16 +1183,16 @@ bool SystemTools::WriteRegistryValue(const std::string& key,
const std::string& value, KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
DWORD dwDummy;
wchar_t lpClass[] = L"";
- if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass,
+ if (RegCreateKeyExW(primaryKey, second.c_str(), 0, lpClass,
REG_OPTION_NON_VOLATILE,
SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr,
&hKey, &dwDummy) != ERROR_SUCCESS) {
@@ -1219,14 +1227,14 @@ bool SystemTools::WriteRegistryValue(const std::string&, const std::string&,
bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_WRITE, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1448,15 +1456,15 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
{
- auto itr = SystemTools::Statics->Cyg2Win32Map.find(path);
- if (itr != SystemTools::Statics->Cyg2Win32Map.end()) {
+ auto itr = SystemToolsStatics->Cyg2Win32Map.find(path);
+ if (itr != SystemToolsStatics->Cyg2Win32Map.end()) {
strncpy(win32_path, itr->second.c_str(), MAX_PATH);
} else {
if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) !=
0) {
win32_path[0] = 0;
}
- SystemTools::Statics->Cyg2Win32Map.insert(
+ SystemToolsStatics->Cyg2Win32Map.insert(
SystemToolsStatic::StringMap::value_type(path, win32_path));
}
return win32_path[0] != 0;
@@ -1858,7 +1866,7 @@ char* SystemTools::DuplicateString(const char* str)
// Return a cropped string
std::string SystemTools::CropString(const std::string& s, size_t max_len)
{
- if (!s.size() || max_len == 0 || max_len >= s.size()) {
+ if (s.empty() || max_len == 0 || max_len >= s.size()) {
return s;
}
@@ -1867,7 +1875,7 @@ std::string SystemTools::CropString(const std::string& s, size_t max_len)
size_t middle = max_len / 2;
- n += s.substr(0, middle);
+ n.assign(s, 0, middle);
n += s.substr(s.size() - (max_len - middle));
if (max_len > 2) {
@@ -1893,10 +1901,10 @@ std::vector<std::string> SystemTools::SplitString(const std::string& p,
}
if (isPath && path[0] == '/') {
path.erase(path.begin());
- paths.push_back("/");
+ paths.emplace_back("/");
}
std::string::size_type pos1 = 0;
- std::string::size_type pos2 = path.find(sep, pos1 + 1);
+ std::string::size_type pos2 = path.find(sep, pos1);
while (pos2 != std::string::npos) {
paths.push_back(path.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
@@ -2065,8 +2073,10 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
#ifdef HAVE_GETPWNAM
else if (pathCString[0] == '~') {
std::string::size_type idx = path.find_first_of("/\0");
- std::string user = path.substr(1, idx - 1);
- passwd* pw = getpwnam(user.c_str());
+ char oldch = path[idx];
+ path[idx] = '\0';
+ passwd* pw = getpwnam(path.c_str() + 1);
+ path[idx] = oldch;
if (pw) {
path.replace(0, idx, pw->pw_dir);
}
@@ -2797,7 +2807,7 @@ std::string SystemTools::FindProgram(const std::string& name,
for (std::string const& ext : extensions) {
tryPath = name;
tryPath += ext;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -2805,7 +2815,7 @@ std::string SystemTools::FindProgram(const std::string& name,
#endif
// now try just the name
- if (SystemTools::FileExists(name, true)) {
+ if (SystemTools::FileIsExecutable(name)) {
return SystemTools::CollapseFullPath(name);
}
// now construct the path
@@ -2835,7 +2845,7 @@ std::string SystemTools::FindProgram(const std::string& name,
tryPath = p;
tryPath += name;
tryPath += ext;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -2843,7 +2853,7 @@ std::string SystemTools::FindProgram(const std::string& name,
// now try it without them
tryPath = p;
tryPath += name;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -2998,6 +3008,15 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
}
}
+bool SystemTools::FileIsExecutable(const std::string& name)
+{
+#if defined(_WIN32)
+ return SystemTools::FileExists(name, true);
+#else
+ return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
+#endif
+}
+
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
@@ -3107,16 +3126,14 @@ int SystemTools::ChangeDirectory(const std::string& dir)
return Chdir(dir);
}
-std::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+std::string SystemTools::GetCurrentWorkingDirectory()
{
char buf[2048];
const char* cwd = Getcwd(buf, 2048);
std::string path;
if (cwd) {
path = cwd;
- }
- if (collapse) {
- return SystemTools::CollapseFullPath(path);
+ SystemTools::ConvertToUnixSlashes(path);
}
return path;
}
@@ -3132,17 +3149,17 @@ bool SystemTools::SplitProgramPath(const std::string& in_name,
std::string& dir, std::string& file, bool)
{
dir = in_name;
- file = "";
+ file.clear();
SystemTools::ConvertToUnixSlashes(dir);
if (!SystemTools::FileIsDirectory(dir)) {
std::string::size_type slashPos = dir.rfind("/");
if (slashPos != std::string::npos) {
file = dir.substr(slashPos + 1);
- dir = dir.substr(0, slashPos);
+ dir.resize(slashPos);
} else {
file = dir;
- dir = "";
+ dir.clear();
}
}
if (!(dir.empty()) && !SystemTools::FileIsDirectory(dir)) {
@@ -3164,7 +3181,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
failures.push_back(self);
SystemTools::ConvertToUnixSlashes(self);
self = SystemTools::FindProgram(self);
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
if (buildDir) {
std::string intdir = ".";
#ifdef CMAKE_INTDIR
@@ -3179,14 +3196,14 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
}
}
if (installPrefix) {
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
self = installPrefix;
self += "/bin/";
self += exeName;
}
}
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
std::ostringstream msg;
msg << "Can not find the command line program ";
@@ -3208,11 +3225,6 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
return true;
}
-std::string SystemTools::CollapseFullPath(const std::string& in_relative)
-{
- return SystemTools::CollapseFullPath(in_relative, nullptr);
-}
-
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
void SystemTools::AddTranslationPath(const std::string& a,
const std::string& b)
@@ -3237,7 +3249,7 @@ void SystemTools::AddTranslationPath(const std::string& a,
path_b += '/';
}
if (!(path_a == path_b)) {
- SystemTools::Statics->TranslationMap.insert(
+ SystemToolsStatics->TranslationMap.insert(
SystemToolsStatic::StringMap::value_type(std::move(path_a),
std::move(path_b)));
}
@@ -3267,9 +3279,9 @@ void SystemTools::CheckTranslationPath(std::string& path)
// In case a file was specified we still have to go through this:
// Now convert any path found in the table back to the one desired:
- for (auto const& pair : SystemTools::Statics->TranslationMap) {
+ for (auto const& pair : SystemToolsStatics->TranslationMap) {
// We need to check of the path is a substring of the other path
- if (path.find(pair.first) == 0) {
+ if (path.compare(0, pair.first.size(), pair.first) == 0) {
path = path.replace(0, pair.first.size(), pair.second);
}
}
@@ -3302,25 +3314,10 @@ static void SystemToolsAppendComponents(
}
}
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
- const char* in_base)
-{
- // Use the current working directory as a base path.
- char buf[2048];
- const char* res_in_base = in_base;
- if (!res_in_base) {
- if (const char* cwd = Getcwd(buf, 2048)) {
- res_in_base = cwd;
- } else {
- res_in_base = "";
- }
- }
-
- return SystemTools::CollapseFullPath(in_path, std::string(res_in_base));
-}
+namespace {
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
- const std::string& in_base)
+std::string CollapseFullPathImpl(std::string const& in_path,
+ std::string const* in_base)
{
// Collect the output path components.
std::vector<std::string> out_components;
@@ -3333,8 +3330,15 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
// If the input path is relative, start with a base path.
if (path_components[0].empty()) {
std::vector<std::string> base_components;
- // Use the given base path.
- SystemTools::SplitPath(in_base, base_components);
+
+ if (in_base) {
+ // Use the given base path.
+ SystemTools::SplitPath(*in_base, base_components);
+ } else {
+ // Use the current working directory as a base path.
+ std::string cwd = SystemTools::GetCurrentWorkingDirectory();
+ SystemTools::SplitPath(cwd, base_components);
+ }
// Append base path components to the output path.
out_components.push_back(base_components[0]);
@@ -3367,12 +3371,34 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
SystemTools::CheckTranslationPath(newPath);
#endif
#ifdef _WIN32
- newPath = SystemTools::Statics->GetActualCaseForPathCached(newPath);
+ newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath);
SystemTools::ConvertToUnixSlashes(newPath);
#endif
// Return the reconstructed path.
return newPath;
}
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path)
+{
+ return CollapseFullPathImpl(in_path, nullptr);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+ const char* in_base)
+{
+ if (!in_base) {
+ return CollapseFullPathImpl(in_path, nullptr);
+ }
+ std::string tmp_base = in_base;
+ return CollapseFullPathImpl(in_path, &tmp_base);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+ std::string const& in_base)
+{
+ return CollapseFullPathImpl(in_path, &in_base);
+}
// compute the relative path from here to there
std::string SystemTools::RelativePath(const std::string& local,
@@ -3541,7 +3567,7 @@ void SystemTools::SplitPath(const std::string& p,
// Expand home directory references if requested.
if (expand_home_dir && !root.empty() && root[0] == '~') {
std::string homedir;
- root = root.substr(0, root.size() - 1);
+ root.resize(root.size() - 1);
if (root.size() == 1) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!SystemTools::GetEnv("USERPROFILE", homedir))
@@ -3571,14 +3597,14 @@ void SystemTools::SplitPath(const std::string& p,
for (; *last; ++last) {
if (*last == '/' || *last == '\\') {
// End of a component. Save it.
- components.push_back(std::string(first, last));
+ components.emplace_back(first, last);
first = last + 1;
}
}
// Save the last component unless there were no components.
if (last != c) {
- components.push_back(std::string(first, last));
+ components.emplace_back(first, last);
}
}
@@ -3594,7 +3620,7 @@ std::string SystemTools::JoinPath(
// Construct result in a single string.
std::string result;
size_t len = 0;
- for (std::vector<std::string>::const_iterator i = first; i != last; ++i) {
+ for (auto i = first; i != last; ++i) {
len += 1 + i->size();
}
result.reserve(len);
@@ -3686,18 +3712,19 @@ std::string SystemTools::GetFilenamePath(const std::string& filename)
SystemTools::ConvertToUnixSlashes(fn);
std::string::size_type slash_pos = fn.rfind("/");
- if (slash_pos != std::string::npos) {
- std::string ret = fn.substr(0, slash_pos);
- if (ret.size() == 2 && ret[1] == ':') {
- return ret + '/';
- }
- if (ret.empty()) {
- return "/";
- }
- return ret;
- } else {
+ if (slash_pos == 0) {
+ return "/";
+ }
+ if (slash_pos == 2 && fn[1] == ':') {
+ // keep the / after a drive letter
+ fn.resize(3);
+ return fn;
+ }
+ if (slash_pos == std::string::npos) {
return "";
}
+ fn.resize(slash_pos);
+ return fn;
}
/**
@@ -3727,7 +3754,8 @@ std::string SystemTools::GetFilenameExtension(const std::string& filename)
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.find('.');
if (dot_pos != std::string::npos) {
- return name.substr(dot_pos);
+ name.erase(0, dot_pos);
+ return name;
} else {
return "";
}
@@ -3742,7 +3770,8 @@ std::string SystemTools::GetFilenameLastExtension(const std::string& filename)
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.rfind('.');
if (dot_pos != std::string::npos) {
- return name.substr(dot_pos);
+ name.erase(0, dot_pos);
+ return name;
} else {
return "";
}
@@ -3758,10 +3787,9 @@ std::string SystemTools::GetFilenameWithoutExtension(
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.find('.');
if (dot_pos != std::string::npos) {
- return name.substr(0, dot_pos);
- } else {
- return name;
+ name.resize(dot_pos);
}
+ return name;
}
/**
@@ -3775,10 +3803,9 @@ std::string SystemTools::GetFilenameWithoutLastExtension(
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.rfind('.');
if (dot_pos != std::string::npos) {
- return name.substr(0, dot_pos);
- } else {
- return name;
+ name.resize(dot_pos);
}
+ return name;
}
bool SystemTools::FileHasSignature(const char* filename, const char* signature,
@@ -3828,7 +3855,7 @@ SystemTools::FileTypeEnum SystemTools::DetectFileType(const char* filename,
// Allocate buffer and read bytes
- unsigned char* buffer = new unsigned char[length];
+ auto* buffer = new unsigned char[length];
size_t read_length = fread(buffer, 1, length, fp);
fclose(fp);
if (read_length == 0) {
@@ -4000,7 +4027,8 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
// if the path passed in has quotes around it, first remove the quotes
if (!path.empty() && path[0] == '"' && path.back() == '"') {
- tempPath = path.substr(1, path.length() - 2);
+ tempPath.resize(path.length() - 1);
+ tempPath.erase(0, 1);
}
std::wstring wtempPath = Encoding::ToWide(tempPath);
@@ -4219,8 +4247,8 @@ bool SystemTools::IsSubDirectory(const std::string& cSubdir,
if (subdir[expectedSlashPosition] != '/') {
return false;
}
- std::string s = subdir.substr(0, dir.size());
- return SystemTools::ComparePath(s, dir);
+ subdir.resize(dir.size());
+ return SystemTools::ComparePath(subdir, dir);
}
void SystemTools::Delay(unsigned int msec)
@@ -4516,7 +4544,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion()
bool SystemTools::ParseURLProtocol(const std::string& URL,
std::string& protocol,
- std::string& dataglom)
+ std::string& dataglom, bool decode)
{
// match 0 entire url
// match 1 protocol
@@ -4529,13 +4557,17 @@ bool SystemTools::ParseURLProtocol(const std::string& URL,
protocol = urlRe.match(1);
dataglom = urlRe.match(2);
+ if (decode) {
+ dataglom = DecodeURL(dataglom);
+ }
+
return true;
}
bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
std::string& username, std::string& password,
std::string& hostname, std::string& dataport,
- std::string& database)
+ std::string& database, bool decode)
{
kwsys::RegularExpression urlRe(VTK_URL_REGEX);
if (!urlRe.find(URL))
@@ -4559,13 +4591,37 @@ bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
dataport = urlRe.match(8);
database = urlRe.match(9);
+ if (decode) {
+ username = DecodeURL(username);
+ password = DecodeURL(password);
+ hostname = DecodeURL(hostname);
+ dataport = DecodeURL(dataport);
+ database = DecodeURL(database);
+ }
+
return true;
}
-// These must NOT be initialized. Default initialization to zero is
-// necessary.
+// ----------------------------------------------------------------------
+std::string SystemTools::DecodeURL(const std::string& url)
+{
+ kwsys::RegularExpression urlByteRe(VTK_URL_BYTE_REGEX);
+ std::string ret;
+ for (size_t i = 0; i < url.length(); i++) {
+ if (urlByteRe.find(url.substr(i, 3))) {
+ char bytes[] = { url[i + 1], url[i + 2], '\0' };
+ ret += static_cast<char>(strtoul(bytes, nullptr, 16));
+ i += 2;
+ } else {
+ ret += url[i];
+ }
+ }
+ return ret;
+}
+
+// ----------------------------------------------------------------------
+// Do NOT initialize. Default initialization to zero is necessary.
static unsigned int SystemToolsManagerCount;
-SystemToolsStatic* SystemTools::Statics;
// SystemToolsManager manages the SystemTools singleton.
// SystemToolsManager should be included in any translation unit
@@ -4608,7 +4664,7 @@ void SystemTools::ClassInitialize()
#endif
// Create statics singleton instance
- SystemTools::Statics = new SystemToolsStatic;
+ SystemToolsStatics = new SystemToolsStatic;
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
// Add some special translation paths for unix. These are not added
@@ -4658,7 +4714,7 @@ void SystemTools::ClassInitialize()
void SystemTools::ClassFinalize()
{
- delete SystemTools::Statics;
+ delete SystemToolsStatics;
}
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index c4ab9d4..cd7b728 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -411,11 +411,11 @@ public:
* (which defaults to the current working directory). The full path
* is returned.
*/
- static std::string CollapseFullPath(const std::string& in_relative);
- static std::string CollapseFullPath(const std::string& in_relative,
+ static std::string CollapseFullPath(std::string const& in_path);
+ static std::string CollapseFullPath(std::string const& in_path,
const char* in_base);
- static std::string CollapseFullPath(const std::string& in_relative,
- const std::string& in_base);
+ static std::string CollapseFullPath(std::string const& in_path,
+ std::string const& in_base);
/**
* Get the real path for a given path, removing all symlinks. In
@@ -677,6 +677,11 @@ public:
static bool FileIsDirectory(const std::string& name);
/**
+ * Return true if the file is an executable
+ */
+ static bool FileIsExecutable(const std::string& name);
+
+ /**
* Return true if the file is a symlink
*/
static bool FileIsSymlink(const std::string& name);
@@ -869,7 +874,7 @@ public:
/**
* Get current working directory CWD
*/
- static std::string GetCurrentWorkingDirectory(bool collapse = true);
+ static std::string GetCurrentWorkingDirectory();
/**
* Change directory to the directory specified
@@ -935,22 +940,32 @@ public:
* Parse a character string :
* protocol://dataglom
* and fill protocol as appropriate.
+ * decode the dataglom using DecodeURL if set to true.
* Return false if the URL does not have the required form, true otherwise.
*/
static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
- std::string& dataglom);
+ std::string& dataglom, bool decode = false);
/**
* Parse a string (a URL without protocol prefix) with the form:
* protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
* and fill protocol, username, password, hostname, dataport, and datapath
* when values are found.
+ * decode all string except the protocol using DecodeUrl if set to true.
* Return true if the string matches the format; false otherwise.
*/
static bool ParseURL(const std::string& URL, std::string& protocol,
std::string& username, std::string& password,
std::string& hostname, std::string& dataport,
- std::string& datapath);
+ std::string& datapath, bool decode = false);
+
+ /**
+ * Decode the percent-encoded string from an URL or an URI
+ * into their correct char values.
+ * Does not perform any other sort of validation.
+ * Return the decoded string
+ */
+ static std::string DecodeURL(const std::string& url);
private:
/**
@@ -971,7 +986,6 @@ private:
return &SystemToolsManagerInstance;
}
- static SystemToolsStatic* Statics;
friend class SystemToolsStatic;
friend class SystemToolsManager;
};
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index 28d3f68..89be4b8 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -1,185 +1,185 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
-SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
-SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
+set(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
+set(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
-MACRO(KWSYS_PLATFORM_TEST lang var description invert)
- IF(NOT DEFINED ${var}_COMPILED)
- MESSAGE(STATUS "${description}")
+macro(KWSYS_PLATFORM_TEST lang var description invert)
+ if(NOT DEFINED ${var}_COMPILED)
+ message(STATUS "${description}")
set(maybe_cxx_standard "")
if(CMAKE_VERSION VERSION_LESS 3.8 AND CMAKE_CXX_STANDARD)
set(maybe_cxx_standard "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
endif()
- TRY_COMPILE(${var}_COMPILED
+ try_compile(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}"
${maybe_cxx_standard}
OUTPUT_VARIABLE OUTPUT)
- IF(${var}_COMPILED)
- FILE(APPEND
+ if(${var}_COMPILED)
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
+ endif()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ message(STATUS "${description} - no")
+ else()
+ message(STATUS "${description} - yes")
+ endif()
+ else()
+ if(${var}_COMPILED)
+ message(STATUS "${description} - yes")
+ else()
+ message(STATUS "${description} - no")
+ endif()
+ endif()
+ endif()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ set(${var} 0)
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ if(${var}_COMPILED)
+ set(${var} 1)
+ else()
+ set(${var} 0)
+ endif()
+ endif()
+endmacro()
-MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
- IF(NOT DEFINED ${var})
- MESSAGE(STATUS "${description}")
- TRY_RUN(${var} ${var}_COMPILED
+macro(KWSYS_PLATFORM_TEST_RUN lang var description invert)
+ if(NOT DEFINED ${var})
+ message(STATUS "${description}")
+ try_run(${var} ${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
OUTPUT_VARIABLE OUTPUT)
# Note that ${var} will be a 0 return value on success.
- IF(${var}_COMPILED)
- IF(${var})
- FILE(APPEND
+ if(${var}_COMPILED)
+ if(${var})
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- ELSE()
- FILE(APPEND
+ endif()
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- SET(${var} -1 CACHE INTERNAL "${description} failed to compile.")
- ENDIF()
+ set(${var} -1 CACHE INTERNAL "${description} failed to compile.")
+ endif()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ENDIF()
- ENDIF()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ if(${var})
+ message(STATUS "${description} - yes")
+ else()
+ message(STATUS "${description} - no")
+ endif()
+ else()
+ message(STATUS "${description} - failed to compile")
+ endif()
+ else()
+ if(${var}_COMPILED)
+ if(${var})
+ message(STATUS "${description} - no")
+ else()
+ message(STATUS "${description} - yes")
+ endif()
+ else()
+ message(STATUS "${description} - failed to compile")
+ endif()
+ endif()
+ endif()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ if(${var})
+ set(${var} 1)
+ else()
+ set(${var} 0)
+ endif()
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ if(${var}_COMPILED)
+ if(${var})
+ set(${var} 0)
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ set(${var} 0)
+ endif()
+ endif()
+endmacro()
-MACRO(KWSYS_PLATFORM_C_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
-MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST_RUN var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
-MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
+macro(KWSYS_PLATFORM_CXX_TEST var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+ set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+ set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
+endmacro()
-MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
#-----------------------------------------------------------------------------
# KWSYS_PLATFORM_INFO_TEST(lang var description)
#
# Compile test named by ${var} and store INFO strings extracted from binary.
-MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
+macro(KWSYS_PLATFORM_INFO_TEST lang var description)
# We can implement this macro on CMake 2.6 and above.
- IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
- SET(${var} "")
- ELSE()
+ if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
+ set(${var} "")
+ else()
# Choose a location for the result binary.
- SET(KWSYS_PLATFORM_INFO_FILE
+ set(KWSYS_PLATFORM_INFO_FILE
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin)
# Compile the test binary.
- IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
- MESSAGE(STATUS "${description}")
- TRY_COMPILE(${var}_COMPILED
+ if(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
+ message(STATUS "${description}")
+ try_compile(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var}
@@ -188,29 +188,29 @@ MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
OUTPUT_VARIABLE OUTPUT
COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
)
- IF(${var}_COMPILED)
- FILE(APPEND
+ if(${var}_COMPILED)
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - compiled")
- ELSE()
- MESSAGE(STATUS "${description} - failed")
- ENDIF()
- ENDIF()
+ endif()
+ if(${var}_COMPILED)
+ message(STATUS "${description} - compiled")
+ else()
+ message(STATUS "${description} - failed")
+ endif()
+ endif()
# Parse info strings out of the compiled binary.
- IF(${var}_COMPILED)
- FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
- ELSE()
- SET(${var} "")
- ENDIF()
+ if(${var}_COMPILED)
+ file(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
+ else()
+ set(${var} "")
+ endif()
- SET(KWSYS_PLATFORM_INFO_FILE)
- ENDIF()
-ENDMACRO()
+ set(KWSYS_PLATFORM_INFO_FILE)
+ endif()
+endmacro()
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 1778a9b..79ebe1a 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -98,7 +98,7 @@ int testCommandLineArguments(int argc, char* argv[])
std::vector<std::string> stl_strings_argument;
std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
- typedef kwsys::CommandLineArguments argT;
+ using argT = kwsys::CommandLineArguments;
arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT,
&some_int_variable, "Set some random int variable");
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 64561b1..cbc3002 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -25,7 +25,7 @@ int testCommandLineArguments1(int argc, char* argv[])
std::string p;
int res = 0;
- typedef kwsys::CommandLineArguments argT;
+ using argT = kwsys::CommandLineArguments;
arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N");
arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M");
arg.AddBooleanArgument("-p", &p, "Argument P");
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 2421ac0..703ad4d 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -25,7 +25,7 @@ static std::string GetLibName(const char* lname, const char* subdir = nullptr)
{
// Construct proper name of lib
std::string slname;
- slname = EXECUTABLE_OUTPUT_PATH;
+ slname = RUNTIME_OUTPUT_DIRECTORY;
if (subdir) {
slname += "/";
slname += subdir;
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 988697b..d672aed 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -85,7 +85,7 @@ static int testRobustEncoding()
std::wstring wstr = kwsys::Encoding::ToWide(cstr);
wstr = kwsys::Encoding::ToWide(nullptr);
- if (wstr != L"") {
+ if (!wstr.empty()) {
const wchar_t* wcstr = wstr.c_str();
std::cout << "ToWide(NULL) returned";
for (size_t i = 0; i < wstr.size(); i++) {
@@ -95,7 +95,7 @@ static int testRobustEncoding()
ret++;
}
wstr = kwsys::Encoding::ToWide("");
- if (wstr != L"") {
+ if (!wstr.empty()) {
const wchar_t* wcstr = wstr.c_str();
std::cout << "ToWide(\"\") returned";
for (size_t i = 0; i < wstr.size(); i++) {
@@ -113,13 +113,13 @@ static int testRobustEncoding()
#endif
std::string str = kwsys::Encoding::ToNarrow(nullptr);
- if (str != "") {
+ if (!str.empty()) {
std::cout << "ToNarrow(NULL) returned " << str << std::endl;
ret++;
}
str = kwsys::Encoding::ToNarrow(L"");
- if (wstr != L"") {
+ if (!wstr.empty()) {
std::cout << "ToNarrow(\"\") returned " << str << std::endl;
ret++;
}
@@ -140,14 +140,13 @@ static int testWithNulls()
strings.push_back(std::string("k") + '\0' + '\0');
strings.push_back(std::string("\0\0\0\0", 4) + "lmn" +
std::string("\0\0\0\0", 4));
- for (std::vector<std::string>::iterator it = strings.begin();
- it != strings.end(); ++it) {
- std::wstring wstr = kwsys::Encoding::ToWide(*it);
+ for (auto& string : strings) {
+ std::wstring wstr = kwsys::Encoding::ToWide(string);
std::string str = kwsys::Encoding::ToNarrow(wstr);
- std::string s(*it);
+ std::string s(string);
std::replace(s.begin(), s.end(), '\0', ' ');
- std::cout << "'" << s << "' (" << it->size() << ")" << std::endl;
- if (str != *it) {
+ std::cout << "'" << s << "' (" << string.size() << ")" << std::endl;
+ if (str != string) {
std::replace(str.begin(), str.end(), '\0', ' ');
std::cout << "string with null was different: '" << str << "' ("
<< str.size() << ")" << std::endl;
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
index 4ed2f89..18cae7f 100644
--- a/Source/kwsys/testHashSTL.cxx
+++ b/Source/kwsys/testHashSTL.cxx
@@ -27,30 +27,30 @@ template class kwsys::hash_set<int>;
static bool test_hash_map()
{
- typedef kwsys::hash_map<const char*, int> mtype;
+ using mtype = kwsys::hash_map<const char*, int>;
mtype m;
const char* keys[] = { "hello", "world" };
m[keys[0]] = 1;
m.insert(mtype::value_type(keys[1], 2));
int sum = 0;
- for (mtype::iterator mi = m.begin(); mi != m.end(); ++mi) {
- std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
+ for (auto& mi : m) {
+ std::cout << "Found entry [" << mi.first << "," << mi.second << "]"
<< std::endl;
- sum += mi->second;
+ sum += mi.second;
}
return sum == 3;
}
static bool test_hash_set()
{
- typedef kwsys::hash_set<int> stype;
+ using stype = kwsys::hash_set<int>;
stype s;
s.insert(1);
s.insert(2);
int sum = 0;
- for (stype::iterator si = s.begin(); si != s.end(); ++si) {
- std::cout << "Found entry [" << *si << "]" << std::endl;
- sum += *si;
+ for (int si : s) {
+ std::cout << "Found entry [" << si << "]" << std::endl;
+ sum += si;
}
return sum == 3;
}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 39aaa23..5507dfb 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -631,7 +631,8 @@ int main(int argc, const char* argv[])
}
fprintf(stderr, "Invalid test number %d.\n", n);
return 1;
- } else if (n >= 1 && n <= 10) {
+ }
+ if (n >= 1 && n <= 10) {
/* This is the parent process for a requested test number. */
int states[10] = {
kwsysProcess_State_Exited, kwsysProcess_State_Exited,
@@ -709,7 +710,8 @@ int main(int argc, const char* argv[])
free(argv0);
#endif
return r;
- } else if (argc > 2 && strcmp(argv[1], "0") == 0) {
+ }
+ if (argc > 2 && strcmp(argv[1], "0") == 0) {
/* This is the special debugging test to run a given command
line. */
const char** cmd = argv + 2;
@@ -720,9 +722,8 @@ int main(int argc, const char* argv[])
int r =
runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0, 0, 0);
return r;
- } else {
- /* Improper usage. */
- fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
- return 1;
}
+ /* Improper usage. */
+ fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
+ return 1;
}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 3f6eeb8..8909b49 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -328,7 +328,14 @@ static bool CheckFileOperations()
}
// While we're at it, check proper TestFileAccess functionality.
- if (kwsys::SystemTools::TestFileAccess(testNewFile,
+ bool do_write_test = true;
+#if defined(__linux__)
+ // If we are running as root on linux ignore this check, as
+ // root can always write to files
+ do_write_test = (getuid() != 0);
+#endif
+ if (do_write_test &&
+ kwsys::SystemTools::TestFileAccess(testNewFile,
kwsys::TEST_FILE_WRITE)) {
std::cerr
<< "TestFileAccess incorrectly indicated that this is a writable file:"
@@ -721,8 +728,7 @@ static std::string StringVectorToString(const std::vector<std::string>& vec)
{
std::stringstream ss;
ss << "vector(";
- for (std::vector<std::string>::const_iterator i = vec.begin();
- i != vec.end(); ++i) {
+ for (auto i = vec.begin(); i != vec.end(); ++i) {
if (i != vec.begin()) {
ss << ", ";
}
@@ -743,16 +749,16 @@ static bool CheckGetPath()
const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
std::vector<std::string> originalPaths;
- originalPaths.push_back(registryPath);
+ originalPaths.emplace_back(registryPath);
std::vector<std::string> expectedPaths;
- expectedPaths.push_back(registryPath);
+ expectedPaths.emplace_back(registryPath);
#ifdef _WIN32
expectedPaths.push_back("C:/Somewhere/something");
expectedPaths.push_back("D:/Temp");
#else
- expectedPaths.push_back("/Somewhere/something");
- expectedPaths.push_back("/tmp");
+ expectedPaths.emplace_back("/Somewhere/something");
+ expectedPaths.emplace_back("/tmp");
#endif
bool res = true;
@@ -817,7 +823,7 @@ static bool CheckFind()
}
std::vector<std::string> searchPaths;
- searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
+ searchPaths.emplace_back(TEST_SYSTEMTOOLS_BINARY_DIR);
if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true)
.empty()) {
std::cerr << "Problem with FindFile without system paths for: "
@@ -1086,6 +1092,70 @@ static bool CheckCopyFileIfDifferent()
return ret;
}
+static bool CheckURLParsing()
+{
+ bool ret = true;
+ std::string url = "http://user:pw@hostname:42/full/url.com";
+
+ std::string protocol, username, password, hostname, dataport, database;
+ kwsys::SystemTools::ParseURL(url, protocol, username, password, hostname,
+ dataport, database);
+ if (protocol != "http" || username != "user" || password != "pw" ||
+ hostname != "hostname" || dataport != "42" ||
+ database != "full/url.com") {
+ std::cerr << "Incorrect URL parsing" << std::endl;
+ ret = false;
+ }
+
+ std::string uri =
+ "file://hostname/path/to/"
+ "a%20file%20with%20str%C3%A0ng%C3%A8%20ch%40r%20and%20s%C2%B5aces";
+ kwsys::SystemTools::ParseURL(uri, protocol, username, password, hostname,
+ dataport, database, true);
+ if (protocol != "file" || hostname != "hostname" ||
+ database != "path/to/a file with stràngè ch@r and sµaces") {
+ std::cerr << "Incorrect URL parsing or decoding" << std::endl;
+ ret = false;
+ }
+ return ret;
+}
+
+static bool CheckSplitString()
+{
+ bool ret = true;
+
+ auto check_split = [](std::string const& input,
+ std::initializer_list<const char*> expected) -> bool {
+ auto const components = kwsys::SystemTools::SplitString(input, '/');
+ if (components.size() != expected.size()) {
+ std::cerr << "Incorrect split count for " << input << ": "
+ << components.size() << std::endl;
+ return false;
+ }
+ size_t i = 0;
+ for (auto& part : expected) {
+ if (components[i] != part) {
+ std::cerr << "Incorrect split component " << i << " for " << input
+ << ": " << components[i] << std::endl;
+ return false;
+ }
+ ++i;
+ }
+ return true;
+ };
+
+ // No separators
+ ret &= check_split("nosep", { "nosep" });
+ // Simple
+ ret &= check_split("first/second", { "first", "second" });
+ // Separator at beginning
+ ret &= check_split("/starts/sep", { "", "starts", "sep" });
+ // Separator at end
+ ret &= check_split("ends/sep/", { "ends", "sep", "" });
+
+ return ret;
+}
+
int testSystemTools(int, char* [])
{
bool res = true;
@@ -1133,5 +1203,9 @@ int testSystemTools(int, char* [])
res &= CheckCopyFileIfDifferent();
+ res &= CheckURLParsing();
+
+ res &= CheckSplitString();
+
return res ? 0 : 1;
}
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
index 022e36e..e4b89a7 100644
--- a/Source/kwsys/testSystemTools.h.in
+++ b/Source/kwsys/testSystemTools.h.in
@@ -3,7 +3,7 @@
#ifndef @KWSYS_NAMESPACE@_testSystemtools_h
#define @KWSYS_NAMESPACE@_testSystemtools_h
-#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
+#define RUNTIME_OUTPUT_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"