summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt15
-rw-r--r--Source/CMakeVersion.cmake6
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx2
-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.cxx24
-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.cxx29
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx5
-rw-r--r--Source/CPack/cmCPackGenerator.cxx11
-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.cxx4
-rw-r--r--Source/CTest/cmCTestBZR.cxx4
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx32
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx24
-rw-r--r--Source/CTest/cmCTestCVS.cxx6
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx2
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx6
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx54
-rw-r--r--Source/CTest/cmCTestCurl.h2
-rw-r--r--Source/CTest/cmCTestGIT.cxx4
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx60
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx78
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h8
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx6
-rw-r--r--Source/CTest/cmCTestRunTest.cxx97
-rw-r--r--Source/CTest/cmCTestRunTest.h15
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx53
-rw-r--r--Source/CTest/cmCTestScriptHandler.h26
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx11
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx29
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx13
-rw-r--r--Source/CTest/cmCTestTestCommand.h1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx196
-rw-r--r--Source/CTest/cmCTestTestHandler.h5
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx3
-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.cxx26
-rw-r--r--Source/CTest/cmProcess.h14
-rw-r--r--Source/Checks/cm_cxx_features.cmake2
-rw-r--r--Source/CursesDialog/ccmake.cxx5
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx17
-rw-r--r--Source/CursesDialog/cmCursesColor.cxx59
-rw-r--r--Source/CursesDialog/cmCursesColor.h5
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx5
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx32
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.cxx4
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx10
-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.cxx41
-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/QtDialog/QCMakeCacheView.cxx60
-rw-r--r--Source/QtDialog/RegexExplorer.cxx3
-rw-r--r--Source/bindexplib.cxx20
-rw-r--r--Source/cmAddExecutableCommand.cxx11
-rw-r--r--Source/cmAddLibraryCommand.cxx22
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx5
-rw-r--r--Source/cmAffinity.cxx2
-rw-r--r--Source/cmAlgorithms.h42
-rw-r--r--Source/cmArchiveWrite.cxx28
-rw-r--r--Source/cmArchiveWrite.h5
-rw-r--r--Source/cmArgumentParser.cxx1
-rw-r--r--Source/cmArgumentParser.h3
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx7
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx15
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.cxx15
-rw-r--r--Source/cmBuildCommand.cxx2
-rw-r--r--Source/cmBuildNameCommand.cxx4
-rw-r--r--Source/cmCMakeLanguageCommand.cxx137
-rw-r--r--Source/cmCMakeLanguageCommand.h20
-rw-r--r--Source/cmCPluginAPI.cxx45
-rw-r--r--Source/cmCTest.cxx271
-rw-r--r--Source/cmCTest.h12
-rw-r--r--Source/cmCacheManager.cxx328
-rw-r--r--Source/cmCacheManager.h196
-rw-r--r--Source/cmCallVisualStudioMacro.cxx38
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx40
-rw-r--r--Source/cmCommandArgumentParserHelper.h3
-rw-r--r--Source/cmCommands.cxx2
-rw-r--r--Source/cmCommonTargetGenerator.cxx51
-rw-r--r--Source/cmCommonTargetGenerator.h6
-rw-r--r--Source/cmComputeLinkInformation.cxx125
-rw-r--r--Source/cmComputeTargetDepends.cxx27
-rw-r--r--Source/cmConditionEvaluator.cxx7
-rw-r--r--Source/cmConfigureFileCommand.cxx25
-rw-r--r--Source/cmConnection.cxx11
-rw-r--r--Source/cmConnection.h2
-rw-r--r--Source/cmConvertMSBuildXMLToJSON.py9
-rw-r--r--Source/cmCoreTryCompile.cxx62
-rw-r--r--Source/cmCryptoHash.cxx6
-rw-r--r--Source/cmCurl.h2
-rw-r--r--Source/cmCustomCommand.cxx4
-rw-r--r--Source/cmCustomCommand.h7
-rw-r--r--Source/cmCustomCommandGenerator.cxx5
-rw-r--r--Source/cmDefinePropertyCommand.cxx2
-rw-r--r--Source/cmDepends.cxx35
-rw-r--r--Source/cmDepends.h12
-rw-r--r--Source/cmDependsC.cxx41
-rw-r--r--Source/cmDependsC.h4
-rw-r--r--Source/cmDependsFortran.cxx60
-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/cmELF.cxx6
-rw-r--r--Source/cmExecuteProcessCommand.cxx25
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx13
-rw-r--r--Source/cmExportBuildFileGenerator.cxx5
-rw-r--r--Source/cmExportCommand.cxx30
-rw-r--r--Source/cmExportFileGenerator.cxx85
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx2
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx5
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx15
-rw-r--r--Source/cmExprParserHelper.h2
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx12
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx4
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx35
-rw-r--r--Source/cmExtraKateGenerator.cxx13
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx29
-rw-r--r--Source/cmFileAPI.cxx2
-rw-r--r--Source/cmFileAPI.h6
-rw-r--r--Source/cmFileAPICMakeFiles.cxx2
-rw-r--r--Source/cmFileAPICMakeFiles.h2
-rw-r--r--Source/cmFileAPICache.cxx8
-rw-r--r--Source/cmFileAPICache.h2
-rw-r--r--Source/cmFileAPICodemodel.cxx70
-rw-r--r--Source/cmFileAPICodemodel.h2
-rw-r--r--Source/cmFileCommand.cxx382
-rw-r--r--Source/cmFileMonitor.h2
-rw-r--r--Source/cmFindBase.cxx15
-rw-r--r--Source/cmFindBase.h10
-rw-r--r--Source/cmFindCommon.cxx8
-rw-r--r--Source/cmFindLibraryCommand.cxx15
-rw-r--r--Source/cmFindPackageCommand.cxx31
-rw-r--r--Source/cmFindPackageCommand.h2
-rw-r--r--Source/cmFindPathCommand.cxx12
-rw-r--r--Source/cmFindProgramCommand.cxx12
-rw-r--r--Source/cmForEachCommand.cxx13
-rw-r--r--Source/cmFunctionBlocker.cxx2
-rw-r--r--Source/cmFunctionCommand.cxx3
-rw-r--r--Source/cmGeneratedFileStream.cxx4
-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.cxx83
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h12
-rw-r--r--Source/cmGeneratorExpressionNode.cxx271
-rw-r--r--Source/cmGeneratorTarget.cxx1480
-rw-r--r--Source/cmGeneratorTarget.h118
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx13
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx16
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx4
-rw-r--r--Source/cmGetPipes.cxx3
-rw-r--r--Source/cmGetPropertyCommand.cxx103
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx52
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx17
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx107
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h1
-rw-r--r--Source/cmGlobalCommonGenerator.cxx5
-rw-r--r--Source/cmGlobalGenerator.cxx120
-rw-r--r--Source/cmGlobalGenerator.h7
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx115
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h2
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx165
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx140
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h18
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx7
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx12
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx40
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx52
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx14
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx21
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h4
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx12
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx153
-rw-r--r--Source/cmGlobalXCodeGenerator.h8
-rw-r--r--Source/cmGraphVizWriter.cxx224
-rw-r--r--Source/cmGraphVizWriter.h36
-rw-r--r--Source/cmIfCommand.cxx3
-rw-r--r--Source/cmIncludeCommand.cxx35
-rw-r--r--Source/cmInstallCommand.cxx19
-rw-r--r--Source/cmInstallCommandArguments.cxx2
-rw-r--r--Source/cmInstallExportGenerator.cxx11
-rw-r--r--Source/cmInstallExportGenerator.h7
-rw-r--r--Source/cmInstallTargetGenerator.cxx7
-rw-r--r--Source/cmInstalledFile.cxx6
-rw-r--r--Source/cmInstalledFile.h4
-rw-r--r--Source/cmJsonObjects.cxx24
-rw-r--r--Source/cmJsonObjects.h2
-rw-r--r--Source/cmLinkItem.h17
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx14
-rw-r--r--Source/cmListCommand.cxx29
-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.cxx1001
-rw-r--r--Source/cmLocalGenerator.h43
-rw-r--r--Source/cmLocalNinjaGenerator.cxx50
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx151
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx158
-rw-r--r--Source/cmLocalVisualStudio7Generator.h7
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx7
-rw-r--r--Source/cmMachO.cxx31
-rw-r--r--Source/cmMacroCommand.cxx3
-rw-r--r--Source/cmMakefile.cxx367
-rw-r--r--Source/cmMakefile.h34
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx32
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx32
-rw-r--r--Source/cmMakefileProfilingData.cxx114
-rw-r--r--Source/cmMakefileProfilingData.h29
-rw-r--r--Source/cmMakefileTargetGenerator.cxx220
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmMathCommand.cxx2
-rw-r--r--Source/cmMessageCommand.cxx3
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx121
-rw-r--r--Source/cmNinjaTargetGenerator.cxx685
-rw-r--r--Source/cmNinjaTargetGenerator.h4
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx5
-rw-r--r--Source/cmOSXBundleGenerator.cxx26
-rw-r--r--Source/cmOSXBundleGenerator.h12
-rw-r--r--Source/cmOptionCommand.cxx5
-rw-r--r--Source/cmOutputConverter.cxx14
-rw-r--r--Source/cmOutputConverter.h9
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx6
-rw-r--r--Source/cmPipeConnection.h2
-rw-r--r--Source/cmPolicies.cxx2
-rw-r--r--Source/cmPolicies.h22
-rw-r--r--Source/cmProcessOutput.cxx23
-rw-r--r--Source/cmProjectCommand.cxx8
-rw-r--r--Source/cmProperty.h4
-rw-r--r--Source/cmPropertyDefinition.cxx43
-rw-r--r--Source/cmPropertyDefinition.h41
-rw-r--r--Source/cmPropertyDefinitionMap.cxx35
-rw-r--r--Source/cmPropertyDefinitionMap.h30
-rw-r--r--Source/cmPropertyMap.cxx10
-rw-r--r--Source/cmPropertyMap.h4
-rw-r--r--Source/cmQTWrapCPPCommand.cxx4
-rw-r--r--Source/cmQtAutoGen.cxx3
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx11
-rw-r--r--Source/cmQtAutoGenInitializer.cxx118
-rw-r--r--Source/cmQtAutoGenerator.cxx4
-rw-r--r--Source/cmQtAutoGenerator.h2
-rw-r--r--Source/cmQtAutoMocUic.cxx35
-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.cxx38
-rw-r--r--Source/cmServer.h11
-rw-r--r--Source/cmServerConnection.cxx2
-rw-r--r--Source/cmServerProtocol.cxx21
-rw-r--r--Source/cmServerProtocol.h2
-rw-r--r--Source/cmSetCommand.cxx7
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx40
-rw-r--r--Source/cmSetPropertyCommand.cxx239
-rw-r--r--Source/cmSetPropertyCommand.h29
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx181
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx70
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx75
-rw-r--r--Source/cmSiteNameCommand.cxx3
-rw-r--r--Source/cmSourceFile.cxx31
-rw-r--r--Source/cmSourceFile.h5
-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.h15
-rw-r--r--Source/cmState.cxx170
-rw-r--r--Source/cmState.h26
-rw-r--r--Source/cmStateDirectory.cxx38
-rw-r--r--Source/cmStateDirectory.h5
-rw-r--r--Source/cmStateSnapshot.cxx6
-rw-r--r--Source/cmString.hxx3
-rw-r--r--Source/cmStringAlgorithms.cxx2
-rw-r--r--Source/cmStringAlgorithms.h2
-rw-r--r--Source/cmStringCommand.cxx25
-rw-r--r--Source/cmSubcommandTable.h3
-rw-r--r--Source/cmSystemTools.cxx40
-rw-r--r--Source/cmSystemTools.h3
-rw-r--r--Source/cmTarget.cxx196
-rw-r--r--Source/cmTarget.h22
-rw-r--r--Source/cmTargetPropCommandBase.cxx7
-rw-r--r--Source/cmTargetPropertyComputer.h25
-rw-r--r--Source/cmTest.cxx9
-rw-r--r--Source/cmTestGenerator.cxx31
-rw-r--r--Source/cmTimestamp.cxx10
-rw-r--r--Source/cmTryRunCommand.cxx6
-rw-r--r--Source/cmUVHandlePtr.cxx2
-rw-r--r--Source/cmUVHandlePtr.h2
-rw-r--r--Source/cmUVProcessChain.cxx2
-rw-r--r--Source/cmUVProcessChain.h4
-rw-r--r--Source/cmUVSignalHackRAII.h2
-rw-r--r--Source/cmUVStreambuf.h2
-rw-r--r--Source/cmUtilitySourceCommand.cxx16
-rw-r--r--Source/cmVSSetupHelper.cxx14
-rw-r--r--Source/cmVSSetupHelper.h4
-rw-r--r--Source/cmVariableWatchCommand.cxx2
-rw-r--r--Source/cmVersion.h2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx1092
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h27
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx29
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h1
-rw-r--r--Source/cmVisualStudioSlnParser.cxx10
-rw-r--r--Source/cmVisualStudioSlnParser.h5
-rw-r--r--Source/cmWhileCommand.cxx3
-rw-r--r--Source/cmWorkerPool.cxx71
-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.cxx29
-rw-r--r--Source/cmXMLParser.cxx4
-rw-r--r--Source/cmXMLWriter.h2
-rw-r--r--Source/cm_get_date.c4
-rw-r--r--Source/cm_static_string_view.hxx41
-rw-r--r--Source/cmake.cxx300
-rw-r--r--Source/cmake.h31
-rw-r--r--Source/cmakemain.cxx31
-rw-r--r--Source/cmcldeps.cxx58
-rw-r--r--Source/cmcmd.cxx86
-rw-r--r--Source/ctest.cxx1
-rw-r--r--Source/kwsys/Base64.c5
-rw-r--r--Source/kwsys/CMakeLists.txt1317
-rw-r--r--Source/kwsys/CommandLineArguments.cxx44
-rw-r--r--Source/kwsys/Configure.h.in8
-rw-r--r--Source/kwsys/Directory.cxx83
-rw-r--r--Source/kwsys/Directory.hxx.in15
-rw-r--r--Source/kwsys/DynamicLoader.cxx22
-rw-r--r--Source/kwsys/EncodingCXX.cxx4
-rw-r--r--Source/kwsys/ExtraTest.cmake.in2
-rw-r--r--Source/kwsys/Glob.cxx26
-rw-r--r--Source/kwsys/Glob.hxx.in1
-rw-r--r--Source/kwsys/IOStream.cxx255
-rw-r--r--Source/kwsys/IOStream.hxx.in126
-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.c10
-rw-r--r--Source/kwsys/RegularExpression.cxx7
-rw-r--r--Source/kwsys/RegularExpression.hxx.in6
-rw-r--r--Source/kwsys/SharedForward.h.in6
-rw-r--r--Source/kwsys/String.hxx.in8
-rw-r--r--Source/kwsys/System.c2
-rw-r--r--Source/kwsys/SystemInformation.cxx394
-rw-r--r--Source/kwsys/SystemInformation.hxx.in21
-rw-r--r--Source/kwsys/SystemTools.cxx406
-rw-r--r--Source/kwsys/SystemTools.hxx.in41
-rw-r--r--Source/kwsys/hash_fun.hxx.in166
-rw-r--r--Source/kwsys/hash_map.hxx.in423
-rw-r--r--Source/kwsys/hash_set.hxx.in392
-rw-r--r--Source/kwsys/hashtable.hxx.in995
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake300
-rw-r--r--Source/kwsys/kwsysPlatformTestsC.c37
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx161
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx6
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx10
-rw-r--r--Source/kwsys/testDirectory.cxx37
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testDynload.c2
-rw-r--r--Source/kwsys/testEncoding.cxx27
-rw-r--r--Source/kwsys/testFStream.cxx5
-rw-r--r--Source/kwsys/testHashSTL.cxx64
-rw-r--r--Source/kwsys/testProcess.c17
-rw-r--r--Source/kwsys/testSystemInformation.cxx18
-rw-r--r--Source/kwsys/testSystemTools.cxx112
-rw-r--r--Source/kwsys/testSystemTools.h.in2
405 files changed, 10495 insertions, 10321 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c57f71347..1b6bb00d4 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1,9 +1,16 @@
# 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")
+if(WIN32)
+ set(HAVE_ELF_H 0)
+elseif(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
CHECK_INCLUDE_FILES("stdint.h;elf_abi.h" HAVE_ELF_H)
else()
CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H)
@@ -354,6 +361,7 @@ set(SRCS
cmMakefileTargetGenerator.cxx
cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx
+ cmMakefileProfilingData.cxx
cmMakefileUtilityTargetGenerator.cxx
cmMessageType.h
cmMessenger.cxx
@@ -377,8 +385,6 @@ set(SRCS
cmProperty.h
cmPropertyDefinition.cxx
cmPropertyDefinition.h
- cmPropertyDefinitionMap.cxx
- cmPropertyDefinitionMap.h
cmPropertyMap.cxx
cmPropertyMap.h
cmQtAutoGen.cxx
@@ -486,6 +492,8 @@ set(SRCS
cmBuildNameCommand.h
cmCMakeHostSystemInformationCommand.cxx
cmCMakeHostSystemInformationCommand.h
+ cmCMakeLanguageCommand.cxx
+ cmCMakeLanguageCommand.h
cmCMakeMinimumRequired.cxx
cmCMakeMinimumRequired.h
cmCMakePolicyCommand.cxx
@@ -690,7 +698,6 @@ set(SRCS
cmWriteFileCommand.cxx
cmWriteFileCommand.h
- cm_static_string_view.hxx
cm_get_date.h
cm_get_date.c
cm_utf8.h
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 661be1034..63a538ccb 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 5)
+set(CMake_VERSION_MINOR 18)
+set(CMake_VERSION_PATCH 0)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
@@ -21,7 +21,7 @@ endif()
if(NOT CMake_VERSION_NO_GIT)
# If this source was exported by 'git archive', use its commit info.
- set(git_info [==[566e96d42d CMake 3.17.5]==])
+ set(git_info [==[d421274e3e CMake 3.18.0]==])
# Otherwise, try to identify the current development source version.
if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* "
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 9fa74be76..20d392d21 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWCommon.h"
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <utility>
#include <vector>
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 509ac6507..2806c614e 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 9a9cd5678..56a74c58b 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 a6965491e..f5e87443b 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 21d27a02d..bdaf779af 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 e71a38fd2..72af10b3c 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 d1933483f..d5a16ec05 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 3668b4613..9685a7f49 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 c0d879a0c..b4085d5b8 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 ca232f94b..122ffaff5 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 fd9103bc1..8b26c4eec 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -2,7 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXPatchParser.h"
-#include "cm_expat.h"
+#include <utility>
+
+#include <cm/memory>
+
+#include <cm3p/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 87dd89288..8d5d2adc4 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 43f2946bd..967cc6060 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -8,6 +8,8 @@
#include <utility>
#include <vector>
+#include <cm3p/archive.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 8d677208f..7eb566597 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 d92acdebf..3d5fe6b9d 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -135,16 +135,17 @@ void DebGenerator::generateDebianBinaryFile() const
{
// debian-binary file
const std::string dbfilename = WorkDir + "/debian-binary";
- cmGeneratedFileStream out(dbfilename);
- out << "2.0";
- out << std::endl; // required for valid debian package
+ cmGeneratedFileStream out;
+ out.Open(dbfilename, false, true);
+ out << "2.0\n"; // required for valid debian package
}
void DebGenerator::generateControlFile() const
{
std::string ctlfilename = WorkDir + "/control";
- cmGeneratedFileStream out(ctlfilename);
+ cmGeneratedFileStream out;
+ out.Open(ctlfilename, false, true);
for (auto const& kv : ControlValues) {
out << kv.first << ": " << kv.second << "\n";
}
@@ -156,8 +157,7 @@ void DebGenerator::generateControlFile() const
totalSize += cmSystemTools::FileLength(file);
}
}
- out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
- out << std::endl;
+ out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n\n";
}
bool DebGenerator::generateDataTar() const
@@ -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.
@@ -247,7 +248,8 @@ std::string DebGenerator::generateMD5File() const
{
std::string md5filename = WorkDir + "/md5sums";
- cmGeneratedFileStream out(md5filename);
+ cmGeneratedFileStream out;
+ out.Open(md5filename, false, true);
std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/');
for (std::string const& file : PackageFiles) {
@@ -291,6 +293,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 +413,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.
@@ -754,15 +758,17 @@ int cmCPackDebGenerator::createDeb()
const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
debian_pkg_shlibs && *debian_pkg_shlibs;
if (gen_shibs) {
- cmGeneratedFileStream out(shlibsfilename);
+ cmGeneratedFileStream out;
+ out.Open(shlibsfilename, false, true);
out << debian_pkg_shlibs;
- out << std::endl;
+ out << '\n';
}
const std::string postinst = strGenWDIR + "/postinst";
const std::string postrm = strGenWDIR + "/postrm";
if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
- cmGeneratedFileStream out(postinst);
+ cmGeneratedFileStream out;
+ out.Open(postinst, false, true);
out << "#!/bin/sh\n\n"
"set -e\n\n"
"if [ \"$1\" = \"configure\" ]; then\n"
@@ -770,7 +776,8 @@ int cmCPackDebGenerator::createDeb()
"fi\n";
}
if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
- cmGeneratedFileStream out(postrm);
+ cmGeneratedFileStream out;
+ out.Open(postrm, false, true);
out << "#!/bin/sh\n\n"
"set -e\n\n"
"if [ \"$1\" = \"remove\" ]; then\n"
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 142eb6fbf..11e1aecce 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -8,10 +8,10 @@
#include <cm/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index e3cc352fb..b673006f2 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 e0531442f..288dc58a7 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);
}
}
}
@@ -921,11 +921,11 @@ int cmCPackGenerator::InstallCMakeProject(
}
}
- if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
+ if (auto d = mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
if (!absoluteDestFiles.empty()) {
absoluteDestFiles += ";";
}
- absoluteDestFiles += mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+ absoluteDestFiles += d;
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Got some ABSOLUTE DESTINATION FILES: " << absoluteDestFiles
<< std::endl);
@@ -936,8 +936,7 @@ int cmCPackGenerator::InstallCMakeProject(
GetComponentInstallDirNameSuffix(component);
if (nullptr != this->GetOption(absoluteDestFileComponent)) {
std::string absoluteDestFilesListComponent =
- cmStrCat(this->GetOption(absoluteDestFileComponent), ';',
- mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
+ cmStrCat(this->GetOption(absoluteDestFileComponent), ';', d);
this->SetOption(absoluteDestFileComponent,
absoluteDestFilesListComponent.c_str());
} else {
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index ca675fdc8..49e411393 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 1cb16433c..68ffccee9 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 2a4662798..058b090e0 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 0af37af50..88cba45e8 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 dc316233c..3a400b7db 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 << "\""
@@ -312,7 +312,7 @@ int main(int argc, char const* const* argv)
// The value has not been set on the command line
else {
// get a default value (current working directory)
- cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
+ cpackProjectDirectory = cmSystemTools::GetCurrentWorkingDirectory();
// use default value if no value has been provided by the config file
if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index c87fb83b3..c533cd7f9 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -10,9 +10,9 @@
#include <cmext/algorithm>
-#include "cmsys/RegularExpression.hxx"
+#include <cm3p/expat.h>
-#include "cm_expat.h"
+#include "cmsys/RegularExpression.hxx"
#include "cmCTest.h"
#include "cmCTestVC.h"
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 5e29386c7..db426b2ff 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/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index d1b7701ec..44fdc2945 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -5,7 +5,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 03a3fd306..35c2b1118 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 45ec39066..1209e06d0 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/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 385471081..f42c3f18a 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -6,7 +6,7 @@
#include <sstream>
#include <vector>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be395..7432d0850 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,9 @@
#include <set>
-#include "cm_static_string_view.hxx"
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
@@ -22,7 +22,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 2c8f11937..b839c10ad 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(
@@ -1214,8 +1215,6 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
while (cmSystemTools::GetLineFromStream(ifile, nl)) {
cnt++;
- // TODO: Handle gcov 3.0 non-coverage lines
-
// Skip empty lines
if (nl.empty()) {
continue;
@@ -1226,6 +1225,14 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
continue;
}
+ // Handle gcov 3.0 non-coverage lines
+ // non-coverage lines seem to always start with something not
+ // a space and don't have a ':' in the 9th position
+ // TODO: Verify that this is actually a robust metric
+ if (nl[0] != ' ' && nl[9] != ':') {
+ continue;
+ }
+
// Read the coverage count from the beginning of the gcov output
// line
std::string prefix = nl.substr(0, 12);
@@ -1709,29 +1716,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/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 9c5ba667e..b0d7f0757 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
class cmCTest;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 3f3c1074f..568b0917c 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/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index b1034c9ff..a755632c5 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,7 +7,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 39dec6d87..d0e297452 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index c1ecaf125..85b8ab15f 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 2192843ec..a08cb3480 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -6,30 +6,29 @@
#include <cassert>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdlib>
#include <cstring>
#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 <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+#include <cm3p/uv.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#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 5b429d4ae..e21b912c7 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,14 +6,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
-#include "cm_uv.h"
-
#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
@@ -124,7 +124,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 +137,8 @@ protected:
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
+ bool CheckStopOnFailure();
+
bool CheckStopTimePassed();
void SetStopTimePassed();
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 8f91efb45..21c97de34 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -7,12 +7,12 @@
#include <utility>
#include <vector>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-
static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 58289ea50..2c8e3855f 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -3,7 +3,7 @@
#include "cmCTestRunTest.h"
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <cstdio>
#include <cstring>
@@ -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;
}
@@ -387,6 +391,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)
{
@@ -418,7 +434,7 @@ 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);
+ this->TestResult.Environment.clear();
}
std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -442,6 +458,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)
{
@@ -473,9 +504,9 @@ 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();
+ this->TestResult.Environment.clear();
return false;
}
@@ -487,7 +518,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;
@@ -496,6 +526,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl);
this->TestResult.Output = msg;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Fixture dependency failed";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -504,7 +535,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 "
@@ -517,6 +547,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
this->TestResult.Output = msg;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Missing Configuration";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -526,13 +557,13 @@ 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,
"Unable to find required file: " << file << std::endl);
this->TestResult.Output = "Unable to find required file: " + file;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Required Files Missing";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -542,13 +573,13 @@ 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,
"Unable to find executable: " << args[1] << std::endl);
this->TestResult.Output = "Unable to find executable: " + args[1];
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Unable to find executable";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -654,7 +685,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);
@@ -694,25 +724,43 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
cmSystemTools::SaveRestoreEnvironment sre;
#endif
+ std::ostringstream envMeasurement;
if (environment && !environment->empty()) {
cmSystemTools::AppendEnv(*environment);
+ for (auto const& var : *environment) {
+ envMeasurement << var << std::endl;
+ }
}
if (this->UseAllocatedResources) {
- this->SetupResourcesEnvironment();
+ std::vector<std::string> envLog;
+ this->SetupResourcesEnvironment(&envLog);
+ for (auto const& var : envLog) {
+ envMeasurement << var << std::endl;
+ }
} else {
cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT");
+ // Signify that this variable is being actively unset
+ envMeasurement << "#CTEST_RESOURCE_GROUP_COUNT=" << std::endl;
}
+ this->TestResult.Environment = envMeasurement.str();
+ // Remove last newline
+ this->TestResult.Environment.erase(this->TestResult.Environment.length() -
+ 1);
+
return this->TestProcess->StartProcess(this->MultiTestHandler.Loop,
affinity);
}
-void cmCTestRunTest::SetupResourcesEnvironment()
+void cmCTestRunTest::SetupResourcesEnvironment(std::vector<std::string>* log)
{
std::string processCount = "CTEST_RESOURCE_GROUP_COUNT=";
processCount += std::to_string(this->AllocatedResources.size());
cmSystemTools::PutEnv(processCount);
+ if (log) {
+ log->push_back(processCount);
+ }
std::size_t i = 0;
for (auto const& process : this->AllocatedResources) {
@@ -738,8 +786,14 @@ void cmCTestRunTest::SetupResourcesEnvironment()
var += "id:" + it2.Id + ",slots:" + std::to_string(it2.Slots);
}
cmSystemTools::PutEnv(var);
+ if (log) {
+ log->push_back(var);
+ }
}
cmSystemTools::PutEnv(resourceList);
+ if (log) {
+ log->push_back(resourceList);
+ }
++i;
}
}
@@ -821,7 +875,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 4988839b0..d831247e1 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; }
@@ -112,7 +119,7 @@ private:
// Run post processing of the process output for MemCheck
void MemCheckPostProcess();
- void SetupResourcesEnvironment();
+ void SetupResourcesEnvironment(std::vector<std::string>* log = nullptr);
// Returns "completed/total Test #Index: "
std::string GetTestPrefix(size_t completed, size_t total) const;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7803e3764..4fa4dc0da 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 d0031990b..ebb79055f 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 acb75b2ed..279216eeb 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,10 +8,9 @@
#include <cm/memory>
#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
@@ -172,8 +171,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 22ab48f57..ea36df54a 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -9,9 +9,9 @@
#include <cmext/algorithm>
-#include "cm_curl.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
+#include <cm3p/curl/curl.h>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
#include "cmAlgorithms.h"
#include "cmCTest.h"
@@ -21,6 +21,7 @@
#include "cmCurl.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -260,11 +261,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 +506,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 +556,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 0f9b6958d..c71b409ff 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -6,7 +6,7 @@
#include <cstdlib>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
@@ -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 2345afbcf..792558679 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 4f324ea6d..d0dbaae81 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -5,7 +5,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -18,6 +18,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include <cmsys/Base64.h>
@@ -26,7 +29,6 @@
#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(
@@ -1423,6 +1432,12 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
xml.Attribute("name", "Command Line");
xml.Element("Value", result.FullCommandLine);
xml.EndElement(); // NamedMeasurement
+
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Environment");
+ xml.Element("Value", result.Environment);
+ xml.EndElement(); // NamedMeasurement
for (auto const& measure : result.Properties->Measurements) {
xml.StartElement("NamedMeasurement");
xml.Attribute("type", "text/string");
@@ -1742,6 +1757,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 +1913,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 +2036,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 +2059,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 +2103,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 +2135,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 +2145,6 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
"of "
<< length << " bytes.\n";
output += msg.str();
- return true;
}
bool cmCTestTestHandler::SetTestsProperties(
@@ -2149,16 +2165,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 +2198,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 +2269,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 +2278,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 +2325,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 +2413,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 b1c875502..0d88c306f 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -169,6 +169,7 @@ public:
std::string Path;
std::string Reason;
std::string FullCommandLine;
+ std::string Environment;
cmDuration ExecutionTime;
std::int64_t ReturnValue;
int Status;
@@ -235,7 +236,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 +279,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/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index eaef1ca6a..f86ee0d7c 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -6,8 +6,7 @@
#include <sstream>
#include <cm/vector>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6026c69bb..452d7143b 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 2a4765d28..3037e01c9 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 8c4da7577..84d7de02c 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 e89b9e454..a8200b787 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 05da84e2e..711a8564b 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 1dc5b7038..14417cc30 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 fe0ae0bfd..41cc7f575 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 b16f1014a..dc3064d22 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 2c544954b..8c0870254 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 a494b92b9..044f518ef 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 6097aa5bd..a549117ca 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>
@@ -16,14 +17,13 @@
#include "cmGetPipes.h"
#include "cmStringAlgorithms.h"
#if defined(_WIN32)
-# include "cm_kwiml.h"
+# include <cm3p/kwiml/int.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 ea72a2650..1e6578cf9 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,14 +6,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
#include <stdint.h>
-#include "cm_uv.h"
-
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmUVHandlePtr.h"
@@ -28,7 +29,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 +71,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 +88,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 2a6774885..50ccc7c86 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -36,8 +36,6 @@ function(cm_check_cxx_feature name)
string(REGEX REPLACE "[^\n]*icpc: command line warning #10121: overriding [^\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 01fce8545..9a26db599 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 4d3131b07..35f09fd6a 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -15,6 +15,7 @@
#include "cmCursesPathWidget.h"
#include "cmCursesStringWidget.h"
#include "cmCursesWidget.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -48,42 +49,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/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx
index 641d48cce..c0b468b60 100644
--- a/Source/CursesDialog/cmCursesColor.cxx
+++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -2,6 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesColor.h"
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <unordered_map>
+#include <utility>
+
#include "cmCursesStandardIncludes.h"
bool cmCursesColor::HasColors()
@@ -19,11 +25,54 @@ void cmCursesColor::InitColors()
if (HasColors()) {
start_color();
use_default_colors();
- init_pair(cmCursesColor::BoolOff, COLOR_RED, -1);
- init_pair(cmCursesColor::BoolOn, COLOR_GREEN, -1);
- init_pair(cmCursesColor::String, COLOR_BLUE, -1);
- init_pair(cmCursesColor::Path, COLOR_YELLOW, -1);
- init_pair(cmCursesColor::Options, COLOR_MAGENTA, -1);
+ init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
+ init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
+ init_pair(String, GetColor('S', COLOR_CYAN), -1);
+ init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
+ init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
}
#endif
}
+
+short cmCursesColor::GetColor(char id, short fallback)
+{
+ static bool initialized = false;
+ static std::unordered_map<char, short> env;
+
+ if (!initialized) {
+ if (auto* v = getenv("CCMAKE_COLORS")) {
+ while (v[0] && v[1] && v[1] == '=') {
+ auto const n = std::toupper(*v);
+
+ char buffer[12];
+ memset(buffer, 0, sizeof(buffer));
+
+ if (auto* const e = strchr(v, ':')) {
+ if (static_cast<size_t>(e - v) > sizeof(buffer)) {
+ break;
+ }
+
+ strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
+ v = e + 1;
+ } else {
+ auto const l = strlen(v);
+ if (l > sizeof(buffer)) {
+ break;
+ }
+
+ strncpy(buffer, v + 2, l - 2);
+ v += l;
+ }
+
+ auto const c = atoi(buffer);
+ if (c && c < COLORS) {
+ env.emplace(n, static_cast<short>(c));
+ }
+ }
+ }
+ initialized = true;
+ }
+
+ auto const iter = env.find(id);
+ return (iter == env.end() ? fallback : iter->second);
+}
diff --git a/Source/CursesDialog/cmCursesColor.h b/Source/CursesDialog/cmCursesColor.h
index 78ca52cbb..f83265f05 100644
--- a/Source/CursesDialog/cmCursesColor.h
+++ b/Source/CursesDialog/cmCursesColor.h
@@ -13,12 +13,15 @@ public:
BoolOn,
String,
Path,
- Options
+ Choice
};
static bool HasColors();
static void InitColors();
+
+protected:
+ static short GetColor(char id, short fallback);
};
#endif // cmCursesColor_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index afd2b6b90..591c546e6 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());
}
@@ -67,7 +68,7 @@ void cmCursesLongMessageForm::UpdateStatusBar()
bar[i] = ' ';
}
int width;
- if (x < cmCursesMainForm::MAX_WIDTH) {
+ if (x >= 0 && x < cmCursesMainForm::MAX_WIDTH) {
width = x;
} else {
width = cmCursesMainForm::MAX_WIDTH - 1;
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 65376d1a2..6fc556c08 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -17,6 +17,7 @@
#include "cmCursesStandardIncludes.h"
#include "cmCursesStringWidget.h"
#include "cmCursesWidget.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -161,7 +162,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 +183,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 +242,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 +260,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 +406,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 +618,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 +804,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 +815,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] = "";
}
@@ -852,11 +854,7 @@ void cmCursesMainForm::HandleInput()
}
// switch advanced on/off
else if (key == 't') {
- if (this->AdvancedMode) {
- this->AdvancedMode = false;
- } else {
- this->AdvancedMode = true;
- }
+ this->AdvancedMode = !this->AdvancedMode;
getmaxyx(stdscr, y, x);
this->RePost();
this->Render(1, 1, x, y);
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
index a15241fae..8df32e2f3 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.cxx
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -17,8 +17,8 @@ cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left,
// the widget into a string widget at some point. BOOL is safe for
// now.
if (cmCursesColor::HasColors()) {
- set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Options));
- set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Options));
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Choice));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Choice));
} else {
set_field_fore(this->Field, A_NORMAL);
set_field_back(this->Field, A_STANDOUT);
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index c62947836..4830d6305 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -105,12 +105,10 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
if (!this->InEdit && (key != 10 && key != KEY_ENTER && key != 'i')) {
return false;
}
- // enter edit with return and i (vim binding)
- if (!this->InEdit && (key == 10 || key == KEY_ENTER || key == 'i')) {
- this->OnReturn(fm, w);
- }
- // leave edit with return (but not i -- not a toggle)
- else if (this->InEdit && (key == 10 || key == KEY_ENTER)) {
+ // toggle edit with return
+ if ((key == 10 || key == KEY_ENTER)
+ // enter edit with i (and not-edit mode)
+ || (!this->InEdit && key == 'i')) {
this->OnReturn(fm, w);
} else if (key == KEY_DOWN || key == ctrl('n') || key == KEY_UP ||
key == ctrl('p') || key == KEY_NPAGE || key == ctrl('d') ||
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 15dcda04a..ec7424c4f 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 fdf14d2d3..94cf8a594 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 ee81a7d62..9d928b2ff 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 436a90466..6dbfe1125 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()
@@ -595,7 +595,11 @@ void CMakeSetupDialog::doHelp()
QDialog dialog;
QFontMetrics met(this->font());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
+ int msgWidth = met.horizontalAdvance(msg);
+#else
int msgWidth = met.width(msg);
+#endif
dialog.setMinimumSize(msgWidth / 15, 20);
dialog.setWindowTitle(tr("Help"));
QVBoxLayout* l = new QVBoxLayout(&dialog);
@@ -804,12 +808,19 @@ 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);
+ if (!cxxCompiler.isEmpty()) {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ tr("CXX compiler."), cxxCompiler, false);
+ }
QString cCompiler = dialog.getCCompiler();
- m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
- tr("C compiler."), cCompiler, false);
+ if (!cCompiler.isEmpty()) {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ tr("C compiler."), cCompiler, false);
+ }
} else if (dialog.crossCompilerToolChainFile()) {
QString toolchainFile = dialog.getCrossCompilerToolChainFile();
m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
@@ -1049,14 +1060,7 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
this->GenerateAction->setEnabled(false);
this->OpenProjectButton->setEnabled(false);
this->GenerateButton->setText(tr("&Stop"));
- } else if (s == ReadyConfigure) {
- this->setEnabledState(true);
- this->GenerateButton->setEnabled(true);
- this->GenerateAction->setEnabled(true);
- this->ConfigureButton->setEnabled(true);
- this->ConfigureButton->setText(tr("&Configure"));
- this->GenerateButton->setText(tr("&Generate"));
- } else if (s == ReadyGenerate) {
+ } else if (s == ReadyConfigure || s == ReadyGenerate) {
this->setEnabledState(true);
this->GenerateButton->setEnabled(true);
this->GenerateAction->setEnabled(true);
@@ -1206,7 +1210,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 +1224,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 f23aee6e8..d1e20354b 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 ca28b1972..3c24b9b05 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 d1db5bff6..c26f48984 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 a9089e52f..776af81ff 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 fa4451bc2..110a971d0 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/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 3e6a49e09..b1f4a8229 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -209,18 +209,35 @@ void QCMakeCacheModel::clear()
void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ this->beginResetModel();
+#endif
+
QSet<QCMakeProperty> newProps;
QSet<QCMakeProperty> newProps2;
if (this->ShowNewProperties) {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
newProps = props.toSet();
+#else
+ newProps = QSet<QCMakeProperty>(props.begin(), props.end());
+#endif
newProps2 = newProps;
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QSet<QCMakeProperty> oldProps = this->properties().toSet();
+#else
+ QSet<QCMakeProperty> oldProps = QSet<QCMakeProperty>(
+ this->properties().begin(), this->properties().end());
+#endif
oldProps.intersect(newProps);
newProps.subtract(oldProps);
newProps2.subtract(newProps);
} else {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
newProps2 = props.toSet();
+#else
+ newProps2 = QSet<QCMakeProperty>(props.begin(), props.end());
+#endif
}
bool b = this->blockSignals(true);
@@ -229,10 +246,15 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
this->NewPropertyCount = newProps.size();
if (View == FlatView) {
- QCMakePropertyList newP = newProps.toList();
- QCMakePropertyList newP2 = newProps2.toList();
+ QCMakePropertyList newP = newProps.values();
+ QCMakePropertyList newP2 = newProps2.values();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ std::sort(newP.begin(), newP.end());
+ std::sort(newP2.begin(), newP2.end());
+#else
qSort(newP);
qSort(newP2);
+#endif
int row_count = 0;
foreach (QCMakeProperty const& p, newP) {
this->insertRow(row_count);
@@ -262,10 +284,17 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
parentItems.append(
new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key));
parentItems.append(new QStandardItem());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ parentItems[0]->setData(QBrush(QColor(255, 100, 100)),
+ Qt::BackgroundRole);
+ parentItems[1]->setData(QBrush(QColor(255, 100, 100)),
+ Qt::BackgroundRole);
+#else
parentItems[0]->setData(QBrush(QColor(255, 100, 100)),
Qt::BackgroundColorRole);
parentItems[1]->setData(QBrush(QColor(255, 100, 100)),
Qt::BackgroundColorRole);
+#endif
parentItems[0]->setData(1, GroupRole);
parentItems[1]->setData(1, GroupRole);
root->appendRow(parentItems);
@@ -305,7 +334,11 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
}
this->blockSignals(b);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ this->endResetModel();
+#else
this->reset();
+#endif
}
QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
@@ -315,6 +348,10 @@ QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ this->beginResetModel();
+#endif
+
this->View = t;
QCMakePropertyList props = this->properties();
@@ -330,7 +367,11 @@ void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
this->setProperties(oldProps);
this->setProperties(props);
this->blockSignals(b);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ this->endResetModel();
+#else
this->reset();
+#endif
}
void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
@@ -356,10 +397,15 @@ void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
}
if (isNew) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ this->setData(idx1, QBrush(QColor(255, 100, 100)), Qt::BackgroundRole);
+ this->setData(idx2, QBrush(QColor(255, 100, 100)), Qt::BackgroundRole);
+#else
this->setData(idx1, QBrush(QColor(255, 100, 100)),
Qt::BackgroundColorRole);
this->setData(idx2, QBrush(QColor(255, 100, 100)),
Qt::BackgroundColorRole);
+#endif
}
}
@@ -409,7 +455,11 @@ void QCMakeCacheModel::breakProperties(
reorgProps.append((*iter)[0]);
iter = tmp.erase(iter);
} else {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ std::sort(iter->begin(), iter->end());
+#else
qSort(*iter);
+#endif
++iter;
}
}
@@ -639,9 +689,15 @@ QSize QCMakeCacheModelDelegate::sizeHint(const QStyleOptionViewItem& option,
// increase to checkbox size
QStyleOptionButton opt;
opt.QStyleOption::operator=(option);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
+ sz = sz.expandedTo(
+ style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, nullptr)
+ .size());
+#else
sz = sz.expandedTo(
style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, nullptr)
.size());
+#endif
return sz;
}
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
index 746fd8af2..619494069 100644
--- a/Source/QtDialog/RegexExplorer.cxx
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -147,9 +147,6 @@ bool RegexExplorer::stripEscapes(std::string& source)
} else if (nextc == 'n') {
result.append(1, '\n');
in++;
- } else if (nextc == 't') {
- result.append(1, '\t');
- in++;
} else if (isalnum(nextc) || nextc == '\0') {
return false;
} else {
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 0b2750d85..843574013 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -64,7 +64,7 @@
*/
#include "bindexplib.h"
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <vector>
@@ -276,8 +276,9 @@ public:
symbol.compare(0, 4, vectorPrefix)) {
SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
.Characteristics;
- // skip symbols containing a dot
- if (symbol.find('.') == std::string::npos) {
+ // skip symbols containing a dot or are from managed code
+ if (symbol.find('.') == std::string::npos &&
+ !SymbolIsFromManagedCode(symbol)) {
if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
// Read only (i.e. constants) must be excluded
this->DataSymbols.insert(symbol);
@@ -302,6 +303,13 @@ public:
}
private:
+ bool SymbolIsFromManagedCode(std::string const& symbol)
+ {
+ return symbol == "__t2m" || symbol == "__m2mep" || symbol == "__mep" ||
+ symbol.find("$$F") != std::string::npos ||
+ symbol.find("$$J") != std::string::npos;
+ }
+
std::set<std::string>& Symbols;
std::set<std::string>& DataSymbols;
DWORD_PTR SymbolCount;
@@ -352,14 +360,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/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index e738bc467..9dd8a1921 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -117,14 +117,9 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
"\" is not an executable."));
return false;
}
- if (aliasedTarget->IsImported() &&
- !aliasedTarget->IsImportedGloballyVisible()) {
- status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
- "\" because target \"", aliasedName,
- "\" is imported but not globally visible."));
- return false;
- }
- mf.AddAlias(exename, aliasedName);
+ mf.AddAlias(exename, aliasedName,
+ !aliasedTarget->IsImported() ||
+ aliasedTarget->IsImportedGloballyVisible());
return true;
}
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index f443fc664..3e5d76484 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -9,6 +9,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -181,6 +182,16 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
return false;
}
+ if (mf.GetPolicyStatus(cmPolicies::CMP0107) == cmPolicies::NEW) {
+ // Make sure the target does not already exist.
+ if (mf.FindTargetToUse(libName)) {
+ status.SetError(cmStrCat(
+ "cannot create ALIAS target \"", libName,
+ "\" because another target with the same name already exists."));
+ return false;
+ }
+ }
+
std::string const& aliasedName = *s;
if (mf.IsAlias(aliasedName)) {
status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
@@ -208,14 +219,9 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
"\" is not a library."));
return false;
}
- if (aliasedTarget->IsImported() &&
- !aliasedTarget->IsImportedGloballyVisible()) {
- status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
- "\" because target \"", aliasedName,
- "\" is imported but not globally visible."));
- return false;
- }
- mf.AddAlias(libName, aliasedName);
+ mf.AddAlias(libName, aliasedName,
+ !aliasedTarget->IsImported() ||
+ aliasedTarget->IsImportedGloballyVisible());
return true;
}
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 35eabafcf..83d630600 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/cmAffinity.cxx b/Source/cmAffinity.cxx
index 8f9fe2ad8..35443e795 100644
--- a/Source/cmAffinity.cxx
+++ b/Source/cmAffinity.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAffinity.h"
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#ifndef CMAKE_USE_SYSTEM_LIBUV
# ifdef _WIN32
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index c0ac5512a..c8e8dcb85 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -13,20 +13,10 @@
#include <utility>
#include <vector>
-#include "cm_kwiml.h"
+#include <cmext/algorithm>
#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 +27,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 +120,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 d29b2acf6..addfbff3e 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -7,12 +7,14 @@
#include <iostream>
#include <sstream>
+#include <cm3p/archive.h>
+#include <cm3p/archive_entry.h>
+
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cm_get_date.h"
-#include "cm_libarchive.h"
#include "cmLocale.h"
#include "cmStringAlgorithms.h"
@@ -170,15 +172,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()
@@ -276,7 +282,12 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
time_t epochTime;
iss >> epochTime;
if (iss.eof() && !iss.fail()) {
+ // Set all of the file times to the epoch time to handle archive
+ // formats that include creation/access time.
archive_entry_set_mtime(e, epochTime, 0);
+ archive_entry_set_atime(e, epochTime, 0);
+ archive_entry_set_ctime(e, epochTime, 0);
+ archive_entry_set_birthtime(e, epochTime, 0);
}
}
}
@@ -365,3 +376,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 e791761cb..b643bce87 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/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 4c8717749..4624f1c0a 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -3,7 +3,6 @@
#include "cmArgumentParser.h"
#include <algorithm>
-#include <type_traits>
namespace ArgumentParser {
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 94265372a..5d2dfa224 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -12,8 +12,7 @@
#include <vector>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
namespace ArgumentParser {
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 289bb7217..d6f7500e8 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 0dea8256c..9ce403dcc 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/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index 98250b1c0..0f47146c5 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -14,6 +14,18 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+namespace {
+bool IsMissingSystemDylib(std::string const& path)
+{
+ // Starting on macOS 11, the dynamic loader has a builtin cache of
+ // system-provided dylib files that do not exist on the filesystem.
+ // Tell our caller that these are expected to be missing.
+ return ((cmHasLiteralPrefix(path, "/System/Library/") ||
+ cmHasLiteralPrefix(path, "/usr/lib/")) &&
+ !cmSystemTools::PathExists(path));
+}
+}
+
cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker(
cmRuntimeDependencyArchive* archive)
: cmBinUtilsLinker(archive)
@@ -82,7 +94,8 @@ bool cmBinUtilsMacOSMachOLinker::GetFileDependencies(
return false;
}
if (resolved) {
- if (!this->Archive->IsPostExcluded(path)) {
+ if (!this->Archive->IsPostExcluded(path) &&
+ !IsMissingSystemDylib(path)) {
auto filename = cmSystemTools::GetFilenameName(path);
bool unique;
this->Archive->AddResolvedPath(filename, path, unique);
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 49c943975..b82fb9aac 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 3e517dca4..ad4d66534 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/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
new file mode 100644
index 000000000..eb9269f7f
--- /dev/null
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -0,0 +1,137 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCMakeLanguageCommand.h"
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+namespace {
+std::array<cm::static_string_view, 12> InvalidCommands{
+ { // clang-format off
+ "function"_s, "endfunction"_s,
+ "macro"_s, "endmacro"_s,
+ "if"_s, "elseif"_s, "else"_s, "endif"_s,
+ "while"_s, "endwhile"_s,
+ "foreach"_s, "endforeach"_s
+ } // clang-format on
+};
+}
+
+bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> 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;
+
+ std::vector<std::string> dispatchExpandedArgs;
+ std::vector<cmListFileArgument> dispatchArgs;
+ dispatchArgs.emplace_back(args[0]);
+ makefile.ExpandArguments(dispatchArgs, dispatchExpandedArgs);
+
+ if (dispatchExpandedArgs.empty()) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ if (dispatchExpandedArgs[0] == "CALL") {
+ if ((args.size() == 1 && dispatchExpandedArgs.size() != 2) ||
+ dispatchExpandedArgs.size() > 2) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // First argument is the name of the function to call
+ std::string callCommand;
+ size_t startArg;
+ if (dispatchExpandedArgs.size() == 1) {
+ std::vector<std::string> functionExpandedArg;
+ std::vector<cmListFileArgument> functionArg;
+ functionArg.emplace_back(args[1]);
+ makefile.ExpandArguments(functionArg, functionExpandedArg);
+
+ if (functionExpandedArg.size() != 1) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ callCommand = functionExpandedArg[0];
+ startArg = 2;
+ } else {
+ callCommand = dispatchExpandedArgs[1];
+ startArg = 1;
+ }
+
+ // ensure specified command is valid
+ // start/end flow control commands are not allowed
+ auto cmd = cmSystemTools::LowerCase(callCommand);
+ if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
+ InvalidCommands.cend()) {
+ status.SetError(cmStrCat("invalid command specified: "_s, callCommand));
+ return false;
+ }
+
+ cmListFileFunction func;
+ func.Name = callCommand;
+ func.Line = context.Line;
+
+ // The rest of the arguments are passed to the function call above
+ for (size_t i = startArg; i < args.size(); ++i) {
+ cmListFileArgument lfarg;
+ lfarg.Delim = args[i].Delim;
+ lfarg.Line = context.Line;
+ lfarg.Value = args[i].Value;
+ func.Arguments.emplace_back(lfarg);
+ }
+
+ result = makefile.ExecuteCommand(func, status);
+ } else if (dispatchExpandedArgs[0] == "EVAL") {
+ std::vector<std::string> expandedArgs;
+ makefile.ExpandArguments(args, expandedArgs);
+
+ if (expandedArgs.size() < 2) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ if (expandedArgs[1] != "CODE") {
+ auto code_iter =
+ std::find(expandedArgs.begin() + 2, expandedArgs.end(), "CODE");
+ if (code_iter == expandedArgs.end()) {
+ status.SetError("called without CODE argument");
+ } else {
+ status.SetError(
+ "called with unsupported arguments between EVAL and CODE arguments");
+ }
+ return false;
+ }
+
+ const std::string code =
+ cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.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/cmCMakeLanguageCommand.h b/Source/cmCMakeLanguageCommand.h
new file mode 100644
index 000000000..73065156b
--- /dev/null
+++ b/Source/cmCMakeLanguageCommand.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 cmCMakeLanguageCommand_h
+#define cmCMakeLanguageCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <vector>
+
+class cmExecutionStatus;
+struct cmListFileArgument;
+
+/**
+ * \brief Calls a scripted or build-in command
+ *
+ */
+bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index b5c7e9693..697d435aa 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 04f75bd50..bca75406b 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,6 +16,14 @@
#include <utility>
#include <vector>
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/curl/curl.h>
+#include <cm3p/zlib.h>
+
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -23,18 +31,12 @@
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/SystemInformation.hxx"
-
-#include "cm_curl.h"
-#include "cm_zlib.h"
#if defined(_WIN32)
# include <windows.h> // IWYU pragma: keep
#else
# include <unistd.h> // IWYU pragma: keep
#endif
-#include <cm/memory>
-#include <cmext/algorithm>
-
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestConfigureHandler.h"
@@ -52,6 +54,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.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) {
+ } 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];
- }
- // This is an undocumented / deprecated option.
- // "Track" has been renamed to "Group".
- if (this->CheckArgument(arg, "--track") && 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 7f8f913a9..a39b8fed4 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 dc9aba187..35bd681c9 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 d8be991cd..f0362585b 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmStateTypes.h"
@@ -25,77 +26,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 +67,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 +150,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 +169,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 +200,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 9e152ff80..94b6e186a 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 613ae06d1..87eb91ce1 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,9 +5,13 @@
#include <cstring>
#include <iostream>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -40,10 +44,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(
@@ -66,8 +70,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
return "";
}
if (strcmp(key, "CACHE") == 0) {
- if (const std::string* c =
- this->Makefile->GetState()->GetInitializedCacheValue(var)) {
+ if (cmProp c = this->Makefile->GetState()->GetInitializedCacheValue(var)) {
if (this->EscapeQuotes) {
return this->AddString(cmEscapeQuotes(*c));
}
@@ -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 25e689224..b46edcbea 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 896b6a98d..c94f12886 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -92,6 +92,7 @@
# include "cmAuxSourceDirectoryCommand.h"
# include "cmBuildNameCommand.h"
# include "cmCMakeHostSystemInformationCommand.h"
+# include "cmCMakeLanguageCommand.h"
# include "cmExportCommand.h"
# include "cmExportLibraryDependenciesCommand.h"
# include "cmFLTKWrapUICommand.h"
@@ -198,6 +199,7 @@ void GetScriptingCommands(cmState* state)
#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("cmake_host_system_information",
cmCMakeHostSystemInformationCommand);
+ state->AddBuiltinCommand("cmake_language", cmCMakeLanguageCommand);
state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
state->AddBuiltinCommand("remove", cmRemoveCommand);
state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 033cb6039..051eff6f7 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -73,11 +74,12 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(
void cmCommonTargetGenerator::AppendFortranFormatFlags(
std::string& flags, cmSourceFile const& source)
{
- const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+ const std::string srcfmt = source.GetSafeProperty("Fortran_FORMAT");
cmOutputConverter::FortranFormat format =
cmOutputConverter::GetFortranFormat(srcfmt);
if (format == cmOutputConverter::FortranFormatNone) {
- const char* tgtfmt = this->GeneratorTarget->GetProperty("Fortran_FORMAT");
+ std::string const& tgtfmt =
+ this->GeneratorTarget->GetSafeProperty("Fortran_FORMAT");
format = cmOutputConverter::GetFortranFormat(tgtfmt);
}
const char* var = nullptr;
@@ -97,18 +99,49 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
}
+void cmCommonTargetGenerator::AppendFortranPreprocessFlags(
+ std::string& flags, cmSourceFile const& source)
+{
+ const std::string srcpp = source.GetSafeProperty("Fortran_PREPROCESS");
+ cmOutputConverter::FortranPreprocess preprocess =
+ cmOutputConverter::GetFortranPreprocess(srcpp);
+ if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
+ std::string const& tgtpp =
+ this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
+ preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
+ }
+ const char* var = nullptr;
+ switch (preprocess) {
+ case cmOutputConverter::FortranPreprocess::Needed:
+ var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON";
+ break;
+ case cmOutputConverter::FortranPreprocess::NotNeeded:
+ var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF";
+ break;
+ default:
+ break;
+ }
+ if (var) {
+ this->LocalCommonGenerator->AppendCompileOptions(
+ flags, this->Makefile->GetSafeDefinition(var));
+ }
+}
+
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;
}
@@ -221,9 +254,9 @@ std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
{
std::string aixExports;
if (this->GeneratorTarget->Target->IsAIX()) {
- if (const char* exportAll =
+ if (cmProp exportAll =
this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
- if (cmIsOff(exportAll)) {
+ if (cmIsOff(*exportAll)) {
aixExports = "-n";
}
}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index b40a2edad..c3c3a3a88 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -45,13 +45,17 @@ protected:
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
+ void AppendFortranPreprocessFlags(std::string& flags,
+ cmSourceFile const& source);
+
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
const std::string& config) = 0;
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 11570d644..4c5f57d05 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -9,10 +9,9 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
-#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -22,6 +21,7 @@
#include "cmOrderDirectories.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -514,8 +514,8 @@ bool cmComputeLinkInformation::Compute()
// Restore the target link type so the correct system runtime
// libraries are found.
- const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
- if (cmIsOn(lss)) {
+ cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+ if (lss && cmIsOn(*lss)) {
this->SetCurrentLinkType(LinkStatic);
} else {
this->SetCurrentLinkType(this->StartLinkType);
@@ -587,33 +587,18 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
}
void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
-{ // Add the lang runtime library flags. This is activated by the presence
- // of a default selection whether or not it is overridden by a property.
- std::string defaultVar =
- cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT");
- const char* langRuntimeLibraryDefault =
- this->Makefile->GetDefinition(defaultVar);
- if (langRuntimeLibraryDefault && *langRuntimeLibraryDefault) {
- const char* runtimeLibraryValue =
- this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
- if (!runtimeLibraryValue) {
- runtimeLibraryValue = langRuntimeLibraryDefault;
- }
-
- std::string runtimeLibrary =
- cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
- runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
- this->Target));
- if (!runtimeLibrary.empty()) {
- if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
- "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" +
- runtimeLibrary)) {
- std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
- for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
- this->AddItem(i, nullptr);
- }
- }
+{
+ std::string const& runtimeLibrary =
+ this->Target->GetRuntimeLinkLibrary(lang, this->Config);
+ if (runtimeLibrary.empty()) {
+ return;
+ }
+ if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) {
+ std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
+ for (std::string const& i : libsVec) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
+ this->AddItem(i, nullptr);
}
}
}
@@ -627,7 +612,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);
}
}
@@ -855,8 +840,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
}
// Lookup the starting link type from the target (linked statically?).
- const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
- this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
+ cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+ this->StartLinkType = (lss && cmIsOn(*lss)) ? LinkStatic : LinkShared;
this->CurrentLinkType = this->StartLinkType;
}
@@ -998,15 +983,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 +1049,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 +1103,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 +1123,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 +1186,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);
}
@@ -1344,18 +1331,13 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
std::vector<std::string> implicitDirVec;
// Get platform-wide implicit directories.
- if (const char* implicitLinks = this->Makefile->GetDefinition(
- "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) {
- cmExpandList(implicitLinks, implicitDirVec);
- }
+ this->Makefile->GetDefExpandList(
+ "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", implicitDirVec);
// Get language-specific implicit directories.
std::string implicitDirVar = cmStrCat(
"CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
- if (const char* implicitDirs =
- this->Makefile->GetDefinition(implicitDirVar)) {
- cmExpandList(implicitDirs, implicitDirVec);
- }
+ this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(),
implicitDirVec.end());
@@ -1439,7 +1421,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;
@@ -1569,10 +1550,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
std::vector<std::string> implicitDirVec;
// Get platform-wide implicit directories.
- if (const char* implicitLinks = (this->Makefile->GetDefinition(
- "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"))) {
- cmExpandList(implicitLinks, implicitDirVec);
- }
+ this->Makefile->GetDefExpandList("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES",
+ implicitDirVec);
// Append library architecture to all implicit platform directories
// and add them to the set
@@ -1586,10 +1565,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get language-specific implicit directories.
std::string implicitDirVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
- if (const char* implicitDirs =
- this->Makefile->GetDefinition(implicitDirVar)) {
- cmExpandList(implicitDirs, implicitDirVec);
- }
+ this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
// Store implicit link directories.
this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());
@@ -1598,10 +1574,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
std::vector<std::string> implicitLibVec;
std::string implicitLibVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
- if (const char* implicitLibs =
- this->Makefile->GetDefinition(implicitLibVar)) {
- cmExpandList(implicitLibs, implicitLibVec);
- }
+ this->Makefile->GetDefExpandList(implicitLibVar, implicitLibVec);
// Store implicit link libraries.
for (std::string const& item : implicitLibVec) {
@@ -1613,10 +1586,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
}
// Get platform specific rpath link directories
- if (const char* rpathDirs =
- (this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"))) {
- cmExpandList(rpathDirs, this->RuntimeLinkDirs);
- }
+ this->Makefile->GetDefExpandList("CMAKE_PLATFORM_RUNTIME_PATH",
+ this->RuntimeLinkDirs);
}
std::vector<std::string> const&
@@ -1796,11 +1767,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 +1798,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 a98a608e4..41f534635 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 fda687fd3..7a3a3e8ac 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 8767386cf..5b3045db1 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConfigureFileCommand.h"
+#include <set>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -56,6 +61,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 +87,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/cmConnection.cxx b/Source/cmConnection.cxx
index 884e31432..e4d0cf11b 100644
--- a/Source/cmConnection.cxx
+++ b/Source/cmConnection.cxx
@@ -5,7 +5,7 @@
#include <cassert>
#include <cstring>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmServer.h"
@@ -20,8 +20,13 @@ void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
uv_buf_t* buf)
{
(void)(handle);
+#ifndef __clang_analyzer__
char* rawBuffer = new char[suggested_size];
*buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
+#else
+ (void)(suggested_size);
+ (void)(buf);
+#endif /* __clang_analyzer__ */
}
void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
@@ -76,6 +81,7 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
#endif
+#ifndef __clang_analyzer__
auto data = _data;
assert(this->WriteStream.get());
if (BufferStrategy) {
@@ -90,6 +96,9 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
memcpy(req->buf.base, data.c_str(), ds);
uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
on_write);
+#else
+ (void)(_data);
+#endif /* __clang_analyzer__ */
}
void cmEventBasedConnection::ReadData(const std::string& data)
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
index 7bb249404..5335a7f3c 100644
--- a/Source/cmConnection.h
+++ b/Source/cmConnection.h
@@ -9,7 +9,7 @@
#include <memory>
#include <string>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
diff --git a/Source/cmConvertMSBuildXMLToJSON.py b/Source/cmConvertMSBuildXMLToJSON.py
index 02074ba65..2be3781c5 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 73f099b98..8550d04da 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -8,9 +8,9 @@
#include <sstream>
#include <utility>
-#include "cmsys/Directory.hxx"
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
+#include "cmsys/Directory.hxx"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
@@ -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_CUDA_RUNTIME_LIBRARY =
"CMAKE_CUDA_RUNTIME_LIBRARY";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
@@ -103,29 +107,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;
}
}
@@ -298,12 +296,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()) {
@@ -571,6 +567,14 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
*msvcRuntimeLibraryDefault ? "NEW" : "OLD");
}
+ /* Set CUDA architectures policy to match outer project. */
+ if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
+ cmPolicies::NEW &&
+ testLangs.find("CUDA") != testLangs.end() &&
+ this->Makefile->GetSafeDefinition(kCMAKE_CUDA_ARCHITECTURES).empty()) {
+ fprintf(fout, "cmake_policy(SET CMP0104 OLD)\n");
+ }
+
std::string projectLangs;
for (std::string const& li : testLangs) {
projectLangs += " " + li;
@@ -721,6 +725,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_CUDA_RUNTIME_LIBRARY);
vars.insert(kCMAKE_ENABLE_EXPORTS);
vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
@@ -1044,7 +1050,9 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
std::set<std::string> deletedFiles;
for (unsigned long i = 0; i < dir.GetNumberOfFiles(); ++i) {
const char* fileName = dir.GetFile(i);
- if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0) {
+ if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0 &&
+ // Do not delete NFS temporary files.
+ !cmHasPrefix(fileName, ".nfs")) {
if (deletedFiles.insert(fileName).second) {
std::string const fullPath =
std::string(binDir).append("/").append(fileName);
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index dc7d939c9..b1e63ba65 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -4,10 +4,10 @@
#include <cm/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/kwiml/int.h>
+#include <cm3p/rhash.h>
-#include "cm_kwiml.h"
-#include "cm_rhash.h"
+#include "cmsys/FStream.hxx"
static unsigned int const cmCryptoHashAlgoToId[] = {
/* clang-format needs this comment to break after the opening brace */
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index cb73ce631..7bd036e5d 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -7,7 +7,7 @@
#include <string>
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 0dd8722cf..149f5e99e 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 d300fa569..aa572ad81 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/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 2432d2bb1..60504bab7 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -111,13 +112,13 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
!target->IsImported()) {
- const char* emulator_property =
+ cmProp emulator_property =
target->GetProperty("CROSSCOMPILING_EMULATOR");
if (!emulator_property) {
continue;
}
- cmExpandList(emulator_property, this->EmulatorsWithArguments[c]);
+ cmExpandList(*emulator_property, this->EmulatorsWithArguments[c]);
}
}
}
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index f4e4fda4d..4e2d9b08d 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 129a5f72f..d8aa73054 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 d9387758c..8cf528f73 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 e30d9597d..e05c96444 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';
}
}
}
@@ -383,9 +384,7 @@ void cmDependsC::SetupTransforms()
// Get the transformation rules.
std::vector<std::string> transformRules;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- if (const char* xform = mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS")) {
- cmExpandList(xform, transformRules, true);
- }
+ mf->GetDefExpandList("CMAKE_INCLUDE_TRANSFORMS", transformRules, true);
for (std::string const& tr : transformRules) {
this->ParseTransform(tr);
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 868c94ae9..e01faa435 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 36922029a..8f02d9551 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)
{
@@ -82,10 +80,7 @@ cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
// Get the list of definitions.
std::vector<std::string> definitions;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- if (const char* c_defines =
- mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran")) {
- cmExpandList(c_defines, definitions);
- }
+ mf->GetDefExpandList("CMAKE_TARGET_DEFINITIONS_Fortran", definitions);
// translate i.e. FOO=BAR to FOO and add it to the list of defined
// preprocessor symbols
@@ -102,10 +97,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 +180,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 +197,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";
}
@@ -248,10 +240,7 @@ void cmDependsFortran::LocateModules()
// Load information about other targets.
cmMakefile* mf = this->LocalGenerator->GetMakefile();
std::vector<std::string> infoFiles;
- if (const char* infoFilesValue =
- mf->GetDefinition("CMAKE_TARGET_LINKED_INFO_FILES")) {
- cmExpandList(infoFilesValue, infoFiles);
- }
+ mf->GetDefExpandList("CMAKE_TARGET_LINKED_INFO_FILES", infoFiles);
for (std::string const& i : infoFiles) {
std::string targetDir = cmSystemTools::GetFilenamePath(i);
std::string fname = targetDir + "/fortran.internal";
@@ -329,16 +318,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 +345,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 +353,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 +382,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 +390,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 04851152e..3e306dd61 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 516bbbfe0..fc1bbdd96 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 a673b5bbb..c545ee2b7 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 0b72a94b2..a3731c105 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/cmELF.cxx b/Source/cmELF.cxx
index 202b20504..a8d81f7c2 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -3,6 +3,7 @@
#include "cmELF.h"
#include <cstddef>
+#include <cstdint>
#include <map>
#include <memory>
#include <sstream>
@@ -12,14 +13,13 @@
#include <cm/memory>
#include <cmext/algorithm>
-#include "cmsys/FStream.hxx"
+#include <cm3p/kwiml/abi.h>
-#include "cm_kwiml.h"
+#include "cmsys/FStream.hxx"
// Include the ELF format information system header.
#if defined(__OpenBSD__)
# include <elf_abi.h>
-# include <stdint.h>
#elif defined(__HAIKU__)
# include <elf32.h>
# include <elf64.h>
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 5be5bcecf..9c53bdfbc 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -10,11 +10,10 @@
#include <vector>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/Process.h"
-#include "cm_static_string_view.hxx"
-
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -61,6 +60,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 +84,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 +244,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 561e83066..3641cb24c 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"
@@ -46,7 +47,9 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
os << "LOCAL_MODULE := ";
os << targetName << "\n";
os << "LOCAL_SRC_FILES := ";
- std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath());
+ std::string const noConfig; // FIXME: What config to use here?
+ std::string path =
+ cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig));
os << path << "\n";
}
@@ -118,13 +121,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 +168,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 d22bd4862..dd700c5ed 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 e49c17434..9f8a821e6 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -7,12 +7,11 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportBuildAndroidMKGenerator.h"
@@ -24,6 +23,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -146,7 +146,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 +183,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 6441e6f29..4d0e0996a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -125,9 +126,9 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
const std::string& propName, cmGeneratorTarget* target,
ImportPropertyMap& properties)
{
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
if (input) {
- properties[propName] = input;
+ properties[propName] = *input;
}
}
@@ -137,16 +138,16 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
if (input) {
- if (!*input) {
+ if (input->empty()) {
// Set to empty
properties[outputName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets);
@@ -174,10 +175,10 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
if (!target->IsLinkable()) {
return false;
}
- const char* input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
+ cmProp input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
if (input) {
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(
prepro, target, missingTargets, ReplaceFreeTargets);
@@ -276,8 +277,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;
@@ -342,19 +342,19 @@ void cmExportFileGenerator::PopulateSourcesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_SOURCES";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -373,7 +373,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
cmGeneratorExpression ge;
@@ -400,7 +400,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
if (!input && exportDirs.empty()) {
return;
}
- if ((input && !*input) && exportDirs.empty()) {
+ if ((input && input->empty()) && exportDirs.empty()) {
// Set to empty
properties[propName].clear();
return;
@@ -408,7 +408,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
prefixItems(exportDirs);
- std::string includes = (input ? input : "");
+ std::string includes = (input ? *input : "");
const char* sep = input ? ";" : "";
includes += sep + exportDirs;
std::string prepro =
@@ -431,19 +431,19 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DEPENDS";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -462,19 +462,19 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DIRECTORIES";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -497,11 +497,11 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
std::set<std::string>& ifaceProperties)
{
- const char* p = tgt->GetProperty(prop);
+ cmProp p = tgt->GetProperty(prop);
if (!p) {
return;
}
- std::vector<std::string> content = cmExpandedList(p);
+ std::vector<std::string> content = cmExpandedList(*p);
ifaceProperties.insert(content.begin(), content.end());
}
@@ -762,13 +762,12 @@ void cmExportFileGenerator::SetImportLinkInterface(
return;
}
- const char* propContent;
+ cmProp propContent;
- if (const char* prop_suffixed =
+ if (cmProp prop_suffixed =
target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) {
propContent = prop_suffixed;
- } else if (const char* prop =
- target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
+ } else if (cmProp prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
propContent = prop;
} else {
return;
@@ -790,13 +789,13 @@ void cmExportFileGenerator::SetImportLinkInterface(
return;
}
- if (!*propContent) {
+ if (propContent->empty()) {
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(propContent, preprocessRule);
+ cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets,
ReplaceFreeTargets);
@@ -856,8 +855,8 @@ void cmExportFileGenerator::SetImportDetailProperties(
cmGeneratorTarget::ManagedType::Native) {
std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix);
std::string propval;
- if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- propval = p;
+ if (cmProp p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ propval = *p;
} else if (target->IsCSharpOnly()) {
// C# projects do not have the /clr flag, so we set the property
// here to mark the target as (only) managed (i.e. no .lib file
@@ -925,12 +924,14 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
/* clang-format on */
// Isolate the file policy level.
- // We use 2.6 here instead of the current version because newer
- // versions of CMake should be able to export files imported by 2.6
- // until the import format changes.
+ // Support CMake versions as far back as 2.6 but also support using NEW
+ // policy settings for up to CMake 3.17 (this upper limit may be reviewed
+ // and increased from time to time). This reduces the opportunity for CMake
+ // warnings when an older export file is later used with newer CMake
+ // versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.6)\n";
+ << "cmake_policy(VERSION 2.6...3.17)\n";
/* clang-format on */
}
@@ -1116,7 +1117,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 +1216,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 +1229,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 +1245,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 9702e0e7c..80f776e25 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 6011ba4b0..7f31dd218 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -14,6 +14,7 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -95,8 +96,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 3df6a5c9a..c6b6184bb 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
@@ -58,7 +59,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
const std::string& propName, cmGeneratorTarget const* tgt,
std::string const& language, std::set<cmGeneratorTarget const*>& emitted)
{
- const char* prop = tgt->GetProperty(propName);
+ cmProp prop = tgt->GetProperty(propName);
if (!prop) {
return std::string();
}
@@ -67,11 +68,11 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
- true);
+ cmTarget::PerConfig::Yes);
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
@@ -95,11 +96,11 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::vector<std::string> props = target->GetPropertyKeys();
for (std::string const& p : props) {
- properties[p] = target->GetProperty(p);
+ 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/cmExprParserHelper.h b/Source/cmExprParserHelper.h
index eaf5dc78a..717acdcc0 100644
--- a/Source/cmExprParserHelper.h
+++ b/Source/cmExprParserHelper.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
class cmExprParserHelper
{
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index b710467c5..32b0ca93b 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;
}
@@ -723,7 +723,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
if (generator == "NMake Makefiles" || generator == "NMake Makefiles JOM") {
// For Windows ConvertToOutputPath already adds quotes when required.
// These need to be escaped, see
- // https://gitlab.kitware.com/cmake/cmake/issues/13952
+ // https://gitlab.kitware.com/cmake/cmake/-/issues/13952
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
command += " /NOLOGO /f ";
command += makefileName;
@@ -731,7 +731,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
command += target;
} else if (generator == "MinGW Makefiles") {
// no escaping of spaces in this case, see
- // https://gitlab.kitware.com/cmake/cmake/issues/10014
+ // https://gitlab.kitware.com/cmake/cmake/-/issues/10014
std::string const& makefileName = makefile;
command += " -f \"";
command += makefileName;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index de40c77d5..bf7555d98 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 78cabce17..7bc45360d 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -19,6 +19,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
@@ -187,10 +188,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';
}
}
@@ -243,8 +244,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue);
std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
- const std::string* cacheValue =
- lg.GetState()->GetInitializedCacheValue(cacheEntryName);
+ cmProp cacheValue = lg.GetState()->GetInitializedCacheValue(cacheEntryName);
// now we have both, decide which one to use
std::string valueToUse;
@@ -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);
}
@@ -430,7 +430,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
if (this->IsOutOfSourceBuild) {
// create a linked resource to CMAKE_SOURCE_DIR
// (this is not done anymore for each project because of
- // https://gitlab.kitware.com/cmake/cmake/issues/9978 and because I found
+ // https://gitlab.kitware.com/cmake/cmake/-/issues/9978 and because I found
// it actually quite confusing in bigger projects with many directories and
// projects, Alex
@@ -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 3a22846cc..01fac5a73 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 413449c78..613a94374 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -199,11 +200,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;
}
@@ -327,7 +328,7 @@ std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
std::string makefileName;
if (generator == "MinGW Makefiles") {
// no escaping of spaces in this case, see
- // https://gitlab.kitware.com/cmake/cmake/issues/10014
+ // https://gitlab.kitware.com/cmake/cmake/-/issues/10014
makefileName = makefile;
} else {
makefileName = cmSystemTools::ConvertToOutputPath(makefile);
@@ -358,14 +359,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 +388,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 +420,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/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index a56ad22f6..594969b1b 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -665,7 +665,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
-static unsigned int const CodeModelV2Minor = 0;
+static unsigned int const CodeModelV2Minor = 1;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index e183e0d97..ae076129a 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -11,9 +11,9 @@
#include <unordered_set>
#include <vector>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
class cmake;
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index 44ba96c25..1e4f3b62b 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -6,7 +6,7 @@
#include <string>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileAPI.h"
#include "cmGlobalGenerator.h"
diff --git a/Source/cmFileAPICMakeFiles.h b/Source/cmFileAPICMakeFiles.h
index a851c32f4..1ae1e4f1a 100644
--- a/Source/cmFileAPICMakeFiles.h
+++ b/Source/cmFileAPICMakeFiles.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index ef7779567..3ba943a45 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -7,9 +7,10 @@
#include <utility>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileAPI.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmake.h"
@@ -67,7 +68,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 +95,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/cmFileAPICache.h b/Source/cmFileAPICache.h
index 09d9e1ce9..2f30c76d5 100644
--- a/Source/cmFileAPICache.h
+++ b/Source/cmFileAPICache.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 955195f4f..fe331ec8d 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -17,7 +17,7 @@
#include <cmext/algorithm>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmCryptoHash.h"
#include "cmFileAPI.h"
@@ -31,6 +31,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
@@ -278,12 +279,14 @@ struct CompileData
std::string Sysroot;
std::vector<JBT<std::string>> Flags;
std::vector<JBT<std::string>> Defines;
+ std::vector<JBT<std::string>> PrecompileHeaders;
std::vector<IncludeEntry> Includes;
friend bool operator==(CompileData const& l, CompileData const& r)
{
return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
l.Flags == r.Flags && l.Defines == r.Defines &&
+ l.PrecompileHeaders == r.PrecompileHeaders &&
l.Includes == r.Includes);
}
};
@@ -313,6 +316,10 @@ struct hash<CompileData>
result = result ^ hash<std::string>()(i.Value) ^
hash<Json::ArrayIndex>()(i.Backtrace.Index);
}
+ for (auto const& i : in.PrecompileHeaders) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
return result;
}
};
@@ -369,6 +376,7 @@ class Target
Json::Value DumpPaths();
Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
+ Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -825,6 +833,11 @@ void Target::ProcessLanguage(std::string const& lang)
this->ToJBT(i),
this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
}
+ std::vector<BT<std::string>> precompileHeaders =
+ this->GT->GetPrecompileHeaders(this->Config, lang);
+ for (BT<std::string> const& pch : precompileHeaders) {
+ cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
+ }
}
Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
@@ -855,8 +868,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 +885,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 +962,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());
@@ -967,6 +993,9 @@ CompileData Target::MergeCompileData(CompileData const& fd)
// All compile groups share the sysroot of the target.
cd.Sysroot = td.Sysroot;
+ // All compile groups share the precompile headers of the target.
+ cd.PrecompileHeaders = td.PrecompileHeaders;
+
// Use target-wide flags followed by source-specific flags.
cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
@@ -1117,6 +1146,13 @@ Json::Value Target::DumpCompileData(CompileData const& cd)
}
result["defines"] = std::move(defines);
}
+ if (!cd.PrecompileHeaders.empty()) {
+ Json::Value precompileHeaders = Json::arrayValue;
+ for (JBT<std::string> const& pch : cd.PrecompileHeaders) {
+ precompileHeaders.append(this->DumpPrecompileHeader(pch));
+ }
+ result["precompileHeaders"] = std::move(precompileHeaders);
+ }
return result;
}
@@ -1132,6 +1168,14 @@ Json::Value Target::DumpInclude(CompileData::IncludeEntry const& inc)
return include;
}
+Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header)
+{
+ Json::Value precompileHeader = Json::objectValue;
+ precompileHeader["header"] = header.Value;
+ this->AddBacktrace(precompileHeader, header.Backtrace);
+ return precompileHeader;
+}
+
Json::Value Target::DumpDefine(JBT<std::string> const& def)
{
Json::Value define = Json::objectValue;
@@ -1411,9 +1455,9 @@ Json::Value Target::DumpDependency(cmTargetDepend const& td)
Json::Value Target::DumpFolder()
{
Json::Value folder;
- if (const char* f = this->GT->GetProperty("FOLDER")) {
+ if (cmProp f = this->GT->GetProperty("FOLDER")) {
folder = Json::objectValue;
- folder["name"] = f;
+ folder["name"] = *f;
}
return folder;
}
diff --git a/Source/cmFileAPICodemodel.h b/Source/cmFileAPICodemodel.h
index ffbd92863..a6c6bddae 100644
--- a/Source/cmFileAPICodemodel.h
+++ b/Source/cmFileAPICodemodel.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index e36abdce8..7101e229f 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -16,13 +16,14 @@
#include <cm/memory>
#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/kwiml/int.h>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_kwiml.h"
-#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
#include "cmAlgorithms.h"
@@ -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,10 +50,11 @@
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_curl.h"
+# include <cm3p/curl/curl.h>
# include "cmCurl.h"
# include "cmFileLockResult.h"
@@ -672,12 +676,12 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
}
}
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
std::vector<std::string> files;
bool configureDepends = false;
bool warnConfigureLate = false;
bool warnFollowedSymlinks = false;
- const cmake::WorkingMode workingMode =
- status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
+ const cmake::WorkingMode workingMode = cm->GetWorkingMode();
while (i != args.end()) {
if (*i == "LIST_DIRECTORIES") {
++i; // skip LIST_DIRECTORIES
@@ -765,12 +769,17 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
MessageType::AUTHOR_WARNING,
"Cyclic recursion detected while globbing for '" + *i + "':\n" +
globMessage.content);
- } else {
+ } else if (globMessage.type == cmsys::Glob::error) {
status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"Error has occurred while globbing for '" + *i + "' - " +
globMessage.content);
shouldExit = true;
+ } else if (cm->GetDebugOutput() || cm->GetTrace()) {
+ status.GetMakefile().IssueMessage(
+ MessageType::LOG,
+ cmStrCat("Globbing for\n ", *i, "\nEncountered an error:\n ",
+ globMessage.content));
}
}
if (shouldExit) {
@@ -790,7 +799,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
std::sort(foundFiles.begin(), foundFiles.end());
foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
foundFiles.end());
- status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry(
+ cm->AddGlobCacheEntry(
recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
(recurse ? g.GetRecurseThroughSymlinks() : false),
(g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable,
@@ -1606,7 +1615,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 +1623,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 +1765,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 +1935,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 +1978,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 +2079,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 +2368,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 +2818,314 @@ 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 = cmSystemTools::CollapseFullPath(
+ args[2], status.GetMakefile().GetCurrentBinaryDirectory());
+
+ 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 Compression;
+ std::string MTime;
+ bool Verbose = false;
+ std::vector<std::string> Paths;
+ };
+
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("FORMAT"_s, &Arguments::Format)
+ .Bind("COMPRESSION"_s, &Arguments::Compression)
+ .Bind("MTIME"_s, &Arguments::MTime)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("PATHS"_s, &Arguments::Paths);
+
+ 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",
+ "COMPRESSION", "MTIME",
+ "PATHS" };
+ 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.Compression.empty() &&
+ cm::contains(zipFileFormats, parsedArgs.Format)) {
+ status.SetError(cmStrCat("archive format ", parsedArgs.Format,
+ " does not support COMPRESSION 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 } };
+
+ cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
+ auto typeIt = compressionTypeMap.find(parsedArgs.Compression);
+ if (typeIt != compressionTypeMap.end()) {
+ compress = typeIt->second;
+ } else if (!parsedArgs.Compression.empty()) {
+ status.SetError(cmStrCat("compression type ", parsedArgs.Compression,
+ " is not supported"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (parsedArgs.Paths.empty()) {
+ status.SetError("ARCHIVE_CREATE requires a non-empty list of PATHS");
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths, compress,
+ parsedArgs.Verbose, parsedArgs.MTime,
+ parsedArgs.Format)) {
+ status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));
+ 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> Patterns;
+ };
+
+ 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("PATTERNS"_s, &Arguments::Patterns);
+
+ 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",
+ "PATTERNS" };
+ 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;
+
+ if (parsedArgs.ListOnly) {
+ if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns,
+ parsedArgs.Verbose)) {
+ status.SetError(cmStrCat("failed to list: ", inFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ } else {
+ std::string destDir = status.GetMakefile().GetCurrentBinaryDirectory();
+ 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, parsedArgs.Patterns,
+ 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 +3179,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/cmFileMonitor.h b/Source/cmFileMonitor.h
index b510a2cd2..fc75b0cee 100644
--- a/Source/cmFileMonitor.h
+++ b/Source/cmFileMonitor.h
@@ -9,7 +9,7 @@
#include <string>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
class cmRootWatcher;
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index bec99bb7e..743ac75fa 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -10,6 +10,7 @@
#include <cmext/algorithm>
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmSearchPath.h"
#include "cmState.h"
@@ -22,10 +23,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 +112,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 +297,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 +313,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 fce0b1189..4cbf09ef3 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/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 82acfedad..3e97150e7 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <array>
-#include <cstring>
#include <utility>
#include <cmext/algorithm>
@@ -280,12 +279,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
// Construct the list of path roots with no trailing slashes.
for (const char** pathName = paths; *pathName; ++pathName) {
// Get the list of paths to ignore from the variable.
- const char* ignorePath = this->Makefile->GetDefinition(*pathName);
- if ((ignorePath == nullptr) || (strlen(ignorePath) == 0)) {
- continue;
- }
-
- cmExpandList(ignorePath, ignore);
+ this->Makefile->GetDefExpandList(*pathName, ignore);
}
for (std::string& i : ignore) {
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index d5a4bde97..3242b6d97 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;
}
@@ -425,7 +433,8 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
#endif
if (name.Regex.find(testName)) {
this->TestPath = cmStrCat(path, origName);
- if (!cmSystemTools::FileIsDirectory(this->TestPath)) {
+ // Make sure the path is readable and is not a directory.
+ if (cmSystemTools::FileExists(this->TestPath, true)) {
this->DebugLibraryFound(name.Raw, dir);
// This is a matching file. Check if it is better than the
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 297c72b0f..8d5b177f2 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -24,6 +24,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmSearchPath.h"
#include "cmState.h"
@@ -279,9 +280,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 +323,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);
@@ -498,9 +505,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
case cmPolicies::NEW: {
// NEW behavior is to honor the <pkg>_ROOT variables.
std::string const rootVar = this->Name + "_ROOT";
- if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) {
- cmExpandList(pkgRoot, rootPaths, false);
- }
+ this->Makefile->GetDefExpandList(rootVar, rootPaths, false);
cmSystemTools::GetPath(rootPaths, rootVar.c_str());
} break;
}
@@ -1060,8 +1065,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 +1119,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 +1131,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/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index ae9ade73e..7058a54ea 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
#include "cmFindCommon.h"
#include "cmPolicies.h"
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 908f0c13c..4bab46976 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 3e4917262..4b88bea4d 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"
@@ -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/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 054618659..3b82e0a2d 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -4,7 +4,7 @@
#include <algorithm>
#include <cassert>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
// NOTE The declaration of `std::abs` has moved to `cmath` since C++17
// See https://en.cppreference.com/w/cpp/numeric/math/abs
// ALERT But IWYU used to lint `#include`s do not "understand"
@@ -18,8 +18,7 @@
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
@@ -114,8 +113,8 @@ bool cmForEachFunctionBlocker::ReplayItems(
// At end of for each execute recorded commands
// store the old value
std::string oldDef;
- if (mf.GetDefinition(this->Args.front())) {
- oldDef = mf.GetDefinition(this->Args.front());
+ if (auto d = mf.GetDefinition(this->Args.front())) {
+ oldDef = d;
}
auto restore = false;
@@ -187,8 +186,8 @@ bool cmForEachFunctionBlocker::ReplayZipLists(
// Store old values for iteration variables
std::map<std::string, std::string> oldDefs;
for (auto i = 0u; i < values.size(); ++i) {
- if (mf.GetDefinition(iterationVars[i])) {
- oldDefs.emplace(iterationVars[i], mf.GetDefinition(iterationVars[i]));
+ if (auto d = mf.GetDefinition(iterationVars[i])) {
+ oldDefs.emplace(iterationVars[i], d);
}
}
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
index 5778a7152..643cd823f 100644
--- a/Source/cmFunctionBlocker.cxx
+++ b/Source/cmFunctionBlocker.cxx
@@ -3,7 +3,9 @@
#include "cmFunctionBlocker.h"
#include <cassert>
+#include <memory> // IWYU pragma: keep
#include <sstream>
+#include <string> // IWYU pragma: keep
#include <utility>
#include "cmExecutionStatus.h"
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index a4c907232..b6f58bd05 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -7,8 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
#include <cmext/algorithm>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2af04b691..9cee0e6e9 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -8,8 +8,9 @@
#include "cmSystemTools.h"
#if !defined(CMAKE_BOOTSTRAP)
+# include <cm3p/zlib.h>
+
# include "cm_codecvt.hxx"
-# include "cm_zlib.h"
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
@@ -180,6 +181,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 81d1e4692..6e293d51a 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 c4be3a13b..75bba02d2 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 6d973310c..42cbe2a4c 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 4709fa024..bceff12bd 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 643ba346d..4f379cd7b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -6,6 +6,9 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
@@ -44,12 +47,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 +138,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 +196,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 f2c49bbf2..c2c5b6b6b 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 14478c22c..e4fb67e69 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -15,12 +15,13 @@
#include <cm/iterator>
#include <cm/string_view>
+#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
-#include "cm_static_string_view.hxx"
-
#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
@@ -34,6 +35,7 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateSnapshot.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,22 +909,21 @@ 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.
std::vector<std::string> mappedConfigs;
std::string mapProp = cmStrCat(
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
- if (const char* mapValue =
- context->CurrentTarget->GetProperty(mapProp)) {
- cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
- return cmContains(mappedConfigs,
- cmSystemTools::UpperCase(parameters.front()))
+ if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
+ cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
+ return cm::contains(mappedConfigs,
+ cmSystemTools::UpperCase(parameters.front()))
? "1"
: "0";
}
@@ -1039,6 +1043,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,
@@ -1130,6 +1342,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
return std::string();
}
+ if (propertyName == "ALIAS_GLOBAL"_s) {
+ if (context->LG->GetMakefile()->IsAlias(targetName)) {
+ return context->LG->GetGlobalGenerator()->IsAlias(targetName)
+ ? "TRUE"
+ : "FALSE";
+ }
+ return std::string();
+ }
target = context->LG->FindGeneratorTargetToUse(targetName);
if (!target) {
@@ -1156,6 +1376,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();
@@ -1270,8 +1491,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
std::string result;
bool haveProp = false;
- if (const char* p = target->GetProperty(propertyName)) {
- result = p;
+ if (cmProp p = target->GetProperty(propertyName)) {
+ result = *p;
haveProp = true;
} else if (evaluatingLinkLibraries) {
return std::string();
@@ -1418,11 +1639,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 {
@@ -1509,13 +1730,13 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
for (auto const& lit : testedFeatures) {
std::vector<std::string> const& langAvailable =
availableFeatures[lit.first];
- const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
+ cmProp standardDefault = context->LG->GetMakefile()->GetDef(
"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) {
+ if (standardDefault && standardDefault->empty()) {
// This compiler has no notion of language standard levels.
// All features known for the language are always available.
continue;
@@ -1523,12 +1744,12 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
if (!context->LG->GetMakefile()->HaveStandardAvailable(
target->Target, lit.first, it)) {
if (evalLL) {
- const char* l = target->GetProperty(lit.first + "_STANDARD");
+ cmProp l = target->GetProperty(lit.first + "_STANDARD");
if (!l) {
l = standardDefault;
}
assert(l);
- context->MaxLanguageStandard[target][lit.first] = l;
+ context->MaxLanguageStandard[target][lit.first] = *l;
} else {
return "0";
}
@@ -2314,6 +2535,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 36cf213bf..f2011ee66 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -17,6 +17,8 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -35,6 +37,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmOutputConverter.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmSourceFile.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 <>
@@ -236,17 +239,23 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
return ee;
}
-std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+struct EvaluatedTargetPropertyEntries
+{
+ std::vector<EvaluatedTargetPropertyEntry> Entries;
+ bool HadContextSensitiveCondition = false;
+};
+
+EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
cmGeneratorTarget const* thisTarget, std::string const& config,
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
in)
{
- std::vector<EvaluatedTargetPropertyEntry> out;
- out.reserve(in.size());
+ EvaluatedTargetPropertyEntries out;
+ out.Entries.reserve(in.size());
for (auto& entry : in) {
- out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
- dagChecker, *entry));
+ out.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ thisTarget, config, lang, dagChecker, *entry));
}
return out;
}
@@ -308,6 +317,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;
@@ -346,29 +362,29 @@ const std::string& cmGeneratorTarget::GetName() const
std::string cmGeneratorTarget::GetExportName() const
{
- const char* exportName = this->GetProperty("EXPORT_NAME");
+ cmProp exportName = this->GetProperty("EXPORT_NAME");
- if (exportName && *exportName) {
- if (!cmGeneratorExpression::IsValidTargetName(exportName)) {
+ if (exportName && !exportName->empty()) {
+ if (!cmGeneratorExpression::IsValidTargetName(*exportName)) {
std::ostringstream e;
- e << "EXPORT_NAME property \"" << exportName << "\" for \""
+ e << "EXPORT_NAME property \"" << *exportName << "\" for \""
<< this->GetName() << "\": is not valid.";
cmSystemTools::Error(e.str());
return "";
}
- return exportName;
+ return *exportName;
}
return this->GetName();
}
-const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
+cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
{
if (!cmTargetPropertyComputer::PassesWhitelist(
this->GetType(), prop, this->Makefile->GetMessenger(),
this->GetBacktrace())) {
return nullptr;
}
- if (const char* result = cmTargetPropertyComputer::GetProperty(
+ if (cmProp result = cmTargetPropertyComputer::GetProperty(
this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
return result;
}
@@ -378,13 +394,16 @@ const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
return this->Target->GetProperty(prop);
}
-const char* cmGeneratorTarget::GetSafeProperty(const std::string& prop) const
+std::string const& cmGeneratorTarget::GetSafeProperty(
+ std::string const& prop) const
{
- const char* ret = this->GetProperty(prop);
- if (!ret) {
- return "";
+ cmProp ret = this->GetProperty(prop);
+ if (ret) {
+ return *ret;
}
- return ret;
+
+ static std::string const s_empty;
+ return s_empty;
}
const char* cmGeneratorTarget::GetOutputTargetType(
@@ -473,8 +492,8 @@ std::string cmGeneratorTarget::GetOutputName(
std::string outName;
for (std::string const& p : props) {
- if (const char* outNameProp = this->GetProperty(p)) {
- outName = outNameProp;
+ if (cmProp outNameProp = this->GetProperty(p)) {
+ outName = *outNameProp;
break;
}
}
@@ -530,18 +549,46 @@ std::string cmGeneratorTarget::GetFileSuffix(
std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
{
- const char* postfix = nullptr;
+ cmProp 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;
+ }
}
- return postfix ? postfix : std::string();
+ return postfix ? *postfix : std::string();
+}
+
+std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
+ const std::string& config) const
+{
+ cmProp 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();
}
const char* cmGeneratorTarget::GetFilePrefixInternal(
@@ -574,7 +621,7 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
}
// Compute prefix value.
- const char* targetPrefix =
+ cmProp targetPrefix =
(isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
: this->GetProperty("PREFIX"));
@@ -582,17 +629,17 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
if (!language.empty() && prefixVar && *prefixVar) {
std::string langPrefix = prefixVar + std::string("_") + language;
- targetPrefix = this->Makefile->GetDefinition(langPrefix);
+ targetPrefix = this->Makefile->GetDef(langPrefix);
}
// if there is no prefix on the target nor specific language
// use the cmake definition.
if (!targetPrefix && prefixVar) {
- targetPrefix = this->Makefile->GetDefinition(prefixVar);
+ targetPrefix = this->Makefile->GetDef(prefixVar);
}
}
- return targetPrefix;
+ return targetPrefix ? targetPrefix->c_str() : nullptr;
}
const char* cmGeneratorTarget::GetFileSuffixInternal(
std::string const& config, cmStateEnums::ArtifactType artifact,
@@ -624,7 +671,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
}
// Compute suffix value.
- const char* targetSuffix =
+ cmProp targetSuffix =
(isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
: this->GetProperty("SUFFIX"));
@@ -632,17 +679,17 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
if (!language.empty() && suffixVar && *suffixVar) {
std::string langSuffix = suffixVar + std::string("_") + language;
- targetSuffix = this->Makefile->GetDefinition(langSuffix);
+ targetSuffix = this->Makefile->GetDef(langSuffix);
}
// if there is no suffix on the target nor specific language
// use the cmake definition.
if (!targetSuffix && suffixVar) {
- targetSuffix = this->Makefile->GetDefinition(suffixVar);
+ targetSuffix = this->Makefile->GetDef(suffixVar);
}
}
- return targetSuffix;
+ return targetSuffix ? targetSuffix->c_str() : nullptr;
}
void cmGeneratorTarget::ClearSourcesCache()
@@ -705,9 +752,9 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
std::vector<std::string>& result,
bool excludeImported, std::string const& language)
{
- if (const char* dirs =
+ if (cmProp dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
dagChecker, depTgt, language),
result);
}
@@ -715,9 +762,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
return;
}
- if (const char* dirs =
- depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ if (cmProp dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
+ cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
dagChecker, depTgt, language),
result);
}
@@ -773,12 +819,12 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
if (!config.empty()) {
std::string featureConfig =
cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
- if (const char* value = this->GetProperty(featureConfig)) {
- return value;
+ if (cmProp value = this->GetProperty(featureConfig)) {
+ return value->c_str();
}
}
- if (const char* value = this->GetProperty(feature)) {
- return value;
+ if (cmProp value = this->GetProperty(feature)) {
+ return value->c_str();
}
return this->LocalGenerator->GetFeature(feature, config);
}
@@ -931,51 +977,12 @@ void cmGeneratorTarget::GetExternalObjects(
IMPLEMENT_VISIT(SourceKindExternalObject);
}
-void cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& headers,
- const std::string& config) const
-{
- KindedSources const& kinded = this->GetKindedSources(config);
- headers = kinded.ExpectedResxHeaders;
-}
-
-void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile const*>& data,
- const std::string& config) const
-{
- IMPLEMENT_VISIT(SourceKindResx);
-}
-
-void cmGeneratorTarget::GetAppManifest(std::vector<cmSourceFile const*>& data,
- const std::string& config) const
-{
- IMPLEMENT_VISIT(SourceKindAppManifest);
-}
-
void cmGeneratorTarget::GetManifests(std::vector<cmSourceFile const*>& data,
const std::string& config) const
{
IMPLEMENT_VISIT(SourceKindManifest);
}
-void cmGeneratorTarget::GetCertificates(std::vector<cmSourceFile const*>& data,
- const std::string& config) const
-{
- IMPLEMENT_VISIT(SourceKindCertificate);
-}
-
-void cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
- const std::string& config) const
-{
- KindedSources const& kinded = this->GetKindedSources(config);
- headers = kinded.ExpectedXamlHeaders;
-}
-
-void cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
- const std::string& config) const
-{
- KindedSources const& kinded = this->GetKindedSources(config);
- srcs = kinded.ExpectedXamlSources;
-}
-
std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
{
if (!this->UtilityItemsDone) {
@@ -995,12 +1002,6 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
return this->UtilityItems;
}
-void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data,
- const std::string& config) const
-{
- IMPLEMENT_VISIT(SourceKindXaml);
-}
-
const std::string& cmGeneratorTarget::GetLocation(
const std::string& config) const
{
@@ -1052,7 +1053,8 @@ const std::string& cmGeneratorTarget::GetLocationForBuild() const
}
// Now handle the deprecated build-time configuration location.
- location = this->GetDirectory();
+ std::string const noConfig;
+ location = this->GetDirectory(noConfig);
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
if (cfgid && strcmp(cfgid, ".") != 0) {
location += "/";
@@ -1134,8 +1136,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
bool& maybeInterfaceProp = i->second;
// If this target itself has a non-empty property value, we are done.
- const char* p = this->GetProperty(prop);
- maybeInterfaceProp = p && *p;
+ cmProp p = this->GetProperty(prop);
+ maybeInterfaceProp = p && !p->empty();
// Otherwise, recurse to interface dependencies.
if (!maybeInterfaceProp) {
@@ -1191,7 +1193,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;
@@ -1202,13 +1203,16 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
cmGeneratorTarget const* headTarget =
context->HeadTarget ? context->HeadTarget : this;
- if (const char* p = this->GetProperty(prop)) {
+ if (cmProp p = this->GetProperty(prop)) {
result = cmGeneratorExpressionNode::EvaluateDependentExpression(
- p, context->LG, context, headTarget, &dagChecker, this);
+ *p, context->LG, context, headTarget, &dagChecker, this);
}
if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
context->Config, headTarget, usage_requirements_only)) {
+ context->HadContextSensitiveCondition =
+ context->HadContextSensitiveCondition ||
+ iface->HadContextSensitiveCondition;
for (cmLinkItem const& lib : iface->Libraries) {
// Broken code can have a target in its own link interface.
// Don't follow such link interface entries so as not to create a
@@ -1247,15 +1251,96 @@ 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,
+ EvaluatedTargetPropertyEntries& 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 (cmProp 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.Entries.emplace_back(std::move(entry));
+ }
+ }
+ }
+ }
+}
+
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
+ EvaluatedTargetPropertyEntries& entries,
bool usage_requirements_only = true)
{
if (cmLinkImplementationLibraries const* impl =
headTarget->GetLinkImplementationLibraries(config)) {
+ entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
@@ -1269,7 +1354,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
prop, &context, dagChecker, usage_requirements_only),
ee.Values);
ee.ContextDependent = context.HadContextSensitiveCondition;
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
}
@@ -1278,10 +1363,11 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
void AddObjectEntries(cmGeneratorTarget const* headTarget,
std::string const& config,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<EvaluatedTargetPropertyEntry>& entries)
+ EvaluatedTargetPropertyEntries& entries)
{
if (cmLinkImplementationLibraries const* impl =
headTarget->GetLinkImplementationLibraries(config)) {
+ entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target &&
lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
@@ -1300,23 +1386,23 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
if (cge->GetHadContextSensitiveCondition()) {
ee.ContextDependent = true;
}
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
}
}
bool processSources(cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
+ EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& srcs,
std::unordered_set<std::string>& uniqueSrcs,
bool debugSources)
{
cmMakefile* mf = tgt->Target->GetMakefile();
- bool contextDependent = false;
+ bool contextDependent = entries.HadContextSensitiveCondition;
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
if (entry.ContextDependent) {
contextDependent = true;
}
@@ -1401,14 +1487,11 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
}
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugSources =
- !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
+ !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
this->DebugSourcesDone = true;
@@ -1417,16 +1500,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
- this->SourceEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, std::string(), &dagChecker, this->SourceEntries);
std::unordered_set<std::string> uniqueSrcs;
bool contextDependentDirectSources =
processSources(this, entries, files, uniqueSrcs, debugSources);
// Collect INTERFACE_SOURCES of all direct link-dependencies.
- std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+ EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
&dagChecker, linkInterfaceSourcesEntries);
std::vector<std::string>::size_type numFilesBefore = files.size();
@@ -1437,7 +1519,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
bool contextDependentObjects = false;
std::vector<std::string>::size_type numFilesBefore2 = files.size();
if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
- std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+ EvaluatedTargetPropertyEntries linkObjectsEntries;
AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
contextDependentObjects = processSources(this, linkObjectsEntries, files,
uniqueSrcs, debugSources);
@@ -1573,10 +1655,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")) {
@@ -1595,14 +1681,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
}
} else if (ext == "resx") {
kind = SourceKindResx;
- // Build and save the name of the corresponding .h file
- // This relationship will be used later when building the project files.
- // Both names would have been auto generated from Visual Studio
- // where the user supplied the file name and Visual Studio
- // appended the suffix.
- std::string resx = sf->ResolveFullPath();
- std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
- files.ExpectedResxHeaders.insert(hFileName);
} else if (ext == "appxmanifest") {
kind = SourceKindAppManifest;
} else if (ext == "manifest") {
@@ -1611,16 +1689,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
kind = SourceKindCertificate;
} else if (ext == "xaml") {
kind = SourceKindXaml;
- // Build and save the name of the corresponding .h and .cpp file
- // This relationship will be used later when building the project files.
- // Both names would have been auto generated from Visual Studio
- // where the user supplied the file name and Visual Studio
- // appended the suffix.
- std::string xaml = sf->ResolveFullPath();
- std::string hFileName = xaml + ".h";
- std::string cppFileName = xaml + ".cpp";
- files.ExpectedXamlHeaders.insert(hFileName);
- files.ExpectedXamlSources.insert(cppFileName);
} else if (header_regex.find(sf->ResolveFullPath())) {
kind = SourceKindHeader;
} else {
@@ -1678,6 +1746,18 @@ void cmGeneratorTarget::ComputeAllConfigSources() const
}
}
+std::vector<cmGeneratorTarget::AllConfigSource>
+cmGeneratorTarget::GetAllConfigSources(SourceKind kind) const
+{
+ std::vector<AllConfigSource> result;
+ for (AllConfigSource const& source : this->GetAllConfigSources()) {
+ if (source.Kind == kind) {
+ result.push_back(source);
+ }
+ }
+ return result;
+}
+
std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const
{
std::set<std::string> languages;
@@ -1703,14 +1783,14 @@ std::string cmGeneratorTarget::GetCompilePDBName(
// Check for a per-configuration output directory target property.
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
- const char* config_name = this->GetProperty(configProp);
- if (config_name && *config_name) {
- return prefix + config_name + ".pdb";
+ cmProp config_name = this->GetProperty(configProp);
+ if (config_name && !config_name->empty()) {
+ return prefix + *config_name + ".pdb";
}
- const char* name = this->GetProperty("COMPILE_PDB_NAME");
- if (name && *name) {
- return prefix + name + ".pdb";
+ cmProp name = this->GetProperty("COMPILE_PDB_NAME");
+ if (name && !name->empty()) {
+ return prefix + *name + ".pdb";
}
return "";
@@ -1892,10 +1972,9 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
if (this->GetType() != cmStateEnums::SHARED_LIBRARY) {
return false;
}
- const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+ cmProp install_name = this->GetProperty("INSTALL_NAME_DIR");
bool use_install_name = this->MacOSXUseInstallNameDir();
- if (install_name && use_install_name &&
- std::string(install_name) == "@rpath") {
+ if (install_name && use_install_name && *install_name == "@rpath") {
install_name_is_rpath = true;
} else if (install_name && use_install_name) {
return false;
@@ -1908,7 +1987,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 {
@@ -1951,7 +2030,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
return false;
}
- const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+ cmProp macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
if (macosx_rpath_str) {
return this->GetPropertyAsBool("MACOSX_RPATH");
}
@@ -1968,10 +2047,10 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
{
- const char* build_with_install_name =
+ cmProp build_with_install_name =
this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR");
if (build_with_install_name) {
- return cmIsOn(build_with_install_name);
+ return cmIsOn(*build_with_install_name);
}
cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
@@ -2025,7 +2104,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;
@@ -2053,11 +2132,8 @@ std::string cmGeneratorTarget::GetAppBundleDirectory(
{
std::string fpath = cmStrCat(
this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
- ext = "app";
- }
- fpath += ext;
+ cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+ fpath += (ext ? *ext : "app");
if (shouldAddContentLevel(level) &&
!this->Makefile->PlatformIsAppleEmbedded()) {
fpath += "/Contents";
@@ -2079,8 +2155,10 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(
{
std::string fpath = cmStrCat(
this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
+ std::string ext;
+ if (cmProp p = this->GetProperty("BUNDLE_EXTENSION")) {
+ ext = *p;
+ } else {
if (this->IsXCTestOnApple()) {
ext = "xctest";
} else {
@@ -2103,11 +2181,8 @@ std::string cmGeneratorTarget::GetFrameworkDirectory(
{
std::string fpath = cmStrCat(
this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
- ext = "framework";
- }
- fpath += ext;
+ cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+ fpath += (ext ? *ext : "framework");
if (shouldAddFullLevel(level) &&
!this->Makefile->PlatformIsAppleEmbedded()) {
fpath += "/Versions/";
@@ -2158,11 +2233,11 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree(
{
if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
std::string dir;
- const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+ cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
- if (install_name_dir && *install_name_dir) {
- dir = install_name_dir;
+ if (install_name_dir && !install_name_dir->empty()) {
+ dir = *install_name_dir;
cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
dir =
cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config);
@@ -2207,8 +2282,8 @@ const std::string* cmGeneratorTarget::GetExportMacro() const
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::MODULE_LIBRARY ||
this->IsExecutableWithExports()) {
- if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
- this->ExportMacro = custom_export_name;
+ if (cmProp custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
+ this->ExportMacro = *custom_export_name;
} else {
std::string in = cmStrCat(this->GetName(), "_EXPORTS");
this->ExportMacro = cmSystemTools::MakeCidentifier(in);
@@ -2224,11 +2299,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);
}
@@ -2270,11 +2346,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);
@@ -2285,12 +2364,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(
@@ -2321,7 +2407,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) {
@@ -2354,40 +2440,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.
@@ -2395,12 +2477,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(
@@ -2450,9 +2570,9 @@ std::string cmGeneratorTarget::GetEffectiveFolderName() const
return effectiveFolder;
}
- const char* targetFolder = this->GetProperty("FOLDER");
+ cmProp targetFolder = this->GetProperty("FOLDER");
if (targetFolder) {
- effectiveFolder += targetFolder;
+ effectiveFolder += *targetFolder;
}
return effectiveFolder;
@@ -2644,7 +2764,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 "
@@ -2677,8 +2797,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);
@@ -2909,7 +3029,7 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
void cmGeneratorTarget::GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const
{
- const char* archs = nullptr;
+ cmProp archs = nullptr;
if (!config.empty()) {
std::string defVarName =
cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config));
@@ -2919,7 +3039,139 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if (archs) {
- cmExpandList(std::string(archs), archVec);
+ cmExpandList(*archs, archVec);
+ }
+}
+
+void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+{
+ const std::string& property = this->GetSafeProperty("CUDA_ARCHITECTURES");
+
+ if (property.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() +
+ "\".");
+ }
+ }
+
+ // If CUDA_ARCHITECTURES is false we don't add any architectures.
+ if (cmIsOff(property)) {
+ return;
+ }
+
+ struct CudaArchitecture
+ {
+ std::string name;
+ bool real{ true };
+ bool virtual_{ true };
+ };
+ std::vector<CudaArchitecture> architectures;
+
+ {
+ std::vector<std::string> options;
+ cmExpandList(property, options);
+
+ 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 += "]";
+ }
+ } else if (compiler == "Clang") {
+ for (CudaArchitecture& architecture : architectures) {
+ flags += " --cuda-gpu-arch=sm_" + architecture.name;
+
+ if (!architecture.real) {
+ Makefile->IssueMessage(
+ MessageType::WARNING,
+ "Clang doesn't support disabling CUDA real code generation.");
+ }
+
+ if (!architecture.virtual_) {
+ flags += " --no-cuda-include-ptx=sm_" + architecture.name;
+ }
+ }
+ }
+}
+
+void cmGeneratorTarget::AddCUDAToolkitFlags(std::string& flags) const
+{
+ std::string const& compiler =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+ if (compiler == "Clang") {
+ // Pass CUDA toolkit explicitly to Clang.
+ // Clang's searching for the system CUDA toolkit isn't very good and it's
+ // expected the user will explicitly pass the toolkit path.
+ // This also avoids Clang having to search for the toolkit on every
+ // invocation.
+ std::string toolkitRoot =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_LIBRARY_ROOT");
+
+ if (!toolkitRoot.empty()) {
+ flags += " --cuda-path=" +
+ this->LocalGenerator->ConvertToOutputFormat(toolkitRoot,
+ cmOutputConverter::SHELL);
+ }
}
}
@@ -2967,13 +3219,13 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
}
namespace {
-void processIncludeDirectories(
- cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
- std::vector<BT<std::string>>& includes,
- std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
+void processIncludeDirectories(cmGeneratorTarget const* tgt,
+ EvaluatedTargetPropertyEntries& entries,
+ std::vector<BT<std::string>>& includes,
+ std::unordered_set<std::string>& uniqueIncludes,
+ bool debugIncludes)
{
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
bool const fromImported = item.Target && item.Target->IsImported();
@@ -3081,22 +3333,22 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
nullptr, nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugIncludes = !this->DebugIncludesDone &&
- cmContains(debugProperties, "INCLUDE_DIRECTORIES");
+ cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugIncludesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
- this->IncludeDirectoriesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
+
+ if (lang == "Swift") {
+ AddSwiftImplicitIncludeDirectories(this, config, entries);
+ }
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries);
@@ -3118,7 +3370,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
ee.Values.emplace_back(std::move(libDir));
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
@@ -3135,22 +3387,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,
+ EvaluatedTargetPropertyEntries 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)
{
- for (EvaluatedTargetPropertyEntry const& entry : entries) {
+ bool splitOption = !processDeviceOptions;
+ for (EvaluatedTargetPropertyEntry const& entry : entries.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);
@@ -3169,6 +3437,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,
@@ -3192,22 +3517,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugOptions = !this->DebugCompileOptionsDone &&
- cmContains(debugProperties, "COMPILE_OPTIONS");
+ cm::contains(debugProperties, "COMPILE_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileOptionsDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->CompileOptionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->CompileOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
&dagChecker, entries);
@@ -3238,22 +3559,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugFeatures = !this->DebugCompileFeaturesDone &&
- cmContains(debugProperties, "COMPILE_FEATURES");
+ cm::contains(debugProperties, "COMPILE_FEATURES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileFeaturesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
- this->CompileFeaturesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, std::string(), &dagChecker, this->CompileFeaturesEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
std::string(), &dagChecker, entries);
@@ -3286,22 +3603,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
nullptr, nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugDefines = !this->DebugCompileDefinitionsDone &&
- cmContains(debugProperties, "COMPILE_DEFINITIONS");
+ cm::contains(debugProperties, "COMPILE_DEFINITIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileDefinitionsDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->CompileDefinitionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->CompileDefinitionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
&dagChecker, entries);
@@ -3309,7 +3622,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
if (!config.empty()) {
std::string configPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- const char* configProp = this->GetProperty(configPropName);
+ cmProp configProp = this->GetProperty(configPropName);
if (configProp) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
case cmPolicies::WARN: {
@@ -3320,8 +3633,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
case cmPolicies::OLD: {
std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(configProp);
- entries.emplace_back(EvaluateTargetPropertyEntry(
+ CreateTargetPropertyEntry(*configProp);
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
} break;
case cmPolicies::NEW:
@@ -3347,11 +3660,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
nullptr, nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugDefines = !this->DebugPrecompileHeadersDone &&
std::find(debugProperties.begin(), debugProperties.end(),
@@ -3361,9 +3671,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
this->DebugPrecompileHeadersDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->PrecompileHeadersEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->PrecompileHeadersEntries);
AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
&dagChecker, entries);
@@ -3376,7 +3685,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") {
@@ -3387,11 +3697,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
return std::string();
}
const cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
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);
@@ -3402,7 +3712,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
filename = cmStrCat(
@@ -3423,7 +3733,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) {
@@ -3482,27 +3793,28 @@ 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();
}
std::string& filename = inserted.first->second;
const cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
filename =
@@ -3518,13 +3830,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");
@@ -3541,16 +3855,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();
}
@@ -3560,15 +3875,20 @@ std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
pchSource, false, cmSourceFileLocationKind::Known);
filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf));
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ cmSystemTools::ReplaceString(
+ filename, this->GetGlobalGenerator()->GetCMakeCFGIntDir(), config);
+ }
}
return inserted.first->second;
}
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;
@@ -3588,20 +3908,20 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
};
cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
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 +3929,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 +3958,33 @@ 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");
+
+ std::string const& 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 +4013,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) {
@@ -3688,37 +4036,83 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ 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;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->LinkOptionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->LinkOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
&dagChecker, entries,
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 +4158,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;
@@ -3835,14 +4186,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
nullptr, nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries;
- if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
- std::vector<std::string> options = cmExpandedList(linkOptions);
+ EvaluatedTargetPropertyEntries entries;
+ if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
+ std::vector<std::string> options = cmExpandedList(*linkOptions);
for (const auto& option : options) {
std::unique_ptr<TargetPropertyEntry> entry =
CreateTargetPropertyEntry(option);
- entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
- &dagChecker, *entry));
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
}
}
processOptions(this, entries, result, uniqueOptions, false,
@@ -3853,12 +4204,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
namespace {
void processLinkDirectories(cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
+ EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& directories,
std::unordered_set<std::string>& uniqueDirectories,
bool debugDirectories)
{
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
@@ -3944,22 +4295,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
nullptr);
std::vector<std::string> debugProperties;
- const char* debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+ debugProperties);
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
- cmContains(debugProperties, "LINK_DIRECTORIES");
+ cm::contains(debugProperties, "LINK_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkDirectoriesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->LinkDirectoriesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->LinkDirectoriesEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
&dagChecker, entries,
@@ -3990,14 +4337,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries;
- if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(linkDepends);
+ EvaluatedTargetPropertyEntries entries;
+ if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) {
+ std::vector<std::string> depends = cmExpandedList(*linkDepends);
for (const auto& depend : depends) {
std::unique_ptr<TargetPropertyEntry> entry =
CreateTargetPropertyEntry(depend);
- entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
- &dagChecker, *entry));
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
}
}
AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
@@ -4152,8 +4499,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
}
// Check for library version properties.
- const char* version = this->GetProperty("VERSION");
- const char* soversion = this->GetProperty("SOVERSION");
+ cmProp version = this->GetProperty("VERSION");
+ cmProp soversion = this->GetProperty("SOVERSION");
if (!this->HasSOName(config) ||
this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
this->IsFrameworkOnApple()) {
@@ -4188,17 +4535,18 @@ 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,
targetNames.Base, suffix, targetNames.Output,
- soversion);
+ (soversion ? soversion->c_str() : nullptr));
// The library's real name on disk.
this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base,
- suffix, targetNames.Output, version);
+ suffix, targetNames.Output,
+ (version ? version->c_str() : nullptr));
}
// The import library name.
@@ -4231,10 +4579,13 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
// This versioning is supported only for executables and then only
// when the platform supports symbolic links.
#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* version = 0;
+ const char* version = nullptr;
#else
// Check for executable version properties.
- const char* version = this->GetProperty("VERSION");
+ const char* version = nullptr;
+ if (cmProp p = this->GetProperty("VERSION")) {
+ version = p->c_str();
+ }
if (this->GetType() != cmStateEnums::EXECUTABLE ||
this->Makefile->IsOn("XCODE")) {
version = nullptr;
@@ -4364,15 +4715,23 @@ 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")) {
+ if (cmProp soversion = this->GetProperty("SOVERSION")) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
!isImportedLibraryArtifact &&
this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) {
outBase += "-";
- outBase += soversion;
+ outBase += *soversion;
}
}
@@ -4403,8 +4762,8 @@ std::string cmGeneratorTarget::GetPDBOutputName(
props.emplace_back("PDB_NAME");
for (std::string const& p : props) {
- if (const char* outName = this->GetProperty(p)) {
- base = outName;
+ if (cmProp outName = this->GetProperty(p)) {
+ base = *outName;
break;
}
}
@@ -4430,8 +4789,8 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
props.emplace_back("PDB_NAME");
for (std::string const& p : props) {
- if (const char* outName = this->GetProperty(p)) {
- base = outName;
+ if (cmProp outName = this->GetProperty(p)) {
+ base = *outName;
break;
}
}
@@ -4503,16 +4862,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/");
@@ -4533,8 +4892,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
this->SourceFileFlagsConstructed = true;
// Process public headers to mark the source files.
- if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("PUBLIC_HEADER")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4546,8 +4905,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process private headers after public headers so that they take
// precedence if a file is listed in both.
- if (const char* files = this->GetProperty("PRIVATE_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("PRIVATE_HEADER")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4558,8 +4917,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
}
// Mark sources listed as resources.
- if (const char* files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("RESOURCE")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4586,9 +4945,9 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
this->GetLinkImplementationClosure(config);
for (cmGeneratorTarget const* li : deps) {
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
- if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
+ if (cmProp prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
std::vector<std::string> props; \
- cmExpandList(prop, props); \
+ cmExpandList(*prop, props); \
compat.Props##x.insert(props.begin(), props.end()); \
}
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -4696,12 +5055,12 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
const std::string& config, CompatibleType t,
PropertyType* /*unused*/)
{
- const char* prop = dependee->GetProperty(propName);
+ cmProp prop = dependee->GetProperty(propName);
if (!prop) {
return;
}
- std::vector<std::string> props = cmExpandedList(prop);
+ std::vector<std::string> props = cmExpandedList(*prop);
std::string pdir =
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
@@ -4855,7 +5214,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.";
@@ -4930,8 +5290,9 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
return tgt->GetPropertyAsBool(prop);
}
- const char* value = tgt->GetProperty(prop);
- return cmIsOn(genexInterpreter->Evaluate(value, prop));
+ cmProp value = tgt->GetProperty(prop);
+ return cmIsOn(
+ genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop));
}
template <>
@@ -4939,13 +5300,14 @@ const char* getTypedProperty<const char*>(
cmGeneratorTarget const* tgt, const std::string& prop,
cmGeneratorExpressionInterpreter* genexInterpreter)
{
- const char* value = tgt->GetProperty(prop);
+ cmProp value = tgt->GetProperty(prop);
if (genexInterpreter == nullptr) {
- return value;
+ return value ? value->c_str() : nullptr;
}
- return genexInterpreter->Evaluate(value, prop).c_str();
+ return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop)
+ .c_str();
}
template <>
@@ -4953,13 +5315,13 @@ std::string getTypedProperty<std::string>(
cmGeneratorTarget const* tgt, const std::string& prop,
cmGeneratorExpressionInterpreter* genexInterpreter)
{
- const char* value = tgt->GetProperty(prop);
+ cmProp value = tgt->GetProperty(prop);
if (genexInterpreter == nullptr) {
- return valueAsString(value);
+ return valueAsString(value ? value->c_str() : nullptr);
}
- return genexInterpreter->Evaluate(value, prop);
+ return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop);
}
template <typename PropertyType>
@@ -5104,7 +5466,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 +5506,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 +5599,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
{
@@ -5323,13 +5692,13 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property,
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
- if (const char* version = this->GetProperty(property)) {
+ if (cmProp version = this->GetProperty(property)) {
// Try to parse the version number and store the results that were
// successfully parsed.
int parsed_major;
int parsed_minor;
int parsed_patch;
- switch (sscanf(version, "%d.%d.%d", &parsed_major, &parsed_minor,
+ switch (sscanf(version->c_str(), "%d.%d.%d", &parsed_major, &parsed_minor,
&parsed_patch)) {
case 3:
patch = parsed_patch;
@@ -5346,6 +5715,25 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property,
}
}
+std::string cmGeneratorTarget::GetRuntimeLinkLibrary(
+ std::string const& lang, std::string const& config) const
+{
+ // This is activated by the presence of a default selection whether or
+ // not it is overridden by a property.
+ cmProp runtimeLibraryDefault = this->Makefile->GetDef(
+ cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"));
+ if (!runtimeLibraryDefault || runtimeLibraryDefault->empty()) {
+ return std::string();
+ }
+ cmProp runtimeLibraryValue =
+ this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
+ if (!runtimeLibraryValue) {
+ runtimeLibraryValue = runtimeLibraryDefault;
+ }
+ return cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+ *runtimeLibraryValue, this->LocalGenerator, config, this));
+}
+
std::string cmGeneratorTarget::GetFortranModuleDirectory(
std::string const& working_dir) const
{
@@ -5363,8 +5751,8 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
{
std::string mod_dir;
std::string target_mod_dir;
- if (const char* prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
- target_mod_dir = prop;
+ if (cmProp prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
+ target_mod_dir = *prop;
} else {
std::string const& default_mod_dir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -5395,11 +5783,11 @@ std::string cmGeneratorTarget::GetFrameworkVersion() const
{
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
- if (const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) {
- return fversion;
+ if (cmProp fversion = this->GetProperty("FRAMEWORK_VERSION")) {
+ return *fversion;
}
- if (const char* tversion = this->GetProperty("VERSION")) {
- return tversion;
+ if (cmProp tversion = this->GetProperty("VERSION")) {
+ return *tversion;
}
return "A";
}
@@ -5429,14 +5817,11 @@ void cmGeneratorTarget::ReportPropertyOrigin(
const std::string& compatibilityType) const
{
std::vector<std::string> debugProperties;
- const char* debugProp = this->Target->GetMakefile()->GetDefinition(
- "CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp) {
- cmExpandList(debugProp, debugProperties);
- }
+ this->Target->GetMakefile()->GetDefExpandList(
+ "CMAKE_DEBUG_TARGET_PROPERTIES", 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 +5877,44 @@ 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& hadContextSensitiveCondition,
+ 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();
+ hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
+ 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 +5927,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 +5945,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 +5956,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 +5974,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 +5985,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 +6005,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;
}
}
@@ -5612,11 +6022,11 @@ void cmGeneratorTarget::ComputeLinkInterface(
// How many repetitions are needed if this library has cyclic
// dependencies?
std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix);
- if (const char* config_reps = this->GetProperty(propName)) {
- sscanf(config_reps, "%u", &iface.Multiplicity);
- } else if (const char* reps =
+ if (cmProp config_reps = this->GetProperty(propName)) {
+ sscanf(config_reps->c_str(), "%u", &iface.Multiplicity);
+ } else if (cmProp reps =
this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) {
- sscanf(reps, "%u", &iface.Multiplicity);
+ sscanf(reps->c_str(), "%u", &iface.Multiplicity);
}
}
}
@@ -5638,7 +6048,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)
@@ -5767,21 +6176,21 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
}
// Select an output directory.
- if (const char* config_outdir = this->GetProperty(configProp)) {
+ if (cmProp config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
config);
// Skip per-configuration subdirectory.
conf.clear();
- } else if (const char* outdir = this->GetProperty(propertyName)) {
+ } else if (cmProp outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
out =
- cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+ cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
- if (out != outdir) {
+ if (out != *outdir) {
conf.clear();
}
} else if (this->GetType() == cmStateEnums::EXECUTABLE) {
@@ -5843,21 +6252,21 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
}
// Select an output directory.
- if (const char* config_outdir = this->GetProperty(configProp)) {
+ if (cmProp config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
config);
// Skip per-configuration subdirectory.
conf.clear();
- } else if (const char* outdir = this->GetProperty(propertyName)) {
+ } else if (cmProp outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
out =
- cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+ cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
- if (out != outdir) {
+ if (out != *outdir) {
conf.clear();
}
}
@@ -5903,12 +6312,13 @@ bool cmGeneratorTarget::GetRPATH(const std::string& config,
const std::string& prop,
std::string& rpath) const
{
- const char* value = this->GetProperty(prop);
+ cmProp value = this->GetProperty(prop);
if (!value) {
return false;
}
- rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config);
+ rpath =
+ cmGeneratorExpression::Evaluate(*value, this->LocalGenerator, config);
return true;
}
@@ -5927,7 +6337,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
- const char* explicitLibraries = nullptr;
+ cmProp explicitLibraries = nullptr;
std::string linkIfaceProp;
bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
@@ -5956,10 +6366,10 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
!this->PolicyWarnedCMP0022) {
// Compare the explicitly set old link interface properties to the
// preferred new link interface property one and warn if different.
- const char* newExplicitLibraries =
+ cmProp newExplicitLibraries =
this->GetProperty("INTERFACE_LINK_LIBRARIES");
if (newExplicitLibraries &&
- strcmp(newExplicitLibraries, explicitLibraries) != 0) {
+ (*newExplicitLibraries != *explicitLibraries)) {
std::ostringstream w;
/* clang-format off */
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
@@ -5968,9 +6378,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
linkIfaceProp << " properties."
"\n"
"INTERFACE_LINK_LIBRARIES:\n"
- " " << newExplicitLibraries << "\n" <<
+ " " << *newExplicitLibraries << "\n" <<
linkIfaceProp << ":\n"
- " " << explicitLibraries << "\n";
+ " " << *explicitLibraries << "\n";
/* clang-format on */
this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
this->PolicyWarnedCMP0022 = true;
@@ -5989,9 +6399,11 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
if (explicitLibraries) {
// The interface libraries have been explicitly set.
- this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
- usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
+ headTarget, usage_requirements_only, iface.Libraries,
+ iface.HadHeadSensitiveCondition,
+ iface.HadContextSensitiveCondition,
+ 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
@@ -6009,11 +6421,15 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// preferred new link interface property and warn if different.
std::vector<cmLinkItem> ifaceLibs;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
- if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
+ if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
bool hadHeadSensitiveConditionDummy = false;
- this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+ bool hadContextSensitiveConditionDummy = false;
+ bool hadLinkLanguageSensitiveConditionDummy = false;
+ this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
headTarget, usage_requirements_only, ifaceLibs,
- hadHeadSensitiveConditionDummy);
+ hadHeadSensitiveConditionDummy,
+ hadContextSensitiveConditionDummy,
+ 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,9 @@ 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.HadContextSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -6132,17 +6553,17 @@ 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;
}
// Get the link interface.
{
std::string linkProp = "INTERFACE_LINK_LIBRARIES";
- const char* propertyLibs = this->GetProperty(linkProp);
+ cmProp propertyLibs = this->GetProperty(linkProp);
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (!propertyLibs) {
@@ -6157,12 +6578,12 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
if (propertyLibs) {
info.LibrariesProp = linkProp;
- info.Libraries = propertyLibs;
+ info.Libraries = *propertyLibs;
}
}
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
if (loc) {
- info.LibName = loc;
+ info.LibName = *loc;
}
return;
}
@@ -6172,47 +6593,46 @@ 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)) {
- info.Location = config_location;
- } else if (const char* location = this->GetProperty("IMPORTED_LOCATION")) {
- info.Location = location;
+ if (cmProp config_location = this->GetProperty(impProp)) {
+ info.Location = *config_location;
+ } else if (cmProp location = this->GetProperty("IMPORTED_LOCATION")) {
+ info.Location = *location;
}
}
// Get the soname.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string soProp = cmStrCat("IMPORTED_SONAME", suffix);
- if (const char* config_soname = this->GetProperty(soProp)) {
- info.SOName = config_soname;
- } else if (const char* soname = this->GetProperty("IMPORTED_SONAME")) {
- info.SOName = soname;
+ if (cmProp config_soname = this->GetProperty(soProp)) {
+ info.SOName = *config_soname;
+ } else if (cmProp soname = this->GetProperty("IMPORTED_SONAME")) {
+ info.SOName = *soname;
}
}
// Get the "no-soname" mark.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix);
- if (const char* config_no_soname = this->GetProperty(soProp)) {
- info.NoSOName = cmIsOn(config_no_soname);
- } else if (const char* no_soname =
- this->GetProperty("IMPORTED_NO_SONAME")) {
- info.NoSOName = cmIsOn(no_soname);
+ if (cmProp config_no_soname = this->GetProperty(soProp)) {
+ info.NoSOName = cmIsOn(*config_no_soname);
+ } else if (cmProp no_soname = this->GetProperty("IMPORTED_NO_SONAME")) {
+ info.NoSOName = cmIsOn(*no_soname);
}
}
// 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);
- if (const char* config_implib = this->GetProperty(impProp)) {
- info.ImportLibrary = config_implib;
- } else if (const char* implib = this->GetProperty("IMPORTED_IMPLIB")) {
- info.ImportLibrary = implib;
+ if (cmProp config_implib = this->GetProperty(impProp)) {
+ info.ImportLibrary = *config_implib;
+ } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+ info.ImportLibrary = *implib;
}
}
@@ -6220,11 +6640,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
{
std::string linkProp =
cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix);
- if (const char* config_libs = this->GetProperty(linkProp)) {
- info.SharedDeps = config_libs;
- } else if (const char* libs =
+ if (cmProp config_libs = this->GetProperty(linkProp)) {
+ info.SharedDeps = *config_libs;
+ } else if (cmProp libs =
this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) {
- info.SharedDeps = libs;
+ info.SharedDeps = *libs;
}
}
@@ -6232,21 +6652,21 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (this->LinkLanguagePropagatesToDependents()) {
std::string linkProp =
cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix);
- if (const char* config_libs = this->GetProperty(linkProp)) {
- info.Languages = config_libs;
- } else if (const char* libs =
+ if (cmProp config_libs = this->GetProperty(linkProp)) {
+ info.Languages = *config_libs;
+ } else if (cmProp libs =
this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) {
- info.Languages = libs;
+ info.Languages = *libs;
}
}
// Get information if target is managed assembly.
{
std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
- if (auto pc = this->GetProperty(linkProp + suffix)) {
- info.Managed = this->CheckManagedType(pc);
- } else if (auto p = this->GetProperty(linkProp)) {
- info.Managed = this->CheckManagedType(p);
+ if (cmProp pc = this->GetProperty(linkProp + suffix)) {
+ info.Managed = this->CheckManagedType(*pc);
+ } else if (cmProp p = this->GetProperty(linkProp)) {
+ info.Managed = this->CheckManagedType(*p);
}
}
@@ -6254,11 +6674,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
std::string linkProp =
cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
- if (const char* config_reps = this->GetProperty(linkProp)) {
- sscanf(config_reps, "%u", &info.Multiplicity);
- } else if (const char* reps =
+ if (cmProp config_reps = this->GetProperty(linkProp)) {
+ sscanf(config_reps->c_str(), "%u", &info.Multiplicity);
+ } else if (cmProp reps =
this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) {
- sscanf(reps, "%u", &info.Multiplicity);
+ sscanf(reps->c_str(), "%u", &info.Multiplicity);
}
}
}
@@ -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);
@@ -6426,15 +6854,15 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
bool cmGeneratorTarget::IsDeprecated() const
{
- const char* deprecation = this->GetProperty("DEPRECATION");
- return deprecation && *deprecation;
+ cmProp deprecation = this->GetProperty("DEPRECATION");
+ return deprecation && !deprecation->empty();
}
std::string cmGeneratorTarget::GetDeprecation() const
{
// find DEPRECATION property
- if (const char* deprecation = this->GetProperty("DEPRECATION")) {
- return deprecation;
+ if (cmProp deprecation = this->GetProperty("DEPRECATION")) {
+ return *deprecation;
}
return std::string();
}
@@ -6491,9 +6919,9 @@ bool cmGeneratorTarget::IsCSharpOnly() const
std::set<std::string> languages = this->GetAllConfigCompileLanguages();
// Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
- const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
- if (linkLang && *linkLang) {
- languages.insert(linkLang);
+ cmProp linkLang = this->GetProperty("LINKER_LANGUAGE");
+ if (linkLang && !linkLang->empty()) {
+ languages.insert(*linkLang);
}
return languages.size() == 1 && languages.count("CSharp") > 0;
}
@@ -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,18 @@ 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->GetHadContextSensitiveCondition()) {
+ impl.HadContextSensitiveCondition = true;
+ }
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ impl.HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& lib : llibs) {
if (this->IsLinkLookupScope(lib, lg)) {
@@ -6598,6 +7033,13 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
// Skip entries that resolve to the target itself or are empty.
std::string name = this->CheckCMP0004(lib);
+ if (this->GetPolicyStatusCMP0108() == cmPolicies::NEW) {
+ // resolve alias name
+ auto target = this->Makefile->FindTargetToUse(name);
+ if (target) {
+ name = target->GetName();
+ }
+ }
if (name == this->GetName() || name.empty()) {
if (name == this->GetName()) {
bool noMessage = false;
@@ -6867,8 +7309,8 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
}
// Check for explicitly set clr target property.
- if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- return this->CheckManagedType(clr);
+ if (cmProp clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ return this->CheckManagedType(*clr);
}
// C# targets are always managed. This language specific check
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index d81bb3d85..3aedbf53e 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -18,6 +18,7 @@
#include "cmLinkItem.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
class cmComputeLinkInformation;
@@ -76,9 +77,9 @@ public:
std::vector<std::string> GetPropertyKeys() const;
//! 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;
+ std::string const& GetSafeProperty(std::string const& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
void GetSourceFiles(std::vector<cmSourceFile*>& files,
const std::string& config) const;
@@ -115,9 +116,6 @@ public:
struct KindedSources
{
std::vector<SourceAndKind> Sources;
- std::set<std::string> ExpectedResxHeaders;
- std::set<std::string> ExpectedXamlHeaders;
- std::set<std::string> ExpectedXamlSources;
bool Initialized = false;
};
@@ -135,6 +133,9 @@ public:
per-source configurations assigned. */
std::vector<AllConfigSource> const& GetAllConfigSources() const;
+ /** Get all sources needed for all configurations with given kind. */
+ std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const;
+
/** Get all languages used to compile sources in any configuration.
This excludes the languages of objects from object libraries. */
std::set<std::string> GetAllConfigCompileLanguages() const;
@@ -149,8 +150,6 @@ public:
void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
- void GetResxSources(std::vector<cmSourceFile const*>&,
- const std::string& config) const;
void GetExternalObjects(std::vector<cmSourceFile const*>&,
const std::string& config) const;
void GetHeaderSources(std::vector<cmSourceFile const*>&,
@@ -159,20 +158,8 @@ public:
const std::string& config) const;
void GetCustomCommands(std::vector<cmSourceFile const*>&,
const std::string& config) const;
- void GetExpectedResxHeaders(std::set<std::string>&,
- const std::string& config) const;
- void GetAppManifest(std::vector<cmSourceFile const*>&,
- const std::string& config) const;
void GetManifests(std::vector<cmSourceFile const*>&,
const std::string& config) const;
- void GetCertificates(std::vector<cmSourceFile const*>&,
- const std::string& config) const;
- void GetXamlSources(std::vector<cmSourceFile const*>&,
- const std::string& config) const;
- void GetExpectedXamlHeaders(std::set<std::string>&,
- const std::string& config) const;
- void GetExpectedXamlSources(std::set<std::string>&,
- const std::string& config) const;
std::set<cmLinkItem> const& GetUtilityItems() const;
@@ -204,6 +191,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,
@@ -225,7 +230,7 @@ public:
/** Get the full path to the target according to the settings in its
makefile and the configuration type. */
std::string GetFullPath(
- const std::string& config = "",
+ const std::string& config,
cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact,
bool realname = false) const;
std::string NormalGetFullPath(const std::string& config,
@@ -263,7 +268,7 @@ public:
/** Get the full name of the target according to the settings in its
makefile. */
- std::string GetFullName(const std::string& config = "",
+ std::string GetFullName(const std::string& config,
cmStateEnums::ArtifactType artifact =
cmStateEnums::RuntimeBinaryArtifact) const;
@@ -306,8 +311,7 @@ public:
std::string GetSOName(const std::string& config) const;
void GetFullNameComponents(std::string& prefix, std::string& base,
- std::string& suffix,
- const std::string& config = "",
+ std::string& suffix, const std::string& config,
cmStateEnums::ArtifactType artifact =
cmStateEnums::RuntimeBinaryArtifact) const;
@@ -357,7 +361,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 +425,9 @@ public:
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
+ void AddCUDAArchitectureFlags(std::string& flags) const;
+ void AddCUDAToolkitFlags(std::string& flags) const;
+
std::string GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
std::string const& config) const;
@@ -479,17 +485,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;
@@ -513,7 +525,7 @@ public:
configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
output directory is given. */
- std::string GetDirectory(const std::string& config = "",
+ std::string GetDirectory(const std::string& config,
cmStateEnums::ArtifactType artifact =
cmStateEnums::RuntimeBinaryArtifact) const;
@@ -521,7 +533,7 @@ public:
If the configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
compiler pdb output directory is given. */
- std::string GetCompilePDBDirectory(const std::string& config = "") const;
+ std::string GetCompilePDBDirectory(const std::string& config) const;
/** Get sources that must be built before the given source. */
std::vector<cmSourceFile*> const* GetSourceDepends(
@@ -550,7 +562,7 @@ public:
std::string GetPDBOutputName(const std::string& config) const;
/** Get the name of the pdb file for the target. */
- std::string GetPDBName(const std::string& config = "") const;
+ std::string GetPDBName(const std::string& config) const;
/** Whether this library has soname enabled and platform supports it. */
bool HasSOName(const std::string& config) const;
@@ -568,10 +580,10 @@ public:
bool IsNullImpliedByLinkLibraries(const std::string& p) const;
/** Get the name of the compiler pdb file for the target. */
- std::string GetCompilePDBName(const std::string& config = "") const;
+ std::string GetCompilePDBName(const std::string& config) const;
/** Get the path for the MSVC /Fd option for this target. */
- std::string GetCompilePDBPath(const std::string& config = "") const;
+ std::string GetCompilePDBPath(const std::string& config) const;
// Get the target base name.
std::string GetOutputName(const std::string& config,
@@ -589,6 +601,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.
*/
@@ -768,6 +783,9 @@ public:
const std::string& fallback_property,
int& major, int& minor, int& patch) const;
+ std::string GetRuntimeLinkLibrary(std::string const& lang,
+ std::string const& config) const;
+
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
const std::string& GetSourcesProperty() const;
@@ -816,8 +834,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 +870,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 +892,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 +929,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 +976,9 @@ private:
const cmGeneratorTarget* headTarget,
bool usage_requirements_only,
std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const;
+ bool& hadHeadSensitiveCondition,
+ bool& hadContextSensitiveCondition,
+ 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 ff4e312f3..79cbe443c 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -7,6 +7,7 @@
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -23,25 +24,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 64438d50a..fa4a40bef 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -7,7 +7,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
-#include "cmStringAlgorithms.h"
+#include "cmProperty.h"
#include "cmSystemTools.h"
namespace {
@@ -37,14 +37,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 +86,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 7d91a7570..811421a6d 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/cmGetPipes.cxx b/Source/cmGetPipes.cxx
index 4eda1c54a..a5b64692e 100644
--- a/Source/cmGetPipes.cxx
+++ b/Source/cmGetPipes.cxx
@@ -2,10 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetPipes.h"
+#include <cm3p/uv.h>
#include <fcntl.h>
-#include "cm_uv.h"
-
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h>
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 947d893db..cba770479 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -11,6 +11,7 @@
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmPropertyDefinition.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -48,7 +49,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
const std::string& propertyName);
bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName);
+ const std::string& propertyName,
+ cmMakefile& directory_makefile,
+ bool source_file_paths_should_be_absolute);
bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
const std::string& propertyName);
@@ -78,6 +81,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
std::string name;
std::string propertyName;
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
// Get the scope from which to get the property.
cmProperty::ScopeType scope;
if (args[1] == "GLOBAL") {
@@ -111,7 +119,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
DoingNone,
DoingName,
DoingProperty,
- DoingType
+ DoingType,
+ DoingSourceDirectory,
+ DoingSourceTargetDirectory
};
Doing doing = DoingName;
for (unsigned int i = 2; i < args.size(); ++i) {
@@ -132,6 +142,20 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
} else if (doing == DoingName) {
doing = DoingNone;
name = args[i];
+ } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+ args[i] == "DIRECTORY") {
+ doing = DoingSourceDirectory;
+ source_file_directory_option_enabled = true;
+ } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+ args[i] == "TARGET_DIRECTORY") {
+ doing = DoingSourceTargetDirectory;
+ source_file_target_option_enabled = true;
+ } else if (doing == DoingSourceDirectory) {
+ source_file_directories.push_back(args[i]);
+ doing = DoingNone;
+ } else if (doing == DoingSourceTargetDirectory) {
+ source_file_target_directories.push_back(args[i]);
+ doing = DoingNone;
} else if (doing == DoingProperty) {
doing = DoingNone;
propertyName = args[i];
@@ -147,6 +171,16 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
return false;
}
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+
// Compute requested output.
if (infoType == OutBriefDoc) {
// Lookup brief documentation.
@@ -180,6 +214,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
}
} else {
// Dispatch property getting.
+ cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled ||
+ source_file_target_option_enabled;
+
switch (scope) {
case cmProperty::GLOBAL:
return HandleGlobalMode(status, name, infoType, variable,
@@ -191,8 +230,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
return HandleTargetMode(status, name, infoType, variable,
propertyName);
case cmProperty::SOURCE_FILE:
- return HandleSourceMode(status, name, infoType, variable,
- propertyName);
+ return HandleSourceMode(status, name, infoType, variable, propertyName,
+ directory_scope_mf,
+ source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, name, infoType, variable, propertyName);
case cmProperty::VARIABLE:
@@ -241,8 +281,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 +297,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 +329,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,
@@ -308,14 +344,24 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
}
if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
- if (propertyName == "ALIASED_TARGET") {
+ if (propertyName == "ALIASED_TARGET" || propertyName == "ALIAS_GLOBAL") {
if (status.GetMakefile().IsAlias(name)) {
- return StoreResult(infoType, status.GetMakefile(), variable,
- target->GetName().c_str());
+ if (propertyName == "ALIASED_TARGET") {
+
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ target->GetName().c_str());
+ }
+ if (propertyName == "ALIAS_GLOBAL") {
+ return StoreResult(
+ infoType, status.GetMakefile(), variable,
+ status.GetMakefile().GetGlobalGenerator()->IsAlias(name)
+ ? "TRUE"
+ : "FALSE");
+ }
}
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 +371,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."));
@@ -334,7 +381,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName)
+ const std::string& propertyName,
+ cmMakefile& directory_makefile,
+ const bool source_file_paths_should_be_absolute)
{
if (name.empty()) {
status.SetError("not given name for SOURCE scope.");
@@ -342,12 +391,17 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
}
// Get the source file.
- if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+ const std::string source_file_absolute_path =
+ SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+ status, name, source_file_paths_should_be_absolute);
+ if (cmSourceFile* sf =
+ directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
return StoreResult(infoType, status.GetMakefile(), variable,
sf->GetPropertyForUser(propertyName));
}
status.SetError(
- cmStrCat("given SOURCE name that could not be found or created: ", name));
+ cmStrCat("given SOURCE name that could not be found or created: ",
+ source_file_absolute_path));
return false;
}
@@ -393,12 +447,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/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index eefdc6ccb..5395bc8ef 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -4,35 +4,71 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- if (args.size() != 3) {
+ std::vector<std::string>::size_type args_size = args.size();
+ if (args_size != 3 && args_size != 5) {
status.SetError("called with incorrect number of arguments");
return false;
}
+
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
+ int property_arg_index = 2;
+ if (args[2] == "DIRECTORY" && args_size == 5) {
+ property_arg_index = 4;
+ source_file_directory_option_enabled = true;
+ source_file_directories.push_back(args[3]);
+ } else if (args[2] == "TARGET_DIRECTORY" && args_size == 5) {
+ property_arg_index = 4;
+ source_file_target_option_enabled = true;
+ source_file_target_directories.push_back(args[3]);
+ }
+
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+
std::string const& var = args[0];
- std::string const& file = args[1];
- cmMakefile& mf = status.GetMakefile();
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+ std::string const file =
+ SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+ status, args[1], source_file_paths_should_be_absolute);
+ cmMakefile& mf = *source_file_directory_makefiles[0];
cmSourceFile* sf = mf.GetSource(file);
// for the location we must create a source file first
- if (!sf && args[2] == "LOCATION") {
+ if (!sf && args[property_arg_index] == "LOCATION") {
sf = mf.CreateSource(file);
}
+
if (sf) {
const char* prop = nullptr;
- if (!args[2].empty()) {
- prop = sf->GetPropertyForUser(args[2]);
+ if (!args[property_arg_index].empty()) {
+ prop = sf->GetPropertyForUser(args[property_arg_index]);
}
if (prop) {
- mf.AddDefinition(var, prop);
+ // Set the value on the original Makefile scope, not the scope of the
+ // requested directory.
+ status.GetMakefile().AddDefinition(var, prop);
return true;
}
}
- mf.AddDefinition(var, "NOTFOUND");
+ status.GetMakefile().AddDefinition(var, "NOTFOUND");
return true;
}
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 7f5df9cfb..8a304be0d 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -5,10 +5,12 @@
#include <sstream>
#include "cmExecutionStatus.h"
+#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmTarget.h"
#include "cmTargetPropertyComputer.h"
@@ -28,13 +30,20 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
cmMakefile& mf = status.GetMakefile();
if (cmTarget* tgt = mf.FindTargetToUse(targetName)) {
- if (args[2] == "ALIASED_TARGET") {
+ if (args[2] == "ALIASED_TARGET" || args[2] == "ALIAS_GLOBAL") {
if (mf.IsAlias(targetName)) {
- prop = tgt->GetName();
prop_exists = true;
+ if (args[2] == "ALIASED_TARGET") {
+
+ prop = tgt->GetName();
+ }
+ if (args[2] == "ALIAS_GLOBAL") {
+ prop =
+ mf.GetGlobalGenerator()->IsAlias(targetName) ? "TRUE" : "FALSE";
+ }
}
} 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 +54,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 5e2248ed1..358d65a8c 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -14,11 +14,12 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
-#include "cmLinkLineComputer.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmSourceGroup.h"
@@ -165,13 +166,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 +183,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 +197,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 +211,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 +234,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 +248,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 +261,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 +289,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 +306,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 +352,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 +449,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 +457,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 +480,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();
@@ -553,8 +550,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
*/
for (auto& sg : groupFilesList) {
std::ostream* fout;
- bool useProjectFile =
- cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
+ bool useProjectFile = cmIsOn(*this->GeneratorTarget->GetProperty(
+ "GHS_NO_SOURCE_GROUP_FILE")) ||
cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
if (useProjectFile || sg.empty()) {
fout = &fout_proj;
@@ -579,12 +576,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 +609,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 +625,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 +692,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,25 +709,25 @@ 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";
}
}
}
bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
{
- const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
+ cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
if (p) {
- return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+ return cmIsOn(*p);
}
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 9af0eac41..3c979550c 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/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index e04eef1b4..9dc86f4e4 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -7,6 +7,7 @@
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
+#include "cmProperty.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
@@ -45,8 +46,8 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const
}
DirectoryTarget::Target t;
t.GT = gt.get();
- if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
- if (cmIsOn(exclude)) {
+ if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
+ if (cmIsOn(*exclude)) {
// This target has been explicitly excluded.
t.ExcludeFromAll = true;
} else {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 238097d04..4dc409221 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"
@@ -41,6 +42,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmState.h"
@@ -51,8 +53,8 @@
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
-# include "cm_jsoncpp_writer.h"
+# include <cm3p/json/value.h>
+# include <cm3p/json/writer.h>
# include "cmCryptoHash.h"
# include "cmQtAutoGenGlobalInitializer.h"
@@ -231,7 +233,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
if (!optional && (path.empty() || !cmSystemTools::FileExists(path))) {
return;
}
- const std::string* cname =
+ cmProp cname =
this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
std::string changeVars;
if (cname && !optional) {
@@ -246,11 +248,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;
@@ -303,10 +304,14 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
for (const auto& target : localGen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::TargetType::UTILITY ||
- cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+ target->GetType() == cmStateEnums::TargetType::UTILITY) {
continue;
}
+ if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+ if (cmIsOn(*p)) {
+ continue;
+ }
+ }
std::vector<std::string> configs;
target->Makefile->GetConfigurations(configs);
@@ -316,7 +321,7 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
} else {
for (std::string const& config : configs) {
target->GetSourceFiles(srcs, config);
- if (srcs.empty()) {
+ if (!srcs.empty()) {
break;
}
}
@@ -371,14 +376,18 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::TargetType::UTILITY ||
- cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+ target->GetType() == cmStateEnums::TargetType::UTILITY) {
continue;
}
+ if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+ if (cmIsOn(*p)) {
+ continue;
+ }
+ }
- const std::string reuseFrom =
+ std::string const& reuseFrom =
target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- const std::string compilePdb =
+ std::string const& compilePdb =
target->GetSafeProperty("COMPILE_PDB_NAME");
if (!reuseFrom.empty() && reuseFrom != compilePdb) {
@@ -404,7 +413,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 +454,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 +539,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 +1104,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;
}
@@ -1418,13 +1427,13 @@ bool cmGlobalGenerator::Compute()
// so create the map from project name to vector of local generators
this->FillProjectMap();
- // Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
- if (!this->QtAutoGen()) {
+ // Add automatically generated sources (e.g. unity build).
+ if (!this->AddAutomaticSources()) {
return false;
}
- // Add automatically generated sources (e.g. unity build).
- if (!this->AddAutomaticSources()) {
+ // Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
+ if (!this->QtAutoGen()) {
return false;
}
@@ -1695,8 +1704,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);
}
}
}
@@ -1807,14 +1816,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);
@@ -2066,9 +2074,8 @@ void cmGlobalGenerator::AddMakefile(std::unique_ptr<cmMakefile> mf)
// update progress
// estimate how many lg there will be
- const std::string* numGenC =
- this->CMakeInstance->GetState()->GetInitializedCacheValue(
- "CMAKE_NUMBER_OF_MAKEFILES");
+ cmProp numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue(
+ "CMAKE_NUMBER_OF_MAKEFILES");
if (!numGenC) {
// If CMAKE_NUMBER_OF_MAKEFILES is not set
@@ -2177,8 +2184,8 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
- if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
- return cmIsOn(exclude);
+ if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
+ return cmIsOn(*exclude);
}
// This target is included in its directory. Check whether the
// directory is excluded.
@@ -2245,7 +2252,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)
@@ -2271,10 +2278,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)];
@@ -2515,9 +2524,8 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
- if (auto testArgs = mf->GetDefinition("CMAKE_CTEST_ARGUMENTS")) {
- std::vector<std::string> args;
- cmExpandList(testArgs, args);
+ std::vector<std::string> args;
+ if (mf->GetDefExpandList("CMAKE_CTEST_ARGUMENTS", args)) {
for (auto const& arg : args) {
singleLine.push_back(arg);
}
@@ -2543,7 +2551,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
}
GlobalTargetInfo gti;
gti.Name = editCacheTargetName;
- gti.PerConfig = false;
+ gti.PerConfig = cmTarget::PerConfig::No;
cmCustomCommandLine singleLine;
// Use generator preference for the edit_cache rule if it is defined.
@@ -2561,6 +2569,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));
@@ -2578,13 +2587,14 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
gti.Name = rebuildCacheTargetName;
gti.Message = "Running CMake to regenerate build system...";
gti.UsesTerminal = true;
- gti.PerConfig = false;
+ gti.PerConfig = cmTarget::PerConfig::No;
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("--regenerate-during-build");
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));
}
@@ -2621,6 +2631,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());
@@ -2690,13 +2701,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";
@@ -2704,13 +2715,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
@@ -2732,7 +2743,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()) {
@@ -2804,7 +2816,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(
@@ -3051,8 +3063,8 @@ 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 targetLabels = target->GetProperty("LABELS");
+ cmProp directoryLabels =
target->Target->GetMakefile()->GetProperty("LABELS");
const char* cmakeDirectoryLabels =
target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS");
@@ -3071,7 +3083,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
// List the target-wide labels. All sources in the target get
// these labels.
if (targetLabels) {
- cmExpandList(targetLabels, labels);
+ cmExpandList(*targetLabels, labels);
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
@@ -3086,7 +3098,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::vector<std::string> cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmExpandList(directoryLabels, directoryLabelsList);
+ cmExpandList(*directoryLabels, directoryLabelsList);
}
if (cmakeDirectoryLabels) {
@@ -3121,10 +3133,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 7dc482238..57c780807 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -28,7 +28,7 @@
#include "cmTargetDepend.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
+# include <cm3p/json/value.h>
# include "cmFileLockPool.h"
#endif
@@ -553,7 +553,8 @@ protected:
std::vector<std::string> Depends;
std::string WorkingDir;
bool UsesTerminal = false;
- bool PerConfig = true;
+ cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
+ 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 bb9dd3734..d36adfb74 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"
@@ -18,6 +19,7 @@
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -90,7 +92,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 +114,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 +134,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 +168,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 +255,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 +271,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 +330,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 +351,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 +369,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
continue;
}
fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
- << " [Project]" << std::endl;
+ << " [Project]\n";
}
}
@@ -374,8 +377,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
std::string& rootBinaryDir)
{
- const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
- const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+ cmProp projName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
if (projName && projType) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
@@ -388,9 +391,9 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
}
}
- std::string projFile = dir + projName + FILE_EXTENSION;
+ std::string projFile = dir + *projName + FILE_EXTENSION;
fout << projFile;
- fout << " " << projType << std::endl;
+ fout << ' ' << *projType << '\n';
} else {
/* Should never happen */
std::string message =
@@ -467,7 +470,8 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+ cmProp p = t->GetProperty("EXCLUDE_FROM_ALL");
+ if (!(p && cmIsOn(*p))) {
defaultTargets.push_back(t);
}
}
@@ -583,14 +587,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 +616,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 +646,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 b82e9f57b..12ca8b648 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 b6c343c1f..843b0f44d 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -12,13 +12,12 @@
#include <cmext/algorithm>
#include <cmext/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
-#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 90c9ef0d2..c31983ba5 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -20,6 +20,7 @@
#include "cmMakefile.h"
#include "cmMakefileTargetGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
@@ -41,7 +42,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
#else
this->UseLinkScript = true;
#endif
- this->CommandDatabase = nullptr;
this->IncludeDirective = "include";
this->DefineWindowsNULL = false;
@@ -49,6 +49,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 +118,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 +165,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 +175,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 +350,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 +487,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 +752,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 +775,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 +788,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 340a7efa5..1caa4b736 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 ccb6c50f1..5dac072c2 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -6,12 +6,12 @@
#include <cm/memory>
+#include <cm3p/json/reader.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_reader.h"
-
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratorTarget.h"
@@ -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/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index f659ff3e3..b8c18b4ac 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -121,6 +121,8 @@ public:
bool IsIPOSupported() const override { return true; }
+ virtual bool IsStdOutEncodingSupported() const { return false; }
+
static std::string GetInstalledNsightTegraVersion();
/** Return the first two components of CMAKE_SYSTEM_VERSION. */
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index d0aec6193..7ada32511 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -91,7 +91,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
cmGeneratorTarget const* t)
{
// check to see if this is a fortran build
- const char* ext = ".vcproj";
+ std::string ext = ".vcproj";
const char* project =
"Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
if (this->TargetIsFortranOnly(t)) {
@@ -102,9 +102,9 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
ext = ".csproj";
project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
}
- const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
+ cmProp targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
if (targetExt) {
- ext = targetExt;
+ ext = *targetExt;
}
std::string guid = this->GetGUID(dspname);
@@ -198,9 +198,9 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
std::vector<std::string> mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
- cmExpandList(m, mapConfig);
+ if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(i))) {
+ cmExpandList(*m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 97991240b..428c74863 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);
}
@@ -342,19 +342,19 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
std::set<std::string> allConfigurations(configs.begin(), configs.end());
- const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
+ cmProp mapping = target->GetProperty("VS_PLATFORM_MAPPING");
this->WriteProjectConfigurations(fout, target->GetName(), *target,
configs, allConfigurations,
- mapping ? mapping : "");
+ mapping ? *mapping : "");
} else {
const std::set<std::string>& configsPartOfDefaultBuild =
this->IsPartOfDefaultBuild(configs, projectTargets, target);
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
- this->WriteProjectConfigurations(fout, vcprojName, *target, configs,
+ this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
configsPartOfDefaultBuild);
}
}
@@ -375,17 +375,18 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
bool written = false;
// handle external vc project files
- const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
std::string project = target->GetName();
- std::string location = expath;
+ std::string location = *expath;
+ cmProp p = target->GetProperty("VS_PROJECT_TYPE");
this->WriteExternalProject(fout, project, location,
- target->GetProperty("VS_PROJECT_TYPE"),
+ p ? p->c_str() : nullptr,
target->GetUtilities());
written = true;
} else {
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
@@ -393,7 +394,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
if (dir == ".") {
dir.clear(); // msbuild cannot handle ".\" prefix
}
- this->WriteProject(fout, vcprojName, dir, target);
+ this->WriteProject(fout, *vcprojName, dir, target);
written = true;
}
}
@@ -438,11 +439,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
std::string dir =
target->GetLocalGenerator()->GetCurrentSourceDirectory();
- this->WriteProjectDepends(fout, vcprojName, dir.c_str(), target);
+ this->WriteProjectDepends(fout, *vcprojName, dir, target);
}
}
}
@@ -505,13 +506,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 +527,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 +677,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 1c62fbd91..29ca1549c 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]);
@@ -240,9 +244,9 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
std::vector<std::string> mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
- cmExpandList(m, mapConfig);
+ if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(i))) {
+ cmExpandList(*m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
@@ -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(
- cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
+ if (cmProp 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 (cmProp 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 8f8e33b8e..6ce67d3e7 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 29d3f1af1..c688da2a3 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -508,9 +508,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 {
@@ -809,9 +809,9 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
// This allows the project to control the language choice in
// a target with none of its own sources, e.g. when also using
// object libraries.
- const char* linkLang = gt->GetProperty("LINKER_LANGUAGE");
- if (linkLang && *linkLang) {
- languages.insert(linkLang);
+ cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE");
+ if (linkLang && !linkLang->empty()) {
+ languages.insert(*linkLang);
}
// Intel Fortran .vfproj files do support the resource compiler.
@@ -933,7 +933,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/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 13ae32a55..605dc8b2a 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -366,6 +366,12 @@ bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance(
return vsSetupAPIHelper.GetVSInstanceInfo(dir);
}
+bool cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion(
+ unsigned long long& vsInstanceVersion) const
+{
+ return vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion);
+}
+
bool cmGlobalVisualStudioVersionedGenerator::IsDefaultToolset(
const std::string& version) const
{
@@ -387,6 +393,21 @@ bool cmGlobalVisualStudioVersionedGenerator::IsDefaultToolset(
return false;
}
+bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
+{
+ // Supported from Visual Studio 16.7 Preview 3.
+ if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) {
+ return true;
+ }
+ if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) {
+ return false;
+ }
+ unsigned long long const vsInstanceVersion16_7_P2 = 4503631666610212;
+ unsigned long long vsInstanceVersion;
+ return (this->GetVSInstanceVersion(vsInstanceVersion) &&
+ vsInstanceVersion > vsInstanceVersion16_7_P2);
+}
+
std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
{
const char* version = this->GetPlatformToolsetVersion();
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index abb609536..cbd3ba77c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -29,9 +29,13 @@ public:
bool GetVSInstance(std::string& dir) const;
+ bool GetVSInstanceVersion(unsigned long long& vsInstanceVersion) const;
+
bool IsDefaultToolset(const std::string& version) const override;
std::string GetAuxiliaryToolset() const override;
+ bool IsStdOutEncodingSupported() const override;
+
protected:
cmGlobalVisualStudioVersionedGenerator(
VSVersion version, cmake* cm, const std::string& name,
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index 308ddda73..d6a7afa7a 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -19,7 +19,7 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
#endif
this->ToolSupportsColor = true;
this->NeedSymbolicMark = true;
- this->EmptyRuleHackCommand = "@cd .";
+ this->EmptyRuleHackCommand = "@%null";
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
#endif
@@ -44,6 +44,16 @@ void cmGlobalWatcomWMakeGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
+bool cmGlobalWatcomWMakeGenerator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
+{
+ if (mf->GetSafeDefinition("CMAKE_SYSTEM_PROCESSOR") == "I86") {
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl");
+ }
+ return this->cmGlobalUnixMakefileGenerator3::SetSystemName(s, mf);
+}
+
void cmGlobalWatcomWMakeGenerator::GetDocumentation(
cmDocumentationEntry& entry)
{
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index c0daf8a7f..c47127feb 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -41,6 +41,9 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
+ /** Tell the generator about the target system. */
+ bool SetSystemName(std::string const& s, cmMakefile* mf) override;
+
/**
* Try to determine system information such as shared library
* extension, pthreads, byte order etc.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index e0005a4ed..a5ce5d18f 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,7 +808,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add flags from target and source file properties.
std::string flags;
- const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
+ std::string const& srcfmt = sf->GetSafeProperty("Fortran_FORMAT");
switch (cmOutputConverter::GetFortranFormat(srcfmt)) {
case cmOutputConverter::FortranFormatFixed:
flags = "-fixed " + flags;
@@ -815,22 +820,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 +853,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 +884,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 +909,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 +998,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 +1425,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 +1467,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 +1475,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,18 +1865,18 @@ 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");
+ cmProp targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
- targetLinkFlags);
+ *targetLinkFlags);
}
if (!configName.empty()) {
std::string linkFlagsVar =
cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName));
- if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) {
- this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
+ if (cmProp linkFlags = gtgt->GetProperty(linkFlagsVar)) {
+ this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *linkFlags);
}
}
std::vector<std::string> opts;
@@ -1906,8 +1912,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string pnsuffix;
gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
- const char* version = gtgt->GetProperty("VERSION");
- const char* soversion = gtgt->GetProperty("SOVERSION");
+ cmProp version = gtgt->GetProperty("VERSION");
+ cmProp soversion = gtgt->GetProperty("SOVERSION");
if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) {
version = nullptr;
soversion = nullptr;
@@ -1923,9 +1929,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string soName = pnbase;
if (version && soversion) {
realName += ".";
- realName += version;
+ realName += *version;
soName += ".";
- soName += soversion;
+ soName += *soversion;
}
// Set attributes to specify the proper name for the target.
@@ -1971,10 +1977,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string fw_version = gtgt->GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(fw_version));
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2012,10 +2018,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
@@ -2046,10 +2052,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string fw_version = gtgt->GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(fw_version));
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2085,10 +2091,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Handle bundles and normal executables separately.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
@@ -2283,7 +2289,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Add Fortran source format attribute if property is set.
const char* format = nullptr;
- const char* tgtfmt = gtgt->GetProperty("Fortran_FORMAT");
+ std::string const& tgtfmt = gtgt->GetSafeProperty("Fortran_FORMAT");
switch (cmOutputConverter::GetFortranFormat(tgtfmt)) {
case cmOutputConverter::FortranFormatFixed:
format = "fixed";
@@ -2406,12 +2412,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()) {
+ std::string const& pr = gtgt->GetSafeProperty(prop);
std::string processed = cmGeneratorExpression::Evaluate(
- gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName);
+ pr, this->CurrentLocalGenerator, configName);
buildSettings->AddAttribute(attribute,
this->CreateString(processed));
}
@@ -2530,8 +2537,8 @@ const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(
const char* cmGlobalXCodeGenerator::GetTargetFileType(
cmGeneratorTarget* target)
{
- if (const char* e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
- return e;
+ if (cmProp e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+ return e->c_str();
}
switch (target->GetType()) {
@@ -2563,8 +2570,8 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(
const char* cmGlobalXCodeGenerator::GetTargetProductType(
cmGeneratorTarget* target)
{
- if (const char* e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
- return e;
+ if (cmProp e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
+ return e->c_str();
}
switch (target->GetType()) {
@@ -3141,12 +3148,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));
@@ -3197,10 +3204,9 @@ std::string cmGlobalXCodeGenerator::GetObjectsDirectory(
void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf)
{
this->Architectures.clear();
- const char* osxArch = mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
const char* sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT");
- if (osxArch && sysroot) {
- cmExpandList(std::string(osxArch), this->Architectures);
+ if (sysroot) {
+ mf->GetDefExpandList("CMAKE_OSX_ARCHITECTURES", this->Architectures);
}
if (this->Architectures.empty()) {
@@ -3390,7 +3396,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;
@@ -3400,12 +3406,12 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
continue;
}
- const char* testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
+ cmProp testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
if (!testee) {
continue;
}
- testables[testee].push_back(obj);
+ testables[*testee].push_back(obj.get());
}
// generate scheme
@@ -3414,14 +3420,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 +3553,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 +3699,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 df68f803e..e380f1c0f 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 e03b2ca6c..0fcda4e3e 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -67,36 +67,6 @@ const char* getShapeForTarget(const cmLinkItem& item)
return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
}
-
-struct DependeesDir
-{
- template <typename T>
- static const cmLinkItem& src(const T& con)
- {
- return con.src;
- }
-
- template <typename T>
- static const cmLinkItem& dst(const T& con)
- {
- return con.dst;
- }
-};
-
-struct DependersDir
-{
- template <typename T>
- static const cmLinkItem& src(const T& con)
- {
- return con.dst;
- }
-
- template <typename T>
- static const cmLinkItem& dst(const T& con)
- {
- return con.src;
- }
-};
}
cmGraphVizWriter::cmGraphVizWriter(std::string const& fileName,
@@ -203,16 +173,18 @@ void cmGraphVizWriter::VisitLink(cmLinkItem const& depender,
return;
}
- // write global data directly
this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
if (this->GeneratePerTarget) {
- PerTargetConnections[depender].emplace_back(depender, dependee, scopeType);
+ auto fileStream = PerTargetFileStreams[depender.AsStr()].get();
+ this->WriteNode(*fileStream, dependee);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
}
if (this->GenerateDependers) {
- TargetDependersConnections[dependee].emplace_back(dependee, depender,
- scopeType);
+ auto fileStream = TargetDependersFileStreams[dependee.AsStr()].get();
+ this->WriteNode(*fileStream, depender);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
}
}
@@ -316,99 +288,23 @@ void cmGraphVizWriter::Write()
}
}
- // write global data and collect all connection data for per target graphs
for (auto const gt : sortedGeneratorTargets) {
auto item = cmLinkItem(gt, false, gt->GetBacktrace());
this->VisitItem(item);
}
-
- if (this->GeneratePerTarget) {
- WritePerTargetConnections<DependeesDir>(PerTargetConnections,
- PerTargetFileStreams);
- }
-
- if (this->GenerateDependers) {
- WritePerTargetConnections<DependersDir>(TargetDependersConnections,
- TargetDependersFileStreams);
- }
-}
-
-void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons,
- std::set<cmLinkItem>& visitedItems)
-{
- // some "targets" are not in map, e.g. linker flags as -lm or
- // targets without dependency.
- // in both cases we are finished with traversing the graph
- if (connectionMap.find(rootItem) == connectionMap.cend()) {
- return;
- }
-
- const Connections& origCons = connectionMap.at(rootItem);
-
- for (const Connection& con : origCons) {
- extendedCons.emplace_back(con);
- const cmLinkItem& dstItem = con.dst;
- bool const visited = visitedItems.find(dstItem) != visitedItems.cend();
- if (!visited) {
- visitedItems.insert(dstItem);
- FindAllConnections(connectionMap, dstItem, extendedCons, visitedItems);
- }
- }
-}
-
-void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons)
-{
- std::set<cmLinkItem> visitedItems = { rootItem };
- FindAllConnections(connectionMap, rootItem, extendedCons, visitedItems);
-}
-
-template <typename DirFunc>
-void cmGraphVizWriter::WritePerTargetConnections(
- const ConnectionsMap& connections, const FileStreamMap& streams)
-{
- // the per target connections must be extended by indirect dependencies
- ConnectionsMap extendedConnections;
- for (auto const& conPerTarget : connections) {
- const cmLinkItem& rootItem = conPerTarget.first;
- Connections& extendedCons = extendedConnections[conPerTarget.first];
- FindAllConnections(connections, rootItem, extendedCons);
- }
-
- for (auto const& conPerTarget : extendedConnections) {
- const cmLinkItem& rootItem = conPerTarget.first;
-
- // some of the nodes are excluded completely and are not written
- if (this->ItemExcluded(rootItem)) {
- continue;
- }
-
- const Connections& cons = conPerTarget.second;
- auto fileStream = streams.at(rootItem.AsStr()).get();
-
- for (const Connection& con : cons) {
- const cmLinkItem& src = DirFunc::src(con);
- const cmLinkItem& dst = DirFunc::dst(con);
- this->WriteNode(*fileStream, con.dst);
- this->WriteConnection(*fileStream, src, dst, con.scopeType);
- }
- }
}
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)
@@ -416,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,
@@ -474,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,
@@ -486,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)
@@ -506,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/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 9766068a2..578660dbb 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -7,18 +7,16 @@
#include <map>
#include <memory>
-#include <set>
#include <string>
-#include <utility>
#include <vector>
#include "cmsys/RegularExpression.hxx"
#include "cmGeneratedFileStream.h"
-#include "cmLinkItem.h"
#include "cmLinkItemGraphVisitor.h"
#include "cmStateTypes.h"
+class cmLinkItem;
class cmGlobalGenerator;
/** This class implements writing files for graphviz (dot) for graphs
@@ -49,22 +47,6 @@ private:
using FileStreamMap =
std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
- struct Connection
- {
- Connection(cmLinkItem s, cmLinkItem d, std::string scope)
- : src(std::move(s))
- , dst(std::move(d))
- , scopeType(std::move(scope))
- {
- }
-
- cmLinkItem src;
- cmLinkItem dst;
- std::string scopeType;
- };
- using Connections = std::vector<Connection>;
- using ConnectionsMap = std::map<cmLinkItem, Connections>;
-
void VisitLink(cmLinkItem const& depender, cmLinkItem const& dependee,
bool isDirectLink, std::string const& scopeType = "");
@@ -84,19 +66,6 @@ private:
cmLinkItem const& dependeeTargetName,
std::string const& edgeStyle);
- void FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons,
- std::set<cmLinkItem>& visitedItems);
-
- void FindAllConnections(const ConnectionsMap& connectionMap,
- const cmLinkItem& rootItem,
- Connections& extendedCons);
-
- template <typename DirFunc>
- void WritePerTargetConnections(const ConnectionsMap& connections,
- const FileStreamMap& streams);
-
bool ItemExcluded(cmLinkItem const& item);
bool ItemNameFilteredOut(std::string const& itemName);
bool TargetTypeEnabled(cmStateEnums::TargetType targetType) const;
@@ -114,9 +83,6 @@ private:
FileStreamMap PerTargetFileStreams;
FileStreamMap TargetDependersFileStreams;
- ConnectionsMap PerTargetConnections;
- ConnectionsMap TargetDependersConnections;
-
std::string GraphName;
std::string GraphHeader;
std::string GraphNodePrefix;
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 290e064b4..5808f90eb 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -7,8 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 14264f487..ae801bb98 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 d669ed7e9..178af738a 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -8,11 +8,10 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include "cmsys/Glob.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportSet.h"
@@ -29,6 +28,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
@@ -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/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 31ba63f2c..a034689c0 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -4,7 +4,7 @@
#include <utility>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmRange.h"
#include "cmSystemTools.h"
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 2c53a2824..6e3508c2d 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 cf28b35d8..43dd00da4 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/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index e05daa8d5..178d5df31 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -133,8 +134,10 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
cmMakefile const* mf = this->Target->Target->GetMakefile();
// Get App Bundle Extension
- const char* ext = this->Target->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
+ std::string ext;
+ if (cmProp p = this->Target->GetProperty("BUNDLE_EXTENSION")) {
+ ext = *p;
+ } else {
ext = "app";
}
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index a65ae037e..32395d10e 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 698151e3c..07f70816e 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 dd3638654..9f17f1557 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -28,6 +28,7 @@
#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmSourceFile.h"
#include "cmState.h"
@@ -90,7 +91,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 +276,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 +291,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 +310,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/cmJsonObjects.h b/Source/cmJsonObjects.h
index 64291cc06..2fd4b26f3 100644
--- a/Source/cmJsonObjects.h
+++ b/Source/cmJsonObjects.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmake;
class cmGlobalGenerator;
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 0ea25c0aa..3d9293528 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"
@@ -53,6 +54,9 @@ struct cmLinkImplementationLibraries
// Libraries linked directly in other configurations.
// Needed only for OLD behavior of CMP0003.
std::vector<cmLinkItem> WrongConfigLibraries;
+
+ // Whether the list depends on a genex referencing the configuration.
+ bool HadContextSensitiveCondition = false;
};
struct cmLinkInterfaceLibraries
@@ -62,6 +66,9 @@ struct cmLinkInterfaceLibraries
// Whether the list depends on a genex referencing the head target.
bool HadHeadSensitiveCondition = false;
+
+ // Whether the list depends on a genex referencing the configuration.
+ bool HadContextSensitiveCondition = false;
};
struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -81,6 +88,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 +110,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 +134,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 65ed34caa..c50a78684 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"
@@ -14,6 +15,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
@@ -176,11 +178,11 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
return false;
}
- if (const char* resolveDeviceSymbols =
+ if (cmProp resolveDeviceSymbols =
target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
// If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
// to honor the value no matter what it is.
- return cmIsOn(resolveDeviceSymbols);
+ return cmIsOn(*resolveDeviceSymbols);
}
// Determine if we have any dependencies that require
@@ -188,10 +190,10 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- if (cmContains(closure->Languages, "CUDA")) {
- if (const char* separableCompilation =
+ if (cm::contains(closure->Languages, "CUDA")) {
+ if (cmProp separableCompilation =
target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
- if (cmIsOn(separableCompilation)) {
+ if (cmIsOn(*separableCompilation)) {
bool doDeviceLinking = false;
switch (target.GetType()) {
case cmStateEnums::SHARED_LIBRARY:
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 5200a160f..edec613ed 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,11 +16,11 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -66,7 +66,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 +1051,7 @@ public:
UNINITIALIZED,
STRING,
FILE_BASENAME,
+ NATURAL,
};
enum class CaseSensitivity
{
@@ -1074,10 +1075,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 +1115,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 +1159,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 47679c932..7ebb02f49 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 9cae8277b..89902ff30 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 92258e27b..5790e169c 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 025ef7e6b..278ec8b14 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 f592b7bd7..3b3f110dc 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -6,7 +6,6 @@
#include <cassert>
#include <cstdio>
#include <cstdlib>
-#include <cstring>
#include <initializer_list>
#include <iterator>
#include <sstream>
@@ -20,7 +19,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -35,8 +33,8 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
-#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.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";
@@ -736,14 +805,14 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
- auto* standard =
+ cmProp standard =
target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
if (!standard) {
- standard = this->Makefile->GetDefinition(
+ standard = this->Makefile->GetDef(
cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
}
target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
- standard);
+ standard ? standard->c_str() : nullptr);
return true;
}
return false;
@@ -752,9 +821,9 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
const char* property) {
if (!target->GetProperty(cmStrCat(lang.first, property)) &&
target->GetProperty(cmStrCat(lang.second, property))) {
- target->Target->SetProperty(
- cmStrCat(lang.first, property),
- target->GetProperty(cmStrCat(lang.second, property)));
+ cmProp p = target->GetProperty(cmStrCat(lang.second, property));
+ target->Target->SetProperty(cmStrCat(lang.first, property),
+ p ? p->c_str() : nullptr);
}
};
for (auto const& lang : pairedLanguages) {
@@ -763,8 +832,8 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
copyPropertyToObjLang(lang, "_EXTENSIONS");
}
}
- if (const char* standard = target->GetProperty("CUDA_STANDARD")) {
- if (std::string{ standard } == "98") {
+ if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
+ if (*standard == "98") {
target->Target->SetProperty("CUDA_STANDARD", "03");
}
}
@@ -792,10 +861,13 @@ cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const
const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
const std::string& prop)
{
+ cmProp p;
if (target) {
- return target->GetProperty(prop);
+ p = target->GetProperty(prop);
+ } else {
+ p = this->Makefile->GetProperty(prop);
}
- return this->Makefile->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -899,7 +971,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,
@@ -922,9 +994,9 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
if (const char* langFlagRegexStr =
this->Makefile->GetDefinition(langFlagRegexVar)) {
// Filter flags acceptable to this language.
- if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+ if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
std::vector<std::string> opts;
- cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+ cmSystemTools::ParseWindowsCommandLine(targetFlags->c_str(), opts);
// Re-escape these flags since COMPILE_FLAGS were already parsed
// as a command line above.
std::string compileOpts;
@@ -939,10 +1011,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr);
} else {
// Use all flags.
- if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+ if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
// COMPILE_FLAGS are not escaped for historical reasons.
std::string compileFlags;
- this->AppendFlags(compileFlags, targetFlags);
+ this->AppendFlags(compileFlags, *targetFlags);
if (!compileFlags.empty()) {
flags.emplace_back(std::move(compileFlags));
}
@@ -954,11 +1026,11 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
for (auto const& it : target->GetMaxLanguageStandards()) {
- const char* standard = target->GetProperty(it.first + "_STANDARD");
+ cmProp standard = target->GetProperty(it.first + "_STANDARD");
if (!standard) {
continue;
}
- if (this->Makefile->IsLaterStandard(it.first, standard, it.second)) {
+ if (this->Makefile->IsLaterStandard(it.first, *standard, it.second)) {
std::ostringstream e;
e << "The COMPILE_FEATURES property of target \"" << target->GetName()
<< "\" was evaluated when computing the link "
@@ -967,12 +1039,11 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
<< "\" for that computation. Computing the "
"COMPILE_FEATURES based on the link implementation resulted in a "
"higher \""
- << it.first << "_STANDARD\" \"" << standard
+ << it.first << "_STANDARD\" \"" << *standard
<< "\". "
"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;
}
@@ -995,10 +1066,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
cmGeneratorTarget::ManagedType::Managed) {
// add /JMC flags if target property VS_JUST_MY_CODE_DEBUGGING is set
// to ON
- if (char const* jmcExprGen =
+ if (cmProp jmcExprGen =
target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) {
std::string isJMCEnabled =
- cmGeneratorExpression::Evaluate(jmcExprGen, this, config);
+ cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
if (cmIsOn(isJMCEnabled)) {
std::vector<std::string> optVec = cmExpandedList(jmc);
std::string jmcFlags;
@@ -1018,7 +1089,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 +1101,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 +1111,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 +1129,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 +1141,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 +1150,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 +1164,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;
}
@@ -1164,11 +1236,10 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// * Compilers like gfortran do not search their own implicit include
// directories for modules ('.mod' files).
if (lang != "Fortran") {
- const char* value = this->Makefile->GetDefinition(
- cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"));
- if (value != nullptr) {
- size_t const impDirVecOldSize = impDirVec.size();
- cmExpandList(value, impDirVec);
+ size_t const impDirVecOldSize = impDirVec.size();
+ if (this->Makefile->GetDefExpandList(
+ cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"),
+ impDirVec)) {
// FIXME: Use cmRange with 'advance()' when it supports non-const.
for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
@@ -1183,7 +1254,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 +1275,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 +1329,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 +1386,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 +1406,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 +1423,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 +1468,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 +1488,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,30 +1497,30 @@ 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 += " ";
}
}
}
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- sharedLibFlags += targetLinkFlags;
+ 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 += *targetLinkFlags;
sharedLibFlags += " ";
}
}
@@ -1452,9 +1543,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 +1572,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);
@@ -1501,16 +1592,16 @@ void cmLocalGenerator::GetTargetFlags(
exeFlags += " ";
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- exeFlags += targetLinkFlags;
+ 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 += *targetLinkFlags;
exeFlags += " ";
}
}
@@ -1541,16 +1632,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 +1656,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 +1845,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 +1904,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 +1914,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 +1936,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 += " ";
@@ -1879,28 +1976,45 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
config);
if (lang == "Swift") {
- if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
+ if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
if (cmSystemTools::VersionCompare(
cmSystemTools::OP_GREATER_EQUAL,
this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"),
"4.2")) {
- this->AppendFlags(flags, "-swift-version " + std::string(v));
+ this->AppendFlags(flags, "-swift-version " + *v);
+ }
+ }
+ } else if (lang == "CUDA") {
+ target->AddCUDAArchitectureFlags(flags);
+ target->AddCUDAToolkitFlags(flags);
+
+ std::string const& compiler =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+ if (compiler == "Clang") {
+ bool separable = target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION");
+
+ if (separable) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "CUDA_SEPARABLE_COMPILATION isn't supported on Clang. "
+ "See CMake issue #20726.");
}
}
}
// Add MSVC runtime library flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
- const char* msvcRuntimeLibraryDefault =
- this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
- if (msvcRuntimeLibraryDefault && *msvcRuntimeLibraryDefault) {
- const char* msvcRuntimeLibraryValue =
+ cmProp msvcRuntimeLibraryDefault =
+ this->Makefile->GetDef("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
+ if (msvcRuntimeLibraryDefault && !msvcRuntimeLibraryDefault->empty()) {
+ cmProp msvcRuntimeLibraryValue =
target->GetProperty("MSVC_RUNTIME_LIBRARY");
if (!msvcRuntimeLibraryValue) {
msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault;
}
std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate(
- msvcRuntimeLibraryValue, this, config, target);
+ *msvcRuntimeLibraryValue, this, config, target);
if (!msvcRuntimeLibrary.empty()) {
if (const char* msvcRuntimeLibraryOptions =
this->Makefile->GetDefinition(
@@ -1950,6 +2064,15 @@ cmGeneratorTarget* cmLocalGenerator::FindGeneratorTargetToUse(
return imported->second;
}
+ // find local alias to imported target
+ auto aliased = this->AliasTargets.find(name);
+ if (aliased != this->AliasTargets.end()) {
+ imported = this->ImportedGeneratorTargets.find(aliased->second);
+ if (imported != this->ImportedGeneratorTargets.end()) {
+ return imported->second;
+ }
+ }
+
if (cmGeneratorTarget* t = this->FindLocalNonAliasGeneratorTarget(name)) {
return t;
}
@@ -1973,7 +2096,6 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
if (name.empty()) {
return false;
}
-
if (cmSystemTools::GetFilenameLastExtension(name) == ".exe") {
name = cmSystemTools::GetFilenameWithoutLastExtension(name);
}
@@ -2013,11 +2135,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
@@ -2082,13 +2202,13 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
}
std::string extProp = lang + "_EXTENSIONS";
bool ext = true;
- if (const char* extPropValue = target->GetProperty(extProp)) {
- if (cmIsOff(extPropValue)) {
+ if (cmProp extPropValue = target->GetProperty(extProp)) {
+ if (cmIsOff(*extPropValue)) {
ext = false;
}
}
std::string stdProp = lang + "_STANDARD";
- const char* standardProp = target->GetProperty(stdProp);
+ cmProp standardProp = target->GetProperty(stdProp);
if (!standardProp) {
if (ext) {
// No language standard is specified and extensions are not disabled.
@@ -2110,7 +2230,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
std::string option_flag =
- "CMAKE_" + lang + standardProp + "_" + type + "_COMPILE_OPTION";
+ "CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag);
@@ -2119,7 +2239,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
e << "Target \"" << target->GetName()
<< "\" requires the language "
"dialect \""
- << lang << standardProp << "\" "
+ << lang << *standardProp << "\" "
<< (ext ? "(with compiler extensions)" : "")
<< ", but CMake "
"does not know the compile flags to use to enable it.";
@@ -2163,7 +2283,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
langStdMap["CUDA"].emplace_back("03");
}
- std::string standard(standardProp);
+ std::string standard(*standardProp);
if (lang == "CUDA" && standard == "98") {
standard = "03";
}
@@ -2236,7 +2356,7 @@ static void AddVisibilityCompileOption(std::string& flags,
}
std::string flagDefine = lang + "_VISIBILITY_PRESET";
- const char* prop = target->GetProperty(flagDefine);
+ cmProp prop = target->GetProperty(flagDefine);
if (!prop) {
return;
}
@@ -2244,17 +2364,17 @@ static void AddVisibilityCompileOption(std::string& flags,
*warnCMP0063 += " " + flagDefine + "\n";
return;
}
- if (strcmp(prop, "hidden") != 0 && strcmp(prop, "default") != 0 &&
- strcmp(prop, "protected") != 0 && strcmp(prop, "internal") != 0) {
+ if ((*prop != "hidden") && (*prop != "default") && (*prop != "protected") &&
+ (*prop != "internal")) {
std::ostringstream e;
- e << "Target " << target->GetName() << " uses unsupported value \"" << prop
- << "\" for " << flagDefine << "."
+ e << "Target " << target->GetName() << " uses unsupported value \""
+ << *prop << "\" for " << flagDefine << "."
<< " The supported values are: default, hidden, protected, and "
"internal.";
cmSystemTools::Error(e.str());
return;
}
- std::string option = std::string(opt) + prop;
+ std::string option = opt + *prop;
lg->AppendFlags(flags, option);
}
@@ -2372,7 +2492,8 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
std::ostringstream e;
e << "Variable " << flagsVar
<< " has been modified. CMake "
- "will ignore the POSITION_INDEPENDENT_CODE target property for "
+ "will ignore the POSITION_INDEPENDENT_CODE target property "
+ "for "
"shared libraries and will use the "
<< flagsVar
<< " variable "
@@ -2434,7 +2555,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 += " ";
}
@@ -2467,10 +2590,13 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
for (std::string const& config : configsList) {
- // FIXME: Refactor collection of sources to not evaluate object libraries.
+ // FIXME: Refactor collection of sources to not evaluate object
+ // libraries.
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
+ const std::string configUpper = cmSystemTools::UpperCase(config);
+
for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
auto langSources = std::count_if(
sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
@@ -2481,151 +2607,353 @@ 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 (!this->GetGlobalGenerator()->IsXcode()) {
- if (!pchReuseFrom) {
- target->AddSource(pchSource, true);
+ if (pchSource.empty() || pchHeader.empty()) {
+ continue;
}
- const std::string pchFile = target->GetPchFile(config, lang);
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
- // 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);
-
- if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+ if (pchExtension.empty()) {
+ continue;
+ }
- const std::string pdb_prefix =
- this->GetGlobalGenerator()->IsMultiConfig()
- ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
- : "";
+ cmProp ReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- const std::string target_compile_pdb_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/");
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
- const std::string copy_script =
- cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
- cmGeneratedFileStream file(copy_script);
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!ReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
- 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 pchFile = target->GetPchFile(config, lang, arch);
- const std::string to_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", target->GetName(), ".dir/${PDB_PREFIX}");
+ // Exclude the pch files from linking
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ if (!ReuseFrom) {
+ pch_sf->AppendProperty(
+ "OBJECT_OUTPUTS",
+ cmStrCat("$<$<CONFIG:", config, ">:", pchFile, ">"));
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
- const std::string to_file =
- cmStrCat(to_dir, pchReuseFrom, extension);
+ if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
- std::string dest_file = to_file;
+ const std::string compilerId =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
- const std::string prefix = target->GetSafeProperty("PREFIX");
- if (!prefix.empty()) {
- dest_file =
- cmStrCat(to_dir, prefix, pchReuseFrom, extension);
- }
+ const std::string compilerVersion =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_VERSION"));
- 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";
+ const std::string langFlags =
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_FLAGS_", configUpper));
+
+ // MSVC 2008 is producing both .pdb and .idb files with /Zi.
+ if ((langFlags.find("/ZI") != std::string::npos ||
+ langFlags.find("-ZI") != std::string::npos) ||
+ (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ compilerVersion.c_str(),
+ "16.0") &&
+ compilerId == "MSVC")) {
+ CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+ { ".pdb", ".idb" });
+ } else if ((langFlags.find("/Zi") != std::string::npos ||
+ langFlags.find("-Zi") != std::string::npos)) {
+ CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+ { ".pdb" });
}
- 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());
- }
- }
+ if (reuseTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang, arch);
- target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- target_compile_pdb_dir);
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ cmStrCat("LINK_FLAGS_", configUpper),
+ cmStrCat(" ",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+ true);
+ }
}
+ } else {
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ }
- std::string pchSourceObj =
- reuseTarget->GetPchFileObject(config, lang);
+ // Add pchHeader to source files, which will
+ // be grouped as "Precompile Header File"
+ auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+ pchHeader, true, cmSourceFileLocationKind::Known);
+ std::string err;
+ pchHeader_sf->ResolveFullPath(&err);
- const std::string configUpper = cmSystemTools::UpperCase(config);
+ // The pch file is generated, but mark it as not generated
+ // so that a clean operation will not remove it from disk
+ pchHeader_sf->SetProperty("GENERATED", "0");
- // Link to the pch object file
- target->Target->AppendProperty(
- cmStrCat("LINK_FLAGS_", configUpper),
- cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
- true);
- }
- } else {
- pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ target->AddSource(pchHeader);
}
+ }
+ }
+ }
+}
+
+void cmLocalGenerator::CopyPchCompilePdb(
+ const std::string& config, cmGeneratorTarget* target,
+ const std::string& ReuseFrom, cmGeneratorTarget* reuseTarget,
+ const std::vector<std::string>& extensions)
+{
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, "/") : "";
+
+ const std::string target_compile_pdb_dir =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/");
+
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
+
+ file << "# CMake generated file\n";
+
+ file << "# The compiler generated pdb file needs to be written to disk\n"
+ << "# by mspdbsrv. The foreach retry loop is needed to make sure\n"
+ << "# the pdb file is ready to be copied.\n\n";
+
+ for (auto const& extension : extensions) {
+ const std::string from_file =
+ cmStrCat(reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
+
+ const std::string to_dir =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/${PDB_PREFIX}");
+
+ const std::string to_file = cmStrCat(to_dir, ReuseFrom, extension);
+
+ std::string dest_file = to_file;
+
+ std::string const& prefix = target->GetSafeProperty("PREFIX");
+ if (!prefix.empty()) {
+ dest_file = cmStrCat(to_dir, prefix, ReuseFrom, extension);
+ }
+
+ file << "foreach(retry RANGE 1 30)\n";
+ file << " if (EXISTS \"" << from_file << "\" AND \"" << from_file
+ << " \" IS_NEWER_THAN \"" << dest_file << "\")\n";
+ file << " execute_process(COMMAND ${CMAKE_COMMAND} -E copy";
+ file << " \"" << from_file << "\""
+ << " \"" << to_dir << "\" RESULT_VARIABLE result "
+ << " ERROR_QUIET)\n";
+ file << " if (NOT result EQUAL 0)\n"
+ << " execute_process(COMMAND ${CMAKE_COMMAND}"
+ << " -E sleep 1)\n"
+ << " else()\n";
+ if (!prefix.empty()) {
+ file << " file(REMOVE \"" << dest_file << "\")\n";
+ file << " file(RENAME \"" << to_file << "\" \"" << dest_file << "\")\n";
+ }
+ file << " break()\n"
+ << " endif()\n";
+ file << " else()\n"
+ << " execute_process(COMMAND ${CMAKE_COMMAND}"
+ << " -E sleep 1)\n"
+ << " endif()\n";
+ file << "endforeach()\n";
+ }
+
+ bool stdPipesUTF8 = true;
+
+ auto configGenex = [&](cm::string_view expr) -> std::string {
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">");
+ }
+ return std::string(expr);
+ };
+
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { configGenex(cmSystemTools::GetCMakeCommand()),
+ configGenex(cmStrCat("-DPDB_PREFIX=", pdb_prefix)), configGenex("-P"),
+ configGenex(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, ReuseFrom, ".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);
+}
+
+namespace {
+
+inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
+ std::string const& filename)
+{
+ target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
+ sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ sf->SetProperty("SKIP_AUTOGEN", "ON");
+}
+
+inline void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file,
+ std::string const& sf_full_path,
+ cmProp beforeInclude,
+ cmProp afterInclude)
+{
+ if (beforeInclude) {
+ unity_file << *beforeInclude << "\n";
+ }
+
+ unity_file << "#include \"" << sf_full_path << "\"\n";
- // 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);
+ if (afterInclude) {
+ unity_file << *afterInclude << "\n";
+ }
+}
+
+std::vector<std::string> AddUnityFilesModeAuto(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base, size_t batchSize)
+{
+ if (batchSize == 0) {
+ batchSize = filtered_sources.size();
+ }
+
+ std::vector<std::string> unity_files;
+ for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
+ itemsLeft > 0; itemsLeft -= chunk, ++batch) {
+
+ chunk = std::min(itemsLeft, batchSize);
+
+ std::string filename = cmStrCat(filename_base, "unity_", batch,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ size_t begin = batch * batchSize;
+ size_t end = begin + chunk;
+
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+
+ for (; begin != end; ++begin) {
+ cmSourceFile* sf = filtered_sources[begin];
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
}
}
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
}
+ return unity_files;
+}
+
+std::vector<std::string> AddUnityFilesModeGroup(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base)
+{
+ std::vector<std::string> unity_files;
+
+ // sources organized by group name. Drop any source
+ // without a group
+ std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping;
+ for (cmSourceFile* sf : filtered_sources) {
+ if (cmProp value = sf->GetProperty("UNITY_GROUP")) {
+ auto i = explicit_mapping.find(*value);
+ if (i == explicit_mapping.end()) {
+ std::vector<cmSourceFile*> sources{ sf };
+ explicit_mapping.emplace(*value, sources);
+ } else {
+ i->second.emplace_back(sf);
+ }
+ }
+ }
+
+ for (auto const& item : explicit_mapping) {
+ auto const& name = item.first;
+ std::string filename = cmStrCat(filename_base, "unity_", name,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+
+ for (cmSourceFile* sf : item.second) {
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
+ }
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
+ }
+
+ return unity_files;
+}
}
void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
@@ -2648,12 +2976,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
- auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
- const size_t unityBatchSize =
- static_cast<size_t>(std::atoi(batchSizeString));
+ cmProp batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+ const size_t unityBatchSize = batchSizeString
+ ? static_cast<size_t>(std::atoi(batchSizeString->c_str()))
+ : 0;
- auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
- auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+ cmProp beforeInclude =
+ target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+ cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+ cmProp unityMode = target->GetProperty("UNITY_BUILD_MODE");
for (std::string lang : { "C", "CXX" }) {
std::vector<cmSourceFile*> filtered_sources;
@@ -2668,53 +2999,28 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
!sf->GetProperty("INCLUDE_DIRECTORIES");
});
- size_t batchSize = unityBatchSize;
- if (unityBatchSize == 0) {
- batchSize = filtered_sources.size();
+ std::vector<std::string> unity_files;
+ if (!unityMode || *unityMode == "BATCH") {
+ unity_files =
+ AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base, unityBatchSize);
+ } else if (unityMode && *unityMode == "GROUP") {
+ unity_files =
+ AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base);
+ } else {
+ // unity mode is set to an unsupported value
+ std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode +
+ " assigned to target " + target->GetName() +
+ ". Acceptable values are BATCH and GROUP.");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
}
- for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
- itemsLeft > 0; itemsLeft -= chunk, ++batch) {
-
- chunk = std::min(itemsLeft, batchSize);
-
- std::string filename = cmStrCat(filename_base, "unity_", batch,
- (lang == "C") ? "_c.c" : "_cxx.cxx");
-
- const std::string filename_tmp = cmStrCat(filename, ".tmp");
- {
- size_t begin = batch * batchSize;
- size_t end = begin + chunk;
-
- cmGeneratedFileStream file(
- filename_tmp, false,
- this->GetGlobalGenerator()->GetMakefileEncoding());
- file << "/* generated by CMake */\n\n";
-
- for (; begin != end; ++begin) {
- cmSourceFile* sf = filtered_sources[begin];
-
- target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
- sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
-
- if (beforeInclude) {
- file << beforeInclude << "\n";
- }
-
- file << "#include \"" << sf->ResolveFullPath() << "\"\n";
-
- if (afterInclude) {
- file << afterInclude << "\n";
- }
- }
- }
- cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
-
- target->AddSource(filename, true);
-
- auto unity = this->Makefile->GetOrCreateSource(filename);
+ for (auto const& file : unity_files) {
+ auto unity = this->GetMakefile()->GetOrCreateSource(file);
+ target->AddSource(file, true);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
- unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ unity->SetProperty("UNITY_SOURCE_FILE", file.c_str());
}
}
}
@@ -2950,11 +3256,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
@@ -2990,16 +3296,16 @@ const char* cmLocalGenerator::GetFeature(const std::string& feature,
const std::string& config)
{
std::string featureName = feature;
- // TODO: Define accumulation policy for features (prepend, append, replace).
- // Currently we always replace.
+ // TODO: Define accumulation policy for features (prepend, append,
+ // replace). Currently we always replace.
if (!config.empty()) {
featureName += "_";
featureName += cmSystemTools::UpperCase(config);
}
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();
}
@@ -3064,8 +3370,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
// Include the user-specified pre-install script for this target.
- if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(preinstall, false, "", false);
+ if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
+ cmInstallScriptGenerator g(*preinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
@@ -3117,8 +3423,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
// Include the user-specified post-install script for this target.
- if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(postinstall, false, "", false);
+ if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
+ cmInstallScriptGenerator g(*postinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
}
@@ -3304,11 +3610,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;
@@ -3326,12 +3633,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/)");
@@ -3467,7 +3774,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
@@ -3529,8 +3835,8 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const
static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target,
const std::string& prop)
{
- if (const char* val = target->GetProperty(prop)) {
- mf->AddDefinition(prop, val);
+ if (cmProp val = target->GetProperty(prop)) {
+ mf->AddDefinition(prop, *val);
}
}
@@ -3539,8 +3845,9 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
const std::string& fname)
{
// Find the Info.plist template.
- const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
- std::string inFile = (in && *in) ? in : "MacOSXBundleInfo.plist.in";
+ cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
+ std::string inFile =
+ (in && !in->empty()) ? *in : "MacOSXBundleInfo.plist.in";
if (!cmSystemTools::FileIsFullPath(inFile)) {
std::string inMod = this->Makefile->GetModulesFile(inFile);
if (!inMod.empty()) {
@@ -3578,8 +3885,9 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
const std::string& fname)
{
// Find the Info.plist template.
- const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
- std::string inFile = (in && *in) ? in : "MacOSXFrameworkInfo.plist.in";
+ cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+ std::string inFile =
+ (in && !in->empty()) ? *in : "MacOSXFrameworkInfo.plist.in";
if (!cmSystemTools::FileIsFullPath(inFile)) {
std::string inMod = this->Makefile->GetModulesFile(inFile);
if (!inMod.empty()) {
@@ -3647,7 +3955,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();
@@ -3709,7 +4017,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);
@@ -3736,7 +4045,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();
@@ -3746,7 +4055,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);
@@ -3777,7 +4086,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);
@@ -3786,7 +4095,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,
@@ -3822,7 +4131,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,9 +4146,9 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
cmImplicitDependsList no_implicit_depends;
cmSourceFile* rule = AddCustomCommand(
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);
+ no_implicit_depends, commandLines, comment, workingDir,
+ /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists,
+ /*depfile=*/"", job_pool, stdPipesUTF8);
if (rule) {
lg.GetMakefile()->AddTargetByproducts(target, byproducts);
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a459384af..f2d914519 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -13,7 +13,7 @@
#include <unordered_map>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
#include "cmCustomCommandTypes.h"
#include "cmListFileCache.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,
@@ -530,6 +540,11 @@ private:
void ComputeObjectMaxPath();
bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
const char* sysroot);
+
+ void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target,
+ const std::string& ReuseFrom,
+ cmGeneratorTarget* reuseTarget,
+ std::vector<std::string> const& extensions);
};
#if !defined(CMAKE_BOOTSTRAP)
@@ -549,7 +564,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 +575,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 +592,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 56e9f813f..87e8aa445 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -23,6 +23,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmNinjaTargetGenerator.h"
+#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmState.h"
@@ -181,8 +182,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),
@@ -243,9 +245,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);
}
@@ -272,8 +273,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(
@@ -288,23 +288,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);
@@ -316,8 +315,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);
@@ -330,8 +328,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);
@@ -344,14 +341,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,
@@ -669,10 +666,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();
}
@@ -694,7 +690,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 += " ";
@@ -705,11 +701,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 c9c656c0d..de1461a79 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -28,6 +28,7 @@
#include "cmMakefile.h"
#include "cmMakefileTargetGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -48,37 +49,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 +468,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 +506,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 +520,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 +601,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 +625,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 */
@@ -738,9 +713,10 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
// "VERBOSE=1" to be added as a make variable which will change the
// name of this special target. This gives a make-time choice to
// the user.
- this->WriteMakeRule(makefileStream,
- "Suppress display of executed commands.",
- "$(VERBOSE).SILENT", no_depends, no_commands, false);
+ // Write directly to the stream since WriteMakeRule escapes '$'.
+ makefileStream << "#Suppress display of executed commands.\n"
+ "$(VERBOSE).SILENT:\n"
+ "\n";
}
// Work-around for makes that drop rules that have no dependencies
@@ -978,7 +954,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 +1034,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 +1078,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 +1096,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 +1169,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 +1305,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 +1324,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 +1492,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);
}
@@ -1578,10 +1548,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
std::vector<std::string> commands;
std::vector<std::string> depends;
- const char* text = gt->GetProperty("EchoString");
- if (!text) {
- text = "Running external command ...";
- }
+ cmProp p = gt->GetProperty("EchoString");
+ const char* text = p ? p->c_str() : "Running external command ...";
depends.reserve(gt->GetUtilities().size());
for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
depends.push_back(u.Value.first);
@@ -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,13 +1866,13 @@ 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 =
+ if (cmProp xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(xform, transformRules);
+ cmExpandList(*xform, transformRules);
}
if (!transformRules.empty()) {
cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -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 68eeb2942..2b07952bb 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/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 02e2c6d16..9076e26d1 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -4,7 +4,7 @@
#include <cmext/algorithm>
-#include "cm_expat.h"
+#include <cm3p/expat.h>
#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 9aa39914a..5d50e2d2b 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2,12 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio7Generator.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include <windows.h>
+#include <cm3p/expat.h>
#include <ctype.h> // for isspace
-#include "cm_expat.h"
-
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -18,6 +20,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmake.h"
@@ -52,14 +55,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()
{
@@ -69,9 +69,9 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* path = l->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
if (path) {
- this->ReadAndStoreExternalGUID(l->GetName(), path);
+ this->ReadAndStoreExternalGUID(l->GetName(), path->c_str());
}
}
@@ -226,7 +226,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 +251,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.
@@ -284,6 +283,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(
}
cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {
{ "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 },
+ { "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 },
{ "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
{ "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 },
{ "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 },
@@ -672,7 +672,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
if (this->FortranProject) {
switch (cmOutputConverter::GetFortranFormat(
- target->GetProperty("Fortran_FORMAT"))) {
+ target->GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
flags += " -fixed";
break;
@@ -682,6 +682,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
default:
break;
}
+
+ switch (cmOutputConverter::GetFortranPreprocess(
+ target->GetSafeProperty("Fortran_PREPROCESS"))) {
+ case cmOutputConverter::FortranPreprocess::Needed:
+ flags += " -fpp";
+ break;
+ case cmOutputConverter::FortranPreprocess::NotNeeded:
+ flags += " -nofpp";
+ break;
+ default:
+ break;
+ }
}
// Get preprocessor definitions for this directory.
@@ -778,12 +790,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
if (this->FortranProject) {
- const char* target_mod_dir =
- target->GetProperty("Fortran_MODULE_DIRECTORY");
+ cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY");
std::string modDir;
if (target_mod_dir) {
modDir = this->MaybeConvertToRelativePath(
- this->GetCurrentBinaryDirectory(), target_mod_dir);
+ this->GetCurrentBinaryDirectory(), *target_mod_dir);
} else {
modDir = ".";
}
@@ -937,17 +948,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
" " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
extraLinkOptions += " ";
- extraLinkOptions += targetLinkFlags;
+ extraLinkOptions += *targetLinkFlags;
}
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
targetLinkFlags = target->GetProperty(linkFlagsConfig);
if (targetLinkFlags) {
extraLinkOptions += " ";
- extraLinkOptions += targetLinkFlags;
+ extraLinkOptions += *targetLinkFlags;
}
std::vector<std::string> opts;
@@ -1006,9 +1017,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";
}
@@ -1206,8 +1216,8 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
std::ostream& fout, std::string const& config, cmGeneratorTarget* target)
{
if (this->WindowsCEProject) {
- const char* dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
- const char* additionalFiles =
+ cmProp dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
+ cmProp additionalFiles =
target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
if (dir == nullptr && additionalFiles == nullptr) {
@@ -1217,15 +1227,15 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
fout << "\t\t\t<DeploymentTool\n"
"\t\t\t\tForceDirty=\"-1\"\n"
"\t\t\t\tRemoteDirectory=\""
- << GetEscapedPropertyIfValueNotNULL(dir)
+ << GetEscapedPropertyIfValueNotNULL(dir->c_str())
<< "\"\n"
"\t\t\t\tRegisterOutput=\"0\"\n"
"\t\t\t\tAdditionalFiles=\""
- << GetEscapedPropertyIfValueNotNULL(additionalFiles) << "\"/>\n";
+ << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str())
+ << "\"/>\n";
if (dir != nullptr) {
- std::string const exe =
- dir + std::string("\\") + target->GetFullName(config);
+ std::string const exe = *dir + "\\" + target->GetFullName(config);
fout << "\t\t\t<DebuggerTool\n"
"\t\t\t\tRemoteExecutable=\""
@@ -1448,14 +1458,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.
@@ -1475,8 +1486,22 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
if (lg->FortranProject) {
+ switch (cmOutputConverter::GetFortranPreprocess(
+ sf.GetSafeProperty("Fortran_PREPROCESS"))) {
+ case cmOutputConverter::FortranPreprocess::Needed:
+ fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags);
+ needfc = true;
+ break;
+ case cmOutputConverter::FortranPreprocess::NotNeeded:
+ fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags);
+ needfc = true;
+ break;
+ default:
+ break;
+ }
+
switch (cmOutputConverter::GetFortranFormat(
- sf.GetProperty("Fortran_FORMAT"))) {
+ sf.GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
fc.CompileFlags = "-fixed " + fc.CompileFlags;
needfc = true;
@@ -1490,31 +1515,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 +1548,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"));
@@ -1877,20 +1901,20 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
{
// if we have all the required Source code control tags
// then add that to the project
- const char* vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider = target->GetProperty("VS_SCC_PROVIDER");
+ cmProp vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
+ cmProp vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
+ cmProp vsProvider = target->GetProperty("VS_SCC_PROVIDER");
if (vsProvider && vsLocalpath && vsProjectname) {
/* clang-format off */
- fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
- << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
- << "\tSccProvider=\"" << vsProvider << "\"\n";
+ fout << "\tSccProjectName=\"" << *vsProjectname << "\"\n"
+ << "\tSccLocalPath=\"" << *vsLocalpath << "\"\n"
+ << "\tSccProvider=\"" << *vsProvider << "\"\n";
/* clang-format on */
- const char* vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
+ cmProp vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
if (vsAuxPath) {
- fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
+ fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n";
}
}
}
@@ -1908,10 +1932,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
<< "\tProjectCreator=\"Intel Fortran\"\n"
<< "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
/* clang-format on */
- const char* keyword = target->GetProperty("VS_KEYWORD");
- if (!keyword) {
- keyword = "Console Application";
- }
+ cmProp p = target->GetProperty("VS_KEYWORD");
+ const char* keyword = p ? p->c_str() : "Console Application";
const char* projectType = 0;
switch (target->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
@@ -1970,20 +1992,16 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "\tProjectType=\"Visual C++\"\n";
/* clang-format on */
fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
- const char* projLabel = target->GetProperty("PROJECT_LABEL");
- if (!projLabel) {
- projLabel = libName.c_str();
- }
- const char* keyword = target->GetProperty("VS_KEYWORD");
- if (!keyword) {
- keyword = "Win32Proj";
- }
+ cmProp p = target->GetProperty("PROJECT_LABEL");
+ const std::string projLabel = p ? *p : libName;
+ p = target->GetProperty("VS_KEYWORD");
+ const std::string keyword = p ? *p : "Win32Proj";
fout << "\tName=\"" << projLabel << "\"\n";
fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
this->WriteProjectSCC(fout, target);
- if (const char* targetFrameworkVersion =
+ if (cmProp targetFrameworkVersion =
target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
- fout << "\tTargetFrameworkVersion=\"" << targetFrameworkVersion << "\"\n";
+ fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n";
}
/* clang-format off */
fout << "\tKeyword=\"" << keyword << "\">\n"
@@ -2010,7 +2028,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 745766ce7..8b9b8ad2a 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 8d508980e..ebd4f96a1 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 6cbed36d9..53112e061 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/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 0b0d9ac31..c88b34318 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -8,8 +8,7 @@
#include <cm/memory>
#include <cm/string_view>
#include <cmext/algorithm>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 18689fa5f..db5cee9bd 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -18,15 +18,16 @@
#include <cm/optional>
#include <cm/vector>
#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -61,6 +62,7 @@
#include "cmake.h"
#ifndef CMAKE_BOOTSTRAP
+# include "cmMakefileProfilingData.h"
# include "cmVariableWatch.h"
#endif
@@ -373,19 +375,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 +698,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 +1022,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 +1040,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 +1059,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 +1077,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 +1099,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 +1227,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 +1256,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 +1394,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 +1425,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());
@@ -1422,6 +1461,9 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
// Imported targets.
this->ImportedTargets = parent->ImportedTargets;
+ // Non-global Alias targets.
+ this->AliasTargets = parent->AliasTargets;
+
// Recursion depth.
this->RecursionDepth = parent->RecursionDepth;
}
@@ -1606,7 +1648,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;
}
@@ -1842,8 +1884,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
cmStateEnums::CacheEntryType type,
bool force)
{
- const std::string* existingValue =
- this->GetState()->GetInitializedCacheValue(name);
+ cmProp existingValue = this->GetState()->GetInitializedCacheValue(name);
// must be outside the following if() to keep it alive long enough
std::string nvalue;
@@ -1973,8 +2014,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;
@@ -1997,10 +2038,13 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
}
}
-void cmMakefile::AddAlias(const std::string& lname, std::string const& tgtName)
+void cmMakefile::AddAlias(const std::string& lname, std::string const& tgtName,
+ bool globallyVisible)
{
this->AliasTargets[lname] = tgtName;
- this->GetGlobalGenerator()->AddAlias(lname, tgtName);
+ if (globallyVisible) {
+ this->GetGlobalGenerator()->AddAlias(lname, tgtName);
+ }
}
cmTarget* cmMakefile::AddLibrary(const std::string& lname,
@@ -2043,11 +2087,11 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName,
cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
const std::string& name)
{
- auto it =
- this->Targets
- .emplace(name,
- cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
- .first;
+ auto it = this->Targets
+ .emplace(name,
+ cmTarget(name, type, cmTarget::VisibilityNormal, this,
+ cmTarget::PerConfig::Yes))
+ .first;
this->OrderedTargets.push_back(&it->second);
this->GetGlobalGenerator()->IndexTarget(&it->second);
this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
@@ -2366,11 +2410,11 @@ cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(
cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name)
{
- const char* delimiter = this->GetDefinition("SOURCE_GROUP_DELIMITER");
- if (delimiter == nullptr) {
- delimiter = "\\";
+ const char* delimiters = this->GetDefinition("SOURCE_GROUP_DELIMITER");
+ if (delimiters == nullptr) {
+ delimiters = "/\\";
}
- return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter));
+ return this->GetOrCreateSourceGroup(cmTokenize(name, delimiters));
}
/**
@@ -2418,14 +2462,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 +2485,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 +2500,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 +2516,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 +2630,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;
}
@@ -2647,7 +2688,7 @@ const std::string& cmMakefile::GetRequiredDefinition(
bool cmMakefile::IsDefinitionSet(const std::string& name) const
{
- const std::string* def = this->StateSnapshot.GetDefinition(name);
+ cmProp def = this->StateSnapshot.GetDefinition(name);
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
@@ -2664,7 +2705,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const
const std::string* cmMakefile::GetDef(const std::string& name) const
{
- const std::string* def = this->StateSnapshot.GetDefinition(name);
+ cmProp def = this->StateSnapshot.GetDefinition(name);
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
@@ -2710,6 +2751,18 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
return *def;
}
+bool cmMakefile::GetDefExpandList(const std::string& name,
+ std::vector<std::string>& out,
+ bool emptyArgs) const
+{
+ cmProp def = this->GetDef(name);
+ if (!def) {
+ return false;
+ }
+ cmExpandList(*def, out, emptyArgs);
+ return true;
+}
+
std::vector<std::string> cmMakefile::GetDefinitions() const
{
std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
@@ -2998,7 +3051,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 +3059,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 +3074,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);
@@ -3238,10 +3291,7 @@ std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs,
bool singleConfig) const
{
if (this->GetGlobalGenerator()->IsMultiConfig()) {
- if (const char* configTypes =
- this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
- cmExpandList(configTypes, configs);
- }
+ this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
return "";
}
const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
@@ -4051,7 +4101,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 +4114,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 +4180,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)) {
@@ -4225,7 +4276,7 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
new cmTarget(name, type,
global ? cmTarget::VisibilityImportedGlobally
: cmTarget::VisibilityImported,
- this, true));
+ this, cmTarget::PerConfig::Yes));
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
@@ -4241,7 +4292,15 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
{
// Look for an imported target. These take priority because they
// are more local in scope and do not have to be globally unique.
- auto imported = this->ImportedTargets.find(name);
+ auto targetName = name;
+ if (!excludeAliases) {
+ // Look for local alias targets.
+ auto alias = this->AliasTargets.find(name);
+ if (alias != this->AliasTargets.end()) {
+ targetName = alias->second;
+ }
+ }
+ auto imported = this->ImportedTargets.find(targetName);
if (imported != this->ImportedTargets.end()) {
return imported->second;
}
@@ -4257,7 +4316,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 +4557,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 +4686,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 +4822,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 +4834,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 +4849,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 +4916,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 +4928,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 +4944,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 +4952,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 +4983,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 +5021,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 +5034,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 +5074,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 +5086,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 +5103,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 +5111,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 +5142,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 +5180,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 +5193,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 +5236,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 +5261,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 +5286,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 d918abe36..45d7109e1 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -26,6 +26,7 @@
#include "cmMessageType.h"
#include "cmNewLineStyle.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmSourceFileLocationKind.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
@@ -117,6 +118,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 +187,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 +205,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 +217,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 +286,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 +322,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
@@ -342,7 +356,8 @@ public:
cmStateEnums::TargetType type,
const std::vector<std::string>& srcs,
bool excludeFromAll = false);
- void AddAlias(const std::string& libname, const std::string& tgt);
+ void AddAlias(const std::string& libname, const std::string& tgt,
+ bool globallyVisible = true);
//@{
/**
@@ -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;
}
/**
@@ -497,6 +513,8 @@ public:
const std::string& GetSafeDefinition(const std::string&) const;
const std::string& GetRequiredDefinition(const std::string& name) const;
bool IsDefinitionSet(const std::string&) const;
+ bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
+ bool emptyArgs = false) const;
/**
* Get the list of all variables in the current space. If argument
* cacheonly is specified and is greater than 0, then only cache
@@ -786,8 +804,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 0471a459e..446f225bd 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());
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- this->LocalGenerator->AddArchitectureFlags(
- flags, 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();
@@ -494,9 +478,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// add it now.
std::string implibRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY");
- if (const char* rule = this->Makefile->GetDefinition(implibRuleVar)) {
- cmExpandList(rule, real_link_commands);
- }
+ this->Makefile->GetDefExpandList(implibRuleVar, real_link_commands);
}
bool useResponseFileForObjects =
@@ -547,7 +529,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 d3f3a4ff0..5809b4a5c 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");
@@ -644,27 +642,21 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arCreateVar, linkLanguage, this->GetConfigName());
- if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
- cmExpandList(rule, archiveCreateCommands);
- }
+ this->Makefile->GetDefExpandList(arCreateVar, archiveCreateCommands);
std::string arAppendVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arAppendVar, linkLanguage, this->GetConfigName());
- if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
- cmExpandList(rule, archiveAppendCommands);
- }
+ this->Makefile->GetDefExpandList(arAppendVar, archiveAppendCommands);
std::string arFinishVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arFinishVar, linkLanguage, this->GetConfigName());
- if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
- cmExpandList(rule, archiveFinishCommands);
- }
+ this->Makefile->GetDefExpandList(arFinishVar, archiveFinishCommands);
}
// Decide whether to use archiving rules.
@@ -756,7 +748,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 000000000..29fd44051
--- /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 <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/SystemInformation.hxx"
+
+#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.Lower;
+ 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 000000000..1babd97eb
--- /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 a8769d8be..8396fa326 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>
@@ -17,7 +18,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
-#include "cmLinkLineComputer.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalCommonGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -25,6 +26,7 @@
#include "cmMakefileLibraryTargetGenerator.h"
#include "cmMakefileUtilityTargetGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -46,9 +48,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 +88,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 +168,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,16 +178,16 @@ 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());
}
// Look for additional files registered for cleaning in this target.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(prop_value);
+ std::vector<std::string> const files = evaluatedFiles(*prop_value);
// For relative path support
std::string const& binaryDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -184,8 +197,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 +313,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 +354,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 +492,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 +533,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(
@@ -495,13 +542,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add Fortran format flags.
if (lang == "Fortran") {
this->AppendFortranFormatFlags(flags, source);
+ this->AppendFortranPreprocessFlags(flags, source);
}
// 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 +557,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 +567,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 +591,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 +607,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 +688,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();
@@ -717,8 +766,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)";
@@ -750,25 +799,24 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
lang == "OBJC" || lang == "OBJCXX")) {
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
- const char* clauncher =
- this->GeneratorTarget->GetProperty(clauncher_prop);
- if (clauncher && *clauncher) {
- compilerLauncher = clauncher;
+ cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && !clauncher->empty()) {
+ compilerLauncher = *clauncher;
}
}
// Maybe insert an include-what-you-use runner.
if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
- const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
std::string const tidy_prop = lang + "_CLANG_TIDY";
- const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+ cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
std::string const cpplint_prop = lang + "_CPPLINT";
- const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
std::string const cppcheck_prop = lang + "_CPPCHECK";
- const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
- if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+ (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
if (!compilerLauncher.empty()) {
// In __run_co_compile case the launcher command is supplied
@@ -777,11 +825,11 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
compilerLauncher.clear();
}
- if (iwyu && *iwyu) {
+ if (iwyu && !iwyu->empty()) {
run_iwyu += " --iwyu=";
- run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
}
- if (tidy && *tidy) {
+ if (tidy && !tidy->empty()) {
run_iwyu += " --tidy=";
const char* driverMode = this->Makefile->GetDefinition(
"CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
@@ -789,18 +837,18 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
driverMode = lang == "C" ? "gcc" : "g++";
}
run_iwyu += this->LocalGenerator->EscapeForShell(
- cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
- if (cpplint && *cpplint) {
+ if (cpplint && !cpplint->empty()) {
run_iwyu += " --cpplint=";
- run_iwyu += this->LocalGenerator->EscapeForShell(cpplint);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
}
- if (cppcheck && *cppcheck) {
+ if (cppcheck && !cppcheck->empty()) {
run_iwyu += " --cppcheck=";
- run_iwyu += this->LocalGenerator->EscapeForShell(cppcheck);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
}
- if ((tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+ (cppcheck && !cppcheck->empty())) {
run_iwyu += " --source=";
run_iwyu += sourceFile;
}
@@ -848,10 +896,15 @@ 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")) {
- // Register these as extra files to clean.
- cmExpandList(extra_outputs_str, outputs);
- this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
+ if (cmProp extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
+ std::string evaluated_outputs = cmGeneratorExpression::Evaluate(
+ *extra_outputs_str, this->LocalGenerator, config);
+
+ if (!evaluated_outputs.empty()) {
+ // Register these as extra files to clean.
+ cmExpandList(evaluated_outputs, outputs);
+ this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
+ }
}
// Write the rule.
@@ -1130,8 +1183,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
@@ -1147,23 +1199,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(
@@ -1206,8 +1254,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);
}
}
@@ -1251,8 +1299,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 ec6b31438..f38f86237 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/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index f11b906d4..56221bf5b 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -4,7 +4,7 @@
#include <cstdio>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
#include "cmExecutionStatus.h"
#include "cmExprParserHelper.h"
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index bf8183bbf..c7bb9a7a3 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -6,8 +6,7 @@
#include <utility>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index ba2ea5b1c..b92548fd3 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmNinjaTypes.h"
#include "cmOSXBundleGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmState.h"
@@ -156,23 +157,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 +194,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 +234,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 +282,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();
@@ -454,14 +454,12 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
- const std::string cudaLinkCmd(
- this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY"));
- cmExpandList(cudaLinkCmd, linkCmds);
+ this->GetMakefile()->GetDefExpandList("CMAKE_CUDA_DEVICE_LINK_LIBRARY",
+ linkCmds);
} break;
case cmStateEnums::EXECUTABLE: {
- const std::string cudaLinkCmd(this->GetMakefile()->GetDefinition(
- "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"));
- cmExpandList(cudaLinkCmd, linkCmds);
+ this->GetMakefile()->GetDefExpandList(
+ "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE", linkCmds);
} break;
default:
break;
@@ -558,9 +556,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
case cmStateEnums::EXECUTABLE:
if (this->TargetLinkLanguage(config) == "Swift") {
if (this->GeneratorTarget->IsExecutableWithExports()) {
- const std::string flags =
- this->Makefile->GetSafeDefinition("CMAKE_EXE_EXPORTS_Swift_FLAG");
- cmExpandList(flags, linkCmds);
+ this->Makefile->GetDefExpandList("CMAKE_EXE_EXPORTS_Swift_FLAG",
+ linkCmds);
}
}
break;
@@ -587,8 +584,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 +669,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 +681,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"] =
@@ -748,9 +733,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
- build.RspFile = this->ConvertToNinjaPath(
- cmStrCat("CMakeFiles/", genTarget->GetName(),
- globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
+ build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
+ genTarget->GetName() + ".rsp");
// Gather order-only dependencies.
this->GetLocalGenerator()->AppendTargetDepends(
@@ -813,8 +797,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,
@@ -849,8 +845,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
}();
vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string {
- if (const char* name = gt->GetProperty("Swift_MODULE_NAME")) {
- return name;
+ if (cmProp name = gt->GetProperty("Swift_MODULE_NAME")) {
+ return *name;
}
return gt->GetName();
}();
@@ -858,15 +854,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string {
std::string directory =
this->GetLocalGenerator()->GetCurrentBinaryDirectory();
- if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+ if (cmProp prop = this->GetGeneratorTarget()->GetProperty(
"Swift_MODULE_DIRECTORY")) {
- directory = prop;
+ directory = *prop;
}
std::string name = module + ".swiftmodule";
- if (const char* prop =
+ if (cmProp prop =
this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
- name = prop;
+ name = *prop;
}
return this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -1026,11 +1022,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
std::string prefix;
std::string base;
std::string suffix;
- gt->GetFullNameComponents(prefix, base, suffix);
+ gt->GetFullNameComponents(prefix, base, suffix, config);
std::string dbg_suffix = ".dbg";
// TODO: Where to document?
- if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {
- dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX");
+ if (auto d = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {
+ dbg_suffix = d;
}
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
@@ -1158,9 +1154,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
globalGen->GetRuleCmdLength(linkBuild.Rule);
}
- linkBuild.RspFile = this->ConvertToNinjaPath(
- cmStrCat("CMakeFiles/", gt->GetName(),
- globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
+ linkBuild.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
+ gt->GetName() + ".rsp");
// Gather order-only dependencies.
this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 486ed8d33..d406c9951 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -7,13 +7,15 @@
#include <iterator>
#include <map>
#include <ostream>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <cm/memory>
#include <cmext/algorithm>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
@@ -27,6 +29,7 @@
#include "cmNinjaNormalTargetGenerator.h"
#include "cmNinjaUtilityTargetGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -94,17 +97,28 @@ 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_SCAN__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
+}
+
+std::string cmNinjaTargetGenerator::LanguageDependencyRule(
+ std::string const& lang, const std::string& config) const
+{
+ return cmStrCat(
+ lang, "_SCAN__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
@@ -129,9 +143,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,11 +169,31 @@ 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") {
this->AppendFortranFormatFlags(flags, *source);
+ this->AppendFortranPreprocessFlags(flags, *source);
}
// Add source file specific flags.
@@ -166,26 +201,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 +252,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 +292,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 +320,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 +388,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 +421,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 +438,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 +471,7 @@ std::string cmNinjaTargetGenerator::GetTargetFilePath(
if (path.empty() || path == ".") {
return name;
}
- path += "/";
- path += name;
+ path += cmStrCat('/', name);
return path;
}
@@ -491,13 +519,98 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
this->WriteCompileRule(language, config);
}
+namespace {
+// Create the command to run the dependency scanner
+std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
+ const std::string& lang, const std::string& ppFile,
+ bool needDyndep, const std::string& ddiFile)
+{
+ std::string ccmd =
+ cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang,
+ " --pp=", ppFile, " --dep=$DEP_FILE");
+ if (needDyndep) {
+ ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile);
+ }
+ return ccmd;
+}
+
+// Helper function to create dependency scanning rule, with optional
+// explicit preprocessing step if preprocessCommand is non-empty
+cmNinjaRule GetPreprocessScanRule(
+ const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars,
+ const std::string& responseFlag, const std::string& flags,
+ const std::string& launcher,
+ cmRulePlaceholderExpander* const rulePlaceholderExpander,
+ std::string scanCommand, cmLocalNinjaGenerator* generator,
+ const std::string& preprocessCommand = "")
+{
+ cmNinjaRule rule(ruleName);
+ // Explicit preprocessing always uses a depfile.
+ rule.DepType = ""; // no deps= for multiple outputs
+ rule.DepFile = "$DEP_FILE";
+
+ cmRulePlaceholderExpander::RuleVariables ppVars;
+ ppVars.CMTargetName = vars.CMTargetName;
+ ppVars.CMTargetType = vars.CMTargetType;
+ ppVars.Language = vars.Language;
+ ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
+ ppVars.PreprocessedSource = "$out";
+ ppVars.DependencyFile = rule.DepFile.c_str();
+
+ // Preprocessing uses the original source, compilation uses
+ // preprocessed output or original source
+ ppVars.Source = vars.Source;
+ vars.Source = "$in";
+
+ // Copy preprocessor definitions to the preprocessor rule.
+ ppVars.Defines = vars.Defines;
+
+ // Copy include directories to the preprocessor rule. The Fortran
+ // compilation rule still needs them for the INCLUDE directive.
+ ppVars.Includes = vars.Includes;
+
+ // Preprocessing and compilation use the same flags.
+ std::string ppFlags = flags;
+
+ // If using a response file, move defines, includes, and flags into it.
+ if (!responseFlag.empty()) {
+ rule.RspFile = "$RSP_FILE";
+ rule.RspContent =
+ cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
+ ppFlags = cmStrCat(responseFlag, rule.RspFile);
+ ppVars.Defines = "";
+ ppVars.Includes = "";
+ }
+
+ ppVars.Flags = ppFlags.c_str();
+
+ // Rule for preprocessing source file.
+ std::vector<std::string> ppCmds;
+
+ if (!preprocessCommand.empty()) {
+ // Lookup the explicit preprocessing rule.
+ cmExpandList(preprocessCommand, ppCmds);
+ for (std::string& i : ppCmds) {
+ i = cmStrCat(launcher, i);
+ rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars);
+ }
+ }
+
+ // Run CMake dependency scanner on either preprocessed output or source file
+ ppCmds.emplace_back(std::move(scanCommand));
+ rule.Command = generator->BuildCommandLine(ppCmds);
+
+ return rule;
+}
+}
+
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& config)
{
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 +635,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 = "@";
@@ -548,82 +661,42 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (explicitPP) {
- cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
- // Explicit preprocessing always uses a depfile.
- rule.DepType = ""; // no deps= for multiple outputs
- rule.DepFile = "$DEP_FILE";
+ // Combined preprocessing and dependency scanning
+ const auto ppScanCommand = GetScanCommand(
+ cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE");
+ const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
- cmRulePlaceholderExpander::RuleVariables ppVars;
- ppVars.CMTargetName = vars.CMTargetName;
- ppVars.CMTargetType = vars.CMTargetType;
- ppVars.Language = vars.Language;
- ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
- ppVars.PreprocessedSource = "$out";
- ppVars.DependencyFile = rule.DepFile.c_str();
+ auto ppRule = GetPreprocessScanRule(
+ this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags,
+ launcher, rulePlaceholderExpander.get(), ppScanCommand,
+ this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar));
- // Preprocessing uses the original source,
- // compilation uses preprocessed output.
- ppVars.Source = vars.Source;
- vars.Source = "$in";
+ // Write the rule for preprocessing file of the given language.
+ ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
+ ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
- // Preprocessing and compilation use the same flags.
- std::string ppFlags = flags;
+ this->GetGlobalGenerator()->AddRule(ppRule);
if (!compilePPWithDefines) {
- // Move preprocessor definitions to the preprocessor rule.
- ppVars.Defines = vars.Defines;
+ // Remove preprocessor definitions from compilation step
vars.Defines = "";
- } else {
- // Copy preprocessor definitions to the preprocessor rule.
- ppVars.Defines = vars.Defines;
}
- // Copy include directories to the preprocessor rule. The Fortran
- // compilation rule still needs them for the INCLUDE directive.
- ppVars.Includes = vars.Includes;
-
- // If using a response file, move defines, includes, and flags into it.
- if (!responseFlag.empty()) {
- rule.RspFile = "$RSP_FILE";
- rule.RspContent =
- cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
- ppFlags = responseFlag + rule.RspFile;
- ppVars.Defines = "";
- ppVars.Includes = "";
- }
+ // Just dependency scanning for files that have preprocessing turned off
+ const auto scanCommand =
+ GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out");
- ppVars.Flags = ppFlags.c_str();
+ auto scanRule = GetPreprocessScanRule(
+ this->LanguageDependencyRule(lang, config), vars, "", flags, launcher,
+ rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator());
- // Rule for preprocessing source file.
- std::vector<std::string> ppCmds;
- {
- // Lookup the explicit preprocessing rule.
- std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
- cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
- }
+ // Write the rule for generating dependencies for the given language.
+ scanRule.Comment = cmStrCat("Rule for generating ", lang,
+ " dependencies on non-preprocessed files.");
+ scanRule.Description =
+ cmStrCat("Generating ", lang, " dependencies for $in");
- for (std::string& i : ppCmds) {
- i = cmStrCat(launcher, i);
- rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
- i, ppVars);
- }
-
- // Run CMake dependency scanner on preprocessed output.
- {
- std::string ccmd =
- cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
- " --lang=", lang, " --pp=$out --dep=$DEP_FILE");
- if (needDyndep) {
- ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE";
- }
- ppCmds.emplace_back(std::move(ccmd));
- }
- rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds);
-
- // Write the rule for preprocessing file of the given language.
- rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
- rule.Description = cmStrCat("Building ", lang, " preprocessed $out");
- this->GetGlobalGenerator()->AddRule(rule);
+ this->GetGlobalGenerator()->AddRule(scanRule);
}
if (needDyndep) {
@@ -658,7 +731,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,15 +744,15 @@ 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()) {
rule.DepType = "gcc";
rule.DepFile = "$DEP_FILE";
- const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
- ? mf->GetSafeDefinition("CMAKE_C_COMPILER")
- : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+ auto d = mf->GetDefinition("CMAKE_C_COMPILER");
+ const std::string cl =
+ d ? d : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
cldeps = cmStrCat('"', cmSystemTools::GetCMClDepsCommand(), "\" ", lang,
' ', vars.Source, " $DEP_FILE $out \"",
mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"),
@@ -688,14 +761,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 +791,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,57 +801,59 @@ 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";
- const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
- if (clauncher && *clauncher) {
- compilerLauncher = clauncher;
+ std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
+ cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && !clauncher->empty()) {
+ compilerLauncher = *clauncher;
}
}
// 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";
- const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
- std::string const tidy_prop = lang + "_CLANG_TIDY";
- const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
- std::string const cpplint_prop = lang + "_CPPLINT";
- const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
- std::string const cppcheck_prop = lang + "_CPPCHECK";
- const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
- if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
+ cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
+ cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+ std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
+ cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
+ cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+ (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
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);
+ if (iwyu && !iwyu->empty()) {
+ run_iwyu += cmStrCat(" --iwyu=",
+ this->GetLocalGenerator()->EscapeForShell(*iwyu));
}
- if (tidy && *tidy) {
+ if (tidy && !tidy->empty()) {
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++";
}
run_iwyu += this->GetLocalGenerator()->EscapeForShell(
- cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
- if (cpplint && *cpplint) {
- run_iwyu += " --cpplint=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint);
+ if (cpplint && !cpplint->empty()) {
+ run_iwyu += cmStrCat(
+ " --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
}
- if (cppcheck && *cppcheck) {
- run_iwyu += " --cppcheck=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cppcheck);
+ if (cppcheck && !cppcheck->empty()) {
+ run_iwyu +=
+ cmStrCat(" --cppcheck=",
+ this->GetLocalGenerator()->EscapeForShell(*cppcheck));
}
- if ((tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+ (cppcheck && !cppcheck->empty())) {
run_iwyu += " --source=$in";
}
run_iwyu += " -- ";
@@ -797,7 +872,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 +947,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;
@@ -957,12 +1033,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
"output-file-map.json");
std::string const targetSwiftDepsPath = [this, config]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
- if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return name;
+ if (cmProp 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
@@ -976,6 +1052,82 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
}
+namespace {
+cmNinjaBuild GetPreprocessOrScanBuild(
+ const std::string& ruleName, const std::string& ppFileName, bool compilePP,
+ bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
+ const std::string& depFileName, bool needDyndep,
+ const std::string& objectFileName)
+{
+ // Explicit preprocessing and dependency
+ cmNinjaBuild ppBuild(ruleName);
+
+ if (!ppFileName.empty()) {
+ ppBuild.Outputs.push_back(ppFileName);
+ ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+ } else {
+ ppBuild.RspFile = "$out.rsp";
+ }
+
+ if (compilePP) {
+ // Move compilation dependencies to the preprocessing build statement.
+ std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
+ std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
+ std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
+ std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
+
+ // The actual compilation will now use the preprocessed source.
+ objBuild.ExplicitDeps.push_back(ppFileName);
+ } else {
+ // Copy compilation dependencies to the preprocessing build statement.
+ ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
+ ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
+ ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
+ ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+ }
+
+ // Preprocessing and compilation generally use the same flags.
+ ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+
+ if (compilePP && !compilePPWithDefines) {
+ // Move preprocessor definitions to the preprocessor build statement.
+ std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
+ } else {
+ // Copy preprocessor definitions to the preprocessor build statement.
+ ppBuild.Variables["DEFINES"] = vars["DEFINES"];
+ }
+
+ // Copy include directories to the preprocessor build statement. The
+ // Fortran compilation build statement still needs them for the INCLUDE
+ // directive.
+ ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
+
+ // Explicit preprocessing always uses a depfile.
+ ppBuild.Variables["DEP_FILE"] = depFileName;
+ if (compilePP) {
+ // The actual compilation does not need a depfile because it
+ // depends on the already-preprocessed source.
+ vars.erase("DEP_FILE");
+ }
+
+ if (needDyndep) {
+ // Tell dependency scanner the object file that will result from
+ // compiling the source.
+ ppBuild.Variables["OBJ_FILE"] = objectFileName;
+
+ // Tell dependency scanner where to store dyndep intermediate results.
+ std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
+ if (ppFileName.empty()) {
+ ppBuild.Outputs.push_back(ddiFile);
+ } else {
+ ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+ ppBuild.ImplicitOuts.push_back(ddiFile);
+ }
+ }
+ return ppBuild;
+}
+}
+
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
cmSourceFile const* source, const std::string& config,
const std::string& fileConfig, bool firstForConfig)
@@ -994,7 +1146,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 +1171,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 +1202,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));
}
@@ -1095,59 +1266,47 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(language);
if (explicitPP) {
- cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
- std::string const ppFileName =
- this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
- ppBuild.Outputs.push_back(ppFileName);
-
- ppBuild.RspFile = ppFileName + ".rsp";
+ // If source/target has preprocessing turned off, we still need to
+ // generate an explicit dependency step
+ const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS");
+ cmOutputConverter::FortranPreprocess preprocess =
+ cmOutputConverter::GetFortranPreprocess(srcpp);
+ if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
+ const auto& tgtpp =
+ this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
+ preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
+ }
- bool const compilePP = this->UsePreprocessedSource(language);
+ bool const compilePP = this->UsePreprocessedSource(language) &&
+ (preprocess != cmOutputConverter::FortranPreprocess::NotNeeded);
bool const compilePPWithDefines =
compilePP && this->CompilePreprocessedSourceWithDefines(language);
- if (compilePP) {
- // Move compilation dependencies to the preprocessing build statement.
- std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
- std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
- std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
- std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
-
- // The actual compilation will now use the preprocessed source.
- objBuild.ExplicitDeps.push_back(ppFileName);
- } else {
- // Copy compilation dependencies to the preprocessing build statement.
- ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
- ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
- ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
- ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
- }
- // Preprocessing and compilation generally use the same flags.
- ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+ std::string const ppFileName = compilePP
+ ? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config))
+ : "";
+
+ std::string const buildName = compilePP
+ ? this->LanguagePreprocessRule(language, config)
+ : this->LanguageDependencyRule(language, config);
+
+ const auto depExtension = compilePP ? ".pp.d" : ".d";
+ const std::string depFileName =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
+
+ cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
+ buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
+ depFileName, needDyndep, objectFileName);
if (compilePP) {
// 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);
- }
-
- if (compilePP && !compilePPWithDefines) {
- // Move preprocessor definitions to the preprocessor build statement.
- std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
- } else {
- // Copy preprocessor definitions to the preprocessor build statement.
- ppBuild.Variables["DEFINES"] = vars["DEFINES"];
- }
-
- // Copy include directories to the preprocessor build statement. The
- // Fortran compilation build statement still needs them for the INCLUDE
- // directive.
- ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
- if (compilePP) {
// Prepend source file's original directory as an include directory
// so e.g. Fortran INCLUDE statements can look for files in it.
std::vector<std::string> sourceDirectory;
@@ -1158,31 +1317,12 @@ 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);
- if (compilePP) {
- // The actual compilation does not need a depfile because it
- // depends on the already-preprocessed source.
- vars.erase("DEP_FILE");
- }
-
- if (needDyndep) {
- // Tell dependency scanner the object file that will result from
- // compiling the source.
- ppBuild.Variables["OBJ_FILE"] = objectFileName;
-
- // Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = objectFileName + ".ddi";
- ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
- ppBuild.ImplicitOuts.push_back(ddiFile);
- if (firstForConfig) {
- this->Configs[config].DDIFiles[language].push_back(ddiFile);
- }
+ if (firstForConfig && needDyndep) {
+ std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
+ this->Configs[config].DDIFiles[language].push_back(ddiFile);
}
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
@@ -1207,8 +1347,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 +1357,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,15 +1366,20 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
objBuild, commandLineLengthLimit);
}
- if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
- cmNinjaBuild build("phony");
- build.Comment = "Additional output files.";
- build.Outputs = cmExpandedList(objectOutputs);
- std::transform(build.Outputs.begin(), build.Outputs.end(),
- build.Outputs.begin(), MapToNinjaPath());
- build.ExplicitDeps = objBuild.Outputs;
- this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
- build);
+ if (cmProp objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
+ std::string evaluatedObjectOutputs = cmGeneratorExpression::Evaluate(
+ *objectOutputs, this->LocalGenerator, config);
+
+ if (!evaluatedObjectOutputs.empty()) {
+ cmNinjaBuild build("phony");
+ build.Comment = "Additional output files.";
+ build.Outputs = cmExpandedList(evaluatedObjectOutputs);
+ std::transform(build.Outputs.begin(), build.Outputs.end(),
+ build.Outputs.begin(), MapToNinjaPath());
+ build.ExplicitDeps = objBuild.Outputs;
+ this->GetGlobalGenerator()->WriteBuild(
+ this->GetImplFileStream(fileConfig), build);
+ }
}
}
@@ -1242,8 +1388,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 +1438,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 +1457,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 +1528,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);
@@ -1404,11 +1551,11 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
{
- if (const char* prop_value =
+ if (cmProp prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
std::vector<std::string> cleanFiles;
- cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
+ cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
this->GeneratorTarget),
cleanFiles);
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
@@ -1494,9 +1641,9 @@ void cmNinjaTargetGenerator::addPoolNinjaVariable(
const std::string& pool_property, cmGeneratorTarget* target,
cmNinjaVars& vars)
{
- const char* pool = target->GetProperty(pool_property);
+ cmProp pool = target->GetProperty(pool_property);
if (pool) {
- vars["pool"] = pool;
+ vars["pool"] = *pool;
}
}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 8678dc3f6..8d4372edc 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -12,7 +12,7 @@
#include <utility>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmCommonTargetGenerator.h"
#include "cmGlobalNinjaGenerator.h"
@@ -70,6 +70,8 @@ protected:
const std::string& config) const;
std::string LanguagePreprocessRule(std::string const& lang,
const std::string& config) const;
+ std::string LanguageDependencyRule(std::string const& lang,
+ const std::string& config) const;
bool NeedExplicitPreprocessing(std::string const& lang) const;
std::string LanguageDyndepRule(std::string const& lang,
const std::string& config) const;
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 6e392421b..8d863c34d 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmLocalNinjaGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -110,9 +111,9 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
std::string command =
lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
std::string desc;
- const char* echoStr = genTarget->GetProperty("EchoString");
+ cmProp echoStr = genTarget->GetProperty("EchoString");
if (echoStr) {
- desc = echoStr;
+ desc = *echoStr;
} else {
desc = "Running utility command for " + this->GetTargetName();
}
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 382b563e2..7eea4b2df 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 232be4883..5bf1d9859 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 22e59ac43..a58e2f8cc 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -6,6 +6,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
@@ -52,7 +53,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 +61,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 1c6fad148..359e9f5a9 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)) {
@@ -170,13 +170,15 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
return format;
}
-cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
- const char* value)
+cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess(
+ cm::string_view value)
{
- if (!value) {
- return FortranFormatNone;
+ if (value.empty()) {
+ return FortranPreprocess::Unset;
}
- return GetFortranFormat(cm::string_view(value));
+
+ return cmIsOn(value) ? FortranPreprocess::Needed
+ : FortranPreprocess::NotNeeded;
}
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 6583ab5cb..a8b452842 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -94,7 +94,14 @@ public:
FortranFormatFree
};
static FortranFormat GetFortranFormat(cm::string_view value);
- static FortranFormat GetFortranFormat(const char* value);
+
+ enum class FortranPreprocess
+ {
+ Unset,
+ NotNeeded,
+ Needed
+ };
+ static FortranPreprocess GetFortranPreprocess(cm::string_view value);
private:
cmState* GetState() const;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 147f97f73..aa5abcb7a 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -15,6 +15,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -117,14 +118,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/cmPipeConnection.h b/Source/cmPipeConnection.h
index 81f8a49f6..121571603 100644
--- a/Source/cmPipeConnection.h
+++ b/Source/cmPipeConnection.h
@@ -6,7 +6,7 @@
#include <string>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmConnection.h"
#include "cmUVHandlePtr.h"
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5c8bc98b2..dea3f8a35 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 1366ff089..a82f4211e 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -305,7 +305,22 @@ 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) \
+ SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
+ 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 +350,10 @@ class cmMakefile;
F(CMP0081) \
F(CMP0083) \
F(CMP0095) \
- F(CMP0099)
+ F(CMP0099) \
+ F(CMP0104) \
+ F(CMP0105) \
+ F(CMP0108)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
index e80ea5c8d..0fb4ff71c 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 a25fd42d1..2ec66d9f1 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/cmProperty.h b/Source/cmProperty.h
index 80f131a76..b0fcce7f5 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
class cmProperty
{
public:
@@ -22,4 +24,6 @@ public:
};
};
+using cmProp = const std::string*;
+
#endif
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 6a3174c7b..1796bb8d0 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -2,19 +2,38 @@
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 <tuple>
+
+cmPropertyDefinition::cmPropertyDefinition(std::string shortDescription,
+ std::string fullDescription,
+ bool chained)
+ : ShortDescription(std::move(shortDescription))
+ , FullDescription(std::move(fullDescription))
+ , Chained(chained)
+{
+}
+
+void cmPropertyDefinitionMap::DefineProperty(
+ const std::string& name, cmProperty::ScopeType scope,
+ const std::string& ShortDescription, const std::string& FullDescription,
+ bool chain)
{
- this->Name = name;
- this->Scope = scope;
- this->Chained = chain;
- if (shortDescription) {
- this->ShortDescription = shortDescription;
+ auto it = this->Map_.find(key_type(name, scope));
+ if (it == this->Map_.end()) {
+ // try_emplace() since C++17
+ this->Map_.emplace(
+ std::piecewise_construct, std::forward_as_tuple(name, scope),
+ std::forward_as_tuple(ShortDescription, FullDescription, chain));
}
- if (fullDescription) {
- this->FullDescription = fullDescription;
+}
+
+cmPropertyDefinition const* cmPropertyDefinitionMap::GetPropertyDefinition(
+ const std::string& name, cmProperty::ScopeType scope) const
+{
+ auto it = this->Map_.find(key_type(name, scope));
+ if (it != this->Map_.end()) {
+ return &it->second;
}
+
+ return nullptr;
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 0d68c328b..f83bc4f74 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -5,7 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
#include <string>
+#include <utility>
#include "cmProperty.h"
@@ -13,28 +15,19 @@
* \brief Property meta-information
*
* This class contains the following meta-information about property:
- * - Name;
* - Various documentation strings;
- * - The scope of the property;
* - If the property is chained.
*/
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 shortDescription,
+ std::string fullDescription, bool chained);
/// Is the property chained?
bool IsChained() const { return this->Chained; }
- /// Get the scope
- cmProperty::ScopeType GetScope() const { return this->Scope; }
-
/// Get the documentation (short version)
const std::string& GetShortDescription() const
{
@@ -47,12 +40,30 @@ public:
return this->FullDescription;
}
-protected:
- std::string Name;
+private:
std::string ShortDescription;
std::string FullDescription;
- cmProperty::ScopeType Scope;
bool Chained;
};
+/** \class cmPropertyDefinitionMap
+ * \brief Map property name and scope to their definition
+ */
+class cmPropertyDefinitionMap
+{
+public:
+ // define the property
+ void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain);
+
+ // get the property definition if present, otherwise nullptr
+ cmPropertyDefinition const* GetPropertyDefinition(
+ const std::string& name, cmProperty::ScopeType scope) const;
+
+private:
+ using key_type = std::pair<std::string, cmProperty::ScopeType>;
+ std::map<key_type, cmPropertyDefinition> Map_;
+};
+
#endif
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
deleted file mode 100644
index f752ed7c6..000000000
--- a/Source/cmPropertyDefinitionMap.cxx
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmPropertyDefinitionMap.h"
-
-#include <utility>
-
-void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription,
- bool chain)
-{
- auto it = this->find(name);
- cmPropertyDefinition* prop;
- if (it == this->end()) {
- prop = &(*this)[name];
- prop->DefineProperty(name, scope, ShortDescription, FullDescription,
- chain);
- }
-}
-
-bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
-{
- return this->find(name) != this->end();
-}
-
-bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
-{
- auto it = this->find(name);
- if (it == this->end()) {
- return false;
- }
-
- return it->second.IsChained();
-}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
deleted file mode 100644
index 8ec791033..000000000
--- a/Source/cmPropertyDefinitionMap.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmPropertyDefinitionMap_h
-#define cmPropertyDefinitionMap_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <map>
-#include <string>
-
-#include "cmProperty.h"
-#include "cmPropertyDefinition.h"
-
-class cmPropertyDefinitionMap
- : public std::map<std::string, cmPropertyDefinition>
-{
-public:
- // define the property
- void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain);
-
- // has a named property been defined
- bool IsPropertyDefined(const std::string& name) const;
-
- // is a named property set to chain
- bool IsPropertyChained(const std::string& name) const;
-};
-
-#endif
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index d4b35523f..f22f36dd4 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 bea437284..5fc46a2b4 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -10,6 +10,8 @@
#include <utility>
#include <vector>
+#include "cmProperty.h"
+
/** \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 cc4df8f89..795c2ee5a 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -5,6 +5,7 @@
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
@@ -39,7 +40,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 d5891c447..57fcd2da7 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 7a6cb4219..3d4f5d722 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -13,6 +13,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
+#include "cmProperty.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenInitializer.h"
#include "cmState.h"
@@ -95,11 +96,11 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
bool const uic = target->GetPropertyAsBool(kw().AUTOUIC);
bool const rcc = target->GetPropertyAsBool(kw().AUTORCC);
if (moc || uic || rcc) {
- std::string const mocExec =
+ std::string const& mocExec =
target->GetSafeProperty(kw().AUTOMOC_EXECUTABLE);
- std::string const uicExec =
+ std::string const& uicExec =
target->GetSafeProperty(kw().AUTOUIC_EXECUTABLE);
- std::string const rccExec =
+ std::string const& rccExec =
target->GetSafeProperty(kw().AUTORCC_EXECUTABLE);
// We support Qt4, Qt5 and Qt6
@@ -164,10 +165,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 d8b91001e..511a018fb 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 <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/SystemInformation.hxx"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
@@ -35,6 +35,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenGlobalInitializer.h"
#include "cmSourceFile.h"
@@ -339,7 +340,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Targets FOLDER
{
- const char* folder =
+ cmProp folder =
this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
if (folder == nullptr) {
folder = this->Makefile->GetState()->GetGlobalProperty(
@@ -350,7 +351,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
folder = this->GenTarget->GetProperty("FOLDER");
}
if (folder != nullptr) {
- this->TargetsFolder = folder;
+ this->TargetsFolder = *folder;
}
}
@@ -440,7 +441,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Autogen target parallel processing
{
- std::string prop = this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
+ std::string const& prop =
+ this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
if (prop.empty() || (prop == "AUTO")) {
// Autodetect number of CPUs
this->AutogenTarget.Parallel = GetParallelCPUCount();
@@ -471,7 +473,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->AutogenTarget.DependOrigin =
this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
- std::string const deps =
+ std::string const& deps =
this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
for (std::string const& depName : cmExpandedList(deps)) {
@@ -569,9 +571,8 @@ bool cmQtAutoGenInitializer::InitMoc()
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
(this->QtVersion >= IntegerVersion(5, 8))) {
// Command
- cmExpandList(this->Makefile->GetSafeDefinition(
- "CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"),
- this->Moc.PredefsCmd);
+ this->Makefile->GetDefExpandList("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND",
+ this->Moc.PredefsCmd);
// Header
if (!this->Moc.PredefsCmd.empty()) {
ConfigFileNames(this->Moc.PredefsFile,
@@ -654,7 +655,7 @@ bool cmQtAutoGenInitializer::InitUic()
{
// Uic search paths
{
- std::string const usp =
+ std::string const& usp =
this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
this->Uic.SearchPaths =
@@ -847,7 +848,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 +896,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 +1095,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 +1140,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));
@@ -1180,54 +1182,11 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (useNinjaDepfile) {
// Create a custom command that generates a timestamp file and
// has a depfile assigned. The depfile is created by JobDepFilesMergeT.
- //
- // Also create an additional '_autogen_timestamp_deps' that the custom
- // command will depend on. It will have no sources or commands to
- // execute, but it will have dependencies that would originally be
- // assigned to the pre-Qt 5.15 'autogen' target. These dependencies will
- // serve as a list of order-only dependencies for the custom command,
- // without forcing the custom command to re-execute.
- //
- // The dependency tree would then look like
- // '_autogen_timestamp_deps (order-only)' <- '/timestamp' file <-
- // '_autogen' target.
- const auto timestampTargetName =
- cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
- std::vector<std::string> timestampTargetProvides;
- cmCustomCommandLines timestampTargetCommandLines;
-
- // Add additional autogen target dependencies to
- // '_autogen_timestamp_deps'.
+
+ // Add additional autogen target dependencies
for (const cmTarget* t : this->AutogenTarget.DependTargets) {
dependencies.push_back(t->GetName());
}
-
- cmTarget* timestampTarget = this->LocalGen->AddUtilityCommand(
- timestampTargetName, true, this->Dir.Work.c_str(),
- /*byproducts=*/timestampTargetProvides,
- /*depends=*/dependencies, timestampTargetCommandLines, false, nullptr);
- this->LocalGen->AddGeneratorTarget(
- cm::make_unique<cmGeneratorTarget>(timestampTarget, this->LocalGen));
-
- // Set FOLDER property on the timestamp target, so it appears in the
- // appropriate folder in an IDE or in the file api.
- if (!this->TargetsFolder.empty()) {
- timestampTarget->SetProperty("FOLDER", this->TargetsFolder);
- }
-
- // Make '/timestamp' file depend on '_autogen_timestamp_deps' and on the
- // moc and uic executables (whichever are enabled).
- dependencies.clear();
- dependencies.push_back(timestampTargetName);
-
- if (this->Moc.ExecutableTarget != nullptr) {
- dependencies.push_back(this->Moc.ExecutableTarget->Target->GetName());
- }
- if (this->Uic.ExecutableTarget != nullptr) {
- dependencies.push_back(this->Uic.ExecutableTarget->Target->GetName());
- }
-
- // Create the custom command that outputs the timestamp file.
const char timestampFileName[] = "timestamp";
const std::string outputFile =
cmStrCat(this->Dir.Build, "/", timestampFileName);
@@ -1251,7 +1210,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
@@ -1322,6 +1282,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
@@ -1350,7 +1311,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(
@@ -1390,7 +1352,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);
@@ -1508,7 +1471,6 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
info.Set("DEP_FILE", this->AutogenTarget.DepFile);
info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
- info.SetArray("CMAKE_LIST_FILES", this->Makefile->GetListFiles());
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
info.SetArrayArray(
@@ -1648,10 +1610,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;
}
@@ -1712,6 +1673,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(
@@ -1733,9 +1701,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);
}
@@ -1743,8 +1711,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
@@ -1827,7 +1795,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Custom executable
{
std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
- std::string const val = this->GenTarget->Target->GetSafeProperty(prop);
+ std::string const& val = this->GenTarget->Target->GetSafeProperty(prop);
if (!val.empty()) {
// Evaluate generator expression
{
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index da963052f..ee2bc0937 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerator.h"
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
-#include "cm_jsoncpp_reader.h"
+#include "cmsys/FStream.hxx"
#include "cmQtAutoGen.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index bbe6dd015..83fb3ed88 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -13,7 +13,7 @@
#include <cm/string_view>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileTime.h"
#include "cmQtAutoGen.h"
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 49eb018e7..9adcabb80 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -18,11 +18,11 @@
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cm3p/json/value.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_value.h"
-
#include "cmCryptoHash.h"
#include "cmFileTime.h"
#include "cmGccDepfileReader.h"
@@ -184,7 +184,6 @@ public:
std::string DepFile;
std::string DepFileRuleName;
std::vector<std::string> HeaderExtensions;
- std::vector<std::string> ListFiles;
};
/** Shared common variables. */
@@ -701,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();
@@ -2164,9 +2163,7 @@ std::string escapeDependencyPath(cm::string_view path)
void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
{
if (Log().Verbose()) {
- Log().Info(GenT::MOC,
- cmStrCat("Merging MOC dependencies into ",
- MessagePath(BaseConst().DepFile.c_str())));
+ Log().Info(GenT::MOC, "Merging MOC dependencies");
}
auto processDepFile =
[](const std::string& mocOutputFile) -> std::vector<std::string> {
@@ -2177,7 +2174,7 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
return dependenciesFromDepFile(f.c_str());
};
- std::vector<std::string> dependencies = BaseConst().ListFiles;
+ std::vector<std::string> dependencies;
ParseCacheT& parseCache = BaseEval().ParseCache;
auto processMappingEntry = [&](const MappingMapT::value_type& m) {
auto cacheEntry = parseCache.GetOrInsert(m.first);
@@ -2214,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),
@@ -2227,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()
@@ -2259,7 +2255,6 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
!info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
false) ||
!info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
- !info.GetArray("CMAKE_LIST_FILES", BaseConst_.ListFiles, true) ||
!info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
!info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
!info.GetString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) {
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 7f4abf904..26e93bb34 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 5ab1b3ac1..254131b4d 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 7a987c27e..0781d2978 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 52bde7c5c..cfe308755 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 3b2e5f322..7f9740626 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cassert>
+#include <csignal>
#include <cstdint>
#include <iostream>
#include <mutex>
@@ -12,10 +13,10 @@
#include <cm/memory>
#include <cm/shared_mutex>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
#include "cmConnection.h"
#include "cmFileMonitor.h"
@@ -59,16 +60,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 +114,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 +294,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 3d7027b39..954332908 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -10,8 +10,8 @@
#include <cm/shared_mutex>
-#include "cm_jsoncpp_value.h"
-#include "cm_uv.h"
+#include <cm3p/json/value.h>
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.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/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index 279197214..b4f41a09e 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -4,7 +4,7 @@
#include "cmServerConnection.h"
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmServer.h"
#include "cmServerDictionary.h"
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 1d4ea0153..4f7131fc6 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -10,16 +10,17 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
-#include "cmAlgorithms.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileMonitor.h"
#include "cmGlobalGenerator.h"
#include "cmJsonObjectDictionary.h"
#include "cmJsonObjects.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmServer.h"
#include "cmServerDictionary.h"
#include "cmState.h"
@@ -182,7 +183,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 +206,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 +434,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.");
}
}
@@ -446,13 +445,13 @@ cmServerResponse cmServerProtocol1::ProcessCache(
entry[kKEY_KEY] = key;
entry[kTYPE_KEY] =
cmState::CacheEntryTypeToString(state->GetCacheEntryType(key));
- entry[kVALUE_KEY] = state->GetCacheEntryValue(key);
+ entry[kVALUE_KEY] = *state->GetCacheEntryValue(key);
Json::Value props = Json::objectValue;
bool haveProperties = false;
for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
haveProperties = true;
- props[prop] = state->GetCacheEntryProperty(key, prop);
+ props[prop] = *state->GetCacheEntryProperty(key, prop);
}
if (haveProperties) {
entry[kPROPERTIES_KEY] = props;
@@ -564,7 +563,7 @@ cmServerResponse cmServerProtocol1::ProcessConfigure(
if (cm->LoadCache(buildDir)) {
// build directory has been set up before
- const std::string* cachedSourceDir =
+ cmProp cachedSourceDir =
cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
if (!cachedSourceDir) {
return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
@@ -574,7 +573,7 @@ cmServerResponse cmServerProtocol1::ProcessConfigure(
cm->SetHomeDirectory(sourceDir);
}
- const std::string* cachedGenerator =
+ cmProp cachedGenerator =
cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
if (cachedGenerator) {
if (gg && gg->GetName() != *cachedGenerator) {
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 8446c3e76..c71b7bf60 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -8,7 +8,7 @@
#include <string>
#include <utility>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmake.h"
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 5e2a1462c..354b4c327 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -5,6 +5,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -135,7 +136,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 +150,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/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 35daca6ff..07ad24602 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -5,12 +5,6 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend,
- std::string& errors);
-}
-
// cmSetDirectoryPropertiesCommand
bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -20,38 +14,26 @@ bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- std::string errors;
- bool ret =
- RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors);
- if (!ret) {
- status.SetError(errors);
+ // PROPERTIES followed by prop value pairs
+ if (args.size() % 2 != 1) {
+ status.SetError("Wrong number of arguments");
+ return false;
}
- return ret;
-}
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend,
- std::string& errors)
-{
- for (; ait != aitend; ait += 2) {
- if (ait + 1 == aitend) {
- errors = "Wrong number of arguments";
- return false;
- }
- const std::string& prop = *ait;
- const std::string& value = *(ait + 1);
+ for (auto iter = args.begin() + 1; iter != args.end(); iter += 2) {
+ const std::string& prop = *iter;
if (prop == "VARIABLES") {
- errors = "Variables and cache variables should be set using SET command";
+ status.SetError(
+ "Variables and cache variables should be set using SET command");
return false;
}
if (prop == "MACROS") {
- errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
+ status.SetError(
+ "Commands and macros cannot be set using SET_CMAKE_PROPERTIES");
return false;
}
- mf.SetProperty(prop, value.c_str());
+ status.GetMakefile().SetProperty(prop, (iter + 1)->c_str());
}
return true;
}
-}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 3705727d8..6ca763b0b 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -4,6 +4,7 @@
#include <set>
#include <sstream>
+#include <unordered_set>
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
@@ -43,7 +44,9 @@ bool HandleSourceMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
- bool appendMode, bool remove);
+ bool appendMode, bool remove,
+ const std::vector<cmMakefile*>& directory_makefiles,
+ bool source_file_paths_should_be_absolute);
bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove);
@@ -74,6 +77,147 @@ bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
bool appendMode, bool remove);
}
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+ cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& directory_makefiles)
+{
+ std::unordered_set<cmMakefile*> directory_makefiles_set;
+
+ cmMakefile* current_dir_mf = &status.GetMakefile();
+ if (!source_file_directories.empty()) {
+ for (const std::string& dir_path : source_file_directories) {
+ const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
+ dir_path, current_dir_mf->GetCurrentSourceDirectory());
+ cmMakefile* dir_mf =
+ status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+ absolute_dir_path);
+ if (!dir_mf) {
+ status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path));
+ return false;
+ }
+ if (directory_makefiles_set.find(dir_mf) ==
+ directory_makefiles_set.end()) {
+ directory_makefiles.push_back(dir_mf);
+ directory_makefiles_set.insert(dir_mf);
+ }
+ }
+ }
+
+ if (!source_file_target_directories.empty()) {
+ for (const std::string& target_name : source_file_target_directories) {
+ cmTarget* target = current_dir_mf->FindTargetToUse(target_name);
+ if (!target) {
+ status.SetError(cmStrCat(
+ "given non-existent target for TARGET_DIRECTORY ", target_name));
+ return false;
+ }
+ cmProp target_source_dir = target->GetProperty("SOURCE_DIR");
+ cmMakefile* target_dir_mf =
+ status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+ *target_source_dir);
+
+ if (directory_makefiles_set.find(target_dir_mf) ==
+ directory_makefiles_set.end()) {
+ directory_makefiles.push_back(target_dir_mf);
+ directory_makefiles_set.insert(target_dir_mf);
+ }
+ }
+ }
+
+ if (source_file_directories.empty() &&
+ source_file_target_directories.empty()) {
+ directory_makefiles.push_back(current_dir_mf);
+ }
+ return true;
+}
+
+bool HandleSourceFileDirectoryScopeValidation(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories)
+{
+ // Validate source file directory scopes.
+ if (source_file_directory_option_enabled &&
+ source_file_directories.empty()) {
+ std::string errors = "called with incorrect number of arguments "
+ "no value provided to the DIRECTORY option";
+ status.SetError(errors);
+ return false;
+ }
+ if (source_file_target_option_enabled &&
+ source_file_target_directories.empty()) {
+ std::string errors = "called with incorrect number of arguments "
+ "no value provided to the TARGET_DIRECTORY option";
+ status.SetError(errors);
+ return false;
+ }
+ return true;
+}
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& source_file_directory_makefiles)
+{
+ bool scope_options_valid =
+ SetPropertyCommand::HandleSourceFileDirectoryScopeValidation(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories);
+ if (!scope_options_valid) {
+ return false;
+ }
+
+ scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes(
+ status, source_file_directories, source_file_target_directories,
+ source_file_directory_makefiles);
+ return scope_options_valid;
+}
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+ cmExecutionStatus& status, const std::string& source_file_path,
+ const bool needed)
+{
+ if (!needed) {
+ return source_file_path;
+ }
+ const std::string absolute_file_path = cmSystemTools::CollapseFullPath(
+ source_file_path, status.GetMakefile().GetCurrentSourceDirectory());
+ return absolute_file_path;
+}
+
+void MakeSourceFilePathsAbsoluteIfNeeded(
+ cmExecutionStatus& status,
+ std::vector<std::string>& source_files_absolute_paths,
+ std::vector<std::string>::const_iterator files_it_begin,
+ std::vector<std::string>::const_iterator files_it_end, const bool needed)
+{
+
+ // Make the file paths absolute, so that relative source file paths are
+ // picked up relative to the command calling site, regardless of the
+ // directory scope.
+ std::vector<std::string>::difference_type num_files =
+ files_it_end - files_it_begin;
+ source_files_absolute_paths.reserve(num_files);
+
+ if (!needed) {
+ source_files_absolute_paths.assign(files_it_begin, files_it_end);
+ return;
+ }
+
+ for (; files_it_begin != files_it_end; ++files_it_begin) {
+ const std::string absolute_file_path =
+ MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true);
+ source_files_absolute_paths.push_back(absolute_file_path);
+ }
+}
+}
+
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -114,13 +258,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
std::string propertyName;
std::string propertyValue;
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
// Parse the rest of the arguments up to the values.
enum Doing
{
DoingNone,
DoingNames,
DoingProperty,
- DoingValues
+ DoingValues,
+ DoingSourceDirectory,
+ DoingSourceTargetDirectory
};
Doing doing = DoingNames;
const char* sep = "";
@@ -137,8 +288,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
appendMode = true;
remove = false;
appendAsString = true;
+ } else if (doing != DoingProperty && doing != DoingValues &&
+ scope == cmProperty::SOURCE_FILE && arg == "DIRECTORY") {
+ doing = DoingSourceDirectory;
+ source_file_directory_option_enabled = true;
+ } else if (doing != DoingProperty && doing != DoingValues &&
+ scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") {
+ doing = DoingSourceTargetDirectory;
+ source_file_target_option_enabled = true;
} else if (doing == DoingNames) {
names.insert(arg);
+ } else if (doing == DoingSourceDirectory) {
+ source_file_directories.push_back(arg);
+ } else if (doing == DoingSourceTargetDirectory) {
+ source_file_target_directories.push_back(arg);
} else if (doing == DoingProperty) {
propertyName = arg;
doing = DoingValues;
@@ -159,6 +322,18 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
return false;
}
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+
// Dispatch property setting.
switch (scope) {
case cmProperty::GLOBAL:
@@ -172,7 +347,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
appendAsString, appendMode, remove);
case cmProperty::SOURCE_FILE:
return HandleSourceMode(status, names, propertyName, propertyValue,
- appendAsString, appendMode, remove);
+ appendAsString, appendMode, remove,
+ source_file_directory_makefiles,
+ source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
@@ -235,14 +412,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 +478,7 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
if (remove) {
target->SetProperty(propertyName, nullptr);
} else {
- target->SetProperty(propertyName, propertyValue.c_str());
+ target->SetProperty(propertyName, propertyValue);
}
}
@@ -321,21 +492,32 @@ bool HandleSourceMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
- bool appendMode, bool remove)
+ bool appendMode, bool remove,
+ const std::vector<cmMakefile*>& directory_makefiles,
+ const bool source_file_paths_should_be_absolute)
{
- for (std::string const& name : names) {
- // Get the source file.
- if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
- if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
- appendMode, remove)) {
+ std::vector<std::string> files_absolute;
+ std::vector<std::string> unique_files(names.begin(), names.end());
+ SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+ status, files_absolute, unique_files.begin(), unique_files.end(),
+ source_file_paths_should_be_absolute);
+
+ for (const auto mf : directory_makefiles) {
+ for (std::string const& name : files_absolute) {
+ // Get the source file.
+ if (cmSourceFile* sf = mf->GetOrCreateSource(name)) {
+ if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
+ appendMode, remove)) {
+ return false;
+ }
+ } else {
+ status.SetError(cmStrCat(
+ "given SOURCE name that could not be found or created: ", name));
return false;
}
- } else {
- status.SetError(cmStrCat(
- "given SOURCE name that could not be found or created: ", name));
- return false;
}
}
+
return true;
}
@@ -438,7 +620,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 +642,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 +686,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/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index ec36f849e..af566a3a5 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -8,9 +8,38 @@
#include <string>
#include <vector>
+class cmMakefile;
class cmExecutionStatus;
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status);
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+ cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& directory_makefiles);
+
+bool HandleSourceFileDirectoryScopeValidation(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories);
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+ cmExecutionStatus& status, bool source_directories_option_encountered,
+ bool source_target_directories_option_encountered,
+ std::vector<std::string>& source_directories,
+ std::vector<std::string>& source_target_directories,
+ std::vector<cmMakefile*>& source_file_directory_makefiles);
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+ cmExecutionStatus& status, const std::string& source_file_path, bool needed);
+void MakeSourceFilePathsAbsoluteIfNeeded(
+ cmExecutionStatus& status,
+ std::vector<std::string>& source_files_absolute_paths,
+ std::vector<std::string>::const_iterator files_it_begin,
+ std::vector<std::string>::const_iterator files_it_end, bool needed);
+}
+
#endif
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 7ff604be0..c1b0c28db 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -2,17 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetSourceFilesPropertiesCommand.h"
+#include <algorithm>
+#include <iterator>
+
+#include <cm/string_view>
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
-static bool RunCommand(cmMakefile* mf,
- std::vector<std::string>::const_iterator filebeg,
- std::vector<std::string>::const_iterator fileend,
- std::vector<std::string>::const_iterator propbeg,
- std::vector<std::string>::const_iterator propend,
- std::string& errors);
+static bool RunCommandForScope(
+ cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+ std::vector<std::string>::const_iterator file_end,
+ std::vector<std::string>::const_iterator prop_begin,
+ std::vector<std::string>::const_iterator prop_end, std::string& errors);
bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -23,56 +29,106 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
}
// break the arguments into source file names and properties
- int numFiles = 0;
- std::vector<std::string>::const_iterator j;
- j = args.begin();
// old style allows for specifier before PROPERTIES keyword
- while (j != args.end() && *j != "ABSTRACT" && *j != "WRAP_EXCLUDE" &&
- *j != "GENERATED" && *j != "COMPILE_FLAGS" &&
- *j != "OBJECT_DEPENDS" && *j != "PROPERTIES") {
- numFiles++;
- ++j;
+ static const cm::string_view prop_names[] = {
+ "ABSTRACT", "GENERATED", "WRAP_EXCLUDE", "COMPILE_FLAGS",
+ "OBJECT_DEPENDS", "PROPERTIES", "DIRECTORY", "TARGET_DIRECTORY"
+ };
+
+ auto isAPropertyKeyword =
+ [](const std::vector<std::string>::const_iterator& arg_it) {
+ return std::any_of(
+ std::begin(prop_names), std::end(prop_names),
+ [&arg_it](cm::string_view prop_name) { return *arg_it == prop_name; });
+ };
+
+ auto options_begin = std::find_first_of(
+ args.begin(), args.end(), std::begin(prop_names), std::end(prop_names));
+ auto options_it = options_begin;
+
+ // Handle directory options.
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+
+ enum Doing
+ {
+ DoingNone,
+ DoingSourceDirectory,
+ DoingSourceTargetDirectory
+ };
+ Doing doing = DoingNone;
+ for (; options_it != args.end(); ++options_it) {
+ if (*options_it == "DIRECTORY") {
+ doing = DoingSourceDirectory;
+ source_file_directory_option_enabled = true;
+ } else if (*options_it == "TARGET_DIRECTORY") {
+ doing = DoingSourceTargetDirectory;
+ source_file_target_option_enabled = true;
+ } else if (isAPropertyKeyword(options_it)) {
+ break;
+ } else if (doing == DoingSourceDirectory) {
+ source_file_directories.push_back(*options_it);
+ } else if (doing == DoingSourceTargetDirectory) {
+ source_file_target_directories.push_back(*options_it);
+ } else {
+ status.SetError(
+ cmStrCat("given invalid argument \"", *options_it, "\"."));
+ }
+ }
+
+ const auto props_begin = options_it;
+
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
}
- cmMakefile& mf = status.GetMakefile();
+ std::vector<std::string> files;
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+ SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+ status, files, args.begin(), options_begin,
+ source_file_paths_should_be_absolute);
- // now call the worker function
+ // Now call the worker function for each directory scope represented by a
+ // cmMakefile instance.
std::string errors;
- bool ret = RunCommand(&mf, args.begin(), args.begin() + numFiles,
- args.begin() + numFiles, args.end(), errors);
- if (!ret) {
- status.SetError(errors);
+ for (const auto mf : source_file_directory_makefiles) {
+ bool ret = RunCommandForScope(mf, files.begin(), files.end(), props_begin,
+ args.end(), errors);
+ if (!ret) {
+ status.SetError(errors);
+ return ret;
+ }
}
- return ret;
+
+ return true;
}
-static bool RunCommand(cmMakefile* mf,
- std::vector<std::string>::const_iterator filebeg,
- std::vector<std::string>::const_iterator fileend,
- std::vector<std::string>::const_iterator propbeg,
- std::vector<std::string>::const_iterator propend,
- std::string& errors)
+static bool RunCommandForScope(
+ cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+ std::vector<std::string>::const_iterator file_end,
+ std::vector<std::string>::const_iterator prop_begin,
+ std::vector<std::string>::const_iterator prop_end, std::string& errors)
{
std::vector<std::string> propertyPairs;
- bool generated = false;
- std::vector<std::string>::const_iterator j;
// build the property pairs
- for (j = propbeg; j != propend; ++j) {
- // old style allows for specifier before PROPERTIES keyword
- if (*j == "ABSTRACT") {
- propertyPairs.emplace_back("ABSTRACT");
- propertyPairs.emplace_back("1");
- } else if (*j == "WRAP_EXCLUDE") {
- propertyPairs.emplace_back("WRAP_EXCLUDE");
- propertyPairs.emplace_back("1");
- } else if (*j == "GENERATED") {
- generated = true;
- propertyPairs.emplace_back("GENERATED");
+ for (auto j = prop_begin; j != prop_end; ++j) {
+ // consume old style options
+ if (*j == "ABSTRACT" || *j == "GENERATED" || *j == "WRAP_EXCLUDE") {
+ propertyPairs.emplace_back(*j);
propertyPairs.emplace_back("1");
} else if (*j == "COMPILE_FLAGS") {
propertyPairs.emplace_back("COMPILE_FLAGS");
++j;
- if (j == propend) {
+ if (j == prop_end) {
errors = "called with incorrect number of arguments "
"COMPILE_FLAGS with no flags";
return false;
@@ -81,33 +137,22 @@ static bool RunCommand(cmMakefile* mf,
} else if (*j == "OBJECT_DEPENDS") {
propertyPairs.emplace_back("OBJECT_DEPENDS");
++j;
- if (j == propend) {
+ if (j == prop_end) {
errors = "called with incorrect number of arguments "
"OBJECT_DEPENDS with no dependencies";
return false;
}
propertyPairs.push_back(*j);
} else if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- while (j != propend) {
- propertyPairs.push_back(*j);
- if (*j == "GENERATED") {
- ++j;
- if (j != propend && cmIsOn(*j)) {
- generated = true;
- }
- } else {
- ++j;
- }
- if (j == propend) {
- errors = "called with incorrect number of arguments.";
- return false;
- }
- propertyPairs.push_back(*j);
- ++j;
+ // PROPERTIES is followed by new style prop value pairs
+ cmStringRange newStyleProps{ j + 1, prop_end };
+ if (newStyleProps.size() % 2 != 0) {
+ errors = "called with incorrect number of arguments.";
+ return false;
}
- // break out of the loop because j is already == end
+ // set newStyleProps as is.
+ cm::append(propertyPairs, newStyleProps);
+ // break out of the loop.
break;
} else {
errors = "called with illegal arguments, maybe missing a "
@@ -116,15 +161,13 @@ static bool RunCommand(cmMakefile* mf,
}
}
- // now loop over all the files
- for (j = filebeg; j != fileend; ++j) {
+ // loop over all the files
+ for (const std::string& sfname : cmStringRange{ file_begin, file_end }) {
// get the source file
- cmSourceFile* sf = mf->GetOrCreateSource(*j, generated);
- if (sf) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- sf->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+ if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) {
+ // loop through the props and set them
+ for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) {
+ sf->SetProperty(*k, (k + 1)->c_str());
}
}
}
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index cd0fa402a..bdc84af20 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -2,19 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetTargetPropertiesCommand.h"
+#include <algorithm>
#include <iterator>
-#include <cmext/algorithm>
-
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-static bool SetOneTarget(const std::string& tname,
- std::vector<std::string>& propertyPairs,
- cmMakefile* mf);
-
bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -23,61 +18,38 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- // first collect up the list of files
- std::vector<std::string> propertyPairs;
- int numFiles = 0;
- for (auto j = args.begin(); j != args.end(); ++j) {
- if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- if (std::distance(j, args.end()) % 2 != 0) {
- status.SetError("called with incorrect number of arguments.");
- return false;
- }
- cm::append(propertyPairs, j, args.end());
- break;
- }
- numFiles++;
+ // first identify the properties arguments
+ auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+ if (propsIter == args.end() || propsIter + 1 == args.end()) {
+ status.SetError("called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?");
+ return false;
}
- if (propertyPairs.empty()) {
- status.SetError("called with illegal arguments, maybe missing "
- "a PROPERTIES specifier?");
+
+ if (std::distance(propsIter, args.end()) % 2 != 1) {
+ status.SetError("called with incorrect number of arguments.");
return false;
}
cmMakefile& mf = status.GetMakefile();
- // now loop over all the targets
- for (int i = 0; i < numFiles; ++i) {
- if (mf.IsAlias(args[i])) {
+ // loop over all the targets
+ for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+ if (mf.IsAlias(tname)) {
status.SetError("can not be used on an ALIAS target.");
return false;
}
- bool ret = SetOneTarget(args[i], propertyPairs, &mf);
- if (!ret) {
+ if (cmTarget* target = mf.FindTargetToUse(tname)) {
+ // loop through all the props and set them
+ for (auto k = propsIter + 1; k != args.end(); k += 2) {
+ target->SetProperty(*k, *(k + 1));
+ target->CheckProperty(*k, &mf);
+ }
+ } else {
status.SetError(
- cmStrCat("Can not find target to add properties to: ", args[i]));
+ cmStrCat("Can not find target to add properties to: ", tname));
return false;
}
}
return true;
}
-
-static bool SetOneTarget(const std::string& tname,
- std::vector<std::string>& propertyPairs,
- cmMakefile* mf)
-{
- if (cmTarget* target = mf->FindTargetToUse(tname)) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- target->SetProperty(propertyPairs[k], propertyPairs[k + 1]);
- target->CheckProperty(propertyPairs[k], mf);
- }
- }
- // if file is not already in the makefile, then add it
- else {
- return false;
- }
- return true;
-}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index 2e7aecabc..c4bff76f6 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -2,19 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetTestsPropertiesCommand.h"
+#include <algorithm>
#include <iterator>
-#include <cmext/algorithm>
-
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmTest.h"
-static bool SetOneTest(const std::string& tname,
- std::vector<std::string>& propertyPairs, cmMakefile* mf,
- std::string& errors);
-
bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -23,61 +18,33 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- cmMakefile& mf = status.GetMakefile();
-
- // first collect up the list of files
- std::vector<std::string> propertyPairs;
- int numFiles = 0;
- std::vector<std::string>::const_iterator j;
- for (j = args.begin(); j != args.end(); ++j) {
- if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- if (std::distance(j, args.end()) % 2 != 0) {
- status.SetError("called with incorrect number of arguments.");
- return false;
- }
- cm::append(propertyPairs, j, args.end());
- break;
- }
- numFiles++;
- }
- if (propertyPairs.empty()) {
- status.SetError("called with illegal arguments, maybe "
- "missing a PROPERTIES specifier?");
+ // first identify the properties arguments
+ auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+ if (propsIter == args.end() || propsIter + 1 == args.end()) {
+ status.SetError("called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?");
return false;
}
- // now loop over all the targets
- int i;
- for (i = 0; i < numFiles; ++i) {
- std::string errors;
- bool ret = SetOneTest(args[i], propertyPairs, &mf, errors);
- if (!ret) {
- status.SetError(errors);
- return ret;
- }
+ if (std::distance(propsIter, args.end()) % 2 != 1) {
+ status.SetError("called with incorrect number of arguments.");
+ return false;
}
- return true;
-}
-
-static bool SetOneTest(const std::string& tname,
- std::vector<std::string>& propertyPairs, cmMakefile* mf,
- std::string& errors)
-{
- if (cmTest* test = mf->GetTest(tname)) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- if (!propertyPairs[k].empty()) {
- test->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+ // loop over all the tests
+ for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+ if (cmTest* test = status.GetMakefile().GetTest(tname)) {
+ // loop through all the props and set them
+ for (auto k = propsIter + 1; k != args.end(); k += 2) {
+ if (!k->empty()) {
+ test->SetProperty(*k, (k + 1)->c_str());
+ }
}
+ } else {
+ status.SetError(
+ cmStrCat("Can not find test to add properties to: ", tname));
+ return false;
}
- } else {
- errors = cmStrCat("Can not find test to add properties to: ", tname);
- return false;
}
-
return true;
}
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index d47f121e0..b2d905e5b 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 fd9cacdbf..f5254392d 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 e22829f18..e6690152e 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -11,6 +11,7 @@
#include "cmCustomCommand.h"
#include "cmListFileCache.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmSourceFileLocation.h"
#include "cmSourceFileLocationKind.h"
@@ -45,7 +46,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;
@@ -157,7 +158,7 @@ private:
"\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
"rc|def|r|odl|idl|hpj|bat)$"
-#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
+#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$"
#define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$"
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 5f807b87f..e852c05ba 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 8c3ec9fec..155068cbe 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 581dc5dee..623cded23 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 cc62952d8..bb75a14ba 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 13f7622a7..cc67ac20e 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. */
@@ -50,7 +63,7 @@
#define YY_NO_UNPUT 1
#define ECHO
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
typedef KWIML_INT_int8_t flex_int8_t;
typedef KWIML_INT_uint8_t flex_uint8_t;
typedef KWIML_INT_int16_t flex_int16_t;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 9fc76152f..0b6b40f4d 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -34,30 +34,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,36 +137,23 @@ 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(
- std::string const& key) const
+cmProp cmState::GetInitializedCacheValue(std::string const& key) const
{
return this->CacheManager->GetInitializedCacheValue(key);
}
@@ -160,8 +161,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 +174,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,20 +251,19 @@ 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()
{
this->GlobalProperties.Clear();
- this->PropertyDefinitions.clear();
+ this->PropertyDefinitions = {};
this->GlobVerificationManager->Reset();
cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
@@ -335,42 +326,26 @@ 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);
+ this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription,
+ FullDescription, chained);
}
cmPropertyDefinition const* cmState::GetPropertyDefinition(
const std::string& name, cmProperty::ScopeType scope) const
{
- if (this->IsPropertyDefined(name, scope)) {
- cmPropertyDefinitionMap const& defs =
- this->PropertyDefinitions.find(scope)->second;
- return &defs.find(name)->second;
- }
- return nullptr;
-}
-
-bool cmState::IsPropertyDefined(const std::string& name,
- cmProperty::ScopeType scope) const
-{
- auto it = this->PropertyDefinitions.find(scope);
- if (it == this->PropertyDefinitions.end()) {
- return false;
- }
- return it->second.IsPropertyDefined(name);
+ return this->PropertyDefinitions.GetPropertyDefinition(name, scope);
}
bool cmState::IsPropertyChained(const std::string& name,
cmProperty::ScopeType scope) const
{
- auto it = this->PropertyDefinitions.find(scope);
- if (it == this->PropertyDefinitions.end()) {
- return false;
+ if (auto def = this->GetPropertyDefinition(name, scope)) {
+ return def->IsChained();
}
- return it->second.IsPropertyChained(name);
+ return false;
}
void cmState::SetLanguageEnabled(std::string const& l)
@@ -573,7 +548,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 +572,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 +623,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 6ee2b0c80..885496a92 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -17,7 +17,7 @@
#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmProperty.h"
-#include "cmPropertyDefinitionMap.h"
+#include "cmPropertyDefinition.h"
#include "cmPropertyMap.h"
#include "cmStatePrivate.h"
#include "cmStateTypes.h"
@@ -25,7 +25,6 @@
class cmCacheManager;
class cmCommand;
class cmGlobVerificationManager;
-class cmPropertyDefinition;
class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
@@ -51,7 +50,8 @@ public:
CPack,
};
- static const char* GetTargetTypeName(cmStateEnums::TargetType targetType);
+ static const std::string& GetTargetTypeName(
+ cmStateEnums::TargetType targetType);
cmStateSnapshot CreateBaseSnapshot();
cmStateSnapshot CreateBuildsystemDirectorySnapshot(
@@ -87,12 +87,11 @@ 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;
+ cmProp GetInitializedCacheValue(std::string const& key) const;
cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const;
void SetCacheEntryValue(std::string const& key, std::string const& value);
- void SetCacheValue(std::string const& key, std::string const& value);
void RemoveCacheEntry(std::string const& key);
@@ -102,8 +101,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,16 +120,13 @@ 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(
const std::string& name, cmProperty::ScopeType scope) const;
- // Is a property defined?
- bool IsPropertyDefined(const std::string& name,
- cmProperty::ScopeType scope) const;
bool IsPropertyChained(const std::string& name,
cmProperty::ScopeType scope) const;
@@ -171,7 +167,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;
@@ -222,7 +218,7 @@ private:
const std::string& variable,
cmListFileBacktrace const& bt);
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
+ cmPropertyDefinitionMap PropertyDefinitions;
std::vector<std::string> EnabledLanguages;
std::map<std::string, Command> BuiltinCommands;
std::map<std::string, Command> ScriptedCommands;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 4f003ed8f..a4fe66304 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 53a2d546d..765af6f4e 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -12,6 +12,7 @@
#include "cmAlgorithms.h"
#include "cmLinkedTree.h"
#include "cmListFileCache.h"
+#include "cmProperty.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
@@ -86,8 +87,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 832e74ec7..c22343185 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -11,6 +11,7 @@
#include "cmDefinitions.h"
#include "cmListFileCache.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -411,11 +412,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/cmString.hxx b/Source/cmString.hxx
index 9e9198650..87bfdffcf 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -16,8 +16,7 @@
#include <utility>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
namespace cm {
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index bb6dcd734..71d28a49d 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -4,7 +4,7 @@
#include <algorithm>
#include <cerrno>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 0e405dea6..a5ecca758 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 9212195f5..a7c21ccf0 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -11,11 +11,10 @@
#include <memory>
#include <cm/iterator>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmCryptoHash.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -124,6 +123,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 +956,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/cmSubcommandTable.h b/Source/cmSubcommandTable.h
index 65eb8c794..7deaaed69 100644
--- a/Source/cmSubcommandTable.h
+++ b/Source/cmSubcommandTable.h
@@ -11,8 +11,7 @@
#include <vector>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
class cmExecutionStatus;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9127c50e9..1e78d3693 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1,10 +1,20 @@
/* 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>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmDuration.h"
#include "cmProcessOutput.h"
@@ -12,7 +22,8 @@
#include "cmStringAlgorithms.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_libarchive.h"
+# include <cm3p/archive.h>
+# include <cm3p/archive_entry.h>
# include "cmArchiveWrite.h"
# include "cmLocale.h"
@@ -25,6 +36,9 @@
#endif
#if !defined(CMAKE_BOOTSTRAP)
+# if defined(_WIN32)
+# include <cm/memory>
+# endif
# include "cmCryptoHash.h"
#endif
@@ -809,7 +823,9 @@ void cmSystemTools::InitializeLibUV()
// Perform libuv one-time initialization now, and then un-do its
// global _fmode setting so that using libuv does not change the
// default file text/binary mode. See libuv issue 840.
- uv_loop_close(uv_default_loop());
+ if (uv_loop_t* loop = uv_default_loop()) {
+ uv_loop_close(loop);
+ }
# ifdef _MSC_VER
_set_fmode(_O_TEXT);
# else
@@ -908,7 +924,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 +935,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 +976,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
}
}
}
- delete[] certData;
}
}
CloseHandle(certFile);
@@ -1054,8 +1068,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 +1324,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;
@@ -2068,6 +2082,12 @@ std::string const& cmSystemTools::GetCMakeRoot()
return cmSystemToolsCMakeRoot;
}
+std::string cmSystemTools::GetCurrentWorkingDirectory()
+{
+ return cmSystemTools::CollapseFullPath(
+ cmsys::SystemTools::GetCurrentWorkingDirectory());
+}
+
void cmSystemTools::MakefileColorEcho(int color, const char* message,
bool newline, bool enabled)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index ee149a029..b886c58dd 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -390,6 +390,9 @@ public:
static std::string const& GetCMClDepsCommand();
static std::string const& GetCMakeRoot();
+ /** Get the CWD mapped through the KWSys translation map. */
+ static std::string GetCurrentWorkingDirectory();
+
/** Echo a message in color using KWSys's Terminal cprintf. */
static void MakefileColorEcho(int color, const char* message, bool newLine,
bool enabled);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1ad9fd1a1..36e1ad5fd 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
@@ -215,7 +215,7 @@ public:
};
cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf, bool perConfig)
+ Visibility vis, cmMakefile* mf, PerConfig perConfig)
: impl(cm::make_unique<cmTargetInternals>())
{
assert(mf);
@@ -231,7 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
impl->BuildInterfaceIncludesAppended = false;
- impl->PerConfig = perConfig;
+ impl->PerConfig = (perConfig == PerConfig::Yes);
// Check whether this is a DLL platform.
impl->IsDLLPlatform =
@@ -303,9 +303,11 @@ 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");
+ initProp("Fortran_PREPROCESS");
initProp("GNUtoMS");
initProp("OSX_ARCHITECTURES");
initProp("IOS_INSTALL_COMBINED");
@@ -362,6 +364,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 +373,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("DISABLE_PRECOMPILE_HEADERS");
initProp("UNITY_BUILD");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+ initPropValue("UNITY_BUILD_MODE", "BATCH");
+ initPropValue("PCH_WARN_INVALID", "ON");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -438,6 +443,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);
+ }
}
}
@@ -521,7 +533,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("JOB_POOL_PRECOMPILE_HEADER");
}
- if (impl->TargetType <= cmStateEnums::UTILITY) {
+ if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
@@ -883,7 +895,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 +1014,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 +1307,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 +1512,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 +1550,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 +1595,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 +1616,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 +1642,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 +1671,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 +1684,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 +1693,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 +1702,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 +1711,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 +1720,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 +1730,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 +1746,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 +1755,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 +1786,26 @@ 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
+std::string const& cmTarget::GetSafeProperty(std::string const& prop) const
{
- const char* ret = this->GetProperty(prop);
- if (!ret) {
- return "";
+ cmProp ret = this->GetProperty(prop);
+ if (ret) {
+ return *ret;
}
- return ret;
+
+ static std::string const s_empty;
+ return s_empty;
}
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 +1934,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 +2007,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 +2030,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 +2045,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 +2077,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 286933b51..f0ddb686a 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -15,6 +15,7 @@
#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTargetLinkLibraryType.h"
@@ -43,8 +44,14 @@ public:
VisibilityImportedGlobally
};
+ enum class PerConfig
+ {
+ Yes,
+ No
+ };
+
cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf, bool perConfig);
+ Visibility vis, cmMakefile* mf, PerConfig perConfig);
cmTarget(cmTarget const&) = delete;
cmTarget(cmTarget&&) noexcept;
@@ -170,14 +177,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;
+ std::string const& GetSafeProperty(std::string const& 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 +197,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 0de8d6d05..e7147209b 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -5,6 +5,7 @@
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -157,9 +158,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 df34f188d..f87b7c2d2 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -8,6 +8,7 @@
#include <string>
#include "cmListFileCache.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -18,11 +19,11 @@ 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 +53,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 +72,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocationForBuild(tgt).c_str();
+ return &ComputeLocationForBuild(tgt);
}
// Support "LOCATION_<CONFIG>".
@@ -82,7 +83,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 +96,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocation(tgt, configName).c_str();
+ return &ComputeLocation(tgt, configName);
}
}
}
@@ -103,8 +104,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 3b731cc5b..a26bef3db 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 333d4d5ee..e10a8e207 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmStateTypes.h"
@@ -76,7 +77,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
cmGeneratorExpression ge(this->Test->GetBacktrace());
// Start the test command.
- os << indent << "add_test(" << this->Test->GetName() << " ";
+ os << indent << "add_test(\"" << this->Test->GetName() << "\" ";
// Evaluate command line arguments
std::vector<std::string> argv =
@@ -100,9 +101,9 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
exe = target->GetFullPath(config);
// Prepend with the emulator when cross compiling if required.
- const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
- if (emulator != nullptr && *emulator) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+ cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
+ if (emulator != nullptr && !emulator->empty()) {
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
@@ -126,20 +127,21 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
os << ")\n";
// Output properties for the test.
- os << indent << "set_tests_properties(" << this->Test->GetName()
- << " PROPERTIES ";
+ os << indent << "set_tests_properties(\"" << this->Test->GetName()
+ << "\" PROPERTIES ";
for (auto const& i : this->Test->GetProperties().GetList()) {
os << " " << i.first << " "
<< cmOutputConverter::EscapeForCMake(
ge.Parse(i.second)->Evaluate(this->LG, config));
}
this->GenerateInternalProperties(os);
- os << ")" << std::endl;
+ os << ")\n";
}
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
{
- os << indent << "add_test(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
+ os << indent << "add_test(\"" << this->Test->GetName()
+ << "\" NOT_AVAILABLE)\n";
}
bool cmTestGenerator::NeedsScriptNoConfig() const
@@ -159,9 +161,8 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
std::string exe = command[0];
cmSystemTools::ConvertToUnixSlashes(exe);
- fout << indent;
- fout << "add_test(";
- fout << this->Test->GetName() << " \"" << exe << "\"";
+ fout << indent << "add_test(\"" << this->Test->GetName() << "\" \"" << exe
+ << "\"";
for (std::string const& arg : cmMakeRange(command).advance(1)) {
// Just double-quote all arguments so they are re-parsed
@@ -176,9 +177,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 +189,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 +214,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 390fd16b0..13f73dc48 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 0e8e986ab..64d71bcda 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -9,6 +9,7 @@
#include "cmDuration.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -242,8 +243,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 +265,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/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index 23dabb770..df2f64ec5 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -7,7 +7,7 @@
#include <cstdlib>
#include <mutex>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
namespace cm {
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index 3083b60c8..d9de7f3da 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -8,7 +8,7 @@
#include <memory>
#include <type_traits>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#if defined(__SUNPRO_CC)
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 543c3308a..6040fd816 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -9,7 +9,7 @@
#include <cm/memory>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
index 05a7cc82c..b5ccb19f1 100644
--- a/Source/cmUVProcessChain.h
+++ b/Source/cmUVProcessChain.h
@@ -4,14 +4,14 @@
#define cmUVProcessChain_h
#include <array>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
class cmUVProcessChain;
diff --git a/Source/cmUVSignalHackRAII.h b/Source/cmUVSignalHackRAII.h
index 63599db82..60e4ca84e 100644
--- a/Source/cmUVSignalHackRAII.h
+++ b/Source/cmUVSignalHackRAII.h
@@ -3,7 +3,7 @@
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#if defined(CMAKE_USE_SYSTEM_LIBUV) && !defined(_WIN32) && \
UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR < 19
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index 1c8a7717c..50faede83 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -8,7 +8,7 @@
#include <streambuf>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index a43165cce..6de78ff67 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -84,8 +84,8 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args,
std::string utilityDirectory =
status.GetMakefile().GetCurrentBinaryDirectory();
std::string exePath;
- if (status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
- exePath = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ if (auto d = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
+ exePath = d;
}
if (!exePath.empty()) {
utilityDirectory = exePath;
@@ -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/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index dd9f058b8..9626599a3 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -258,6 +258,20 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation)
return isInstalled;
}
+bool cmVSSetupAPIHelper::GetVSInstanceVersion(
+ unsigned long long& vsInstanceVersion)
+{
+ vsInstanceVersion = 0;
+ bool isInstalled = this->EnumerateAndChooseVSInstance();
+
+ if (isInstalled) {
+ vsInstanceVersion =
+ static_cast<unsigned long long>(chosenInstanceInfo.ullVersion);
+ }
+
+ return isInstalled;
+}
+
bool cmVSSetupAPIHelper::GetVCToolsetVersion(std::string& vsToolsetVersion)
{
vsToolsetVersion.clear();
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 0980cef53..a926eee92 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -8,13 +8,12 @@
#endif
// Published by Visual Studio Setup team
+#include <cm3p/Setup.Configuration.h>
#include <string>
#include <vector>
#include <windows.h>
-#include "cmvssetup/Setup.Configuration.h"
-
template <class T>
class SmartCOMPtr
{
@@ -107,6 +106,7 @@ public:
bool IsVSInstalled();
bool GetVSInstanceInfo(std::string& vsInstallLocation);
+ bool GetVSInstanceVersion(unsigned long long& vsInstanceVersion);
bool GetVCToolsetVersion(std::string& vsToolsetVersion);
bool IsWin10SDKInstalled();
bool IsWin81SDKInstalled();
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 35b9a1d5b..ecae16dae 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/cmVersion.h b/Source/cmVersion.h
index bfd994d09..932ef0467 100644
--- a/Source/cmVersion.h
+++ b/Source/cmVersion.h
@@ -3,7 +3,7 @@
#ifndef cmVersion_h
#define cmVersion_h
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
/** \class cmVersion
* \brief Helper class for providing CMake and CTest version information.
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 163ff19d8..a3ccd2bae 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"
@@ -18,10 +19,12 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
+#include "cmGlobalVisualStudioVersionedGenerator.h"
#include "cmLinkLineDeviceComputer.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVisualStudioGeneratorOptions.h"
@@ -61,10 +64,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 +81,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()
{
@@ -246,6 +249,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
this->Makefile->GetCurrentBinaryDirectory());
+ this->ClassifyAllConfigSources();
}
cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -429,32 +433,32 @@ void cmVisualStudio10TargetGenerator::Generate()
this->VerifyNecessaryFiles();
}
- const char* vsProjectTypes =
+ cmProp vsProjectTypes =
this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
if (vsProjectTypes) {
const char* tagName = "ProjectTypes";
if (this->ProjectType == csproj) {
tagName = "ProjectTypeGuids";
}
- e1.Element(tagName, vsProjectTypes);
+ e1.Element(tagName, *vsProjectTypes);
}
- const char* vsProjectName =
+ cmProp vsProjectName =
this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalPath =
+ cmProp vsLocalPath =
this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider =
+ cmProp vsProvider =
this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER");
if (vsProjectName && vsLocalPath && vsProvider) {
- e1.Element("SccProjectName", vsProjectName);
- e1.Element("SccLocalPath", vsLocalPath);
- e1.Element("SccProvider", vsProvider);
+ e1.Element("SccProjectName", *vsProjectName);
+ e1.Element("SccLocalPath", *vsLocalPath);
+ e1.Element("SccProvider", *vsProvider);
- const char* vsAuxPath =
+ cmProp vsAuxPath =
this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH");
if (vsAuxPath) {
- e1.Element("SccAuxPath", vsAuxPath);
+ e1.Element("SccAuxPath", *vsAuxPath);
}
}
@@ -462,45 +466,44 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("WinMDAssembly", "true");
}
- const char* vsGlobalKeyword =
+ cmProp vsGlobalKeyword =
this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
if (!vsGlobalKeyword) {
e1.Element("Keyword", "Win32Proj");
} else {
- e1.Element("Keyword", vsGlobalKeyword);
+ e1.Element("Keyword", *vsGlobalKeyword);
}
- const char* vsGlobalRootNamespace =
+ cmProp vsGlobalRootNamespace =
this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
if (vsGlobalRootNamespace) {
- e1.Element("RootNamespace", vsGlobalRootNamespace);
+ e1.Element("RootNamespace", *vsGlobalRootNamespace);
}
e1.Element("Platform", this->Platform);
- const char* projLabel =
- this->GeneratorTarget->GetProperty("PROJECT_LABEL");
+ cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
if (!projLabel) {
- projLabel = this->Name.c_str();
+ projLabel = &this->Name;
}
- e1.Element("ProjectName", projLabel);
+ e1.Element("ProjectName", *projLabel);
{
- const char* targetFramework =
+ cmProp targetFramework =
this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
if (targetFramework) {
- if (std::strchr(targetFramework, ';') != nullptr) {
- e1.Element("TargetFrameworks", targetFramework);
+ if (std::strchr(targetFramework->c_str(), ';') != nullptr) {
+ e1.Element("TargetFrameworks", *targetFramework);
} else {
- e1.Element("TargetFramework", targetFramework);
+ e1.Element("TargetFramework", *targetFramework);
}
} else {
// TODO: add deprecation warning for VS_* property?
- const char* targetFrameworkVersion =
- this->GeneratorTarget->GetProperty(
- "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
- if (!targetFrameworkVersion) {
- targetFrameworkVersion = this->GeneratorTarget->GetProperty(
+ cmProp p = this->GeneratorTarget->GetProperty(
+ "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
+ if (!p) {
+ p = this->GeneratorTarget->GetProperty(
"DOTNET_TARGET_FRAMEWORK_VERSION");
}
+ const char* targetFrameworkVersion = p ? p->c_str() : nullptr;
if (!targetFrameworkVersion && this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE() &&
this->GlobalGenerator->GetVersion() ==
@@ -519,18 +522,15 @@ void cmVisualStudio10TargetGenerator::Generate()
}
if (this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE()) {
- const char* targetFrameworkId = this->GeneratorTarget->GetProperty(
+ cmProp targetFrameworkId = this->GeneratorTarget->GetProperty(
"VS_TARGET_FRAMEWORK_IDENTIFIER");
- if (!targetFrameworkId) {
- targetFrameworkId = "WindowsEmbeddedCompact";
- }
- e1.Element("TargetFrameworkIdentifier", targetFrameworkId);
- const char* targetFrameworkVer = this->GeneratorTarget->GetProperty(
+ e1.Element("TargetFrameworkIdentifier",
+ targetFrameworkId ? *targetFrameworkId
+ : "WindowsEmbeddedCompact");
+ cmProp targetFrameworkVer = this->GeneratorTarget->GetProperty(
"VS_TARGET_FRAMEWORKS_TARGET_VERSION");
- if (!targetFrameworkVer) {
- targetFrameworkVer = "v8.0";
- }
- e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
+ e1.Element("TargetFrameworkTargetsVersion",
+ targetFrameworkVer ? *targetFrameworkVer : "v8.0");
}
if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
.empty()) {
@@ -556,19 +556,20 @@ 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") {
continue;
}
- const char* value = this->GeneratorTarget->GetProperty(keyIt);
+ cmProp value = this->GeneratorTarget->GetProperty(keyIt);
if (!value)
continue;
- e1.Element(globalKey, value);
+ e1.Element(globalKey, *value);
}
if (this->Managed) {
@@ -673,9 +674,8 @@ void cmVisualStudio10TargetGenerator::Generate()
props = VS10_CSharp_USER_PROPS;
break;
}
- if (const char* p =
- this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
- props = p;
+ if (cmProp p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
+ props = *p;
}
if (!props.empty()) {
ConvertToWindowsSlash(props);
@@ -781,50 +781,41 @@ void cmVisualStudio10TargetGenerator::Generate()
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
{
std::vector<std::string> packageReferences;
- if (const char* vsPackageReferences =
+ if (cmProp vsPackageReferences =
this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(vsPackageReferences, packageReferences);
+ cmExpandList(*vsPackageReferences, packageReferences);
}
if (!packageReferences.empty()) {
Elem e1(e0, "ItemGroup");
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;
- if (const char* vsDotNetReferences =
+ if (cmProp vsDotNetReferences =
this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
- cmExpandList(vsDotNetReferences, references);
+ cmExpandList(*vsDotNetReferences, references);
}
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 +828,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, "", "");
@@ -869,9 +860,9 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
e2.Element("ReferenceOutputAssembly", "true");
if (!hint.empty()) {
const char* privateReference = "True";
- if (const char* value = this->GeneratorTarget->GetProperty(
+ if (cmProp value = this->GeneratorTarget->GetProperty(
"VS_DOTNET_REFERENCES_COPY_LOCAL")) {
- if (cmIsOff(value)) {
+ if (cmIsOff(*value)) {
privateReference = "False";
}
}
@@ -883,11 +874,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 +900,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) {
@@ -925,7 +911,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
{
- std::string const documentationFile =
+ std::string const& documentationFile =
this->GeneratorTarget->GetSafeProperty("VS_DOTNET_DOCUMENTATION_FILE");
if (this->ProjectType == csproj && !documentationFile.empty()) {
@@ -937,13 +923,11 @@ void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
{
- std::vector<cmSourceFile const*> resxObjs;
- this->GeneratorTarget->GetResxSources(resxObjs, "");
- if (!resxObjs.empty()) {
+ if (!this->ResxObjs.empty()) {
Elem e1(e0, "ItemGroup");
std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
ConvertToWindowsSlash(srcDir);
- for (cmSourceFile const* oi : resxObjs) {
+ for (cmSourceFile const* oi : this->ResxObjs) {
std::string obj = oi->GetFullPath();
ConvertToWindowsSlash(obj);
bool useRelativePath = false;
@@ -952,7 +936,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 +965,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 +978,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 +997,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);
}
@@ -1037,16 +1016,14 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
{
- std::vector<cmSourceFile const*> xamlObjs;
- this->GeneratorTarget->GetXamlSources(xamlObjs, "");
- if (!xamlObjs.empty()) {
+ if (!this->XamlObjs.empty()) {
Elem e1(e0, "ItemGroup");
- for (cmSourceFile const* oi : xamlObjs) {
+ for (cmSourceFile const* oi : this->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 +1031,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");
}
}
@@ -1117,9 +1075,9 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
{
std::vector<std::string> references;
- if (const char* vsWinRTReferences =
+ if (cmProp vsWinRTReferences =
this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
- cmExpandList(vsWinRTReferences, references);
+ cmExpandList(*vsWinRTReferences, references);
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
@@ -1160,9 +1118,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
if (this->ProjectType != csproj) {
std::string configType;
- if (const char* vsConfigurationType =
+ if (cmProp vsConfigurationType =
this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
- configType = cmGeneratorExpression::Evaluate(vsConfigurationType,
+ configType = cmGeneratorExpression::Evaluate(*vsConfigurationType,
this->LocalGenerator, c);
} else {
switch (this->GeneratorTarget->GetType()) {
@@ -1218,9 +1176,9 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
if (!this->GlobalGenerator->TargetsWindowsCE()) {
return;
}
- const char* additionalFiles =
+ cmProp additionalFiles =
this->GeneratorTarget->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
- const char* remoteDirectory =
+ cmProp remoteDirectory =
this->GeneratorTarget->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
if (!(additionalFiles || remoteDirectory)) {
return;
@@ -1230,10 +1188,10 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
e1.Attribute("Condition", this->CalcCondition(c));
if (remoteDirectory) {
- e1.Element("RemoteDirectory", remoteDirectory);
+ e1.Element("RemoteDirectory", *remoteDirectory);
}
if (additionalFiles) {
- e1.Element("CEAdditionalFiles", additionalFiles);
+ e1.Element("CEAdditionalFiles", *additionalFiles);
}
}
}
@@ -1271,7 +1229,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
} else {
e1.Element("CharacterSet", "MultiByte");
}
- if (const char* toolset = gg->GetPlatformToolset()) {
+ if (cmProp projectToolsetOverride =
+ this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+ e1.Element("PlatformToolset", *projectToolsetOverride);
+ } else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}
if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
@@ -1314,7 +1275,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
o.RemoveFlag("Platform");
}
- if (const char* toolset = gg->GetPlatformToolset()) {
+ if (cmProp projectToolsetOverride =
+ this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+ e1.Element("PlatformToolset", *projectToolsetOverride);
+ } else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}
@@ -1322,8 +1286,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
std::string assemblyName = this->GeneratorTarget->GetOutputName(
config, cmStateEnums::RuntimeBinaryArtifact);
- if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
- assemblyName += postfix;
+ if (cmProp postfix = this->GeneratorTarget->GetProperty(postfixName)) {
+ assemblyName += *postfix;
}
e1.Element("AssemblyName", assemblyName);
@@ -1343,43 +1307,47 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
const char* toolset = gg->GetPlatformToolset();
e1.Element("NdkToolchainVersion", toolset ? toolset : "Default");
- if (const char* minApi =
- this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
- e1.Element("AndroidMinAPI", "android-" + std::string(minApi));
+ if (cmProp minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
+ e1.Element("AndroidMinAPI", "android-" + *minApi);
}
- if (const char* api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
- e1.Element("AndroidTargetAPI", "android-" + std::string(api));
+ if (cmProp api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
+ e1.Element("AndroidTargetAPI", "android-" + *api);
}
- if (const char* cpuArch =
- this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
- e1.Element("AndroidArch", cpuArch);
+ if (cmProp cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
+ e1.Element("AndroidArch", *cpuArch);
}
- if (const char* stlType =
+ if (cmProp stlType =
this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
- e1.Element("AndroidStlType", stlType);
+ e1.Element("AndroidStlType", *stlType);
}
}
void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
{
this->CSharpCustomCommandNames.clear();
- std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, "");
- for (cmSourceFile const* si : customCommands) {
- this->WriteCustomCommand(e0, si);
+
+ cmSourceFile const* srcCMakeLists =
+ this->LocalGenerator->CreateVCProjBuildRule();
+
+ for (cmGeneratorTarget::AllConfigSource const& si :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ if (si.Source == srcCMakeLists) {
+ // Skip explicit reference to CMakeLists.txt source.
+ continue;
+ }
+ this->WriteCustomCommand(e0, si.Source);
}
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- if (cmSourceFile const* sf =
- this->LocalGenerator->CreateVCProjBuildRule()) {
+ if (srcCMakeLists) {
// Write directly rather than through WriteCustomCommand because
// we do not want the de-duplication and it has no dependencies.
- if (cmCustomCommand const* command = sf->GetCustomCommand()) {
- this->WriteCustomRule(e0, sf, *command);
+ if (cmCustomCommand const* command = srcCMakeLists->GetCustomCommand()) {
+ this->WriteCustomRule(e0, srcCMakeLists, *command);
}
}
}
@@ -1439,16 +1407,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);
@@ -1662,11 +1628,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
}
}
- std::vector<cmSourceFile const*> resxObjs;
- this->GeneratorTarget->GetResxSources(resxObjs, "");
- if (!resxObjs.empty()) {
+ if (!this->ResxObjs.empty()) {
Elem e1(e0, "ItemGroup");
- for (cmSourceFile const* oi : resxObjs) {
+ for (cmSourceFile const* oi : this->ResxObjs) {
std::string obj = oi->GetFullPath();
ConvertToWindowsSlash(obj);
Elem e2(e1, "EmbeddedResource");
@@ -1694,7 +1658,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
}
}
- if (!resxObjs.empty() || !this->AddedFiles.empty()) {
+ if (!this->ResxObjs.empty() || !this->AddedFiles.empty()) {
std::string guidName = "SG_Filter_Resource Files";
std::string guid = this->GlobalGenerator->GetGUID(guidName);
Elem e2(e1, "Filter");
@@ -1779,9 +1743,63 @@ 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,
@@ -1789,15 +1807,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
{
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 +1814,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 +1911,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 +1940,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 +2038,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 +2097,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);
}
@@ -2202,10 +2211,10 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
}
} break;
case cmGeneratorTarget::SourceKindResx:
- // Handled elsewhere.
+ this->ResxObjs.push_back(si.Source);
break;
case cmGeneratorTarget::SourceKindXaml:
- // Handled elsewhere.
+ this->XamlObjs.push_back(si.Source);
break;
}
@@ -2245,7 +2254,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,41 +2299,36 @@ 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());
- std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
- const std::string& linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage("");
- bool needForceLang = false;
- // source file does not match its extension language
- if (lang != sourceLang) {
- needForceLang = true;
- lang = sourceLang;
- }
- // if the source file does not match the linker language
- // then force c or c++
+
+ // Force language if the file extension does not match.
+ // Note that MSVC treats the upper-case '.C' extension as C and not C++.
+ std::string const ext = sf.GetExtension();
+ std::string const extLang = ext == "C"
+ ? "C"
+ : this->GlobalGenerator->GetLanguageFromExtension(ext.c_str());
+ std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf);
const char* compileAs = 0;
- if (needForceLang || (linkLanguage != lang)) {
+ if (lang != extLang) {
if (lang == "CXX") {
// force a C++ file type
compileAs = "CompileAsCpp";
@@ -2333,6 +2337,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
compileAs = "CompileAsC";
}
}
+
bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
// for the first time we need a new line if there is something
// produced here.
@@ -2347,13 +2352,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 +2459,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()) {
@@ -2504,34 +2503,34 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
const std::string cond = this->CalcCondition(config);
if (ttype <= cmStateEnums::UTILITY) {
- if (const char* workingDir = this->GeneratorTarget->GetProperty(
+ if (cmProp workingDir = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_WORKING_DIRECTORY")) {
std::string genWorkingDir = cmGeneratorExpression::Evaluate(
- workingDir, this->LocalGenerator, config);
+ *workingDir, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
genWorkingDir);
}
- if (const char* environment =
+ if (cmProp environment =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
std::string genEnvironment = cmGeneratorExpression::Evaluate(
- environment, this->LocalGenerator, config);
+ *environment, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
genEnvironment);
}
- if (const char* debuggerCommand =
+ if (cmProp debuggerCommand =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
std::string genDebuggerCommand = cmGeneratorExpression::Evaluate(
- debuggerCommand, this->LocalGenerator, config);
+ *debuggerCommand, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
genDebuggerCommand);
}
- if (const char* commandArguments = this->GeneratorTarget->GetProperty(
+ if (cmProp commandArguments = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_COMMAND_ARGUMENTS")) {
std::string genCommandArguments = cmGeneratorExpression::Evaluate(
- commandArguments, this->LocalGenerator, config);
+ *commandArguments, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
genCommandArguments);
}
@@ -2716,7 +2715,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;
@@ -2735,13 +2734,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
langForClCompile, configName);
}
- // set the correct language
- if (linkLanguage == "C") {
- clOptions.AddFlag("CompileAs", "CompileAsC");
- }
- if (linkLanguage == "CXX") {
- clOptions.AddFlag("CompileAs", "CompileAsCpp");
- }
// Put the IPO enabled configurations into a set.
if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
@@ -2791,9 +2783,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->Makefile->IssueMessage(MessageType::WARNING, message);
}
}
- if (auto* clr =
+ if (cmProp clr =
this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- std::string clrString = clr;
+ std::string clrString = *clr;
if (!clrString.empty()) {
clrString = ":" + clrString;
}
@@ -2911,9 +2903,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
oh.OutputPreprocessorDefinitions(this->LangForClCompile);
if (this->NsightTegra) {
- if (const char* processMax =
+ if (cmProp processMax =
this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) {
- e2.Element("ProcessMax", processMax);
+ e2.Element("ProcessMax", *processMax);
}
}
@@ -3142,6 +3134,17 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA"));
cudaOptions.AddFlag("UseHostInclude", "false");
+ // Add runtime library selection flag.
+ std::string const& cudaRuntime =
+ this->GeneratorTarget->GetRuntimeLinkLibrary("CUDA", configName);
+ if (cudaRuntime == "STATIC") {
+ cudaOptions.AddFlag("CudaRuntime", "Static");
+ } else if (cudaRuntime == "SHARED") {
+ cudaOptions.AddFlag("CudaRuntime", "Shared");
+ } else if (cudaRuntime == "NONE") {
+ cudaOptions.AddFlag("CudaRuntime", "None");
+ }
+
this->CudaOptions[configName] = std::move(pOptions);
return true;
}
@@ -3182,6 +3185,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 +3194,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 +3425,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;
@@ -3449,7 +3461,7 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
std::vector<cmSourceFile const*> manifest_srcs;
this->GeneratorTarget->GetManifests(manifest_srcs, config);
- const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
+ cmProp dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
if (!manifest_srcs.empty() || dpiAware) {
Elem e2(e1, "Manifest");
@@ -3463,15 +3475,14 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
e2.Element("AdditionalManifestFiles", oss.str());
}
if (dpiAware) {
- if (!strcmp(dpiAware, "PerMonitor")) {
+ if (*dpiAware == "PerMonitor") {
e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
- } else if (cmIsOn(dpiAware)) {
+ } else if (cmIsOn(*dpiAware)) {
e2.Element("EnableDpiAwareness", "true");
- } else if (cmIsOff(dpiAware)) {
+ } else if (cmIsOff(*dpiAware)) {
e2.Element("EnableDpiAwareness", "false");
} else {
- cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " +
- std::string(dpiAware));
+ cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + *dpiAware);
}
}
}
@@ -3484,12 +3495,12 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
// its location as the root source directory.
std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory();
{
- std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, "");
- for (cmSourceFile const* si : extraSources) {
- if ("androidmanifest.xml" ==
- cmSystemTools::LowerCase(si->GetLocation().GetName())) {
- rootDir = si->GetLocation().GetDirectory();
+ for (cmGeneratorTarget::AllConfigSource const& source :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+ "androidmanifest.xml" ==
+ cmSystemTools::LowerCase(source.Source->GetLocation().GetName())) {
+ rootDir = source.Source->GetLocation().GetDirectory();
break;
}
}
@@ -3511,51 +3522,51 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
e2.Element("EnableProGuard", "true");
}
- if (const char* proGuardConfigLocation =
+ if (cmProp proGuardConfigLocation =
this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) {
- e2.Element("ProGuardConfigLocation", proGuardConfigLocation);
+ e2.Element("ProGuardConfigLocation", *proGuardConfigLocation);
}
- if (const char* securePropertiesLocation =
+ if (cmProp securePropertiesLocation =
this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) {
- e2.Element("SecurePropertiesLocation", securePropertiesLocation);
+ e2.Element("SecurePropertiesLocation", *securePropertiesLocation);
}
- if (const char* nativeLibDirectoriesExpression =
+ if (cmProp nativeLibDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) {
std::string nativeLibDirs = cmGeneratorExpression::Evaluate(
- nativeLibDirectoriesExpression, this->LocalGenerator, configName);
+ *nativeLibDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDirectories", nativeLibDirs);
}
- if (const char* nativeLibDependenciesExpression =
+ if (cmProp nativeLibDependenciesExpression =
this->GeneratorTarget->GetProperty(
"ANDROID_NATIVE_LIB_DEPENDENCIES")) {
std::string nativeLibDeps = cmGeneratorExpression::Evaluate(
- nativeLibDependenciesExpression, this->LocalGenerator, configName);
+ *nativeLibDependenciesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDependencies", nativeLibDeps);
}
- if (const char* javaSourceDir =
+ if (cmProp javaSourceDir =
this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) {
- e2.Element("JavaSourceDir", javaSourceDir);
+ e2.Element("JavaSourceDir", *javaSourceDir);
}
- if (const char* jarDirectoriesExpression =
+ if (cmProp jarDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) {
std::string jarDirectories = cmGeneratorExpression::Evaluate(
- jarDirectoriesExpression, this->LocalGenerator, configName);
+ *jarDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("JarDirectories", jarDirectories);
}
- if (const char* jarDeps =
+ if (cmProp jarDeps =
this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) {
- e2.Element("JarDependencies", jarDeps);
+ e2.Element("JarDependencies", *jarDeps);
}
- if (const char* assetsDirectories =
+ if (cmProp assetsDirectories =
this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) {
- e2.Element("AssetsDirectories", assetsDirectories);
+ e2.Element("AssetsDirectories", *assetsDirectories);
}
{
@@ -3564,10 +3575,10 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
e2.Element("AndroidManifestLocation", manifest_xml);
}
- if (const char* antAdditionalOptions =
+ if (cmProp antAdditionalOptions =
this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) {
e2.Element("AdditionalOptions",
- std::string(antAdditionalOptions) + " %(AdditionalOptions)");
+ *antAdditionalOptions + " %(AdditionalOptions)");
}
}
@@ -3619,17 +3630,15 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
flags += " ";
flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
- const char* targetLinkFlags =
- this->GeneratorTarget->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
flags += " ";
- flags += targetLinkFlags;
+ flags += *targetLinkFlags;
}
std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
- if (const char* flagsConfig =
- this->GeneratorTarget->GetProperty(flagsProp)) {
+ if (cmProp flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) {
flags += " ";
- flags += flagsConfig;
+ flags += *flagsConfig;
}
std::vector<std::string> opts;
@@ -3650,10 +3659,6 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec, config);
- if (cmContains(linkClosure->Languages, "CUDA") &&
- this->CudaOptions[config] != nullptr) {
- this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
- }
std::string standardLibsVar =
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar);
@@ -3924,7 +3929,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 +4057,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 +4066,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 {
@@ -4102,9 +4113,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
cmLocalGenerator* lg = dt->GetLocalGenerator();
std::string name = dt->GetName();
std::string path;
- const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
if (p) {
- path = p;
+ path = *p;
} else {
path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
computeProjectFileExtension(dt));
@@ -4120,7 +4131,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
}
// Don't reference targets that don't produce any output.
- if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
+ if (dt->GetManagedType(this->Configurations[0]) ==
+ cmGeneratorTarget::ManagedType::Undefined) {
e2.Element("ReferenceOutputAssembly", "false");
e2.Element("CopyToOutputDirectory", "Never");
}
@@ -4132,17 +4144,17 @@ void cmVisualStudio10TargetGenerator::WritePlatformExtensions(Elem& e1)
// This only applies to Windows 10 apps
if (this->GlobalGenerator->TargetsWindowsStore() &&
cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
- const char* desktopExtensionsVersion =
+ cmProp desktopExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
if (desktopExtensionsVersion) {
this->WriteSinglePlatformExtension(e1, "WindowsDesktop",
- desktopExtensionsVersion);
+ *desktopExtensionsVersion);
}
- const char* mobileExtensionsVersion =
+ cmProp mobileExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
if (mobileExtensionsVersion) {
this->WriteSinglePlatformExtension(e1, "WindowsMobile",
- mobileExtensionsVersion);
+ *mobileExtensionsVersion);
}
}
}
@@ -4167,9 +4179,9 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
{
std::vector<std::string> sdkReferences;
std::unique_ptr<Elem> spe1;
- if (const char* vsSDKReferences =
+ if (cmProp vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
- cmExpandList(vsSDKReferences, sdkReferences);
+ cmExpandList(*vsSDKReferences, sdkReferences);
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
for (std::string const& ri : sdkReferences) {
Elem(*spe1, "SDKReference").Attribute("Include", ri);
@@ -4179,11 +4191,11 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
// This only applies to Windows 10 apps
if (this->GlobalGenerator->TargetsWindowsStore() &&
cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
- const char* desktopExtensionsVersion =
+ cmProp desktopExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
- const char* mobileExtensionsVersion =
+ cmProp mobileExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
- const char* iotExtensionsVersion =
+ cmProp iotExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION");
if (desktopExtensionsVersion || mobileExtensionsVersion ||
@@ -4193,15 +4205,15 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
}
if (desktopExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsDesktop",
- desktopExtensionsVersion);
+ *desktopExtensionsVersion);
}
if (mobileExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsMobile",
- mobileExtensionsVersion);
+ *mobileExtensionsVersion);
}
if (iotExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsIoT",
- iotExtensionsVersion);
+ *iotExtensionsVersion);
}
}
}
@@ -4221,12 +4233,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
this->GlobalGenerator->TargetsWindowsPhone()) &&
(cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) {
std::string pfxFile;
- std::vector<cmSourceFile const*> certificates;
- this->GeneratorTarget->GetCertificates(certificates, "");
- for (cmSourceFile const* si : certificates) {
- pfxFile = this->ConvertPath(si->GetFullPath(), false);
- ConvertToWindowsSlash(pfxFile);
- break;
+ for (cmGeneratorTarget::AllConfigSource const& source :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ if (source.Kind == cmGeneratorTarget::SourceKindCertificate) {
+ pfxFile = this->ConvertPath(source.Source->GetFullPath(), false);
+ ConvertToWindowsSlash(pfxFile);
+ break;
+ }
}
if (this->IsMissingFiles &&
@@ -4272,28 +4285,61 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
}
}
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSources()
+{
+ for (cmGeneratorTarget::AllConfigSource const& source :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ this->ClassifyAllConfigSource(source);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource(
+ cmGeneratorTarget::AllConfigSource const& acs)
+{
+ switch (acs.Kind) {
+ case cmGeneratorTarget::SourceKindResx: {
+ // Build and save the name of the corresponding .h file
+ // This relationship will be used later when building the project files.
+ // Both names would have been auto generated from Visual Studio
+ // where the user supplied the file name and Visual Studio
+ // appended the suffix.
+ std::string resx = acs.Source->ResolveFullPath();
+ std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
+ this->ExpectedResxHeaders.insert(hFileName);
+ } break;
+ case cmGeneratorTarget::SourceKindXaml: {
+ // Build and save the name of the corresponding .h and .cpp file
+ // This relationship will be used later when building the project files.
+ // Both names would have been auto generated from Visual Studio
+ // where the user supplied the file name and Visual Studio
+ // appended the suffix.
+ std::string xaml = acs.Source->ResolveFullPath();
+ std::string hFileName = xaml + ".h";
+ std::string cppFileName = xaml + ".cpp";
+ this->ExpectedXamlHeaders.insert(hFileName);
+ this->ExpectedXamlSources.insert(cppFileName);
+ } break;
+ default:
+ break;
+ }
+}
+
bool cmVisualStudio10TargetGenerator::IsResxHeader(
const std::string& headerFile)
{
- std::set<std::string> expectedResxHeaders;
- this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
- return expectedResxHeaders.count(headerFile) > 0;
+ return this->ExpectedResxHeaders.count(headerFile) > 0;
}
bool cmVisualStudio10TargetGenerator::IsXamlHeader(
const std::string& headerFile)
{
- std::set<std::string> expectedXamlHeaders;
- this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, "");
- return expectedXamlHeaders.count(headerFile) > 0;
+ return this->ExpectedXamlHeaders.count(headerFile) > 0;
}
bool cmVisualStudio10TargetGenerator::IsXamlSource(
const std::string& sourceFile)
{
- std::set<std::string> expectedXamlSources;
- this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, "");
- return expectedXamlSources.count(sourceFile) > 0;
+ return this->ExpectedXamlSources.count(sourceFile) > 0;
}
void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
@@ -4352,10 +4398,10 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
if (!targetPlatformVersion.empty()) {
e1.Element("WindowsTargetPlatformVersion", targetPlatformVersion);
}
- const char* targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
+ cmProp targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
"VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
if (targetPlatformMinVersion) {
- e1.Element("WindowsTargetPlatformMinVersion", targetPlatformMinVersion);
+ e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion);
} else if (isWindowsStore && rev == "10.0") {
// If the min version is not set, then use the TargetPlatformVersion
if (!targetPlatformVersion.empty()) {
@@ -4374,39 +4420,38 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
// For Windows and Windows Phone executables, we will assume that if a
// manifest is not present that we need to add all the necessary files
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
- std::vector<cmSourceFile const*> manifestSources;
- this->GeneratorTarget->GetAppManifest(manifestSources, "");
- {
- std::string const& v = this->GlobalGenerator->GetSystemVersion();
- if (this->GlobalGenerator->TargetsWindowsPhone()) {
- if (v == "8.0") {
- // Look through the sources for WMAppManifest.xml
- std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, "");
- bool foundManifest = false;
- for (cmSourceFile const* si : extraSources) {
- // Need to do a lowercase comparison on the filename
- if ("wmappmanifest.xml" ==
- cmSystemTools::LowerCase(si->GetLocation().GetName())) {
- foundManifest = true;
- break;
- }
- }
- if (!foundManifest) {
- this->IsMissingFiles = true;
- }
- } else if (v == "8.1") {
- if (manifestSources.empty()) {
- this->IsMissingFiles = true;
+ std::vector<cmGeneratorTarget::AllConfigSource> manifestSources =
+ this->GeneratorTarget->GetAllConfigSources(
+ cmGeneratorTarget::SourceKindAppManifest);
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if (this->GlobalGenerator->TargetsWindowsPhone()) {
+ if (v == "8.0") {
+ // Look through the sources for WMAppManifest.xml
+ bool foundManifest = false;
+ for (cmGeneratorTarget::AllConfigSource const& source :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+ "wmappmanifest.xml" ==
+ cmSystemTools::LowerCase(
+ source.Source->GetLocation().GetName())) {
+ foundManifest = true;
+ break;
}
}
- } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+ if (!foundManifest) {
+ this->IsMissingFiles = true;
+ }
+ } else if (v == "8.1") {
if (manifestSources.empty()) {
- if (v == "8.0") {
- this->IsMissingFiles = true;
- } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
- this->IsMissingFiles = true;
- }
+ this->IsMissingFiles = true;
+ }
+ }
+ } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+ if (manifestSources.empty()) {
+ if (v == "8.0") {
+ this->IsMissingFiles = true;
+ } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
+ this->IsMissingFiles = true;
}
}
}
@@ -4845,11 +4890,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 +4914,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 +4954,10 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
return path;
}
+
+void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
+{
+ if (this->GlobalGenerator->IsStdOutEncodingSupported()) {
+ e1.Element("StdOutEncoding", "UTF-8");
+ }
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 30027c9e7..7c71de3dc 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -10,12 +10,14 @@
#include <memory>
#include <set>
#include <string>
+#include <unordered_map>
#include <vector>
+#include "cmGeneratorTarget.h"
+
class cmComputeLinkInformation;
class cmCustomCommand;
class cmGeneratedFileStream;
-class cmGeneratorTarget;
class cmGlobalVisualStudio10Generator;
class cmLocalVisualStudio10Generator;
class cmMakefile;
@@ -73,8 +75,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 +183,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 +238,23 @@ private:
using ToolSourceMap = std::map<std::string, ToolSources>;
ToolSourceMap Tools;
+
+ std::set<std::string> ExpectedResxHeaders;
+ std::set<std::string> ExpectedXamlHeaders;
+ std::set<std::string> ExpectedXamlSources;
+ std::vector<cmSourceFile const*> ResxObjs;
+ std::vector<cmSourceFile const*> XamlObjs;
+ void ClassifyAllConfigSources();
+ void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs);
+
+ 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/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 4004b6648..937b4ce4a 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -151,35 +151,6 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const
return false;
}
-void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target)
-{
- std::map<std::string, FlagValue>::const_iterator i =
- this->FlagMap.find("CudaRuntime");
- if (i == this->FlagMap.end()) {
- // User didn't provide am override so get the property value
- const char* runtimeLibraryValue =
- target->GetProperty("CUDA_RUNTIME_LIBRARY");
- if (runtimeLibraryValue) {
- std::string cudaRuntime =
- cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
- runtimeLibraryValue, this->LocalGenerator, this->Configuration,
- target));
- if (cudaRuntime == "STATIC") {
- this->AddFlag("CudaRuntime", "Static");
- }
- if (cudaRuntime == "SHARED") {
- this->AddFlag("CudaRuntime", "Shared");
- }
- if (cudaRuntime == "NONE") {
- this->AddFlag("CudaRuntime", "None");
- }
- } else {
- // nvcc default is static
- this->AddFlag("CudaRuntime", "Static");
- }
- }
-}
-
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
{
// Extract temporary values stored by our flag table.
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index b335694f2..f9b50a7a3 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -63,7 +63,6 @@ public:
bool UsingSBCS() const;
void FixCudaCodeGeneration();
- void FixCudaRuntime(cmGeneratorTarget* target);
void FixManifestUACFlags();
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 4533e9b69..d7822b14d 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 6c05633b8..4557cdb10 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/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 26e7c7537..0d8e894f8 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -7,8 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index aa0d6b3d5..12aba4f96 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -13,7 +13,7 @@
#include <cm/memory>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -469,11 +469,9 @@ void cmWorkerPoolWorker::UVProcessStart(uv_async_t* handle)
void cmWorkerPoolWorker::UVProcessFinished()
{
- {
- std::lock_guard<std::mutex> lock(Proc_.Mutex);
- if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) {
- Proc_.ROP.reset();
- }
+ std::lock_guard<std::mutex> lock(Proc_.Mutex);
+ if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) {
+ Proc_.ROP.reset();
}
// Notify idling thread
Proc_.Condition.notify_one();
@@ -532,6 +530,7 @@ public:
unsigned int JobsProcessing = 0;
std::deque<cmWorkerPool::JobHandleT> Queue;
std::condition_variable Condition;
+ std::condition_variable ConditionFence;
std::vector<std::unique_ptr<cmWorkerPoolWorker>> Workers;
// -- References
@@ -593,19 +592,12 @@ bool cmWorkerPoolInternal::Process()
void cmWorkerPoolInternal::Abort()
{
- bool notifyThreads = false;
// Clear all jobs and set abort flag
- {
- std::lock_guard<std::mutex> guard(Mutex);
- if (Processing && !Aborting) {
- // Register abort and clear queue
- Aborting = true;
- Queue.clear();
- notifyThreads = true;
- }
- }
- if (notifyThreads) {
- // Wake threads
+ std::lock_guard<std::mutex> guard(Mutex);
+ if (!Aborting) {
+ // Register abort and clear queue
+ Aborting = true;
+ Queue.clear();
Condition.notify_all();
}
}
@@ -669,7 +661,7 @@ void cmWorkerPoolInternal::Work(unsigned int workerIndex)
if (Aborting) {
break;
}
- // Wait for new jobs
+ // Wait for new jobs on the main CV
if (Queue.empty()) {
++WorkersIdle;
Condition.wait(uLock);
@@ -677,20 +669,34 @@ void cmWorkerPoolInternal::Work(unsigned int workerIndex)
continue;
}
- // Check for fence jobs
- if (FenceProcessing || Queue.front()->IsFence()) {
- if (JobsProcessing != 0) {
- Condition.wait(uLock);
- continue;
- }
- // No jobs get processed. Set the fence job processing flag.
- FenceProcessing = true;
+ // If there is a fence currently active or waiting,
+ // sleep on the main CV and try again.
+ if (FenceProcessing) {
+ Condition.wait(uLock);
+ continue;
}
// Pop next job from queue
jobHandle = std::move(Queue.front());
Queue.pop_front();
+ // Check for fence jobs
+ bool raisedFence = false;
+ if (jobHandle->IsFence()) {
+ FenceProcessing = true;
+ raisedFence = true;
+ // Wait on the Fence CV until all pending jobs are done.
+ while (JobsProcessing != 0 && !Aborting) {
+ ConditionFence.wait(uLock);
+ }
+ // When aborting, explicitly kick all threads alive once more.
+ if (Aborting) {
+ FenceProcessing = false;
+ Condition.notify_all();
+ break;
+ }
+ }
+
// Unlocked scope for job processing
++JobsProcessing;
{
@@ -701,11 +707,18 @@ void cmWorkerPoolInternal::Work(unsigned int workerIndex)
}
--JobsProcessing;
- // Was this a fence job?
- if (FenceProcessing) {
+ // If this was the thread that entered fence processing
+ // originally, notify all idling workers that the fence
+ // is done.
+ if (raisedFence) {
FenceProcessing = false;
Condition.notify_all();
}
+ // If fence processing is still not done, notify the
+ // the fencing worker when all active jobs are done.
+ if (FenceProcessing && JobsProcessing == 0) {
+ ConditionFence.notify_all();
+ }
}
// Decrement running workers count
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index d4a164de6..4c7576de5 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 34e21b2f2..666ba8769 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 a9bb2ef54..6b133a9e8 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 8e4b80fc1..76fad23fd 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 d9be3d2db..24ecaa22c 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 b34c2f6e1..f4c2f2d4c 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"
@@ -202,14 +204,14 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
// Info tab begin
- if (const char* exe =
+ if (cmProp exe =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) {
xout.StartElement("PathRunnable");
xout.BreakAttributes();
xout.Attribute("runnableDebuggingMode", "0");
- xout.Attribute("FilePath", exe);
+ xout.Attribute("FilePath", *exe);
xout.EndElement(); // PathRunnable
}
@@ -218,9 +220,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
// Arguments tab begin
- if (const char* argList =
+ if (cmProp argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments = cmExpandedList(argList);
+ std::vector<std::string> arguments = cmExpandedList(*argList);
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -238,9 +240,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
}
}
- if (const char* envList =
+ if (cmProp envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs = cmExpandedList(envList);
+ std::vector<std::string> envs = cmExpandedList(*envList);
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
@@ -321,8 +323,9 @@ bool cmXCodeScheme::WriteLaunchActionBooleanAttribute(
cmXMLWriter& xout, const std::string& attrName, const std::string& varName,
bool defaultValue)
{
- auto property = Target->GetTarget()->GetProperty(varName);
- bool isOn = (property == nullptr && defaultValue) || cmIsOn(property);
+ cmProp property = Target->GetTarget()->GetProperty(varName);
+ bool isOn =
+ (property == nullptr && defaultValue) || (property && cmIsOn(*property));
if (isOn) {
xout.Attribute(attrName.c_str(), "YES");
@@ -393,7 +396,8 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
xout.BreakAttributes();
xout.Attribute("BuildableIdentifier", "primary");
xout.Attribute("BlueprintIdentifier", xcObj->GetId());
- xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName());
+ std::string const noConfig; // FIXME: What config to use here?
+ xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig));
xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName());
xout.Attribute("ReferencedContainer", "container:" + container);
xout.EndElement();
@@ -402,8 +406,9 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
void cmXCodeScheme::WriteCustomWorkingDirectory(
cmXMLWriter& xout, const std::string& configuration)
{
- std::string propertyValue = this->Target->GetTarget()->GetSafeProperty(
- "XCODE_SCHEME_WORKING_DIRECTORY");
+ std::string const& propertyValue =
+ this->Target->GetTarget()->GetSafeProperty(
+ "XCODE_SCHEME_WORKING_DIRECTORY");
if (propertyValue.empty()) {
xout.Attribute("useCustomWorkingDirectory", "NO");
} else {
@@ -427,7 +432,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/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index ad5c4ba28..24da8c60e 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -7,9 +7,9 @@
#include <iostream>
#include <sstream>
-#include "cmsys/FStream.hxx"
+#include <cm3p/expat.h>
-#include "cm_expat.h"
+#include "cmsys/FStream.hxx"
cmXMLParser::cmXMLParser()
{
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index bc445aa5b..00ea08cef 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <ctime>
#include <ostream>
#include <stack>
diff --git a/Source/cm_get_date.c b/Source/cm_get_date.c
index 4bef80315..49f55772b 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/cm_static_string_view.hxx b/Source/cm_static_string_view.hxx
deleted file mode 100644
index 708ac9579..000000000
--- a/Source/cm_static_string_view.hxx
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cm_static_string_view_hxx
-#define cm_static_string_view_hxx
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cstddef>
-
-#include <cm/string_view>
-
-namespace cm {
-
-/** A string_view that only binds to static storage.
- *
- * This is used together with the `""_s` user-defined literal operator
- * to construct a type-safe abstraction of a string_view that only views
- * statically allocated strings. These strings are const and available
- * for the entire lifetime of the program.
- */
-class static_string_view : public string_view
-{
- static_string_view(string_view v)
- : string_view(v)
- {
- }
-
- friend static_string_view operator"" _s(const char* data, size_t size);
-};
-
-/** Create a static_string_view using `""_s` literal syntax. */
-inline static_string_view operator"" _s(const char* data, size_t size)
-{
- return string_view(data, size);
-}
-
-} // namespace cm
-
-using cm::operator"" _s;
-
-#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a99d9a633..162e807f1 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>
@@ -18,6 +19,7 @@
#endif
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
@@ -25,7 +27,6 @@
#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"
@@ -53,7 +57,7 @@
#if !defined(CMAKE_BOOTSTRAP)
# include <unordered_map>
-# include "cm_jsoncpp_writer.h"
+# include <cm3p/json/writer.h>
# include "cmFileAPI.h"
# include "cmGraphVizWriter.h"
@@ -134,6 +138,7 @@ using JsonValueMapType = std::unordered_map<std::string, Json::Value>;
static bool cmakeCheckStampFile(const std::string& stampName);
static bool cmakeCheckStampList(const std::string& stampList);
+#ifndef CMAKE_BOOTSTRAP
static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
void* ctx, const char* /*unused*/,
const cmMakefile* /*unused*/)
@@ -141,6 +146,7 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
cmake* cm = reinterpret_cast<cmake*>(ctx);
cm->MarkCliAsUsed(variable);
}
+#endif
cmake::cmake(Role role, cmState::Mode mode)
: FileTimeCache(cm::make_unique<cmFileTimeCache>())
@@ -285,10 +291,11 @@ void cmake::CleanupCommandsAndMacros()
// Parse the args
bool cmake::SetCacheArgs(const std::vector<std::string>& args)
{
- bool findPackageMode = false;
+ auto findPackageMode = false;
+ auto seenScriptOption = 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;
@@ -309,8 +316,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
bool haveValue = false;
std::string cachedValue;
if (this->WarnUnusedCli) {
- if (const std::string* v =
- this->State->GetInitializedCacheValue(var)) {
+ if (cmProp v = this->State->GetInitializedCacheValue(var)) {
haveValue = true;
cachedValue = *v;
}
@@ -377,7 +383,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 +413,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 +428,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 +447,12 @@ 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) {
+ seenScriptOption = true;
+ } else if (arg == "--" && seenScriptOption) {
+ // Stop processing CMake args and avoid possible errors
+ // when arbitrary args are given to CMake script.
+ break;
+ } else if (cmHasLiteralPrefix(arg, "--find-package")) {
findPackageMode = true;
}
}
@@ -520,11 +531,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 +546,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 +624,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 +648,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 +671,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 +716,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 +731,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 +743,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 +762,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 +806,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 +822,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 +846,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 +877,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 +1035,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 +1046,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 +1057,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 +1404,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 +1454,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 +1495,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;
}
@@ -1493,9 +1536,8 @@ int cmake::ActualConfigure()
// no generator specified on the command line
if (!this->GlobalGenerator) {
- const std::string* genName =
- this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
- const std::string* extraGenName =
+ cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+ cmProp extraGenName =
this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
if (genName) {
std::string fullName =
@@ -1518,8 +1560,7 @@ int cmake::ActualConfigure()
}
}
- const std::string* genName =
- this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+ cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
if (genName) {
if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) {
std::string message =
@@ -1541,7 +1582,7 @@ int cmake::ActualConfigure()
cmStateEnums::INTERNAL);
}
- if (const std::string* instance =
+ if (cmProp instance =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) {
std::string message =
@@ -1558,7 +1599,7 @@ int cmake::ActualConfigure()
"Generator instance identifier.", cmStateEnums::INTERNAL);
}
- if (const std::string* platformName =
+ if (cmProp platformName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
if (this->GeneratorPlatformSet &&
this->GeneratorPlatform != *platformName) {
@@ -1576,7 +1617,7 @@ int cmake::ActualConfigure()
"Name of generator platform.", cmStateEnums::INTERNAL);
}
- if (const std::string* tsName =
+ if (cmProp tsName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) {
if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) {
std::string message =
@@ -1891,13 +1932,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 +1974,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);
@@ -1946,7 +1988,7 @@ std::string cmake::StripExtension(const std::string& file) const
const char* cmake::GetCacheDefinition(const std::string& name) const
{
- const std::string* p = this->State->GetInitializedCacheValue(name);
+ cmProp p = this->State->GetInitializedCacheValue(name);
return p ? p->c_str() : nullptr;
}
@@ -2153,7 +2195,7 @@ void cmake::PrintGeneratorList()
void cmake::UpdateConversionPathTable()
{
// Update the path conversion table with any specified file:
- const std::string* tablepath =
+ cmProp tablepath =
this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE");
if (tablepath) {
@@ -2244,9 +2286,7 @@ int cmake::CheckBuildSystem()
// If any byproduct of makefile generation is missing we must re-run.
std::vector<std::string> products;
- if (const char* productStr = mf.GetDefinition("CMAKE_MAKEFILE_PRODUCTS")) {
- cmExpandList(productStr, products);
- }
+ mf.GetDefExpandList("CMAKE_MAKEFILE_PRODUCTS", products);
for (std::string const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
if (verbose) {
@@ -2261,11 +2301,8 @@ int cmake::CheckBuildSystem()
// Get the set of dependencies and outputs.
std::vector<std::string> depends;
std::vector<std::string> outputs;
- const char* dependsStr = mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS");
- const char* outputsStr = mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
- if (dependsStr && outputsStr) {
- cmExpandList(dependsStr, depends);
- cmExpandList(outputsStr, outputs);
+ if (mf.GetDefExpandList("CMAKE_MAKEFILE_DEPENDS", depends)) {
+ mf.GetDefExpandList("CMAKE_MAKEFILE_OUTPUTS", outputs);
}
if (depends.empty() || outputs.empty()) {
// Not enough information was provided to do the test. Just rerun.
@@ -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,16 +2829,16 @@ 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;
}
- const std::string* extraGenName =
+ cmProp extraGenName =
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 35425ec52..086ec8765 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -16,16 +16,19 @@
#include <utility>
#include <vector>
+#include <cm/string_view>
+
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
+# include <cm3p/json/value.h>
#endif
class cmExternalMakefileProjectGeneratorFactory;
@@ -34,6 +37,9 @@ class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
+#if !defined(CMAKE_BOOTSTRAP)
+class cmMakefileProfilingData;
+#endif
class cmMessenger;
class cmVariableWatch;
struct cmDocumentationEntry;
@@ -135,13 +141,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 +269,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 +279,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 +289,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 +299,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 +367,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 +555,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 +668,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 494d5d982..d662a9abc 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -1,6 +1,8 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h" // IWYU pragma: keep
+
#include <cassert>
#include <cctype>
#include <climits>
@@ -11,9 +13,12 @@
#include <cmext/algorithm>
+#include <cm3p/uv.h>
+
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -27,8 +32,6 @@
#endif
#include "cmsys/Encoding.hxx"
-
-#include "cm_uv.h"
#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
@@ -93,6 +96,14 @@ 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. Supported formats: "
+ "google-trace" },
+ { "--profiling-output=<file>",
+ "Select an output path for the profiling data enabled through "
+ "--profiling-format." },
+# endif
{ nullptr, nullptr }
};
@@ -286,16 +297,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;
}
@@ -312,6 +323,7 @@ int do_cmake(int ac, char const* const* av)
return 0;
}
+#ifndef CMAKE_BOOTSTRAP
int extract_job_number(int& index, char const* current, char const* next,
int len_of_flag)
{
@@ -341,6 +353,7 @@ int extract_job_number(int& index, char const* current, char const* next,
}
return jobs;
}
+#endif
int do_build(int ac, char const* const* av)
{
@@ -706,6 +719,8 @@ int main(int ac, char const* const* av)
#ifndef CMAKE_BOOTSTRAP
cmDynamicLoader::FlushCache();
#endif
- uv_loop_close(uv_default_loop());
+ if (uv_loop_t* loop = uv_default_loop()) {
+ uv_loop_close(loop);
+ }
return ret;
}
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index caf645301..5c27ac103 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 2b8ea24fb..de76d734e 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -4,11 +4,9 @@
#include <cmext/algorithm>
+#include <cm3p/uv.h>
#include <fcntl.h>
-#include "cm_uv.h"
-
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -90,6 +88,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 +179,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 +684,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 +933,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 +1087,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 +1218,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 +1336,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 +1543,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 +1598,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 +1686,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 +1879,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 +2005,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 +2116,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 +2195,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 fbdf75ada..3b5bf8c4c 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 bf876f2d5..42650184a 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 09bcdb943..b0a854292 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,309 +131,253 @@ 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_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
# capabilities and parent project's request. Enforce 0/1 as only
# possible values for configuration into Configure.hxx.
-# Check existence and uniqueness of long long and __int64.
-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)
- 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)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
- "Checking whether long long and __int64 are the same type" DIRECT)
- 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()
-
-# 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)
+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()
-
-IF(KWSYS_USE_IOStream)
- # Determine whether iostreams support 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)
- 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()
+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 +390,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 +438,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 +447,564 @@ 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()
- 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
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
- 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
- COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
- 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
- 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)
- 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
- 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
- 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
- COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
- 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
- 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
- COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ endif()
+ endif()
+ 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)
-
-IF(NOT CMake_SOURCE_DIR)
- SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
- hashtable hash_fun hash_map hash_set
- )
-ENDIF()
+set(KWSYS_CLASSES)
+set(KWSYS_H_FILES Configure SharedForward)
+set(KWSYS_HXX_FILES Configure String)
# Add selected C++ classes.
-SET(cppclasses
+set(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
+ CommandLineArguments 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
- testHashSTL.cxx
- )
- ENDIF()
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ 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 +1019,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 +1064,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 +1073,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 3fd195561..e45db36ac 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -20,9 +20,9 @@
#include <sstream>
#include <vector>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#ifdef _MSC_VER
# pragma warning(disable : 4786)
@@ -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/Configure.h.in b/Source/kwsys/Configure.h.in
index 5323c57be..8a237cea3 100644
--- a/Source/kwsys/Configure.h.in
+++ b/Source/kwsys/Configure.h.in
@@ -13,9 +13,6 @@
/* Disable some warnings inside kwsys source files. */
#if defined(KWSYS_NAMESPACE)
-# if defined(__BORLANDC__)
-# pragma warn - 8027 /* function not inlined. */
-# endif
# if defined(__INTEL_COMPILER)
# pragma warning(disable : 1572) /* floating-point equality test */
# endif
@@ -68,11 +65,6 @@
# pragma warning(disable : 4710) /* function not inlined */
# pragma warning(disable : 4786) /* identifier truncated in debug info */
# endif
-# if defined(__BORLANDC__) && !defined(__cplusplus)
-/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
- unused parameter using "(param)" syntax (i.e. no cast to void). */
-# pragma warn - 8019
-# endif
#endif
/* MSVC 6.0 in release mode will warn about code it produces with its
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index e3791826b..0c2190aee 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;
@@ -80,26 +92,12 @@ void Directory::Clear()
# include <sys/stat.h>
# include <sys/types.h>
-// Wide function names can vary depending on compiler:
-# ifdef __BORLANDC__
-# define _wfindfirst_func __wfindfirst
-# define _wfindnext_func __wfindnext
-# else
-# define _wfindfirst_func _wfindfirst
-# define _wfindnext_func _wfindnext
-# endif
-
namespace KWSYS_NAMESPACE {
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
{
this->Clear();
-# if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
- // Older Visual C++ and Embarcadero compilers.
- long srchHandle;
-# else // Newer Visual C++
intptr_t srchHandle;
-# endif
char* buf;
size_t n = name.size();
if (name.back() == '/' || name.back() == '\\') {
@@ -118,8 +116,8 @@ bool Directory::Load(const std::string& name)
struct _wfinddata_t data; // data of current file
// Now put them into the file array
- srchHandle = _wfindfirst_func(
- (wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
+ srchHandle =
+ _wfindfirst((wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
delete[] buf;
if (srchHandle == -1) {
@@ -129,19 +127,15 @@ bool Directory::Load(const std::string& name)
// Loop through names
do {
this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
- } while (_wfindnext_func(srchHandle, &data) != -1);
+ } while (_wfindnext(srchHandle, &data) != -1);
this->Internal->Path = name;
return _findclose(srchHandle) != -1;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+ std::string* errorMessage)
{
-# if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
- // Older Visual C++ and Embarcadero compilers.
- long srchHandle;
-# else // Newer Visual C++
intptr_t srchHandle;
-# endif
char* buf;
size_t n = name.size();
if (name.back() == '/') {
@@ -154,8 +148,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
struct _wfinddata_t data; // data of current file
// Now put them into the file array
- srchHandle =
- _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
+ srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
delete[] buf;
if (srchHandle == -1) {
@@ -166,7 +159,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
unsigned long count = 0;
do {
count++;
- } while (_wfindnext_func(srchHandle, &data) != -1);
+ } while (_wfindnext(srchHandle, &data) != -1);
_findclose(srchHandle);
return count;
}
@@ -180,6 +173,8 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
# include <sys/types.h>
# include <dirent.h>
+# include <errno.h>
+# include <string.h>
// PGI with glibc has trouble with dirent and large file support:
// http://www.pgroup.com/userforum/viewtopic.php?
@@ -197,29 +192,46 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
namespace KWSYS_NAMESPACE {
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
{
this->Clear();
+ errno = 0;
DIR* dir = opendir(name.c_str());
if (!dir) {
- return 0;
+ if (errorMessage != nullptr) {
+ *errorMessage = std::string(strerror(errno));
+ }
+ return false;
}
+ errno = 0;
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);
+ }
+ if (errno != 0) {
+ if (errorMessage != nullptr) {
+ *errorMessage = std::string(strerror(errno));
+ }
+ return false;
}
+
this->Internal->Path = name;
closedir(dir);
- return 1;
+ return true;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+ std::string* errorMessage)
{
+ errno = 0;
DIR* dir = opendir(name.c_str());
if (!dir) {
+ if (errorMessage != nullptr) {
+ *errorMessage = std::string(strerror(errno));
+ }
return 0;
}
@@ -227,6 +239,13 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
count++;
}
+ if (errno != 0) {
+ if (errorMessage != nullptr) {
+ *errorMessage = std::string(strerror(errno));
+ }
+ return false;
+ }
+
closedir(dir);
return count;
}
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index ad8c51b86..7bc9db024 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();
/**
@@ -30,7 +35,7 @@ public:
* in that directory. 0 is returned if the directory can not be
* opened, 1 if it is opened.
*/
- bool Load(const std::string&);
+ bool Load(const std::string&, std::string* errorMessage = nullptr);
/**
* Return the number of files in the current directory.
@@ -41,7 +46,8 @@ public:
* Return the number of files in the specified directory.
* A higher performance static method.
*/
- static unsigned long GetNumberOfFilesInDirectory(const std::string&);
+ static unsigned long GetNumberOfFilesInDirectory(
+ const std::string&, std::string* errorMessage = nullptr);
/**
* Return the file at the given index, the indexing is 0 based
@@ -62,10 +68,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/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index a4b864118..66ee9eafa 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -246,17 +246,6 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
// should have a tool to help get the symbol with the desired
// calling convention. Currently we assume cdecl.
//
- // Borland:
- // __cdecl = "_func" (default)
- // __fastcall = "@_func"
- // __stdcall = "func"
- //
- // Watcom:
- // __cdecl = "_func"
- // __fastcall = "@_func@X"
- // __stdcall = "_func@X"
- // __watcall = "func_" (default)
- //
// MSVC:
// __cdecl = "func" (default)
// __fastcall = "@_func@X"
@@ -265,20 +254,9 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
// Note that the "@X" part of the name above is the total size (in
// bytes) of the arguments on the stack.
void* result;
-# if defined(__BORLANDC__) || defined(__WATCOMC__)
- // Need to prepend symbols with '_'
- std::string ssym = '_' + sym;
- const char* rsym = ssym.c_str();
-# else
const char* rsym = sym.c_str();
-# endif
result = (void*)GetProcAddress(lib, rsym);
-// Hack to cast pointer-to-data to pointer-to-function.
-# ifdef __WATCOMC__
- return *(DynamicLoader::SymbolPointer*)(&result);
-# else
return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
-# endif
}
# define DYNLOAD_ERROR_BUFFER_SIZE 1024
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 5cad934ec..c68c73c8e 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -17,8 +17,8 @@
# include "Encoding.hxx.in"
#endif
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include <vector>
#ifdef _MSC_VER
diff --git a/Source/kwsys/ExtraTest.cmake.in b/Source/kwsys/ExtraTest.cmake.in
index e8c0a1cdb..4cec9e295 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 34bb0d0fe..5452f733b 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -23,9 +23,9 @@
#include <string>
#include <vector>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
namespace KWSYS_NAMESPACE {
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
// On Windows and Apple, no difference between lower and upper case
@@ -182,7 +182,15 @@ bool Glob::RecurseDirectory(std::string::size_type start,
const std::string& dir, GlobMessages* messages)
{
kwsys::Directory d;
- if (!d.Load(dir)) {
+ std::string errorMessage;
+ if (!d.Load(dir, &errorMessage)) {
+ if (messages) {
+ if (!errorMessage.empty()) {
+ messages->push_back(Message(Glob::warning,
+ "Error listing directory '" + dir +
+ "'! Reason: '" + errorMessage + "'"));
+ }
+ }
return true;
}
unsigned long cc;
@@ -278,7 +286,9 @@ void Glob::ProcessDirectory(std::string::size_type start,
// std::cout << "ProcessDirectory: " << dir << std::endl;
bool last = (start == this->Internals->Expressions.size() - 1);
if (last && this->Recurse) {
- this->RecurseDirectory(start, dir, messages);
+ if (kwsys::SystemTools::FileIsDirectory(dir)) {
+ this->RecurseDirectory(start, dir, messages);
+ }
return;
}
@@ -385,10 +395,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 +424,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/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 170766f4b..b5a34d59a 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -28,6 +28,7 @@ public:
enum MessageType
{
error,
+ warning,
cyclicRecursion
};
diff --git a/Source/kwsys/IOStream.cxx b/Source/kwsys/IOStream.cxx
deleted file mode 100644
index e21f87d45..000000000
--- a/Source/kwsys/IOStream.cxx
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(Configure.hxx)
-
-// Include the streams library.
-#include <iostream>
-#include KWSYS_HEADER(IOStream.hxx)
-
-// Work-around CMake dependency scanning limitation. This must
-// duplicate the above list of headers.
-#if 0
-# include "Configure.hxx.in"
-# include "IOStream.hxx.in"
-#endif
-
-// Implement the rest of this file only if it is needed.
-#if KWSYS_IOS_NEED_OPERATORS_LL
-
-# include <stdio.h> // sscanf, sprintf
-# include <string.h> // memchr
-
-# if defined(_MAX_INT_DIG)
-# define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
-# else
-# define KWSYS_IOS_INT64_MAX_DIG 32
-# endif
-
-namespace KWSYS_NAMESPACE {
-
-// Scan an input stream for an integer value.
-static int IOStreamScanStream(std::istream& is, char* buffer)
-{
- // Prepare to write to buffer.
- char* out = buffer;
- char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1;
-
- // Look for leading sign.
- if (is.peek() == '+') {
- *out++ = '+';
- is.ignore();
- } else if (is.peek() == '-') {
- *out++ = '-';
- is.ignore();
- }
-
- // Determine the base. If not specified in the stream, try to
- // detect it from the input. A leading 0x means hex, and a leading
- // 0 alone means octal.
- int base = 0;
- int flags = is.flags() & std::ios_base::basefield;
- if (flags == std::ios_base::oct) {
- base = 8;
- } else if (flags == std::ios_base::dec) {
- base = 10;
- } else if (flags == std::ios_base::hex) {
- base = 16;
- }
- bool foundDigit = false;
- bool foundNonZero = false;
- if (is.peek() == '0') {
- foundDigit = true;
- is.ignore();
- if ((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16)) {
- base = 16;
- foundDigit = false;
- is.ignore();
- } else if (base == 0) {
- base = 8;
- }
- }
-
- // Determine the range of digits allowed for this number.
- const char* digits = "0123456789abcdefABCDEF";
- int maxDigitIndex = 10;
- if (base == 8) {
- maxDigitIndex = 8;
- } else if (base == 16) {
- maxDigitIndex = 10 + 6 + 6;
- }
-
- // Scan until an invalid digit is found.
- for (; is.peek() != EOF; is.ignore()) {
- if (memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0) {
- if ((foundNonZero || *out != '0') && out < end) {
- ++out;
- foundNonZero = true;
- }
- foundDigit = true;
- } else {
- break;
- }
- }
-
- // Correct the buffer contents for degenerate cases.
- if (foundDigit && !foundNonZero) {
- *out++ = '0';
- } else if (!foundDigit) {
- out = buffer;
- }
-
- // Terminate the string in the buffer.
- *out = '\0';
-
- return base;
-}
-
-// Read an integer value from an input stream.
-template <class T>
-std::istream& IOStreamScanTemplate(std::istream& is, T& value, char type)
-{
- int state = std::ios_base::goodbit;
-
- // Skip leading whitespace.
- std::istream::sentry okay(is);
-
- if (okay) {
- try {
- // Copy the string to a buffer and construct the format string.
- char buffer[KWSYS_IOS_INT64_MAX_DIG];
-# if defined(_MSC_VER)
- char format[] = "%I64_";
- const int typeIndex = 4;
-# else
- char format[] = "%ll_";
- const int typeIndex = 3;
-# endif
- switch (IOStreamScanStream(is, buffer)) {
- case 8:
- format[typeIndex] = 'o';
- break;
- case 0: // Default to decimal if not told otherwise.
- case 10:
- format[typeIndex] = type;
- break;
- case 16:
- format[typeIndex] = 'x';
- break;
- };
-
- // Use sscanf to parse the number from the buffer.
- T result;
- int success = (sscanf(buffer, format, &result) == 1) ? 1 : 0;
-
- // Set flags for resulting state.
- if (is.peek() == EOF) {
- state |= std::ios_base::eofbit;
- }
- if (!success) {
- state |= std::ios_base::failbit;
- } else {
- value = result;
- }
- } catch (...) {
- state |= std::ios_base::badbit;
- }
- }
-
- is.setstate(std::ios_base::iostate(state));
- return is;
-}
-
-// Print an integer value to an output stream.
-template <class T>
-std::ostream& IOStreamPrintTemplate(std::ostream& os, T value, char type)
-{
- std::ostream::sentry okay(os);
- if (okay) {
- try {
- // Construct the format string.
- char format[8];
- char* f = format;
- *f++ = '%';
- if (os.flags() & std::ios_base::showpos) {
- *f++ = '+';
- }
- if (os.flags() & std::ios_base::showbase) {
- *f++ = '#';
- }
-# if defined(_MSC_VER)
- *f++ = 'I';
- *f++ = '6';
- *f++ = '4';
-# else
- *f++ = 'l';
- *f++ = 'l';
-# endif
- long bflags = os.flags() & std::ios_base::basefield;
- if (bflags == std::ios_base::oct) {
- *f++ = 'o';
- } else if (bflags != std::ios_base::hex) {
- *f++ = type;
- } else if (os.flags() & std::ios_base::uppercase) {
- *f++ = 'X';
- } else {
- *f++ = 'x';
- }
- *f = '\0';
-
- // Use sprintf to print to a buffer and then write the
- // buffer to the stream.
- char buffer[2 * KWSYS_IOS_INT64_MAX_DIG];
- sprintf(buffer, format, value);
- os << buffer;
- } catch (...) {
- os.clear(os.rdstate() | std::ios_base::badbit);
- }
- }
- return os;
-}
-
-# if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-// Implement input stream operator for IOStreamSLL.
-std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value)
-{
- return IOStreamScanTemplate(is, value, 'd');
-}
-
-// Implement input stream operator for IOStreamULL.
-std::istream& IOStreamScan(std::istream& is, IOStreamULL& value)
-{
- return IOStreamScanTemplate(is, value, 'u');
-}
-# endif
-
-# if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-// Implement output stream operator for IOStreamSLL.
-std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value)
-{
- return IOStreamPrintTemplate(os, value, 'd');
-}
-
-// Implement output stream operator for IOStreamULL.
-std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value)
-{
- return IOStreamPrintTemplate(os, value, 'u');
-}
-# endif
-
-} // namespace KWSYS_NAMESPACE
-
-#else
-
-namespace KWSYS_NAMESPACE {
-
-// Create one public symbol in this object file to avoid warnings from
-// archivers.
-void IOStreamSymbolToAvoidWarning();
-void IOStreamSymbolToAvoidWarning()
-{
-}
-
-} // namespace KWSYS_NAMESPACE
-
-#endif // KWSYS_IOS_NEED_OPERATORS_LL
diff --git a/Source/kwsys/IOStream.hxx.in b/Source/kwsys/IOStream.hxx.in
deleted file mode 100644
index db8a23ef5..000000000
--- a/Source/kwsys/IOStream.hxx.in
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-#ifndef @KWSYS_NAMESPACE@_IOStream_hxx
-#define @KWSYS_NAMESPACE@_IOStream_hxx
-
-#include <iosfwd>
-
-/* Define these macros temporarily to keep the code readable. */
-#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-/* Whether istream supports long long. */
-#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG \
- @KWSYS_IOS_HAS_ISTREAM_LONG_LONG@
-
-/* Whether ostream supports long long. */
-#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG \
- @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
-
-/* Determine whether we need to define the streaming operators for
- long long or __int64. */
-#if @KWSYS_USE_LONG_LONG@
-# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
- !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
-namespace @KWSYS_NAMESPACE@ {
-typedef long long IOStreamSLL;
-typedef unsigned long long IOStreamULL;
-}
-# endif
-#elif defined(_MSC_VER) && _MSC_VER < 1300
-# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
-namespace @KWSYS_NAMESPACE@ {
-typedef __int64 IOStreamSLL;
-typedef unsigned __int64 IOStreamULL;
-}
-#endif
-#if !defined(@KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL)
-# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
-# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
-
-/* Input stream operator implementation functions. */
-namespace @KWSYS_NAMESPACE@ {
-kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&);
-kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&);
-}
-
-/* Provide input stream operator for long long. */
-# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) && \
- !defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
-# define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
-# define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED
-inline std::istream& operator>>(std::istream& is,
- @KWSYS_NAMESPACE@::IOStreamSLL& value)
-{
- return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
-}
-# endif
-
-/* Provide input stream operator for unsigned long long. */
-# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) && \
- !defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
-# define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-# define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline std::istream& operator>>(std::istream& is,
- @KWSYS_NAMESPACE@::IOStreamULL& value)
-{
- return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
-}
-# endif
-# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */
-
-# if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-
-/* Output stream operator implementation functions. */
-namespace @KWSYS_NAMESPACE@ {
-kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL);
-kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL);
-}
-
-/* Provide output stream operator for long long. */
-# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) && \
- !defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
-# define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
-# define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED
-inline std::ostream& operator<<(std::ostream& os,
- @KWSYS_NAMESPACE@::IOStreamSLL value)
-{
- return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
-}
-# endif
-
-/* Provide output stream operator for unsigned long long. */
-# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) && \
- !defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
-# define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-# define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline std::ostream& operator<<(std::ostream& os,
- @KWSYS_NAMESPACE@::IOStreamULL value)
-{
- return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
-}
-# endif
-# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */
-#endif /* @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL */
-
-/* Undefine temporary macros. */
-#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysEXPORT
-#endif
-
-/* If building a C++ file in kwsys itself, give the source file
- access to the macros without a configured namespace. */
-#if defined(KWSYS_NAMESPACE)
-# define KWSYS_IOS_HAS_ISTREAM_LONG_LONG \
- @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
-# define KWSYS_IOS_HAS_OSTREAM_LONG_LONG \
- @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-# define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
-#endif
-
-#endif
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
index 97cf9ba68..fb18a5bba 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 73ea9dbfc..9f2162b3d 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 f65690b31..cc4552913 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 68c52185e..12670762d 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -31,9 +31,6 @@ a UNIX-style select system call.
#include <io.h> /* _unlink */
#include <stdio.h> /* sprintf */
#include <string.h> /* strlen, strdup */
-#ifdef __WATCOMC__
-# define _unlink unlink
-#endif
#ifndef _MAX_FNAME
# define _MAX_FNAME 4096
@@ -48,11 +45,6 @@ a UNIX-style select system call.
# pragma warning(disable : 4706)
#endif
-#if defined(__BORLANDC__)
-# pragma warn - 8004 /* assigned a value that is never used */
-# pragma warn - 8060 /* Assignment inside if() condition. */
-#endif
-
/* There are pipes for the process pipeline's stdout and stderr. */
#define KWSYSPE_PIPE_COUNT 2
#define KWSYSPE_PIPE_STDOUT 0
@@ -761,7 +753,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/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 5e6f8da50..4f74eba53 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -28,8 +28,8 @@
# include "RegularExpression.hxx.in"
#endif
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
namespace KWSYS_NAMESPACE {
@@ -367,8 +367,7 @@ bool RegularExpression::compile(const char* exp)
// Allocate space.
//#ifndef _WIN32
- if (this->program != nullptr)
- delete[] this->program;
+ delete[] this->program;
//#endif
this->program = new char[comp.regsize];
this->progsize = static_cast<int>(comp.regsize);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index d11db8828..2709cde5f 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -26,12 +26,6 @@
#include <string>
-/* Disable useless Borland warnings. KWSys tries not to force things
- on its includers, but there is no choice here. */
-#if defined(__BORLANDC__)
-# pragma warn - 8027 /* function not inlined. */
-#endif
-
namespace @KWSYS_NAMESPACE@ {
// Forward declaration
diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in
index 5716cd4f1..091334b75 100644
--- a/Source/kwsys/SharedForward.h.in
+++ b/Source/kwsys/SharedForward.h.in
@@ -66,12 +66,6 @@
# endif
# endif
-# if defined(__BORLANDC__) && !defined(__cplusplus)
-/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
- unused parameter using "(param)" syntax (i.e. no cast to void). */
-# pragma warn - 8019
-# endif
-
/* Full path to the directory in which this executable is built. Do
not include a trailing slash. */
# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD)
diff --git a/Source/kwsys/String.hxx.in b/Source/kwsys/String.hxx.in
index db1cf22a9..c36f4ce4a 100644
--- a/Source/kwsys/String.hxx.in
+++ b/Source/kwsys/String.hxx.in
@@ -52,14 +52,6 @@ public:
}
}; // End Class: String
-#if defined(__WATCOMC__)
-inline bool operator<(String const& l, String const& r)
-{
- return (static_cast<std::string const&>(l) <
- static_cast<std::string const&>(r));
-}
-#endif
-
} // namespace @KWSYS_NAMESPACE@
#endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index d43cc6fbb..dbfd2fd16 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 6ec6e48ff..ed1cdc0ab 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -64,9 +64,9 @@ typedef int siginfo_t;
#else
# include <sys/types.h>
-# include <errno.h> // extern int errno;
+# include <cerrno> // extern int errno;
+# include <csignal>
# include <fcntl.h>
-# include <signal.h>
# include <sys/resource.h> // getrlimit
# include <sys/time.h>
# include <sys/utsname.h> // int uname(struct utsname *buf);
@@ -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;
@@ -163,39 +163,11 @@ typedef struct rlimit ResourceLimitType;
# undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP
#endif
-#include <ctype.h> // int isdigit(int c);
+#include <cctype> // int isdigit(int c);
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(KWSYS_USE_LONG_LONG)
-# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
-# define iostreamLongLong(x) (x)
-# else
-# define iostreamLongLong(x) ((long)(x))
-# endif
-#elif defined(KWSYS_USE___INT64)
-# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
-# define iostreamLongLong(x) (x)
-# else
-# define iostreamLongLong(x) ((long)(x))
-# endif
-#else
-# error "No Long Long"
-#endif
-
-#if defined(KWSYS_CXX_HAS_ATOLL)
-# define atoLongLong atoll
-#else
-# if defined(KWSYS_CXX_HAS__ATOI64)
-# define atoLongLong _atoi64
-# elif defined(KWSYS_CXX_HAS_ATOL)
-# define atoLongLong atol
-# else
-# define atoLongLong atoi
-# endif
-#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64) && \
!defined(__clang__)
@@ -204,15 +176,15 @@ 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
# define USE_CPUID_INTRINSICS 0
#endif
-#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS || \
- defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS
# define USE_CPUID 1
#else
# define USE_CPUID 0
@@ -272,21 +244,6 @@ static bool call_cpuid(int select, int result[4])
}
memcpy(result, tmp, sizeof(tmp));
-# elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
- unsigned int a, b, c, d;
- __asm {
- mov EAX, select;
- cpuid
- mov a, EAX;
- mov b, EBX;
- mov c, ECX;
- mov d, EDX;
- }
-
- result[0] = a;
- result[1] = b;
- result[2] = c;
- result[3] = d;
# endif
// The cpuid instruction succeeded.
@@ -303,34 +260,33 @@ 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;
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,29 +295,29 @@ 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();
+ long long GetProcessId();
// Retrieve memory information in KiB.
- LongLong GetHostMemoryTotal();
- LongLong GetHostMemoryAvailable(const char* envVarName);
- LongLong GetHostMemoryUsed();
+ long long GetHostMemoryTotal();
+ long long GetHostMemoryAvailable(const char* hostLimitEnvVarName);
+ long long GetHostMemoryUsed();
- LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName,
- const char* procLimitEnvVarName);
- LongLong GetProcMemoryUsed();
+ long long GetProcMemoryAvailable(const char* hostLimitEnvVarName,
+ const char* procLimitEnvVarName);
+ long long GetProcMemoryUsed();
double GetLoadAverage();
@@ -377,60 +333,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,8 +475,9 @@ protected:
void CPUCountWindows(); // For windows
unsigned char GetAPICId(); // For windows
- bool IsSMTSupported();
- static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
+ bool IsSMTSupported() const;
+ static long long GetCyclesDifference(DELAY_FUNC,
+ unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
bool RetreiveInformationFromCpuInfoFile();
@@ -768,42 +768,41 @@ std::string SystemInformation::GetMemoryDescription(
const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
{
std::ostringstream oss;
- oss << "Host Total: " << iostreamLongLong(this->GetHostMemoryTotal())
+ oss << "Host Total: " << this->GetHostMemoryTotal()
<< " KiB, Host Available: "
- << iostreamLongLong(this->GetHostMemoryAvailable(hostLimitEnvVarName))
+ << this->GetHostMemoryAvailable(hostLimitEnvVarName)
<< " KiB, Process Available: "
- << iostreamLongLong(this->GetProcMemoryAvailable(hostLimitEnvVarName,
- procLimitEnvVarName))
+ << this->GetProcMemoryAvailable(hostLimitEnvVarName, procLimitEnvVarName)
<< " KiB";
return oss.str();
}
// host memory info in units of KiB.
-SystemInformation::LongLong SystemInformation::GetHostMemoryTotal()
+long long SystemInformation::GetHostMemoryTotal()
{
return this->Implementation->GetHostMemoryTotal();
}
-SystemInformation::LongLong SystemInformation::GetHostMemoryAvailable(
+long long SystemInformation::GetHostMemoryAvailable(
const char* hostLimitEnvVarName)
{
return this->Implementation->GetHostMemoryAvailable(hostLimitEnvVarName);
}
-SystemInformation::LongLong SystemInformation::GetHostMemoryUsed()
+long long SystemInformation::GetHostMemoryUsed()
{
return this->Implementation->GetHostMemoryUsed();
}
// process memory info in units of KiB.
-SystemInformation::LongLong SystemInformation::GetProcMemoryAvailable(
+long long SystemInformation::GetProcMemoryAvailable(
const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
{
return this->Implementation->GetProcMemoryAvailable(hostLimitEnvVarName,
procLimitEnvVarName);
}
-SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
+long long SystemInformation::GetProcMemoryUsed()
{
return this->Implementation->GetProcMemoryUsed();
}
@@ -813,7 +812,7 @@ double SystemInformation::GetLoadAverage()
return this->Implementation->GetLoadAverage();
}
-SystemInformation::LongLong SystemInformation::GetProcessId()
+long long SystemInformation::GetProcessId()
{
return this->Implementation->GetProcessId();
}
@@ -885,7 +884,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 +898,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);
@@ -1322,9 +1321,9 @@ std::string SymbolProperties::GetFileName(const std::string& path) const
{
std::string file(path);
if (!this->ReportPath) {
- size_t at = file.rfind("/");
+ size_t at = file.rfind('/');
if (at != std::string::npos) {
- file = file.substr(at + 1);
+ file.erase(0, at + 1);
}
}
return file;
@@ -1464,10 +1463,6 @@ SystemInformationImplementation::SystemInformationImplementation()
this->OSIs64Bit = (sizeof(void*) == 8);
}
-SystemInformationImplementation::~SystemInformationImplementation()
-{
-}
-
void SystemInformationImplementation::RunCPUCheck()
{
#ifdef _WIN32
@@ -1564,7 +1559,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 +1755,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 +1763,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 +1771,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 +1779,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 +1793,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 +1845,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 +2126,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 +2841,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
@@ -3344,8 +3342,8 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
size_t pos = buffer.find(word, init);
if (pos != std::string::npos) {
this->CurrentPositionInFile = pos;
- pos = buffer.find(":", pos);
- size_t pos2 = buffer.find("\n", pos);
+ pos = buffer.find(':', pos);
+ size_t pos2 = buffer.find('\n', pos);
if (pos != std::string::npos && pos2 != std::string::npos) {
// It may happen that the beginning matches, but this is still not the
// requested key.
@@ -3358,7 +3356,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 +3409,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 +3441,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 +3502,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());
}
@@ -3584,8 +3583,7 @@ bool SystemInformationImplementation::QueryProcessor()
/**
Get total system RAM in units of KiB.
*/
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryTotal()
+long long SystemInformationImplementation::GetHostMemoryTotal()
{
#if defined(_WIN32)
# if defined(_MSC_VER) && _MSC_VER < 1300
@@ -3600,7 +3598,7 @@ SystemInformationImplementation::GetHostMemoryTotal()
return statex.ullTotalPhys / 1024;
# endif
#elif defined(__linux)
- SystemInformation::LongLong memTotal = 0;
+ long long memTotal = 0;
int ierr = GetFieldFromFile("/proc/meminfo", "MemTotal:", memTotal);
if (ierr) {
return -1;
@@ -3623,11 +3621,10 @@ SystemInformationImplementation::GetHostMemoryTotal()
Get total system RAM in units of KiB. This may differ from the
host total if a host-wide resource limit is applied.
*/
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryAvailable(
+long long SystemInformationImplementation::GetHostMemoryAvailable(
const char* hostLimitEnvVarName)
{
- SystemInformation::LongLong memTotal = this->GetHostMemoryTotal();
+ long long memTotal = this->GetHostMemoryTotal();
// the following mechanism is provided for systems that
// apply resource limits across groups of processes.
@@ -3638,8 +3635,7 @@ SystemInformationImplementation::GetHostMemoryAvailable(
if (hostLimitEnvVarName) {
const char* hostLimitEnvVarValue = getenv(hostLimitEnvVarName);
if (hostLimitEnvVarValue) {
- SystemInformation::LongLong hostLimit =
- atoLongLong(hostLimitEnvVarValue);
+ long long hostLimit = std::atoll(hostLimitEnvVarValue);
if (hostLimit > 0) {
memTotal = min(hostLimit, memTotal);
}
@@ -3653,20 +3649,17 @@ SystemInformationImplementation::GetHostMemoryAvailable(
Get total system RAM in units of KiB. This may differ from the
host total if a per-process resource limit is applied.
*/
-SystemInformation::LongLong
-SystemInformationImplementation::GetProcMemoryAvailable(
+long long SystemInformationImplementation::GetProcMemoryAvailable(
const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
{
- SystemInformation::LongLong memAvail =
- this->GetHostMemoryAvailable(hostLimitEnvVarName);
+ long long memAvail = this->GetHostMemoryAvailable(hostLimitEnvVarName);
// the following mechanism is provide for systems where rlimits
// are not employed. Units are in KiB.
if (procLimitEnvVarName) {
const char* procLimitEnvVarValue = getenv(procLimitEnvVarName);
if (procLimitEnvVarValue) {
- SystemInformation::LongLong procLimit =
- atoLongLong(procLimitEnvVarValue);
+ long long procLimit = std::atoll(procLimitEnvVarValue);
if (procLimit > 0) {
memAvail = min(procLimit, memAvail);
}
@@ -3678,28 +3671,24 @@ SystemInformationImplementation::GetProcMemoryAvailable(
ResourceLimitType rlim;
ierr = GetResourceLimit(RLIMIT_DATA, &rlim);
if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
- memAvail =
- min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+ memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
}
ierr = GetResourceLimit(RLIMIT_AS, &rlim);
if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
- memAvail =
- min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+ memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
}
#elif defined(__APPLE__)
struct rlimit rlim;
int ierr;
ierr = getrlimit(RLIMIT_DATA, &rlim);
if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
- memAvail =
- min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+ memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
}
ierr = getrlimit(RLIMIT_RSS, &rlim);
if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
- memAvail =
- min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+ memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
}
#endif
@@ -3709,8 +3698,7 @@ SystemInformationImplementation::GetProcMemoryAvailable(
/**
Get RAM used by all processes in the host, in units of KiB.
*/
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryUsed()
+long long SystemInformationImplementation::GetHostMemoryUsed()
{
#if defined(_WIN32)
# if defined(_MSC_VER) && _MSC_VER < 1300
@@ -3727,39 +3715,38 @@ SystemInformationImplementation::GetHostMemoryUsed()
#elif defined(__linux)
// First try to use MemAvailable, but it only works on newer kernels
const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr };
- SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) };
+ long long values2[2] = { 0 };
int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2);
if (ierr) {
const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:",
nullptr };
- SystemInformation::LongLong values4[4] = { SystemInformation::LongLong(
- 0) };
+ long long values4[4] = { 0 };
ierr = GetFieldsFromFile("/proc/meminfo", names4, values4);
if (ierr) {
return ierr;
}
- SystemInformation::LongLong& memTotal = values4[0];
- SystemInformation::LongLong& memFree = values4[1];
- SystemInformation::LongLong& memBuffers = values4[2];
- SystemInformation::LongLong& memCached = values4[3];
+ long long& memTotal = values4[0];
+ long long& memFree = values4[1];
+ long long& memBuffers = values4[2];
+ long long& memCached = values4[3];
return memTotal - memFree - memBuffers - memCached;
}
- SystemInformation::LongLong& memTotal = values2[0];
- SystemInformation::LongLong& memAvail = values2[1];
+ long long& memTotal = values2[0];
+ long long& memAvail = values2[1];
return memTotal - memAvail;
#elif defined(__APPLE__)
- SystemInformation::LongLong psz = getpagesize();
+ long long psz = getpagesize();
if (psz < 1) {
return -1;
}
const char* names[3] = { "Pages wired down:", "Pages active:", nullptr };
- SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) };
+ long long values[2] = { 0 };
int ierr = GetFieldsFromCommand("vm_stat", names, values);
if (ierr) {
return -1;
}
- SystemInformation::LongLong& vmWired = values[0];
- SystemInformation::LongLong& vmActive = values[1];
+ long long& vmWired = values[0];
+ long long& vmActive = values[1];
return ((vmActive + vmWired) * psz) / 1024;
#else
return 0;
@@ -3770,8 +3757,7 @@ SystemInformationImplementation::GetHostMemoryUsed()
Get system RAM used by the process associated with the given
process id in units of KiB.
*/
-SystemInformation::LongLong
-SystemInformationImplementation::GetProcMemoryUsed()
+long long SystemInformationImplementation::GetProcMemoryUsed()
{
#if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI)
long pid = GetCurrentProcessId();
@@ -3788,14 +3774,14 @@ SystemInformationImplementation::GetProcMemoryUsed()
}
return pmc.WorkingSetSize / 1024;
#elif defined(__linux)
- SystemInformation::LongLong memUsed = 0;
+ long long memUsed = 0;
int ierr = GetFieldFromFile("/proc/self/status", "VmRSS:", memUsed);
if (ierr) {
return -1;
}
return memUsed;
#elif defined(__APPLE__)
- SystemInformation::LongLong memUsed = 0;
+ long long memUsed = 0;
pid_t pid = getpid();
std::ostringstream oss;
oss << "ps -o rss= -p " << pid;
@@ -3859,7 +3845,7 @@ double SystemInformationImplementation::GetLoadAverage()
/**
Get the process id of the running process.
*/
-SystemInformation::LongLong SystemInformationImplementation::GetProcessId()
+long long SystemInformationImplementation::GetProcessId()
{
#if defined(_WIN32)
return GetCurrentProcessId();
@@ -3893,7 +3879,7 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
int wholePath)
{
std::ostringstream oss;
- std::string programStack = "";
+ std::string programStack;
#ifdef KWSYS_SYSTEMINFORMATION_HAS_DBGHELP
(void)wholePath;
@@ -4249,39 +4235,44 @@ 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;
}
/** Get Cycle differences */
-SystemInformation::LongLong
-SystemInformationImplementation::GetCyclesDifference(DELAY_FUNC DelayFunction,
- unsigned int uiParameter)
+long long SystemInformationImplementation::GetCyclesDifference(
+ DELAY_FUNC DelayFunction, unsigned int uiParameter)
{
#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 +4341,7 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
}
/** Works only for windows */
-bool SystemInformationImplementation::IsSMTSupported()
+bool SystemInformationImplementation::IsSMTSupported() const
{
return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1;
}
@@ -4399,12 +4390,12 @@ void SystemInformationImplementation::CPUCountWindows()
DWORD Length = 0;
DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length);
assert(FALSE == rc);
- (void)rc; // Silence unused variable warning in Borland C++ 5.81
+ (void)rc; // Silence unused variable warning
assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
ProcInfo.resize(Length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
rc = pGetLogicalProcessorInformation(&ProcInfo[0], &Length);
assert(rc != FALSE);
- (void)rc; // Silence unused variable warning in Borland C++ 5.81
+ (void)rc; // Silence unused variable warning
}
typedef std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>::iterator
@@ -4432,13 +4423,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;
}
@@ -4638,7 +4629,7 @@ std::string SystemInformationImplementation::ExtractValueFromSysCtl(
size_t pos = this->SysCtlBuffer.find(word);
if (pos != std::string::npos) {
pos = this->SysCtlBuffer.find(": ", pos);
- size_t pos2 = this->SysCtlBuffer.find("\n", pos);
+ size_t pos2 = this->SysCtlBuffer.find('\n', pos);
if (pos != std::string::npos && pos2 != std::string::npos) {
return this->SysCtlBuffer.substr(pos + 2, pos2 - pos - 2);
}
@@ -4733,14 +4724,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 +4914,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;
@@ -5447,19 +5441,19 @@ void SystemInformationImplementation::TrimNewline(std::string& output)
{
// remove \r
std::string::size_type pos = 0;
- while ((pos = output.find("\r", pos)) != std::string::npos) {
+ while ((pos = output.find('\r', pos)) != std::string::npos) {
output.erase(pos);
}
// remove \n
pos = 0;
- while ((pos = output.find("\n", pos)) != std::string::npos) {
+ while ((pos = output.find('\n', pos)) != std::string::npos) {
output.erase(pos);
}
}
/** Return true if the machine is 64 bits */
-bool SystemInformationImplementation::Is64Bits()
+bool SystemInformationImplementation::Is64Bits() const
{
return this->OSIs64Bit;
}
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index fc42e9dc7..c8efd51d0 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -15,13 +15,6 @@ class SystemInformationImplementation;
class @KWSYS_NAMESPACE@_EXPORT SystemInformation
{
-#if @KWSYS_USE_LONG_LONG@
- typedef long long LongLong;
-#elif @KWSYS_USE___INT64@
- typedef __int64 LongLong;
-#else
-# error "No Long Long"
-#endif
friend class SystemInformationImplementation;
SystemInformationImplementation* Implementation;
@@ -104,7 +97,7 @@ public:
bool DoesCPUSupportCPUID();
// Retrieve id of the current running process
- LongLong GetProcessId();
+ long long GetProcessId();
// Retrieve memory information in MiB.
size_t GetTotalVirtualMemory();
@@ -120,7 +113,7 @@ public:
// Retrieve amount of physical memory installed on the system in KiB
// units.
- LongLong GetHostMemoryTotal();
+ long long GetHostMemoryTotal();
// Get total system RAM in units of KiB available colectivley to all
// processes in a process group. An example of a process group
@@ -128,7 +121,7 @@ public:
// parallel. The amount of memory reported may differ from the host
// total if a host wide resource limit is applied. Such reource limits
// are reported to us via an application specified environment variable.
- LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr);
+ long long GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr);
// Get total system RAM in units of KiB available to this process.
// This may differ from the host available if a per-process resource
@@ -136,14 +129,14 @@ public:
// system via rlimit API. Resource limits that are not imposed via
// rlimit API may be reported to us via an application specified
// environment variable.
- LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr,
- const char* procLimitEnvVarName = nullptr);
+ long long GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr,
+ const char* procLimitEnvVarName = nullptr);
// Get the system RAM used by all processes on the host, in units of KiB.
- LongLong GetHostMemoryUsed();
+ long long GetHostMemoryUsed();
// Get system RAM used by this process id in units of KiB.
- LongLong GetProcMemoryUsed();
+ long long GetProcMemoryUsed();
// Return the load average of the machine or -0.0 if it cannot
// be determined.
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index d27081b8c..25705ea28 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -6,9 +6,7 @@
# define _XOPEN_SOURCE_EXTENDED
#endif
-#if defined(_WIN32) && \
- (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || \
- defined(__MINGW32__))
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
# define KWSYS_WINDOWS_DIRS
#else
# if defined(__SUNPRO_CC)
@@ -24,6 +22,7 @@
#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(Encoding.hxx)
+#include <algorithm>
#include <fstream>
#include <iostream>
#include <set>
@@ -49,27 +48,27 @@
# pragma set woff 1375 /* base class destructor not virtual */
#endif
-#include <ctype.h>
-#include <errno.h>
+#include <cctype>
+#include <cerrno>
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#if defined(_WIN32) && !defined(_MSC_VER) && defined(__GNUC__)
# include <strings.h> /* for strcasecmp */
#endif
#ifdef _MSC_VER
-# define umask _umask // Note this is still umask on Borland
+# define umask _umask
#endif
// support for realpath call
#ifndef _WIN32
-# include <limits.h>
+# include <climits>
# include <pwd.h>
# include <sys/ioctl.h>
# include <sys/time.h>
@@ -80,7 +79,7 @@
# include <sys/param.h>
# include <termios.h>
# endif
-# include <signal.h> /* sigprocmask */
+# include <csignal> /* sigprocmask */
#endif
#ifdef __linux
@@ -123,9 +122,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
@@ -153,9 +152,7 @@ public:
}
#endif
-#if defined(_WIN32) && \
- (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || \
- defined(__MINGW32__))
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
# include <direct.h>
# include <io.h>
# define _unlink unlink
@@ -169,13 +166,6 @@ public:
#else
# define KWSYS_SYSTEMTOOLS_MAXPATH 16384
#endif
-#if defined(__WATCOMC__)
-# include <direct.h>
-# define _mkdir mkdir
-# define _rmdir rmdir
-# define _getcwd getcwd
-# define _chdir chdir
-#endif
#if defined(__BEOS__) && !defined(__ZETA__)
# include <be/kernel/OS.h>
@@ -221,11 +211,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)
{
@@ -252,11 +248,7 @@ inline const char* Getcwd(char* buf, unsigned int len)
}
inline int Chdir(const std::string& dir)
{
-# if defined(__BORLANDC__)
- return chdir(dir.c_str());
-# else
return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
-# endif
}
inline void Realpath(const std::string& path, std::string& resolved_path,
std::string* errorMessage = 0)
@@ -295,9 +287,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 +342,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 +360,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 +413,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 +444,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 +480,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 +561,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 +608,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 +618,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);
}
@@ -884,8 +878,12 @@ const char* SystemTools::GetExecutableExtension()
FILE* SystemTools::Fopen(const std::string& file, const char* mode)
{
#ifdef _WIN32
+ // Remove any 'e', which is supported on UNIX, but not Windows.
+ std::wstring trimmedMode = Encoding::ToWide(mode);
+ trimmedMode.erase(std::remove(trimmedMode.begin(), trimmedMode.end(), L'e'),
+ trimmedMode.end());
return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(),
- Encoding::ToWide(mode).c_str());
+ trimmedMode.c_str());
#else
return fopen(file.c_str(), mode);
#endif
@@ -913,29 +911,22 @@ 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) {
- // There is a bug in the Borland Run time library which makes MKDIR
- // return EACCES when it should return EEXISTS
+ if (Mkdir(topdir, mode) != 0) {
// if it is some other error besides directory exists
// then return false
- if ((errno != EEXIST)
-#ifdef __BORLANDC__
- && (errno != EACCES)
-#endif
- ) {
+ if (errno != EEXIST) {
return false;
}
- } else if (mode != nullptr) {
- SystemTools::SetPermissions(topdir, *mode);
}
return true;
@@ -1011,38 +1002,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 +1067,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 +1113,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 +1167,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 +1211,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;
@@ -1435,11 +1427,7 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
// long paths, but _wstat64 rejects paths with '?' in them, thinking
// they are wildcards.
std::wstring const& wpath = Encoding::ToWide(path);
-# if defined(__BORLANDC__)
- return _wstati64(wpath.c_str(), buf);
-# else
return _wstat64(wpath.c_str(), buf);
-# endif
#else
return stat(path.c_str(), buf);
#endif
@@ -1448,15 +1436,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 +1846,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 +1855,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 +1881,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 +2053,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);
}
@@ -2103,7 +2093,7 @@ std::string SystemTools::ConvertToUnixOutputPath(const std::string& path)
ret.erase(pos, 1);
}
// escape spaces and () in the path
- if (ret.find_first_of(" ") != std::string::npos) {
+ if (ret.find_first_of(' ') != std::string::npos) {
std::string result;
char lastch = 1;
for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) {
@@ -2501,8 +2491,8 @@ bool SystemTools::CopyADirectory(const std::string& source,
return false;
}
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
- if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
- strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+ if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+ strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2664,8 +2654,8 @@ bool SystemTools::RemoveADirectory(const std::string& source)
dir.Load(source);
size_t fileNum;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
- if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
- strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+ if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+ strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2797,7 +2787,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 +2795,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 +2825,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 +2833,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 +2988,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 +3106,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 +3129,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("/");
+ 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 +3161,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 +3176,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 +3205,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 +3229,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 +3259,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 +3294,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 = "";
- }
- }
+namespace {
- return SystemTools::CollapseFullPath(in_path, std::string(res_in_base));
-}
-
-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 +3310,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 +3351,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 +3547,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 +3577,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 +3600,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);
@@ -3685,19 +3691,20 @@ std::string SystemTools::GetFilenamePath(const std::string& filename)
std::string fn = 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 {
+ std::string::size_type slash_pos = fn.rfind('/');
+ 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 +3734,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 +3750,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 +3767,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 +3783,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 +3835,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 +4007,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 +4227,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 +4524,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 +4537,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 +4571,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 +4644,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 +4694,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 c4ab9d4f3..5dbb726a0 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -67,7 +67,7 @@ static SystemToolsManager SystemToolsManagerInstance;
// combined using the | operator.
typedef int TestFilePermissions;
#if defined(_WIN32) && !defined(__CYGWIN__)
-// On Windows (VC and Borland), no system header defines these constants...
+// On Windows (VC), no system header defines these constants...
static const TestFilePermissions TEST_FILE_OK = 0;
static const TestFilePermissions TEST_FILE_READ = 4;
static const TestFilePermissions TEST_FILE_WRITE = 2;
@@ -317,11 +317,7 @@ public:
* Cross platform wrapper for stat struct
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
-# if defined(__BORLANDC__)
- typedef struct stati64 Stat_t;
-# else
typedef struct _stat64 Stat_t;
-# endif
#else
typedef struct stat Stat_t;
#endif
@@ -411,11 +407,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
@@ -549,12 +545,13 @@ public:
*/
/**
- * Open a file considering unicode.
+ * Open a file considering unicode. On Windows, if 'e' is present in
+ * mode it is first discarded.
*/
static FILE* Fopen(const std::string& file, const char* mode);
/**
- * Visual C++ does not define mode_t (note that Borland does, however).
+ * Visual C++ does not define mode_t.
*/
#if defined(_MSC_VER)
typedef unsigned short mode_t;
@@ -677,6 +674,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 +871,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 +937,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 +983,6 @@ private:
return &SystemToolsManagerInstance;
}
- static SystemToolsStatic* Statics;
friend class SystemToolsStatic;
friend class SystemToolsManager;
};
diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in
deleted file mode 100644
index 8626c2aa2..000000000
--- a/Source/kwsys/hash_fun.hxx.in
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_fun_hxx
-#define @KWSYS_NAMESPACE@_hash_fun_hxx
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#include <stddef.h> // size_t
-#include <string>
-
-namespace @KWSYS_NAMESPACE@ {
-
-template <class _Key>
-struct hash
-{
-};
-
-inline size_t _stl_hash_string(const char* __s)
-{
- unsigned long __h = 0;
- for (; *__s; ++__s)
- __h = 5 * __h + *__s;
-
- return size_t(__h);
-}
-
-template <>
-struct hash<char*>
-{
- size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
-};
-
-template <>
-struct hash<const char*>
-{
- size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
-};
-
-template <>
-struct hash<std::string>
-{
- size_t operator()(const std::string& __s) const
- {
- return _stl_hash_string(__s.c_str());
- }
-};
-
-#if !defined(__BORLANDC__)
-template <>
-struct hash<const std::string>
-{
- size_t operator()(const std::string& __s) const
- {
- return _stl_hash_string(__s.c_str());
- }
-};
-#endif
-
-template <>
-struct hash<char>
-{
- size_t operator()(char __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned char>
-{
- size_t operator()(unsigned char __x) const { return __x; }
-};
-
-template <>
-struct hash<signed char>
-{
- size_t operator()(unsigned char __x) const { return __x; }
-};
-
-template <>
-struct hash<short>
-{
- size_t operator()(short __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned short>
-{
- size_t operator()(unsigned short __x) const { return __x; }
-};
-
-template <>
-struct hash<int>
-{
- size_t operator()(int __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned int>
-{
- size_t operator()(unsigned int __x) const { return __x; }
-};
-
-template <>
-struct hash<long>
-{
- size_t operator()(long __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned long>
-{
- size_t operator()(unsigned long __x) const { return __x; }
-};
-
-// use long long or __int64
-#if @KWSYS_USE_LONG_LONG@
-template <>
-struct hash<long long>
-{
- size_t operator()(long long __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned long long>
-{
- size_t operator()(unsigned long long __x) const { return __x; }
-};
-#elif @KWSYS_USE___INT64@
-template <>
-struct hash<__int64>
-{
- size_t operator()(__int64 __x) const { return __x; }
-};
-template <>
-struct hash<unsigned __int64>
-{
- size_t operator()(unsigned __int64 __x) const { return __x; }
-};
-#endif // use long long or __int64
-
-} // namespace @KWSYS_NAMESPACE@
-
-#endif
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
deleted file mode 100644
index 5f04e9c16..000000000
--- a/Source/kwsys/hash_map.hxx.in
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_map_hxx
-#define @KWSYS_NAMESPACE@_hash_map_hxx
-
-#include <@KWSYS_NAMESPACE@/hashtable.hxx>
-
-#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-
-#include <functional> // equal_to
-
-#if defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning(disable : 4284)
-# pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-# pragma set woff 1174
-# pragma set woff 1375
-#endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-// select1st is an extension: it is not part of the standard.
-template <class T1, class T2>
-struct hash_select1st
-{
- const T1& operator()(const std::pair<T1, T2>& __x) const
- {
- return __x.first;
- }
-};
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
- class _EqualKey = std::equal_to<_Key>,
- class _Alloc = std::allocator<char> >
-class hash_map;
-
-template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
-bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&,
- const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&);
-
-template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_map
-{
-private:
- typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
- hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
- _Ht;
- _Ht _M_ht;
-
-public:
- typedef typename _Ht::key_type key_type;
- typedef _Tp data_type;
- typedef _Tp mapped_type;
- typedef typename _Ht::value_type value_type;
- typedef typename _Ht::hasher hasher;
- typedef typename _Ht::key_equal key_equal;
-
- typedef typename _Ht::size_type size_type;
- typedef typename _Ht::difference_type difference_type;
- typedef typename _Ht::pointer pointer;
- typedef typename _Ht::const_pointer const_pointer;
- typedef typename _Ht::reference reference;
- typedef typename _Ht::const_reference const_reference;
-
- typedef typename _Ht::iterator iterator;
- typedef typename _Ht::const_iterator const_iterator;
-
- typedef typename _Ht::allocator_type allocator_type;
-
- hasher hash_funct() const { return _M_ht.hash_funct(); }
- key_equal key_eq() const { return _M_ht.key_eq(); }
- allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
- hash_map()
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- }
- explicit hash_map(size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- }
- hash_map(size_type __n, const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- }
- hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- }
-
- template <class _InputIterator>
- hash_map(_InputIterator __f, _InputIterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- _M_ht.insert_unique(__f, __l);
- }
-
-public:
- size_type size() const { return _M_ht.size(); }
- size_type max_size() const { return _M_ht.max_size(); }
- bool empty() const { return _M_ht.empty(); }
- void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
-
- friend bool operator==<>(const hash_map&, const hash_map&);
-
- iterator begin() { return _M_ht.begin(); }
- iterator end() { return _M_ht.end(); }
- const_iterator begin() const { return _M_ht.begin(); }
- const_iterator end() const { return _M_ht.end(); }
-
-public:
- std::pair<iterator, bool> insert(const value_type& __obj)
- {
- return _M_ht.insert_unique(__obj);
- }
- template <class _InputIterator>
- void insert(_InputIterator __f, _InputIterator __l)
- {
- _M_ht.insert_unique(__f, __l);
- }
- std::pair<iterator, bool> insert_noresize(const value_type& __obj)
- {
- return _M_ht.insert_unique_noresize(__obj);
- }
-
- iterator find(const key_type& __key) { return _M_ht.find(__key); }
- const_iterator find(const key_type& __key) const
- {
- return _M_ht.find(__key);
- }
-
- _Tp& operator[](const key_type& __key)
- {
- return _M_ht.find_or_insert(value_type(__key, _Tp())).second;
- }
-
- size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
- std::pair<iterator, iterator> equal_range(const key_type& __key)
- {
- return _M_ht.equal_range(__key);
- }
- std::pair<const_iterator, const_iterator> equal_range(
- const key_type& __key) const
- {
- return _M_ht.equal_range(__key);
- }
-
- size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
- void erase(iterator __it) { _M_ht.erase(__it); }
- void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
- void clear() { _M_ht.clear(); }
-
- void resize(size_type __hint) { _M_ht.resize(__hint); }
- size_type bucket_count() const { return _M_ht.bucket_count(); }
- size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
- size_type elems_in_bucket(size_type __n) const
- {
- return _M_ht.elems_in_bucket(__n);
- }
-};
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-bool operator==(const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
- const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
- return __hm1._M_ht == __hm2._M_ht;
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline bool operator!=(
- const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
- const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
- return !(__hm1 == __hm2);
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline void swap(hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
- hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
- __hm1.swap(__hm2);
-}
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
- class _EqualKey = std::equal_to<_Key>,
- class _Alloc = std::allocator<char> >
-class hash_multimap;
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
- const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2);
-
-template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_multimap
-{
-private:
- typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
- hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
- _Ht;
- _Ht _M_ht;
-
-public:
- typedef typename _Ht::key_type key_type;
- typedef _Tp data_type;
- typedef _Tp mapped_type;
- typedef typename _Ht::value_type value_type;
- typedef typename _Ht::hasher hasher;
- typedef typename _Ht::key_equal key_equal;
-
- typedef typename _Ht::size_type size_type;
- typedef typename _Ht::difference_type difference_type;
- typedef typename _Ht::pointer pointer;
- typedef typename _Ht::const_pointer const_pointer;
- typedef typename _Ht::reference reference;
- typedef typename _Ht::const_reference const_reference;
-
- typedef typename _Ht::iterator iterator;
- typedef typename _Ht::const_iterator const_iterator;
-
- typedef typename _Ht::allocator_type allocator_type;
-
- hasher hash_funct() const { return _M_ht.hash_funct(); }
- key_equal key_eq() const { return _M_ht.key_eq(); }
- allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
- hash_multimap()
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- }
- explicit hash_multimap(size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- }
- hash_multimap(size_type __n, const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- }
- hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- }
-
- template <class _InputIterator>
- hash_multimap(_InputIterator __f, _InputIterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- _M_ht.insert_equal(__f, __l);
- }
-
-public:
- size_type size() const { return _M_ht.size(); }
- size_type max_size() const { return _M_ht.max_size(); }
- bool empty() const { return _M_ht.empty(); }
- void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
-
- friend bool operator==<>(const hash_multimap&, const hash_multimap&);
-
- iterator begin() { return _M_ht.begin(); }
- iterator end() { return _M_ht.end(); }
- const_iterator begin() const { return _M_ht.begin(); }
- const_iterator end() const { return _M_ht.end(); }
-
-public:
- iterator insert(const value_type& __obj)
- {
- return _M_ht.insert_equal(__obj);
- }
- template <class _InputIterator>
- void insert(_InputIterator __f, _InputIterator __l)
- {
- _M_ht.insert_equal(__f, __l);
- }
- iterator insert_noresize(const value_type& __obj)
- {
- return _M_ht.insert_equal_noresize(__obj);
- }
-
- iterator find(const key_type& __key) { return _M_ht.find(__key); }
- const_iterator find(const key_type& __key) const
- {
- return _M_ht.find(__key);
- }
-
- size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
- std::pair<iterator, iterator> equal_range(const key_type& __key)
- {
- return _M_ht.equal_range(__key);
- }
- std::pair<const_iterator, const_iterator> equal_range(
- const key_type& __key) const
- {
- return _M_ht.equal_range(__key);
- }
-
- size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
- void erase(iterator __it) { _M_ht.erase(__it); }
- void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
- void clear() { _M_ht.clear(); }
-
-public:
- void resize(size_type __hint) { _M_ht.resize(__hint); }
- size_type bucket_count() const { return _M_ht.bucket_count(); }
- size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
- size_type elems_in_bucket(size_type __n) const
- {
- return _M_ht.elems_in_bucket(__n);
- }
-};
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
- const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
-{
- return __hm1._M_ht == __hm2._M_ht;
-}
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-inline bool operator!=(
- const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
- const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
-{
- return !(__hm1 == __hm2);
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline void swap(hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
- hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
- __hm1.swap(__hm2);
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-# pragma reset woff 1174
-# pragma reset woff 1375
-#endif
-
-#if defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
deleted file mode 100644
index f4a37eebd..000000000
--- a/Source/kwsys/hash_set.hxx.in
+++ /dev/null
@@ -1,392 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_set_hxx
-#define @KWSYS_NAMESPACE@_hash_set_hxx
-
-#include <@KWSYS_NAMESPACE@/hashtable.hxx>
-
-#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-
-#include <functional> // equal_to
-
-#if defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning(disable : 4284)
-# pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-# pragma set woff 1174
-# pragma set woff 1375
-#endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-// identity is an extension: it is not part of the standard.
-template <class _Tp>
-struct _Identity
-{
- const _Tp& operator()(const _Tp& __x) const { return __x; }
-};
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Value, class _HashFcn = hash<_Value>,
- class _EqualKey = std::equal_to<_Value>,
- class _Alloc = std::allocator<char> >
-class hash_set;
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2);
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_set
-{
-private:
- typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
- _Alloc>
- _Ht;
- _Ht _M_ht;
-
-public:
- typedef typename _Ht::key_type key_type;
- typedef typename _Ht::value_type value_type;
- typedef typename _Ht::hasher hasher;
- typedef typename _Ht::key_equal key_equal;
-
- typedef typename _Ht::size_type size_type;
- typedef typename _Ht::difference_type difference_type;
- typedef typename _Ht::const_pointer pointer;
- typedef typename _Ht::const_pointer const_pointer;
- typedef typename _Ht::const_reference reference;
- typedef typename _Ht::const_reference const_reference;
-
- typedef typename _Ht::const_iterator iterator;
- typedef typename _Ht::const_iterator const_iterator;
-
- typedef typename _Ht::allocator_type allocator_type;
-
- hasher hash_funct() const { return _M_ht.hash_funct(); }
- key_equal key_eq() const { return _M_ht.key_eq(); }
- allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
- hash_set()
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- }
- explicit hash_set(size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- }
- hash_set(size_type __n, const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- }
- hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- }
-
- template <class _InputIterator>
- hash_set(_InputIterator __f, _InputIterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- _M_ht.insert_unique(__f, __l);
- }
- template <class _InputIterator>
- hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- _M_ht.insert_unique(__f, __l);
- }
-
-public:
- size_type size() const { return _M_ht.size(); }
- size_type max_size() const { return _M_ht.max_size(); }
- bool empty() const { return _M_ht.empty(); }
- void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); }
-
- friend bool operator==<>(const hash_set&, const hash_set&);
-
- iterator begin() const { return _M_ht.begin(); }
- iterator end() const { return _M_ht.end(); }
-
-public:
- std::pair<iterator, bool> insert(const value_type& __obj)
- {
- typedef typename _Ht::iterator _Ht_iterator;
- std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
- return std::pair<iterator, bool>(__p.first, __p.second);
- }
- template <class _InputIterator>
- void insert(_InputIterator __f, _InputIterator __l)
- {
- _M_ht.insert_unique(__f, __l);
- }
- std::pair<iterator, bool> insert_noresize(const value_type& __obj)
- {
- typedef typename _Ht::iterator _Ht_iterator;
- std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique_noresize(__obj);
- return std::pair<iterator, bool>(__p.first, __p.second);
- }
-
- iterator find(const key_type& __key) const { return _M_ht.find(__key); }
-
- size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
- std::pair<iterator, iterator> equal_range(const key_type& __key) const
- {
- return _M_ht.equal_range(__key);
- }
-
- size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
- void erase(iterator __it) { _M_ht.erase(__it); }
- void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
- void clear() { _M_ht.clear(); }
-
-public:
- void resize(size_type __hint) { _M_ht.resize(__hint); }
- size_type bucket_count() const { return _M_ht.bucket_count(); }
- size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
- size_type elems_in_bucket(size_type __n) const
- {
- return _M_ht.elems_in_bucket(__n);
- }
-};
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- return __hs1._M_ht == __hs2._M_ht;
-}
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-inline bool operator!=(
- const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- return !(__hs1 == __hs2);
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
- hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- __hs1.swap(__hs2);
-}
-
-template <class _Value, class _HashFcn = hash<_Value>,
- class _EqualKey = std::equal_to<_Value>,
- class _Alloc = std::allocator<char> >
-class hash_multiset;
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2);
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_multiset
-{
-private:
- typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
- _Alloc>
- _Ht;
- _Ht _M_ht;
-
-public:
- typedef typename _Ht::key_type key_type;
- typedef typename _Ht::value_type value_type;
- typedef typename _Ht::hasher hasher;
- typedef typename _Ht::key_equal key_equal;
-
- typedef typename _Ht::size_type size_type;
- typedef typename _Ht::difference_type difference_type;
- typedef typename _Ht::const_pointer pointer;
- typedef typename _Ht::const_pointer const_pointer;
- typedef typename _Ht::const_reference reference;
- typedef typename _Ht::const_reference const_reference;
-
- typedef typename _Ht::const_iterator iterator;
- typedef typename _Ht::const_iterator const_iterator;
-
- typedef typename _Ht::allocator_type allocator_type;
-
- hasher hash_funct() const { return _M_ht.hash_funct(); }
- key_equal key_eq() const { return _M_ht.key_eq(); }
- allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
- hash_multiset()
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- }
- explicit hash_multiset(size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- }
- hash_multiset(size_type __n, const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- }
- hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- }
-
- template <class _InputIterator>
- hash_multiset(_InputIterator __f, _InputIterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- {
- _M_ht.insert_equal(__f, __l);
- }
- template <class _InputIterator>
- hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- {
- _M_ht.insert_equal(__f, __l);
- }
-
-public:
- size_type size() const { return _M_ht.size(); }
- size_type max_size() const { return _M_ht.max_size(); }
- bool empty() const { return _M_ht.empty(); }
- void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); }
-
- friend bool operator==<>(const hash_multiset&, const hash_multiset&);
-
- iterator begin() const { return _M_ht.begin(); }
- iterator end() const { return _M_ht.end(); }
-
-public:
- iterator insert(const value_type& __obj)
- {
- return _M_ht.insert_equal(__obj);
- }
- template <class _InputIterator>
- void insert(_InputIterator __f, _InputIterator __l)
- {
- _M_ht.insert_equal(__f, __l);
- }
- iterator insert_noresize(const value_type& __obj)
- {
- return _M_ht.insert_equal_noresize(__obj);
- }
-
- iterator find(const key_type& __key) const { return _M_ht.find(__key); }
-
- size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
- std::pair<iterator, iterator> equal_range(const key_type& __key) const
- {
- return _M_ht.equal_range(__key);
- }
-
- size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
- void erase(iterator __it) { _M_ht.erase(__it); }
- void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
- void clear() { _M_ht.clear(); }
-
-public:
- void resize(size_type __hint) { _M_ht.resize(__hint); }
- size_type bucket_count() const { return _M_ht.bucket_count(); }
- size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
- size_type elems_in_bucket(size_type __n) const
- {
- return _M_ht.elems_in_bucket(__n);
- }
-};
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- return __hs1._M_ht == __hs2._M_ht;
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline bool operator!=(
- const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
- const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- return !(__hs1 == __hs2);
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
- hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
- __hs1.swap(__hs2);
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-# pragma reset woff 1174
-# pragma reset woff 1375
-#endif
-
-#if defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
deleted file mode 100644
index 8c4b0025f..000000000
--- a/Source/kwsys/hashtable.hxx.in
+++ /dev/null
@@ -1,995 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifdef __BORLANDC__
-# pragma warn - 8027 /* 'for' not inlined. */
-# pragma warn - 8026 /* 'exception' not inlined. */
-#endif
-
-#ifndef @KWSYS_NAMESPACE@_hashtable_hxx
-# define @KWSYS_NAMESPACE@_hashtable_hxx
-
-# include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-# include <algorithm> // lower_bound
-# include <iterator> // iterator_traits
-# include <memory> // allocator
-# include <stddef.h> // size_t
-# include <utility> // pair
-# include <vector> // vector
-
-# if defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning(disable : 4284)
-# pragma warning(disable : 4786)
-# pragma warning(disable : 4512) /* no assignment operator for class */
-# endif
-# if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 3970 /* pointer to int conversion */ 3321 3968
-# endif
-
-// In C++11, clang will warn about using dynamic exception specifications
-// as they are deprecated. But as this class is trying to faithfully
-// mimic unordered_set and unordered_map, we want to keep the 'throw()'
-// decorations below. So we suppress the warning.
-# if defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated")
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wdeprecated"
-# endif
-# endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-template <class _Val>
-struct _Hashtable_node
-{
- _Hashtable_node* _M_next;
- _Val _M_val;
- void public_method_to_quiet_warning_about_all_methods_private();
-
-private:
- void operator=(_Hashtable_node<_Val> const&) = delete;
-};
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc = std::allocator<char> >
-class hashtable;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc>
-struct _Hashtable_iterator;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc>
-struct _Hashtable_const_iterator;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc>
-struct _Hashtable_iterator
-{
- typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
- _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
-
- typedef std::forward_iterator_tag iterator_category;
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef _Val& reference;
- typedef _Val* pointer;
-
- _Node* _M_cur;
- _Hashtable* _M_ht;
-
- _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
- : _M_cur(__n)
- , _M_ht(__tab)
- {
- }
- _Hashtable_iterator() {}
- reference operator*() const { return _M_cur->_M_val; }
- pointer operator->() const { return &(operator*()); }
- iterator& operator++();
- iterator operator++(int);
- bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; }
- bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; }
-};
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc>
-struct _Hashtable_const_iterator
-{
- typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
- _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
-
- typedef std::forward_iterator_tag iterator_category;
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef const _Val& reference;
- typedef const _Val* pointer;
-
- const _Node* _M_cur;
- const _Hashtable* _M_ht;
-
- _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
- : _M_cur(__n)
- , _M_ht(__tab)
- {
- }
- _Hashtable_const_iterator() {}
- _Hashtable_const_iterator(const iterator& __it)
- : _M_cur(__it._M_cur)
- , _M_ht(__it._M_ht)
- {
- }
- reference operator*() const { return _M_cur->_M_val; }
- pointer operator->() const { return &(operator*()); }
- const_iterator& operator++();
- const_iterator operator++(int);
- bool operator==(const const_iterator& __it) const
- {
- return _M_cur == __it._M_cur;
- }
- bool operator!=(const const_iterator& __it) const
- {
- return _M_cur != __it._M_cur;
- }
-};
-
-// Note: assumes long is at least 32 bits.
-enum
-{
- _stl_num_primes = 31
-};
-
-// create a function with a static local to that function that returns
-// the static
-static inline const unsigned long* get_stl_prime_list()
-{
-
- static const unsigned long _stl_prime_list[_stl_num_primes] = {
- 5ul, 11ul, 23ul, 53ul, 97ul,
- 193ul, 389ul, 769ul, 1543ul, 3079ul,
- 6151ul, 12289ul, 24593ul, 49157ul, 98317ul,
- 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul,
- 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul,
- 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul,
- 4294967291ul
- };
-
- return &_stl_prime_list[0];
-}
-
-static inline size_t _stl_next_prime(size_t __n)
-{
- const unsigned long* __first = get_stl_prime_list();
- const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes;
- const unsigned long* pos = std::lower_bound(__first, __last, __n);
- return pos == __last ? *(__last - 1) : *pos;
-}
-
-// Forward declaration of operator==.
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-class hashtable;
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
-
-// Hashtables handle allocators a bit differently than other containers
-// do. If we're using standard-conforming allocators, then a hashtable
-// unconditionally has a member variable to hold its allocator, even if
-// it so happens that all instances of the allocator type are identical.
-// This is because, for hashtables, this extra storage is negligible.
-// Additionally, a base class wouldn't serve any other purposes; it
-// wouldn't, for example, simplify the exception-handling code.
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
- class _EqualKey, class _Alloc>
-class hashtable
-{
-public:
- typedef _Key key_type;
- typedef _Val value_type;
- typedef _HashFcn hasher;
- typedef _EqualKey key_equal;
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
- typedef value_type& reference;
- typedef const value_type& const_reference;
-
- hasher hash_funct() const { return _M_hash; }
- key_equal key_eq() const { return _M_equals; }
-
-private:
- typedef _Hashtable_node<_Val> _Node;
-
-public:
- typedef typename _Alloc::template rebind<_Val>::other allocator_type;
- allocator_type get_allocator() const { return _M_node_allocator; }
-
-private:
- typedef
- typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
- typedef
- typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
- typedef std::vector<_Node*, _M_node_ptr_allocator_type> _M_buckets_type;
-
-private:
- _M_node_allocator_type _M_node_allocator;
- hasher _M_hash;
- key_equal _M_equals;
- _ExtractKey _M_get_key;
- _M_buckets_type _M_buckets;
- size_type _M_num_elements;
-
- _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
- void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
-
-public:
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
- _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>
- const_iterator;
-
- friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>;
- friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
- _EqualKey, _Alloc>;
-
-public:
- hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
- const _ExtractKey& __ext,
- const allocator_type& __a = allocator_type())
- : _M_node_allocator(__a)
- , _M_hash(__hf)
- , _M_equals(__eql)
- , _M_get_key(__ext)
- , _M_buckets(__a)
- , _M_num_elements(0)
- {
- _M_initialize_buckets(__n);
- }
-
- hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
- const allocator_type& __a = allocator_type())
- : _M_node_allocator(__a)
- , _M_hash(__hf)
- , _M_equals(__eql)
- , _M_get_key(_ExtractKey())
- , _M_buckets(__a)
- , _M_num_elements(0)
- {
- _M_initialize_buckets(__n);
- }
-
- hashtable(const hashtable& __ht)
- : _M_node_allocator(__ht.get_allocator())
- , _M_hash(__ht._M_hash)
- , _M_equals(__ht._M_equals)
- , _M_get_key(__ht._M_get_key)
- , _M_buckets(__ht.get_allocator())
- , _M_num_elements(0)
- {
- _M_copy_from(__ht);
- }
-
- hashtable& operator=(const hashtable& __ht)
- {
- if (&__ht != this) {
- clear();
- _M_hash = __ht._M_hash;
- _M_equals = __ht._M_equals;
- _M_get_key = __ht._M_get_key;
- _M_copy_from(__ht);
- }
- return *this;
- }
-
- ~hashtable() { clear(); }
-
- size_type size() const { return _M_num_elements; }
- size_type max_size() const { return size_type(-1); }
- bool empty() const { return size() == 0; }
-
- void swap(hashtable& __ht)
- {
- std::swap(_M_hash, __ht._M_hash);
- std::swap(_M_equals, __ht._M_equals);
- std::swap(_M_get_key, __ht._M_get_key);
- _M_buckets.swap(__ht._M_buckets);
- std::swap(_M_num_elements, __ht._M_num_elements);
- }
-
- iterator begin()
- {
- for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
- if (_M_buckets[__n])
- return iterator(_M_buckets[__n], this);
- return end();
- }
-
- iterator end() { return iterator(nullptr, this); }
-
- const_iterator begin() const
- {
- for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
- if (_M_buckets[__n])
- return const_iterator(_M_buckets[__n], this);
- return end();
- }
-
- const_iterator end() const { return const_iterator(nullptr, this); }
-
- friend bool operator==<>(const hashtable&, const hashtable&);
-
-public:
- size_type bucket_count() const { return _M_buckets.size(); }
-
- size_type max_bucket_count() const
- {
- return get_stl_prime_list()[(int)_stl_num_primes - 1];
- }
-
- size_type elems_in_bucket(size_type __bucket) const
- {
- size_type __result = 0;
- for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
- __result += 1;
- return __result;
- }
-
- std::pair<iterator, bool> insert_unique(const value_type& __obj)
- {
- resize(_M_num_elements + 1);
- return insert_unique_noresize(__obj);
- }
-
- iterator insert_equal(const value_type& __obj)
- {
- resize(_M_num_elements + 1);
- return insert_equal_noresize(__obj);
- }
-
- std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
- iterator insert_equal_noresize(const value_type& __obj);
-
- template <class _InputIterator>
- void insert_unique(_InputIterator __f, _InputIterator __l)
- {
- insert_unique(
- __f, __l,
- typename std::iterator_traits<_InputIterator>::iterator_category());
- }
-
- template <class _InputIterator>
- void insert_equal(_InputIterator __f, _InputIterator __l)
- {
- insert_equal(
- __f, __l,
- typename std::iterator_traits<_InputIterator>::iterator_category());
- }
-
- template <class _InputIterator>
- void insert_unique(_InputIterator __f, _InputIterator __l,
- std::input_iterator_tag)
- {
- for (; __f != __l; ++__f)
- insert_unique(*__f);
- }
-
- template <class _InputIterator>
- void insert_equal(_InputIterator __f, _InputIterator __l,
- std::input_iterator_tag)
- {
- for (; __f != __l; ++__f)
- insert_equal(*__f);
- }
-
- template <class _ForwardIterator>
- void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
- std::forward_iterator_tag)
- {
- size_type __n = 0;
- std::distance(__f, __l, __n);
- resize(_M_num_elements + __n);
- for (; __n > 0; --__n, ++__f)
- insert_unique_noresize(*__f);
- }
-
- template <class _ForwardIterator>
- void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
- std::forward_iterator_tag)
- {
- size_type __n = 0;
- std::distance(__f, __l, __n);
- resize(_M_num_elements + __n);
- for (; __n > 0; --__n, ++__f)
- insert_equal_noresize(*__f);
- }
-
- reference find_or_insert(const value_type& __obj);
-
- iterator find(const key_type& __key)
- {
- size_type __n = _M_bkt_num_key(__key);
- _Node* __first;
- for (__first = _M_buckets[__n];
- __first && !_M_equals(_M_get_key(__first->_M_val), __key);
- __first = __first->_M_next) {
- }
- return iterator(__first, this);
- }
-
- const_iterator find(const key_type& __key) const
- {
- size_type __n = _M_bkt_num_key(__key);
- const _Node* __first;
- for (__first = _M_buckets[__n];
- __first && !_M_equals(_M_get_key(__first->_M_val), __key);
- __first = __first->_M_next) {
- }
- return const_iterator(__first, this);
- }
-
- size_type count(const key_type& __key) const
- {
- const size_type __n = _M_bkt_num_key(__key);
- size_type __result = 0;
-
- for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), __key))
- ++__result;
- return __result;
- }
-
- std::pair<iterator, iterator> equal_range(const key_type& __key);
-
- std::pair<const_iterator, const_iterator> equal_range(
- const key_type& __key) const;
-
- size_type erase(const key_type& __key);
- void erase(const iterator& __it);
- void erase(iterator __first, iterator __last);
-
- void erase(const const_iterator& __it);
- void erase(const_iterator __first, const_iterator __last);
-
- void resize(size_type __num_elements_hint);
- void clear();
-
-private:
- size_type _M_next_size(size_type __n) const { return _stl_next_prime(__n); }
-
- void _M_initialize_buckets(size_type __n)
- {
- const size_type __n_buckets = _M_next_size(__n);
- _M_buckets.reserve(__n_buckets);
- _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr);
- _M_num_elements = 0;
- }
-
- size_type _M_bkt_num_key(const key_type& __key) const
- {
- return _M_bkt_num_key(__key, _M_buckets.size());
- }
-
- size_type _M_bkt_num(const value_type& __obj) const
- {
- return _M_bkt_num_key(_M_get_key(__obj));
- }
-
- size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
- {
- return _M_hash(__key) % __n;
- }
-
- size_type _M_bkt_num(const value_type& __obj, size_t __n) const
- {
- return _M_bkt_num_key(_M_get_key(__obj), __n);
- }
-
- void construct(_Val* p, const _Val& v) { new (p) _Val(v); }
- void destroy(_Val* p)
- {
- (void)p;
- p->~_Val();
- }
-
- _Node* _M_new_node(const value_type& __obj)
- {
- _Node* __n = _M_get_node();
- __n->_M_next = nullptr;
- try {
- construct(&__n->_M_val, __obj);
- return __n;
- } catch (...) {
- _M_put_node(__n);
- throw;
- }
- }
-
- void _M_delete_node(_Node* __n)
- {
- destroy(&__n->_M_val);
- _M_put_node(__n);
- }
-
- void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
- void _M_erase_bucket(const size_type __n, _Node* __last);
-
- void _M_copy_from(const hashtable& __ht);
-};
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
-{
- const _Node* __old = _M_cur;
- _M_cur = _M_cur->_M_next;
- if (!_M_cur) {
- size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
- while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
- _M_cur = _M_ht->_M_buckets[__bucket];
- }
- return *this;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
-inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
-{
- iterator __tmp = *this;
- ++*this;
- return __tmp;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
-{
- const _Node* __old = _M_cur;
- _M_cur = _M_cur->_M_next;
- if (!_M_cur) {
- size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
- while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
- _M_cur = _M_ht->_M_buckets[__bucket];
- }
- return *this;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
- class _All>
-inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
-{
- const_iterator __tmp = *this;
- ++*this;
- return __tmp;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-{
- typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
- if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
- return false;
- for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
- _Node* __cur1 = __ht1._M_buckets[__n];
- _Node* __cur2 = __ht2._M_buckets[__n];
- for (; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
- __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {
- }
- if (__cur1 || __cur2)
- return false;
- }
- return true;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
- const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-{
- return !(__ht1 == __ht2);
-}
-
-template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
- class _All>
-inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
- hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
-{
- __ht1.swap(__ht2);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_unique_noresize(
- const value_type& __obj)
-{
- const size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- return std::pair<iterator, bool>(iterator(__cur, this), false);
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return std::pair<iterator, bool>(iterator(__tmp, this), true);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_equal_noresize(
- const value_type& __obj)
-{
- const size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __cur->_M_next;
- __cur->_M_next = __tmp;
- ++_M_num_elements;
- return iterator(__tmp, this);
- }
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return iterator(__tmp, this);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::find_or_insert(
- const value_type& __obj)
-{
- resize(_M_num_elements + 1);
-
- size_type __n = _M_bkt_num(__obj);
- _Node* __first = _M_buckets[__n];
-
- for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
- if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- return __cur->_M_val;
-
- _Node* __tmp = _M_new_node(__obj);
- __tmp->_M_next = __first;
- _M_buckets[__n] = __tmp;
- ++_M_num_elements;
- return __tmp->_M_val;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key)
-{
- typedef std::pair<iterator, iterator> _Pii;
- const size_type __n = _M_bkt_num_key(__key);
-
- for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
- if (_M_equals(_M_get_key(__first->_M_val), __key)) {
- for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
- if (!_M_equals(_M_get_key(__cur->_M_val), __key))
- return _Pii(iterator(__first, this), iterator(__cur, this));
- for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
- if (_M_buckets[__m])
- return _Pii(iterator(__first, this),
- iterator(_M_buckets[__m], this));
- return _Pii(iterator(__first, this), end());
- }
- return _Pii(end(), end());
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
- typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(
- const key_type& __key) const
-{
- typedef std::pair<const_iterator, const_iterator> _Pii;
- const size_type __n = _M_bkt_num_key(__key);
-
- for (const _Node* __first = _M_buckets[__n]; __first;
- __first = __first->_M_next) {
- if (_M_equals(_M_get_key(__first->_M_val), __key)) {
- for (const _Node* __cur = __first->_M_next; __cur;
- __cur = __cur->_M_next)
- if (!_M_equals(_M_get_key(__cur->_M_val), __key))
- return _Pii(const_iterator(__first, this),
- const_iterator(__cur, this));
- for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
- if (_M_buckets[__m])
- return _Pii(const_iterator(__first, this),
- const_iterator(_M_buckets[__m], this));
- return _Pii(const_iterator(__first, this), end());
- }
- }
- return _Pii(end(), end());
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key)
-{
- const size_type __n = _M_bkt_num_key(__key);
- _Node* __first = _M_buckets[__n];
- size_type __erased = 0;
-
- if (__first) {
- _Node* __cur = __first;
- _Node* __next = __cur->_M_next;
- while (__next) {
- if (_M_equals(_M_get_key(__next->_M_val), __key)) {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- __next = __cur->_M_next;
- ++__erased;
- --_M_num_elements;
- } else {
- __cur = __next;
- __next = __cur->_M_next;
- }
- }
- if (_M_equals(_M_get_key(__first->_M_val), __key)) {
- _M_buckets[__n] = __first->_M_next;
- _M_delete_node(__first);
- ++__erased;
- --_M_num_elements;
- }
- }
- return __erased;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it)
-{
- _Node* __p = __it._M_cur;
- if (__p) {
- const size_type __n = _M_bkt_num(__p->_M_val);
- _Node* __cur = _M_buckets[__n];
-
- if (__cur == __p) {
- _M_buckets[__n] = __cur->_M_next;
- _M_delete_node(__cur);
- --_M_num_elements;
- } else {
- _Node* __next = __cur->_M_next;
- while (__next) {
- if (__next == __p) {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- --_M_num_elements;
- break;
- } else {
- __cur = __next;
- __next = __cur->_M_next;
- }
- }
- }
- }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first,
- iterator __last)
-{
- size_type __f_bucket =
- __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
- size_type __l_bucket =
- __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
-
- if (__first._M_cur == __last._M_cur)
- return;
- else if (__f_bucket == __l_bucket)
- _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
- else {
- _M_erase_bucket(__f_bucket, __first._M_cur, nullptr);
- for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
- _M_erase_bucket(__n, nullptr);
- if (__l_bucket != _M_buckets.size())
- _M_erase_bucket(__l_bucket, __last._M_cur);
- }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
- const_iterator __first, const_iterator __last)
-{
- erase(iterator(const_cast<_Node*>(__first._M_cur),
- const_cast<hashtable*>(__first._M_ht)),
- iterator(const_cast<_Node*>(__last._M_cur),
- const_cast<hashtable*>(__last._M_ht)));
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
- const const_iterator& __it)
-{
- erase(iterator(const_cast<_Node*>(__it._M_cur),
- const_cast<hashtable*>(__it._M_ht)));
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(
- size_type __num_elements_hint)
-{
- const size_type __old_n = _M_buckets.size();
- if (__num_elements_hint > __old_n) {
- const size_type __n = _M_next_size(__num_elements_hint);
- if (__n > __old_n) {
- _M_buckets_type __tmp(__n, (_Node*)(nullptr),
- _M_buckets.get_allocator());
- try {
- for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
- _Node* __first = _M_buckets[__bucket];
- while (__first) {
- size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
- _M_buckets[__bucket] = __first->_M_next;
- __first->_M_next = __tmp[__new_bucket];
- __tmp[__new_bucket] = __first;
- __first = _M_buckets[__bucket];
- }
- }
- _M_buckets.swap(__tmp);
- } catch (...) {
- for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
- while (__tmp[__bucket]) {
- _Node* __next = __tmp[__bucket]->_M_next;
- _M_delete_node(__tmp[__bucket]);
- __tmp[__bucket] = __next;
- }
- }
- throw;
- }
- }
- }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
- const size_type __n, _Node* __first, _Node* __last)
-{
- _Node* __cur = _M_buckets[__n];
- if (__cur == __first)
- _M_erase_bucket(__n, __last);
- else {
- _Node* __next;
- for (__next = __cur->_M_next; __next != __first;
- __cur = __next, __next = __cur->_M_next)
- ;
- while (__next != __last) {
- __cur->_M_next = __next->_M_next;
- _M_delete_node(__next);
- __next = __cur->_M_next;
- --_M_num_elements;
- }
- }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
- const size_type __n, _Node* __last)
-{
- _Node* __cur = _M_buckets[__n];
- while (__cur != __last) {
- _Node* __next = __cur->_M_next;
- _M_delete_node(__cur);
- __cur = __next;
- _M_buckets[__n] = __cur;
- --_M_num_elements;
- }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear()
-{
- for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
- _Node* __cur = _M_buckets[__i];
- while (__cur != nullptr) {
- _Node* __next = __cur->_M_next;
- _M_delete_node(__cur);
- __cur = __next;
- }
- _M_buckets[__i] = nullptr;
- }
- _M_num_elements = 0;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(
- const hashtable& __ht)
-{
- _M_buckets.clear();
- _M_buckets.reserve(__ht._M_buckets.size());
- _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)nullptr);
- try {
- for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
- const _Node* __cur = __ht._M_buckets[__i];
- if (__cur) {
- _Node* __copy = _M_new_node(__cur->_M_val);
- _M_buckets[__i] = __copy;
-
- for (_Node* __next = __cur->_M_next; __next;
- __cur = __next, __next = __cur->_M_next) {
- __copy->_M_next = _M_new_node(__next->_M_val);
- __copy = __copy->_M_next;
- }
- }
- }
- _M_num_elements = __ht._M_num_elements;
- } catch (...) {
- clear();
- throw;
- }
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-// Undo warning suppression.
-# if defined(__clang__) && defined(__has_warning)
-# if __has_warning("-Wdeprecated")
-# pragma clang diagnostic pop
-# endif
-# endif
-
-# if defined(_MSC_VER)
-# pragma warning(pop)
-# endif
-
-#endif
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index 28d3f68e2..89be4b885 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/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c
index b0cf7ad3b..d44f7eb9c 100644
--- a/Source/kwsys/kwsysPlatformTestsC.c
+++ b/Source/kwsys/kwsysPlatformTestsC.c
@@ -69,40 +69,3 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
return clock_gettime(CLOCK_MONOTONIC, &ts);
}
#endif
-
-#ifdef TEST_KWSYS_C_TYPE_MACROS
-char* info_macros =
-# if defined(__SIZEOF_SHORT__)
- "INFO:macro[__SIZEOF_SHORT__]\n"
-# endif
-# if defined(__SIZEOF_INT__)
- "INFO:macro[__SIZEOF_INT__]\n"
-# endif
-# if defined(__SIZEOF_LONG__)
- "INFO:macro[__SIZEOF_LONG__]\n"
-# endif
-# if defined(__SIZEOF_LONG_LONG__)
- "INFO:macro[__SIZEOF_LONG_LONG__]\n"
-# endif
-# if defined(__SHORT_MAX__)
- "INFO:macro[__SHORT_MAX__]\n"
-# endif
-# if defined(__INT_MAX__)
- "INFO:macro[__INT_MAX__]\n"
-# endif
-# if defined(__LONG_MAX__)
- "INFO:macro[__LONG_MAX__]\n"
-# endif
-# if defined(__LONG_LONG_MAX__)
- "INFO:macro[__LONG_LONG_MAX__]\n"
-# endif
- "";
-
-int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
-{
- int require = 0;
- require += info_macros[argc];
- (void)argv;
- return require;
-}
-#endif
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index cfd5666f3..0bfa20ee1 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -1,36 +1,5 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-#ifdef TEST_KWSYS_CXX_HAS_CSTDIO
-# include <cstdio>
-int main()
-{
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
-long long f(long long n)
-{
- return n;
-}
-int main()
-{
- long long n = 0;
- return static_cast<int>(f(n));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS___INT64
-__int64 f(__int64 n)
-{
- return n;
-}
-int main()
-{
- __int64 n = 0;
- return static_cast<int>(f(n));
-}
-#endif
#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIM
# include <sys/types.h>
@@ -60,82 +29,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
-void function(long**)
-{
-}
-int main()
-{
- __int64** p = 0;
- function(p);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64
-void function(long long**)
-{
-}
-int main()
-{
- __int64** p = 0;
- function(p);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-# include <iostream>
-int test_istream(std::istream& is, long long& x)
-{
- return (is >> x) ? 1 : 0;
-}
-int main()
-{
- long long x = 0;
- return test_istream(std::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-# include <iostream>
-int test_ostream(std::ostream& os, long long x)
-{
- return (os << x) ? 1 : 0;
-}
-int main()
-{
- long long x = 0;
- return test_ostream(std::cout, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
-# include <iostream>
-int test_istream(std::istream& is, __int64& x)
-{
- return (is >> x) ? 1 : 0;
-}
-int main()
-{
- __int64 x = 0;
- return test_istream(std::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
-# include <iostream>
-int test_ostream(std::ostream& os, __int64 x)
-{
- return (os << x) ? 1 : 0;
-}
-int main()
-{
- __int64 x = 0;
- return test_ostream(std::cout, x);
-}
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_SETENV
# include <stdlib.h>
int main()
@@ -184,33 +77,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_HAS_ATOLL
-# include <stdlib.h>
-int main()
-{
- const char* str = "1024";
- return static_cast<int>(atoll(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ATOL
-# include <stdlib.h>
-int main()
-{
- const char* str = "1024";
- return static_cast<int>(atol(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS__ATOI64
-# include <stdlib.h>
-int main()
-{
- const char* str = "1024";
- return static_cast<int>(_atoi64(str));
-}
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_UTIMES
# include <sys/time.h>
int main()
@@ -288,33 +154,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
-int main()
-{
- int a = 1;
- __asm {
- xor EBX, EBX;
- mov a, EBX;
- }
-
- return a;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
-int main()
-{
- int a = 0;
- __asm {
- xor EAX, EAX;
- cpuid;
- mov a, EAX;
- }
-
- return a;
-}
-#endif
-
#ifdef TEST_KWSYS_STL_HAS_WSTRING
# include <string>
void f(std::wstring*)
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 1778a9ba8..078675159 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -12,8 +12,8 @@
#include <iostream>
#include <vector>
-#include <stddef.h> /* size_t */
-#include <string.h> /* strcmp */
+#include <cstddef> /* size_t */
+#include <cstring> /* strcmp */
static void* random_ptr = reinterpret_cast<void*>(0x123);
@@ -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 64561b1e3..2f6b73578 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -12,8 +12,8 @@
#include <iostream>
#include <vector>
-#include <assert.h> /* assert */
-#include <string.h> /* strcmp */
+#include <cassert> /* assert */
+#include <cstring> /* strcmp */
int testCommandLineArguments1(int argc, char* argv[])
{
@@ -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");
@@ -51,9 +51,7 @@ int testCommandLineArguments1(int argc, char* argv[])
std::cout << "Value of N: " << n << std::endl;
std::cout << "Value of M: " << m << std::endl;
std::cout << "Value of P: " << p << std::endl;
- if (m) {
- delete[] m;
- }
+ delete[] m;
char** newArgv = nullptr;
int newArgc = 0;
diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx
index b1ab0c872..eb3ca3254 100644
--- a/Source/kwsys/testDirectory.cxx
+++ b/Source/kwsys/testDirectory.cxx
@@ -57,7 +57,11 @@ int _doLongPathTest()
Directory testdir;
// Set res to failure if the directory doesn't load
- res += !testdir.Load(testdirpath);
+ std::string errorMessage = "";
+ res += !testdir.Load(testdirpath, &errorMessage);
+ if (errorMessage != "") {
+ std::cerr << "Failed to list directory: " << errorMessage << std::endl;
+ }
// Increment res failure if the directory appears empty
res += testdir.GetNumberOfFiles() == 0;
// Increment res failures if the path has changed from
@@ -73,6 +77,34 @@ int _doLongPathTest()
return res;
}
+int _nonExistentDirectoryTest()
+{
+ using namespace kwsys;
+ int res = 0;
+ std::string testdirpath(TEST_SYSTEMTOOLS_BINARY_DIR
+ "/directory_testing/doesnt_exist/");
+ std::string errorMessage;
+ Directory testdir;
+
+ errorMessage = "foo";
+ // Increment res failure if directory lists
+ res += testdir.Load(testdirpath, &errorMessage);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // Increment res failure if errorMessage is unmodified
+ res += (errorMessage == "foo");
+#endif
+
+ errorMessage = "foo";
+ // Increment res failure if directory has files
+ res += (testdir.GetNumberOfFilesInDirectory(testdirpath, &errorMessage) > 0);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // Increment res failure if errorMessage is unmodified
+ res += (errorMessage == "foo");
+#endif
+
+ return res;
+}
+
int _copyDirectoryTest()
{
using namespace kwsys;
@@ -106,5 +138,6 @@ int _copyDirectoryTest()
int testDirectory(int, char* [])
{
- return _doLongPathTest() + _copyDirectoryTest();
+ return _doLongPathTest() + _nonExistentDirectoryTest() +
+ _copyDirectoryTest();
}
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 2421ac0e1..703ad4dcd 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/testDynload.c b/Source/kwsys/testDynload.c
index c49f747df..33a431e9d 100644
--- a/Source/kwsys/testDynload.c
+++ b/Source/kwsys/testDynload.c
@@ -8,6 +8,6 @@
DL_EXPORT int TestDynamicLoaderData = 0;
-DL_EXPORT void TestDynamicLoaderSymbolPointer()
+DL_EXPORT void TestDynamicLoaderSymbolPointer(void)
{
}
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 988697bff..ee93e8d8d 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -10,10 +10,10 @@
#include KWSYS_HEADER(Encoding.h)
#include <algorithm>
+#include <clocale>
+#include <cstdlib>
+#include <cstring>
#include <iostream>
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -59,7 +59,7 @@ static int testHelloWorldEncoding()
std::string str2 = kwsys::Encoding::ToNarrow(wstr);
wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str());
char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr);
- if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()))) {
+ if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()) != 0)) {
std::cout << "converted string was different: " << str2 << std::endl;
std::cout << "converted string was different: " << c_str2 << std::endl;
ret++;
@@ -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/testFStream.cxx b/Source/kwsys/testFStream.cxx
index 5009e9887..afba9530e 100644
--- a/Source/kwsys/testFStream.cxx
+++ b/Source/kwsys/testFStream.cxx
@@ -7,10 +7,7 @@
#endif
#include KWSYS_HEADER(FStream.hxx)
-#include <string.h>
-#ifdef __BORLANDC__
-# include <mem.h> /* memcmp */
-#endif
+#include <cstring>
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
deleted file mode 100644
index 4ed2f899d..000000000
--- a/Source/kwsys/testHashSTL.cxx
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(hash_map.hxx)
-#include KWSYS_HEADER(hash_set.hxx)
-
-// Work-around CMake dependency scanning limitation. This must
-// duplicate the above list of headers.
-#if 0
-# include "hash_map.hxx.in"
-# include "hash_set.hxx.in"
-#endif
-
-#include <iostream>
-
-#if defined(_MSC_VER)
-# pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 1468 /* inline function cannot be explicitly instantiated \
- */
-#endif
-
-template class kwsys::hash_map<const char*, int>;
-template class kwsys::hash_set<int>;
-
-static bool test_hash_map()
-{
- typedef kwsys::hash_map<const char*, int> mtype;
- 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 << "]"
- << std::endl;
- sum += mi->second;
- }
- return sum == 3;
-}
-
-static bool test_hash_set()
-{
- typedef kwsys::hash_set<int> stype;
- 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;
- }
- return sum == 3;
-}
-
-int testHashSTL(int, char* [])
-{
- bool result = true;
- result = test_hash_map() && result;
- result = test_hash_set() && result;
- return result ? 0 : 1;
-}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 39aaa23ba..0c658f566 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -24,10 +24,6 @@
# include <unistd.h>
#endif
-#if defined(__BORLANDC__)
-# pragma warn - 8060 /* possibly incorrect assignment */
-#endif
-
/* Platform-specific sleep functions. */
#if defined(__BEOS__) && !defined(__ZETA__)
@@ -631,7 +627,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 +706,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 +718,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/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 154517eae..4f0c522e4 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -11,29 +11,13 @@
#include <iostream>
-#if defined(KWSYS_USE_LONG_LONG)
-# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
-# define iostreamLongLong(x) (x)
-# else
-# define iostreamLongLong(x) ((long)x)
-# endif
-#elif defined(KWSYS_USE___INT64)
-# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
-# define iostreamLongLong(x) (x)
-# else
-# define iostreamLongLong(x) ((long)x)
-# endif
-#else
-# error "No Long Long"
-#endif
-
#define printMethod(info, m) std::cout << #m << ": " << info.m() << "\n"
#define printMethod2(info, m, unit) \
std::cout << #m << ": " << info.m() << " " << unit << "\n"
#define printMethod3(info, m, unit) \
- std::cout << #m << ": " << iostreamLongLong(info.m) << " " << unit << "\n"
+ std::cout << #m << ": " << info.m << " " << unit << "\n"
int testSystemInformation(int, char* [])
{
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 3f6eeb8c1..1d3461443 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -20,18 +20,18 @@
// left on disk.
#include <testSystemTools.h>
+#include <cstdlib> /* free */
+#include <cstring> /* strcmp */
#include <iostream>
#include <sstream>
-#include <stdlib.h> /* free */
-#include <string.h> /* strcmp */
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <io.h> /* _umask (MSVC) / umask (Borland) */
+# include <io.h> /* _umask (MSVC) */
# ifdef _MSC_VER
-# define umask _umask // Note this is still umask on Borland
+# define umask _umask
# endif
#endif
#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
-// Visual C++ does not define mode_t (note that Borland does, however).
+// Visual C++ does not define mode_t.
#if defined(_MSC_VER)
typedef unsigned short mode_t;
#endif
@@ -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:"
@@ -500,7 +507,7 @@ static bool CheckStringOperations()
char* cres =
kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with AppendStrings "
<< "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
res = false;
@@ -508,7 +515,7 @@ static bool CheckStringOperations()
delete[] cres;
cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with AppendStrings "
<< "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
res = false;
@@ -522,7 +529,7 @@ static bool CheckStringOperations()
}
cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou");
- if (strcmp(cres, "Mry Hd A Lttl Lmb.")) {
+ if (strcmp(cres, "Mry Hd A Lttl Lmb.") != 0) {
std::cerr << "Problem with RemoveChars "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -530,7 +537,7 @@ static bool CheckStringOperations()
delete[] cres;
cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
- if (strcmp(cres, "A")) {
+ if (strcmp(cres, "A") != 0) {
std::cerr << "Problem with RemoveCharsButUpperHex "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -539,7 +546,7 @@ static bool CheckStringOperations()
char* cres2 = strdup("Mary Had A Little Lamb.");
kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X');
- if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) {
+ if (strcmp(cres2, "MXry HXd A LXttlX LXmb.") != 0) {
std::cerr << "Problem with ReplaceChars "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -561,7 +568,7 @@ static bool CheckStringOperations()
}
cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with DuplicateString "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -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 022e36e2f..e4b89a7c1 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@"