summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt89
-rw-r--r--Source/CMakeVersion.cmake83
-rw-r--r--Source/CMakeVersionCompute.cmake44
-rw-r--r--Source/CMakeVersionSource.cmake30
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx16
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx172
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.h22
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx18
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h8
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx36
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.h4
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.cxx4
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.h6
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx9
-rw-r--r--Source/CPack/WiX/cmCMakeToWixPath.cxx6
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx91
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h13
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx8
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.h3
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx10
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h5
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.h3
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx9
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.h6
-rw-r--r--Source/CPack/WiX/cmWIXPatch.h4
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx4
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h13
-rw-r--r--Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXRichTextFormatWriter.h3
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.h10
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h6
-rw-r--r--Source/CPack/cmCPack7zGenerator.cxx13
-rw-r--r--Source/CPack/cmCPack7zGenerator.h29
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx65
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h31
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx19
-rw-r--r--Source/CPack/cmCPackComponentGroup.cxx9
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx15
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.h6
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx49
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.h6
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx52
-rw-r--r--Source/CPack/cmCPackDebGenerator.h4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx43
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h3
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx31
-rw-r--r--Source/CPack/cmCPackExternalGenerator.h7
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx46
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.h6
-rw-r--r--Source/CPack/cmCPackGenerator.cxx213
-rw-r--r--Source/CPack/cmCPackGenerator.h5
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx68
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.h18
-rw-r--r--Source/CPack/cmCPackLog.cxx10
-rw-r--r--Source/CPack/cmCPackLog.h3
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx114
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h4
-rw-r--r--Source/CPack/cmCPackNuGetGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx51
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx46
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx59
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx25
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx20
-rw-r--r--Source/CPack/cmCPackRPMGenerator.h4
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx14
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.h11
-rw-r--r--Source/CPack/cmCPackTGZGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTGZGenerator.h29
-rw-r--r--Source/CPack/cmCPackTXZGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTXZGenerator.h29
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.cxx13
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.h28
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.h28
-rw-r--r--Source/CPack/cmCPackZIPGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackZIPGenerator.h29
-rw-r--r--Source/CPack/cpack.cxx74
-rw-r--r--Source/CTest/cmCTestBZR.cxx22
-rw-r--r--Source/CTest/cmCTestBZR.h4
-rw-r--r--Source/CTest/cmCTestBinPacker.cxx203
-rw-r--r--Source/CTest/cmCTestBinPacker.h31
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx24
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.h11
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx64
-rw-r--r--Source/CTest/cmCTestBuildCommand.h38
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx92
-rw-r--r--Source/CTest/cmCTestBuildHandler.h26
-rw-r--r--Source/CTest/cmCTestCVS.cxx17
-rw-r--r--Source/CTest/cmCTestCVS.h4
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx27
-rw-r--r--Source/CTest/cmCTestConfigureCommand.h25
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx8
-rw-r--r--Source/CTest/cmCTestConfigureHandler.h2
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx45
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h34
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx83
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h17
-rw-r--r--Source/CTest/cmCTestCurl.cxx11
-rw-r--r--Source/CTest/cmCTestCurl.h3
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx4
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h16
-rw-r--r--Source/CTest/cmCTestGIT.cxx26
-rw-r--r--Source/CTest/cmCTestGIT.h4
-rw-r--r--Source/CTest/cmCTestGenericHandler.cxx9
-rw-r--r--Source/CTest/cmCTestGenericHandler.h5
-rw-r--r--Source/CTest/cmCTestGlobalVC.cxx6
-rw-r--r--Source/CTest/cmCTestGlobalVC.h4
-rw-r--r--Source/CTest/cmCTestHG.cxx13
-rw-r--r--Source/CTest/cmCTestHG.h4
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx185
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h52
-rw-r--r--Source/CTest/cmCTestLaunch.cxx47
-rw-r--r--Source/CTest/cmCTestLaunch.h3
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx21
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.h23
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx24
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h6
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx232
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h37
-rw-r--r--Source/CTest/cmCTestP4.cxx24
-rw-r--r--Source/CTest/cmCTestP4.h4
-rw-r--r--Source/CTest/cmCTestReadCustomFilesCommand.h15
-rw-r--r--Source/CTest/cmCTestResourceAllocator.cxx86
-rw-r--r--Source/CTest/cmCTestResourceAllocator.h39
-rw-r--r--Source/CTest/cmCTestResourceGroupsLexerHelper.cxx55
-rw-r--r--Source/CTest/cmCTestResourceGroupsLexerHelper.h44
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx159
-rw-r--r--Source/CTest/cmCTestResourceSpec.h40
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.cxx6
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.h15
-rw-r--r--Source/CTest/cmCTestRunTest.cxx132
-rw-r--r--Source/CTest/cmCTestRunTest.h28
-rw-r--r--Source/CTest/cmCTestSVN.cxx25
-rw-r--r--Source/CTest/cmCTestSVN.h4
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx156
-rw-r--r--Source/CTest/cmCTestScriptHandler.h12
-rw-r--r--Source/CTest/cmCTestSleepCommand.cxx4
-rw-r--r--Source/CTest/cmCTestSleepCommand.h15
-rw-r--r--Source/CTest/cmCTestStartCommand.cxx20
-rw-r--r--Source/CTest/cmCTestStartCommand.h15
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx177
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h57
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx46
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h10
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx122
-rw-r--r--Source/CTest/cmCTestTestCommand.h53
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx703
-rw-r--r--Source/CTest/cmCTestTestHandler.h53
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx7
-rw-r--r--Source/CTest/cmCTestUpdateCommand.h17
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx29
-rw-r--r--Source/CTest/cmCTestUpdateHandler.h6
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx65
-rw-r--r--Source/CTest/cmCTestUploadCommand.h33
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx6
-rw-r--r--Source/CTest/cmCTestUploadHandler.h6
-rw-r--r--Source/CTest/cmCTestVC.cxx17
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.cxx16
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.h2
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx23
-rw-r--r--Source/CTest/cmParseCacheCoverage.h4
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx18
-rw-r--r--Source/CTest/cmParseDelphiCoverage.cxx15
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx21
-rw-r--r--Source/CTest/cmParseGTMCoverage.h4
-rw-r--r--Source/CTest/cmParseJacocoCoverage.cxx24
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx20
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx16
-rw-r--r--Source/CTest/cmProcess.cxx15
-rw-r--r--Source/CTest/cmProcess.h16
-rw-r--r--Source/Checks/cm_cxx17_check.cpp5
-rw-r--r--Source/CursesDialog/CMakeLists.txt40
-rw-r--r--Source/CursesDialog/ccmake.cxx21
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx4
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx89
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.h17
-rw-r--r--Source/CursesDialog/cmCursesForm.h4
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.h4
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx15
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h6
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx214
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h21
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx4
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.h4
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx42
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.h9
-rw-r--r--Source/CursesDialog/cmCursesWidget.h4
-rw-r--r--Source/LexerParser/cmCTestResourceGroupsLexer.cxx2224
-rw-r--r--Source/LexerParser/cmCTestResourceGroupsLexer.h692
-rw-r--r--Source/LexerParser/cmCTestResourceGroupsLexer.in.l102
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.cxx302
-rw-r--r--Source/LexerParser/cmCommandArgumentParserTokens.h8
-rw-r--r--Source/LexerParser/cmDependsJavaParser.cxx1560
-rw-r--r--Source/LexerParser/cmDependsJavaParserTokens.h8
-rw-r--r--Source/LexerParser/cmExprParser.cxx371
-rw-r--r--Source/LexerParser/cmExprParser.y3
-rw-r--r--Source/LexerParser/cmExprParserTokens.h8
-rw-r--r--Source/LexerParser/cmFortranParser.cxx304
-rw-r--r--Source/LexerParser/cmFortranParserTokens.h12
-rw-r--r--Source/Modules/CheckCXXLinkerFlag.cmake25
-rw-r--r--Source/QtDialog/AddCacheEntry.h1
-rw-r--r--Source/QtDialog/CMakeSetup.cxx32
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx10
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h4
-rw-r--r--Source/QtDialog/Compilers.h4
-rw-r--r--Source/QtDialog/FirstConfigure.cxx16
-rw-r--r--Source/QtDialog/QCMake.cxx7
-rw-r--r--Source/QtDialog/QCMake.h2
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx6
-rw-r--r--Source/QtDialog/QCMakeCacheView.h1
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx3
-rw-r--r--Source/QtDialog/RegexExplorer.h6
-rw-r--r--Source/QtDialog/WarningMessagesDialog.h2
-rw-r--r--Source/bindexplib.cxx89
-rw-r--r--Source/bindexplib.h8
-rw-r--r--Source/cmAddCompileDefinitionsCommand.cxx14
-rw-r--r--Source/cmAddCompileDefinitionsCommand.h19
-rw-r--r--Source/cmAddCompileOptionsCommand.cxx14
-rw-r--r--Source/cmAddCompileOptionsCommand.h19
-rw-r--r--Source/cmAddCustomCommandCommand.cxx209
-rw-r--r--Source/cmAddCustomCommandCommand.h28
-rw-r--r--Source/cmAddCustomTargetCommand.cxx70
-rw-r--r--Source/cmAddCustomTargetCommand.h26
-rw-r--r--Source/cmAddDefinitionsCommand.cxx16
-rw-r--r--Source/cmAddDefinitionsCommand.h25
-rw-r--r--Source/cmAddDependenciesCommand.cxx47
-rw-r--r--Source/cmAddDependenciesCommand.h24
-rw-r--r--Source/cmAddExecutableCommand.cxx91
-rw-r--r--Source/cmAddExecutableCommand.h25
-rw-r--r--Source/cmAddLibraryCommand.cxx190
-rw-r--r--Source/cmAddLibraryCommand.h25
-rw-r--r--Source/cmAddLinkOptionsCommand.cxx14
-rw-r--r--Source/cmAddLinkOptionsCommand.h19
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx56
-rw-r--r--Source/cmAddSubDirectoryCommand.h26
-rw-r--r--Source/cmAddTestCommand.cxx69
-rw-r--r--Source/cmAddTestCommand.h27
-rw-r--r--Source/cmAffinity.cxx7
-rw-r--r--Source/cmAlgorithms.h267
-rw-r--r--Source/cmArchiveWrite.cxx106
-rw-r--r--Source/cmArchiveWrite.h4
-rw-r--r--Source/cmArgumentParser.cxx6
-rw-r--r--Source/cmArgumentParser.h28
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx34
-rw-r--r--Source/cmAuxSourceDirectoryCommand.h28
-rw-r--r--Source/cmBase32.h2
-rw-r--r--Source/cmBinUtilsLinker.cxx16
-rw-r--r--Source/cmBinUtilsLinker.h30
-rw-r--r--Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx19
-rw-r--r--Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h30
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx179
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.h44
-rw-r--r--Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx85
-rw-r--r--Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h26
-rw-r--r--Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx19
-rw-r--r--Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h29
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.cxx231
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.h59
-rw-r--r--Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx100
-rw-r--r--Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h25
-rw-r--r--Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx68
-rw-r--r--Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h25
-rw-r--r--Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx19
-rw-r--r--Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h28
-rw-r--r--Source/cmBinUtilsWindowsPELinker.cxx123
-rw-r--r--Source/cmBinUtilsWindowsPELinker.h33
-rw-r--r--Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx68
-rw-r--r--Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h25
-rw-r--r--Source/cmBreakCommand.cxx14
-rw-r--r--Source/cmBreakCommand.h21
-rw-r--r--Source/cmBuildCommand.cxx75
-rw-r--r--Source/cmBuildCommand.h37
-rw-r--r--Source/cmBuildNameCommand.cxx28
-rw-r--r--Source/cmBuildNameCommand.h11
-rw-r--r--Source/cmCLocaleEnvironmentScope.cxx4
-rw-r--r--Source/cmCLocaleEnvironmentScope.h2
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx104
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.h36
-rw-r--r--Source/cmCMakeMinimumRequired.cxx53
-rw-r--r--Source/cmCMakeMinimumRequired.h25
-rw-r--r--Source/cmCMakePolicyCommand.cxx143
-rw-r--r--Source/cmCMakePolicyCommand.h27
-rw-r--r--Source/cmCPackPropertiesGenerator.cxx6
-rw-r--r--Source/cmCPackPropertiesGenerator.h4
-rw-r--r--Source/cmCPluginAPI.cxx48
-rw-r--r--Source/cmCPluginAPI.h11
-rw-r--r--Source/cmCTest.cxx187
-rw-r--r--Source/cmCTest.h18
-rw-r--r--Source/cmCacheManager.cxx70
-rw-r--r--Source/cmCacheManager.h4
-rw-r--r--Source/cmCallVisualStudioMacro.cxx4
-rw-r--r--Source/cmCheckCustomOutputs.cxx36
-rw-r--r--Source/cmCheckCustomOutputs.h18
-rw-r--r--Source/cmCommand.cxx42
-rw-r--r--Source/cmCommand.h49
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx23
-rw-r--r--Source/cmCommands.cxx234
-rw-r--r--Source/cmCommonTargetGenerator.cxx31
-rw-r--r--Source/cmCommonTargetGenerator.h2
-rw-r--r--Source/cmComputeComponentGraph.cxx3
-rw-r--r--Source/cmComputeComponentGraph.h10
-rw-r--r--Source/cmComputeLinkDepends.cxx66
-rw-r--r--Source/cmComputeLinkDepends.h25
-rw-r--r--Source/cmComputeLinkInformation.cxx268
-rw-r--r--Source/cmComputeLinkInformation.h17
-rw-r--r--Source/cmComputeTargetDepends.cxx25
-rw-r--r--Source/cmComputeTargetDepends.h12
-rw-r--r--Source/cmConditionEvaluator.cxx42
-rw-r--r--Source/cmConditionEvaluator.h2
-rw-r--r--Source/cmConfigure.cmake.h.in4
-rw-r--r--Source/cmConfigureFileCommand.cxx86
-rw-r--r--Source/cmConfigureFileCommand.h29
-rw-r--r--Source/cmConnection.cxx7
-rw-r--r--Source/cmConnection.h7
-rw-r--r--Source/cmContinueCommand.cxx20
-rw-r--r--Source/cmContinueCommand.h21
-rw-r--r--Source/cmCoreTryCompile.cxx253
-rw-r--r--Source/cmCreateTestSourceList.cxx53
-rw-r--r--Source/cmCreateTestSourceList.h24
-rw-r--r--Source/cmCryptoHash.cxx44
-rw-r--r--Source/cmCryptoHash.h14
-rw-r--r--Source/cmCurl.cxx5
-rw-r--r--Source/cmCurl.h3
-rw-r--r--Source/cmCustomCommand.cxx11
-rw-r--r--Source/cmCustomCommand.h23
-rw-r--r--Source/cmCustomCommandGenerator.cxx68
-rw-r--r--Source/cmCustomCommandGenerator.h7
-rw-r--r--Source/cmCustomCommandLines.cxx22
-rw-r--r--Source/cmCustomCommandLines.h19
-rw-r--r--Source/cmCustomCommandTypes.h39
-rw-r--r--Source/cmDefinePropertyCommand.cxx51
-rw-r--r--Source/cmDefinePropertyCommand.h21
-rw-r--r--Source/cmDefinitions.cxx80
-rw-r--r--Source/cmDefinitions.h46
-rw-r--r--Source/cmDepends.cxx28
-rw-r--r--Source/cmDepends.h2
-rw-r--r--Source/cmDependsC.cxx52
-rw-r--r--Source/cmDependsC.h14
-rw-r--r--Source/cmDependsFortran.cxx76
-rw-r--r--Source/cmDependsJava.h4
-rw-r--r--Source/cmDependsJavaParserHelper.cxx18
-rw-r--r--Source/cmDisallowedCommand.cxx31
-rw-r--r--Source/cmDisallowedCommand.h48
-rw-r--r--Source/cmDocumentation.cxx15
-rw-r--r--Source/cmDocumentation.h6
-rw-r--r--Source/cmDocumentationFormatter.cxx8
-rw-r--r--Source/cmDocumentationSection.h6
-rw-r--r--Source/cmDuration.h2
-rw-r--r--Source/cmDynamicLoader.cxx6
-rw-r--r--Source/cmELF.cxx121
-rw-r--r--Source/cmELF.h5
-rw-r--r--Source/cmEnableLanguageCommand.cxx17
-rw-r--r--Source/cmEnableLanguageCommand.h27
-rw-r--r--Source/cmEnableTestingCommand.cxx11
-rw-r--r--Source/cmEnableTestingCommand.h21
-rw-r--r--Source/cmExecProgramCommand.cxx50
-rw-r--r--Source/cmExecProgramCommand.h28
-rw-r--r--Source/cmExecuteProcessCommand.cxx90
-rw-r--r--Source/cmExecuteProcessCommand.h21
-rw-r--r--Source/cmExecutionStatus.h21
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx16
-rw-r--r--Source/cmExportBuildFileGenerator.cxx94
-rw-r--r--Source/cmExportBuildFileGenerator.h15
-rw-r--r--Source/cmExportCommand.cxx136
-rw-r--r--Source/cmExportCommand.h28
-rw-r--r--Source/cmExportFileGenerator.cxx97
-rw-r--r--Source/cmExportFileGenerator.h20
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx10
-rw-r--r--Source/cmExportInstallFileGenerator.cxx91
-rw-r--r--Source/cmExportInstallFileGenerator.h13
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx75
-rw-r--r--Source/cmExportLibraryDependenciesCommand.h22
-rw-r--r--Source/cmExportSet.cxx27
-rw-r--r--Source/cmExportSet.h28
-rw-r--r--Source/cmExportSetMap.cxx31
-rw-r--r--Source/cmExportSetMap.h37
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx18
-rw-r--r--Source/cmExportTryCompileFileGenerator.h4
-rw-r--r--Source/cmExprParserHelper.cxx16
-rw-r--r--Source/cmExprParserHelper.h4
-rw-r--r--Source/cmExternalMakefileProjectGenerator.cxx5
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx61
-rw-r--r--Source/cmExtraCodeBlocksGenerator.h4
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx57
-rw-r--r--Source/cmExtraCodeLiteGenerator.h4
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx93
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h7
-rw-r--r--Source/cmExtraKateGenerator.cxx34
-rw-r--r--Source/cmExtraKateGenerator.h4
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx37
-rw-r--r--Source/cmExtraSublimeTextGenerator.h6
-rw-r--r--Source/cmFLTKWrapUICommand.cxx127
-rw-r--r--Source/cmFLTKWrapUICommand.h47
-rw-r--r--Source/cmFSPermissions.h4
-rw-r--r--Source/cmFileAPI.cxx33
-rw-r--r--Source/cmFileAPI.h10
-rw-r--r--Source/cmFileAPICMakeFiles.cxx10
-rw-r--r--Source/cmFileAPICache.cxx12
-rw-r--r--Source/cmFileAPICodemodel.cxx424
-rw-r--r--Source/cmFileCommand.cxx1262
-rw-r--r--Source/cmFileCommand.h60
-rw-r--r--Source/cmFileCopier.cxx112
-rw-r--r--Source/cmFileCopier.h16
-rw-r--r--Source/cmFileInstaller.cxx67
-rw-r--r--Source/cmFileInstaller.h11
-rw-r--r--Source/cmFileLock.cxx3
-rw-r--r--Source/cmFileLockPool.cxx2
-rw-r--r--Source/cmFileLockPool.h12
-rw-r--r--Source/cmFileLockResult.cxx16
-rw-r--r--Source/cmFileLockResult.h4
-rw-r--r--Source/cmFileLockUnix.cxx9
-rw-r--r--Source/cmFileLockWin32.cxx4
-rw-r--r--Source/cmFileMonitor.cxx9
-rw-r--r--Source/cmFilePathChecksum.cxx4
-rw-r--r--Source/cmFilePathChecksum.h2
-rw-r--r--Source/cmFileTime.cxx5
-rw-r--r--Source/cmFileTime.h2
-rw-r--r--Source/cmFileTimeCache.cxx6
-rw-r--r--Source/cmFileTimeCache.h3
-rw-r--r--Source/cmFileTimes.cxx10
-rw-r--r--Source/cmFileTimes.h2
-rw-r--r--Source/cmFindBase.cxx25
-rw-r--r--Source/cmFindBase.h6
-rw-r--r--Source/cmFindCommon.cxx45
-rw-r--r--Source/cmFindCommon.h17
-rw-r--r--Source/cmFindFileCommand.cxx11
-rw-r--r--Source/cmFindFileCommand.h14
-rw-r--r--Source/cmFindLibraryCommand.cxx43
-rw-r--r--Source/cmFindLibraryCommand.h19
-rw-r--r--Source/cmFindPackageCommand.cxx269
-rw-r--r--Source/cmFindPackageCommand.h31
-rw-r--r--Source/cmFindPathCommand.cxx28
-rw-r--r--Source/cmFindPathCommand.h19
-rw-r--r--Source/cmFindProgramCommand.cxx18
-rw-r--r--Source/cmFindProgramCommand.h19
-rw-r--r--Source/cmForEachCommand.cxx203
-rw-r--r--Source/cmForEachCommand.h43
-rw-r--r--Source/cmFortranParser.h4
-rw-r--r--Source/cmFortranParserImpl.cxx19
-rw-r--r--Source/cmFunctionBlocker.cxx46
-rw-r--r--Source/cmFunctionBlocker.h31
-rw-r--r--Source/cmFunctionCommand.cxx171
-rw-r--r--Source/cmFunctionCommand.h34
-rw-r--r--Source/cmGeneratedFileStream.cxx13
-rw-r--r--Source/cmGeneratedFileStream.h10
-rw-r--r--Source/cmGeneratorExpression.cxx78
-rw-r--r--Source/cmGeneratorExpression.h49
-rw-r--r--Source/cmGeneratorExpressionContext.h4
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx17
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h9
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx22
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h5
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx17
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h2
-rw-r--r--Source/cmGeneratorExpressionLexer.h2
-rw-r--r--Source/cmGeneratorExpressionNode.cxx343
-rw-r--r--Source/cmGeneratorExpressionNode.h4
-rw-r--r--Source/cmGeneratorExpressionParser.cxx21
-rw-r--r--Source/cmGeneratorTarget.cxx1719
-rw-r--r--Source/cmGeneratorTarget.h102
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx21
-rw-r--r--Source/cmGetCMakePropertyCommand.h16
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx54
-rw-r--r--Source/cmGetDirectoryPropertyCommand.h19
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx30
-rw-r--r--Source/cmGetFilenameComponentCommand.h21
-rw-r--r--Source/cmGetPipes.cxx7
-rw-r--r--Source/cmGetPropertyCommand.cxx314
-rw-r--r--Source/cmGetPropertyCommand.h45
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx23
-rw-r--r--Source/cmGetSourceFilePropertyCommand.h16
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx26
-rw-r--r--Source/cmGetTargetPropertyCommand.h16
-rw-r--r--Source/cmGetTestPropertyCommand.cxx17
-rw-r--r--Source/cmGetTestPropertyCommand.h16
-rw-r--r--Source/cmGhsMultiGpj.h1
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx98
-rw-r--r--Source/cmGhsMultiTargetGenerator.h4
-rw-r--r--Source/cmGlobVerificationManager.cxx7
-rw-r--r--Source/cmGlobVerificationManager.h6
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h4
-rw-r--r--Source/cmGlobalCommonGenerator.cxx66
-rw-r--r--Source/cmGlobalCommonGenerator.h24
-rw-r--r--Source/cmGlobalGenerator.cxx369
-rw-r--r--Source/cmGlobalGenerator.h43
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx118
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h16
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h4
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx12
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.cxx6
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h4
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx268
-rw-r--r--Source/cmGlobalNinjaGenerator.h39
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx211
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h11
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx110
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx8
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx93
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx92
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx86
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h20
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx20
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx4
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h6
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx441
-rw-r--r--Source/cmGlobalXCodeGenerator.h12
-rw-r--r--Source/cmGraphAdjacencyList.h4
-rw-r--r--Source/cmGraphVizWriter.cxx48
-rw-r--r--Source/cmGraphVizWriter.h7
-rw-r--r--Source/cmHexFileConverter.cxx6
-rw-r--r--Source/cmHexFileConverter.h1
-rw-r--r--Source/cmIDEOptions.cxx10
-rw-r--r--Source/cmIDEOptions.h2
-rw-r--r--Source/cmIfCommand.cxx291
-rw-r--r--Source/cmIfCommand.h54
-rw-r--r--Source/cmIncludeCommand.cxx63
-rw-r--r--Source/cmIncludeCommand.h21
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx50
-rw-r--r--Source/cmIncludeDirectoryCommand.h30
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx32
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.h26
-rw-r--r--Source/cmIncludeGuardCommand.cxx16
-rw-r--r--Source/cmIncludeGuardCommand.h21
-rw-r--r--Source/cmIncludeRegularExpressionCommand.cxx18
-rw-r--r--Source/cmIncludeRegularExpressionCommand.h25
-rw-r--r--Source/cmInstallCommand.cxx826
-rw-r--r--Source/cmInstallCommand.h61
-rw-r--r--Source/cmInstallCommandArguments.cxx7
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx15
-rw-r--r--Source/cmInstallDirectoryGenerator.h6
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.cxx137
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.h37
-rw-r--r--Source/cmInstallExportGenerator.cxx30
-rw-r--r--Source/cmInstallExportGenerator.h9
-rw-r--r--Source/cmInstallFilesCommand.cxx93
-rw-r--r--Source/cmInstallFilesCommand.h44
-rw-r--r--Source/cmInstallFilesGenerator.cxx14
-rw-r--r--Source/cmInstallFilesGenerator.h6
-rw-r--r--Source/cmInstallGenerator.cxx4
-rw-r--r--Source/cmInstallGenerator.h6
-rw-r--r--Source/cmInstallProgramsCommand.cxx74
-rw-r--r--Source/cmInstallProgramsCommand.h43
-rw-r--r--Source/cmInstallScriptGenerator.cxx6
-rw-r--r--Source/cmInstallScriptGenerator.h6
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx6
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h4
-rw-r--r--Source/cmInstallTargetGenerator.cxx114
-rw-r--r--Source/cmInstallTargetGenerator.h15
-rw-r--r--Source/cmInstallTargetsCommand.cxx30
-rw-r--r--Source/cmInstallTargetsCommand.h26
-rw-r--r--Source/cmInstalledFile.cxx13
-rw-r--r--Source/cmInstalledFile.h13
-rw-r--r--Source/cmJsonObjects.cxx69
-rw-r--r--Source/cmJsonObjects.h4
-rw-r--r--Source/cmLDConfigLDConfigTool.cxx71
-rw-r--r--Source/cmLDConfigLDConfigTool.h22
-rw-r--r--Source/cmLDConfigTool.cxx9
-rw-r--r--Source/cmLDConfigTool.h24
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx33
-rw-r--r--Source/cmLinkDirectoriesCommand.h31
-rw-r--r--Source/cmLinkItem.cxx4
-rw-r--r--Source/cmLinkItem.h11
-rw-r--r--Source/cmLinkLibrariesCommand.cxx26
-rw-r--r--Source/cmLinkLibrariesCommand.h26
-rw-r--r--Source/cmLinkLineComputer.cxx103
-rw-r--r--Source/cmLinkLineComputer.h18
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx100
-rw-r--r--Source/cmLinkLineDeviceComputer.h8
-rw-r--r--Source/cmLinkedTree.h8
-rw-r--r--Source/cmListCommand.cxx629
-rw-r--r--Source/cmListCommand.h46
-rw-r--r--Source/cmListFileCache.cxx15
-rw-r--r--Source/cmListFileCache.h4
-rw-r--r--Source/cmListFileLexer.h13
-rw-r--r--Source/cmLoadCacheCommand.cxx53
-rw-r--r--Source/cmLoadCacheCommand.h32
-rw-r--r--Source/cmLoadCommandCommand.cxx244
-rw-r--r--Source/cmLoadCommandCommand.h11
-rw-r--r--Source/cmLocalCommonGenerator.cxx18
-rw-r--r--Source/cmLocalCommonGenerator.h2
-rw-r--r--Source/cmLocalGenerator.cxx962
-rw-r--r--Source/cmLocalGenerator.h37
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx31
-rw-r--r--Source/cmLocalGhsMultiGenerator.h4
-rw-r--r--Source/cmLocalNinjaGenerator.cxx46
-rw-r--r--Source/cmLocalNinjaGenerator.h5
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx274
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h11
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx7
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx206
-rw-r--r--Source/cmLocalVisualStudio7Generator.h4
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx12
-rw-r--r--Source/cmLocalVisualStudioGenerator.h2
-rw-r--r--Source/cmLocalXCodeGenerator.cxx5
-rw-r--r--Source/cmLocale.h2
-rw-r--r--Source/cmMachO.cxx20
-rw-r--r--Source/cmMachO.h2
-rw-r--r--Source/cmMacroCommand.cxx159
-rw-r--r--Source/cmMacroCommand.h34
-rw-r--r--Source/cmMakeDirectoryCommand.cxx13
-rw-r--r--Source/cmMakeDirectoryCommand.h21
-rw-r--r--Source/cmMakefile.cxx1254
-rw-r--r--Source/cmMakefile.h287
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx100
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx129
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx401
-rw-r--r--Source/cmMakefileTargetGenerator.h8
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx3
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx13
-rw-r--r--Source/cmMarkAsAdvancedCommand.h21
-rw-r--r--Source/cmMathCommand.cxx44
-rw-r--r--Source/cmMathCommand.h22
-rw-r--r--Source/cmMessageCommand.cxx81
-rw-r--r--Source/cmMessageCommand.h21
-rw-r--r--Source/cmMessenger.cxx9
-rw-r--r--Source/cmMessenger.h4
-rw-r--r--Source/cmNewLineStyle.cxx4
-rw-r--r--Source/cmNewLineStyle.h2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx144
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h6
-rw-r--r--Source/cmNinjaTargetGenerator.cxx268
-rw-r--r--Source/cmNinjaTargetGenerator.h13
-rw-r--r--Source/cmNinjaTypes.h6
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx25
-rw-r--r--Source/cmOSXBundleGenerator.cxx80
-rw-r--r--Source/cmOptionCommand.cxx49
-rw-r--r--Source/cmOptionCommand.h22
-rw-r--r--Source/cmOrderDirectories.cxx51
-rw-r--r--Source/cmOrderDirectories.h5
-rw-r--r--Source/cmOutputConverter.cxx198
-rw-r--r--Source/cmOutputConverter.h23
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx109
-rw-r--r--Source/cmOutputRequiredFilesCommand.h21
-rw-r--r--Source/cmParseArgumentsCommand.cxx82
-rw-r--r--Source/cmParseArgumentsCommand.h22
-rw-r--r--Source/cmPipeConnection.h5
-rw-r--r--Source/cmPolicies.cxx18
-rw-r--r--Source/cmPolicies.h16
-rw-r--r--Source/cmProcessOutput.h2
-rw-r--r--Source/cmProcessTools.cxx6
-rw-r--r--Source/cmProcessTools.h7
-rw-r--r--Source/cmProjectCommand.cxx292
-rw-r--r--Source/cmProjectCommand.h31
-rw-r--r--Source/cmProperty.cxx26
-rw-r--r--Source/cmProperty.h18
-rw-r--r--Source/cmPropertyDefinition.h4
-rw-r--r--Source/cmPropertyDefinitionMap.cxx4
-rw-r--r--Source/cmPropertyDefinitionMap.h6
-rw-r--r--Source/cmPropertyMap.cxx77
-rw-r--r--Source/cmPropertyMap.h34
-rw-r--r--Source/cmQTWrapCPPCommand.cxx52
-rw-r--r--Source/cmQTWrapCPPCommand.h25
-rw-r--r--Source/cmQTWrapUICommand.cxx99
-rw-r--r--Source/cmQTWrapUICommand.h24
-rw-r--r--Source/cmQtAutoGen.cxx209
-rw-r--r--Source/cmQtAutoGen.h31
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx70
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h6
-rw-r--r--Source/cmQtAutoGenInitializer.cxx1455
-rw-r--r--Source/cmQtAutoGenInitializer.h192
-rw-r--r--Source/cmQtAutoGenerator.cxx438
-rw-r--r--Source/cmQtAutoGenerator.h128
-rw-r--r--Source/cmQtAutoMocUic.cxx2461
-rw-r--r--Source/cmQtAutoMocUic.h570
-rw-r--r--Source/cmQtAutoRcc.cxx444
-rw-r--r--Source/cmQtAutoRcc.h77
-rw-r--r--Source/cmRST.cxx29
-rw-r--r--Source/cmRST.h3
-rw-r--r--Source/cmRemoveCommand.cxx18
-rw-r--r--Source/cmRemoveCommand.h21
-rw-r--r--Source/cmRemoveDefinitionsCommand.cxx16
-rw-r--r--Source/cmRemoveDefinitionsCommand.h26
-rw-r--r--Source/cmReturnCommand.cxx4
-rw-r--r--Source/cmReturnCommand.h25
-rw-r--r--Source/cmRulePlaceholderExpander.cxx10
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx378
-rw-r--r--Source/cmRuntimeDependencyArchive.h70
-rw-r--r--Source/cmScriptGenerator.cxx15
-rw-r--r--Source/cmScriptGenerator.h4
-rw-r--r--Source/cmSearchPath.cxx8
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx21
-rw-r--r--Source/cmSeparateArgumentsCommand.h21
-rw-r--r--Source/cmServer.cxx27
-rw-r--r--Source/cmServer.h11
-rw-r--r--Source/cmServerConnection.cxx6
-rw-r--r--Source/cmServerProtocol.cxx27
-rw-r--r--Source/cmServerProtocol.h11
-rw-r--r--Source/cmSetCommand.cxx31
-rw-r--r--Source/cmSetCommand.h21
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx29
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.h25
-rw-r--r--Source/cmSetPropertyCommand.cxx434
-rw-r--r--Source/cmSetPropertyCommand.h45
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx39
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.h24
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx45
-rw-r--r--Source/cmSetTargetPropertiesCommand.h24
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx35
-rw-r--r--Source/cmSetTestsPropertiesCommand.h21
-rw-r--r--Source/cmSiteNameCommand.cxx18
-rw-r--r--Source/cmSiteNameCommand.h21
-rw-r--r--Source/cmSourceFile.cxx147
-rw-r--r--Source/cmSourceFile.h67
-rw-r--r--Source/cmSourceFileLocation.cxx12
-rw-r--r--Source/cmSourceGroup.cxx5
-rw-r--r--Source/cmSourceGroup.h3
-rw-r--r--Source/cmSourceGroupCommand.cxx118
-rw-r--r--Source/cmSourceGroupCommand.h46
-rw-r--r--Source/cmState.cxx176
-rw-r--r--Source/cmState.h29
-rw-r--r--Source/cmStateDirectory.cxx67
-rw-r--r--Source/cmStateDirectory.h1
-rw-r--r--Source/cmStatePrivate.h2
-rw-r--r--Source/cmStateSnapshot.cxx45
-rw-r--r--Source/cmStateSnapshot.h4
-rw-r--r--Source/cmStateTypes.h2
-rw-r--r--Source/cmString.hxx16
-rw-r--r--Source/cmStringAlgorithms.cxx325
-rw-r--r--Source/cmStringAlgorithms.h294
-rw-r--r--Source/cmStringCommand.cxx507
-rw-r--r--Source/cmStringCommand.h52
-rw-r--r--Source/cmStringReplaceHelper.cxx3
-rw-r--r--Source/cmStringReplaceHelper.h4
-rw-r--r--Source/cmSubcommandTable.cxx31
-rw-r--r--Source/cmSubcommandTable.h37
-rw-r--r--Source/cmSubdirCommand.cxx29
-rw-r--r--Source/cmSubdirCommand.h26
-rw-r--r--Source/cmSubdirDependsCommand.cxx4
-rw-r--r--Source/cmSubdirDependsCommand.h11
-rw-r--r--Source/cmSystemTools.cxx527
-rw-r--r--Source/cmSystemTools.h139
-rw-r--r--Source/cmTarget.cxx586
-rw-r--r--Source/cmTarget.h30
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx75
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h29
-rw-r--r--Source/cmTargetCompileFeaturesCommand.cxx70
-rw-r--r--Source/cmTargetCompileFeaturesCommand.h21
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx60
-rw-r--r--Source/cmTargetCompileOptionsCommand.h29
-rw-r--r--Source/cmTargetDepend.h2
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx63
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h33
-rw-r--r--Source/cmTargetLinkDirectoriesCommand.cxx57
-rw-r--r--Source/cmTargetLinkDirectoriesCommand.h29
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx317
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h51
-rw-r--r--Source/cmTargetLinkOptionsCommand.cxx59
-rw-r--r--Source/cmTargetLinkOptionsCommand.h29
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx87
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.h16
-rw-r--r--Source/cmTargetPropCommandBase.cxx32
-rw-r--r--Source/cmTargetPropCommandBase.h21
-rw-r--r--Source/cmTargetPropertyComputer.cxx32
-rw-r--r--Source/cmTargetPropertyComputer.h2
-rw-r--r--Source/cmTargetSourcesCommand.cxx89
-rw-r--r--Source/cmTargetSourcesCommand.h39
-rw-r--r--Source/cmTest.cxx17
-rw-r--r--Source/cmTest.h11
-rw-r--r--Source/cmTestGenerator.cxx54
-rw-r--r--Source/cmTestGenerator.h8
-rw-r--r--Source/cmTimestamp.cxx12
-rw-r--r--Source/cmTimestamp.h2
-rw-r--r--Source/cmTryCompileCommand.h9
-rw-r--r--Source/cmTryRunCommand.cxx69
-rw-r--r--Source/cmTryRunCommand.h9
-rw-r--r--Source/cmUVHandlePtr.cxx10
-rw-r--r--Source/cmUVHandlePtr.h4
-rw-r--r--Source/cmUVProcessChain.cxx17
-rw-r--r--Source/cmUVProcessChain.h8
-rw-r--r--Source/cmUVStreambuf.h10
-rw-r--r--Source/cmUnexpectedCommand.cxx22
-rw-r--r--Source/cmUnexpectedCommand.h38
-rw-r--r--Source/cmUnsetCommand.cxx21
-rw-r--r--Source/cmUnsetCommand.h21
-rw-r--r--Source/cmUseMangledMesaCommand.cxx48
-rw-r--r--Source/cmUseMangledMesaCommand.h15
-rw-r--r--Source/cmUtilitySourceCommand.cxx58
-rw-r--r--Source/cmUtilitySourceCommand.h11
-rw-r--r--Source/cmUuid.cxx14
-rw-r--r--Source/cmVSSetupHelper.cxx10
-rw-r--r--Source/cmVSSetupHelper.h26
-rw-r--r--Source/cmVariableRequiresCommand.cxx33
-rw-r--r--Source/cmVariableRequiresCommand.h11
-rw-r--r--Source/cmVariableWatch.cxx3
-rw-r--r--Source/cmVariableWatch.h13
-rw-r--r--Source/cmVariableWatchCommand.cxx78
-rw-r--r--Source/cmVariableWatchCommand.h35
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx498
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h18
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx16
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h2
-rw-r--r--Source/cmVisualStudioSlnData.h4
-rw-r--r--Source/cmVisualStudioSlnParser.cxx31
-rw-r--r--Source/cmVisualStudioSlnParser.h5
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.h3
-rw-r--r--Source/cmWhileCommand.cxx207
-rw-r--r--Source/cmWhileCommand.h51
-rw-r--r--Source/cmWorkerPool.cxx42
-rw-r--r--Source/cmWorkerPool.h9
-rw-r--r--Source/cmWorkingDirectory.cxx4
-rw-r--r--Source/cmWriteFileCommand.cxx27
-rw-r--r--Source/cmWriteFileCommand.h21
-rw-r--r--Source/cmXCodeObject.cxx3
-rw-r--r--Source/cmXCodeObject.h14
-rw-r--r--Source/cmXCodeScheme.cxx42
-rw-r--r--Source/cmXCodeScheme.h7
-rw-r--r--Source/cmXMLParser.cxx10
-rw-r--r--Source/cmXMLParser.h2
-rw-r--r--Source/cmXMLSafe.cxx8
-rw-r--r--Source/cmXMLWriter.cxx3
-rw-r--r--Source/cmXMLWriter.h12
-rw-r--r--Source/cm_codecvt.cxx3
-rw-r--r--Source/cm_codecvt.hxx4
-rw-r--r--Source/cm_get_date.h2
-rw-r--r--Source/cm_static_string_view.hxx4
-rw-r--r--Source/cm_string_view.cxx301
-rw-r--r--Source/cm_string_view.hxx217
-rw-r--r--Source/cm_sys_stat.h9
-rw-r--r--Source/cm_thread.hxx48
-rw-r--r--Source/cmake.cxx458
-rw-r--r--Source/cmake.h136
-rw-r--r--Source/cmakemain.cxx221
-rw-r--r--Source/cmcldeps.cxx8
-rw-r--r--Source/cmcmd.cxx198
-rw-r--r--Source/cmcmd.h3
-rw-r--r--Source/ctest.cxx18
-rw-r--r--Source/kwsys/CMakeLists.txt8
-rw-r--r--Source/kwsys/CommandLineArguments.cxx24
-rw-r--r--Source/kwsys/Configure.hxx.in1
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in18
-rw-r--r--Source/kwsys/Directory.cxx2
-rw-r--r--Source/kwsys/DynamicLoader.cxx20
-rw-r--r--Source/kwsys/EncodingCXX.cxx25
-rw-r--r--Source/kwsys/Glob.cxx2
-rw-r--r--Source/kwsys/Glob.hxx.in2
-rw-r--r--Source/kwsys/RegularExpression.cxx125
-rw-r--r--Source/kwsys/RegularExpression.hxx.in49
-rw-r--r--Source/kwsys/SystemInformation.cxx208
-rw-r--r--Source/kwsys/SystemInformation.hxx.in10
-rw-r--r--Source/kwsys/SystemTools.cxx209
-rw-r--r--Source/kwsys/SystemTools.hxx.in24
-rw-r--r--Source/kwsys/hashtable.hxx.in21
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx4
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx6
-rw-r--r--Source/kwsys/testConsoleBuf.cxx60
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testEncoding.cxx4
-rw-r--r--Source/kwsys/testProcess.c2
-rw-r--r--Source/kwsys/testSystemTools.cxx93
855 files changed, 30035 insertions, 25190 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 695e07598..b1f7b29e5 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -95,9 +95,6 @@ include_directories(
${CMake_HAIKU_INCLUDE_DIRS}
)
-# let cmake know it is supposed to use it
-add_definitions(-DCMAKE_BUILD_WITH_CMAKE)
-
# Check if we can build the ELF parser.
if(CMAKE_USE_ELF_PARSER)
set(ELF_SRCS cmELF.h cmELF.cxx)
@@ -142,12 +139,37 @@ set(SRCS
cmAffinity.cxx
cmAffinity.h
+ cmAlgorithms.h
cmArchiveWrite.cxx
cmArgumentParser.cxx
cmArgumentParser.h
cmBase32.cxx
+ cmBinUtilsLinker.cxx
+ cmBinUtilsLinker.h
+ cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx
+ cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h
+ cmBinUtilsLinuxELFLinker.cxx
+ cmBinUtilsLinuxELFLinker.h
+ cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
+ cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
+ cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx
+ cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h
+ cmBinUtilsMacOSMachOLinker.cxx
+ cmBinUtilsMacOSMachOLinker.h
+ cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
+ cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
+ cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
+ cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
+ cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx
+ cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h
+ cmBinUtilsWindowsPELinker.cxx
+ cmBinUtilsWindowsPELinker.h
+ cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
+ cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
cmCacheManager.cxx
cmCacheManager.h
+ cmCheckCustomOutputs.h
+ cmCheckCustomOutputs.cxx
cmCLocaleEnvironmentScope.h
cmCLocaleEnvironmentScope.cxx
cmCommandArgumentParserHelper.cxx
@@ -171,6 +193,9 @@ set(SRCS
cmCustomCommand.h
cmCustomCommandGenerator.cxx
cmCustomCommandGenerator.h
+ cmCustomCommandLines.cxx
+ cmCustomCommandLines.h
+ cmCustomCommandTypes.h
cmDefinitions.cxx
cmDefinitions.h
cmDepends.cxx
@@ -204,8 +229,6 @@ set(SRCS
cmExportTryCompileFileGenerator.cxx
cmExportSet.h
cmExportSet.cxx
- cmExportSetMap.h
- cmExportSetMap.cxx
cmExternalMakefileProjectGenerator.cxx
cmExternalMakefileProjectGenerator.h
cmExtraCodeBlocksGenerator.cxx
@@ -295,6 +318,10 @@ set(SRCS
cmInstallTargetGenerator.cxx
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
+ cmLDConfigLDConfigTool.cxx
+ cmLDConfigLDConfigTool.h
+ cmLDConfigTool.cxx
+ cmLDConfigTool.h
cmLinkedTree.h
cmLinkItem.cxx
cmLinkItem.h
@@ -338,7 +365,6 @@ set(SRCS
cmProcessOutput.h
cmProcessTools.cxx
cmProcessTools.h
- cmProperty.cxx
cmProperty.h
cmPropertyDefinition.cxx
cmPropertyDefinition.h
@@ -360,6 +386,8 @@ set(SRCS
cmQtAutoRcc.h
cmRST.cxx
cmRST.h
+ cmRuntimeDependencyArchive.cxx
+ cmRuntimeDependencyArchive.h
cmScriptGenerator.h
cmScriptGenerator.cxx
cmSourceFile.cxx
@@ -376,6 +404,8 @@ set(SRCS
cmStateSnapshot.cxx
cmStateSnapshot.h
cmStateTypes.h
+ cmStringAlgorithms.cxx
+ cmStringAlgorithms.h
cmSystemTools.cxx
cmSystemTools.h
cmTarget.cxx
@@ -410,9 +440,6 @@ set(SRCS
cmXMLWriter.h
cmake.cxx
cmake.h
- cm_string_view.cxx
- cm_string_view.hxx
- cm_static_string_view.hxx
cmCommand.cxx
cmCommand.h
@@ -466,8 +493,6 @@ set(SRCS
cmCreateTestSourceList.h
cmDefinePropertyCommand.cxx
cmDefinePropertyCommand.h
- cmDisallowedCommand.cxx
- cmDisallowedCommand.h
cmEnableLanguageCommand.cxx
cmEnableLanguageCommand.h
cmEnableTestingCommand.cxx
@@ -502,6 +527,8 @@ set(SRCS
cmFindProgramCommand.h
cmForEachCommand.cxx
cmForEachCommand.h
+ cmFunctionBlocker.cxx
+ cmFunctionBlocker.h
cmFunctionCommand.cxx
cmFunctionCommand.h
cmGetCMakePropertyCommand.cxx
@@ -607,6 +634,8 @@ set(SRCS
cmStringReplaceHelper.cxx
cmStringCommand.cxx
cmStringCommand.h
+ cmSubcommandTable.cxx
+ cmSubcommandTable.h
cmSubdirCommand.cxx
cmSubdirCommand.h
cmSubdirDependsCommand.cxx
@@ -625,6 +654,8 @@ set(SRCS
cmTargetLinkDirectoriesCommand.h
cmTargetLinkLibrariesCommand.cxx
cmTargetLinkLibrariesCommand.h
+ cmTargetPrecompileHeadersCommand.cxx
+ cmTargetPrecompileHeadersCommand.h
cmTargetPropCommandBase.cxx
cmTargetPropCommandBase.h
cmTargetSourcesCommand.cxx
@@ -635,8 +666,6 @@ set(SRCS
cmTryCompileCommand.h
cmTryRunCommand.cxx
cmTryRunCommand.h
- cmUnexpectedCommand.cxx
- cmUnexpectedCommand.h
cmUnsetCommand.cxx
cmUnsetCommand.h
cmUseMangledMesaCommand.cxx
@@ -652,13 +681,13 @@ set(SRCS
cmWriteFileCommand.cxx
cmWriteFileCommand.h
+ cm_static_string_view.hxx
cm_get_date.h
cm_get_date.c
cm_utf8.h
cm_utf8.c
cm_codecvt.hxx
cm_codecvt.cxx
- cm_thread.hxx
cmDuration.h
cmDuration.cxx
@@ -824,6 +853,7 @@ endforeach()
# create a library used by the command line and the GUI
add_library(CMakeLib ${SRCS})
target_link_libraries(CMakeLib cmsys
+ ${CMAKE_STD_LIBRARY}
${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
${CMAKE_TAR_LIBRARIES}
${CMAKE_CURL_LIBRARIES}
@@ -869,6 +899,7 @@ include_directories(
#
set(CTEST_SRCS cmCTest.cxx
CTest/cmProcess.cxx
+ CTest/cmCTestBinPacker.cxx
CTest/cmCTestBuildAndTestHandler.cxx
CTest/cmCTestBuildCommand.cxx
CTest/cmCTestBuildHandler.cxx
@@ -888,11 +919,14 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
+ CTest/cmCTestResourceAllocator.cxx
+ CTest/cmCTestResourceSpec.cxx
CTest/cmCTestLaunch.cxx
CTest/cmCTestMemCheckCommand.cxx
CTest/cmCTestMemCheckHandler.cxx
CTest/cmCTestMultiProcessHandler.cxx
CTest/cmCTestReadCustomFilesCommand.cxx
+ CTest/cmCTestResourceGroupsLexerHelper.cxx
CTest/cmCTestRunScriptCommand.cxx
CTest/cmCTestRunTest.cxx
CTest/cmCTestScriptHandler.cxx
@@ -923,6 +957,10 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestHG.h
CTest/cmCTestP4.cxx
CTest/cmCTestP4.h
+
+ LexerParser/cmCTestResourceGroupsLexer.cxx
+ LexerParser/cmCTestResourceGroupsLexer.h
+ LexerParser/cmCTestResourceGroupsLexer.in.l
)
# Build CTestLib
@@ -949,12 +987,6 @@ set(CPACK_SRCS
CPack/cmCPackNSISGenerator.cxx
CPack/cmCPackNuGetGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
- CPack/cmCPackTGZGenerator.cxx
- CPack/cmCPackTXZGenerator.cxx
- CPack/cmCPackTarBZip2Generator.cxx
- CPack/cmCPackTarCompressGenerator.cxx
- CPack/cmCPackZIPGenerator.cxx
- CPack/cmCPack7zGenerator.cxx
)
# CPack IFW generator
set(CPACK_SRCS ${CPACK_SRCS}
@@ -1121,7 +1153,7 @@ target_link_libraries(cpack CPackLib)
# Curses GUI
if(BUILD_CursesDialog)
- include(${CMake_SOURCE_DIR}/Source/CursesDialog/CMakeLists.txt)
+ add_subdirectory(CursesDialog)
endif()
# Qt GUI
@@ -1134,6 +1166,21 @@ include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
if(WIN32)
+ # Compute the binary version that appears in the RC file. Version
+ # components in the RC file are 16-bit integers so we may have to
+ # split the patch component.
+ if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$")
+ set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}")
+ set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}")
+ string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}")
+ set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY})
+ unset(CMake_RCVERSION_MONTH_DAY)
+ unset(CMake_RCVERSION_YEAR)
+ else()
+ set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH},0)
+ endif()
+ set(CMake_RCVERSION_STR ${CMake_VERSION})
+
# Add Windows executable version information.
configure_file("CMakeVersion.rc.in" "CMakeVersion.rc" @ONLY)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index c4c477929..ee9401a7d 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,84 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 15)
-set(CMake_VERSION_PATCH 7)
+set(CMake_VERSION_MINOR 16)
+set(CMake_VERSION_PATCH 0)
#set(CMake_VERSION_RC 0)
+set(CMake_VERSION_IS_DIRTY 0)
+
+# Start with the full version number used in tags. It has no dev info.
+set(CMake_VERSION
+ "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+if(DEFINED CMake_VERSION_RC)
+ set(CMake_VERSION "${CMake_VERSION}-rc${CMake_VERSION_RC}")
+endif()
+
+# Releases define a small patch level.
+if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000)
+ set(CMake_VERSION_IS_RELEASE 1)
+else()
+ set(CMake_VERSION_IS_RELEASE 0)
+endif()
+
+if(NOT CMake_VERSION_NO_GIT)
+ # If this source was exported by 'git archive', use its commit info.
+ set(git_info [==[1b4482f65d CMake 3.16.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]* "
+ AND EXISTS ${CMake_SOURCE_DIR}/.git)
+ find_package(Git QUIET)
+ if(GIT_FOUND)
+ macro(_git)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} ${ARGN}
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ RESULT_VARIABLE _git_res
+ OUTPUT_VARIABLE _git_out OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _git_err ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ endmacro()
+ endif()
+ if(COMMAND _git)
+ # Get the commit checked out in this work tree.
+ _git(log -n 1 HEAD "--pretty=format:%h %s" --)
+ set(git_info "${_git_out}")
+ endif()
+ endif()
+
+ # Extract commit information if available.
+ if(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]* (.*)$")
+ # Have commit information.
+ set(git_hash "${CMAKE_MATCH_1}")
+ set(git_subject "${CMAKE_MATCH_2}")
+
+ # If this is not the exact commit of a release, add dev info.
+ if(NOT "${git_subject}" MATCHES "^[Cc][Mm]ake ${CMake_VERSION}$")
+ set(CMake_VERSION "${CMake_VERSION}-g${git_hash}")
+ endif()
+
+ # If this is a work tree, check whether it is dirty.
+ if(COMMAND _git)
+ _git(update-index -q --refresh)
+ _git(diff-index --name-only HEAD --)
+ if(_git_out)
+ set(CMake_VERSION_IS_DIRTY 1)
+ endif()
+ endif()
+ else()
+ # No commit information.
+ if(NOT CMake_VERSION_IS_RELEASE)
+ # Generic development version.
+ set(CMake_VERSION "${CMake_VERSION}-git")
+ endif()
+ endif()
+endif()
+
+# Extract the version suffix component.
+if(CMake_VERSION MATCHES "-(.*)$")
+ set(CMake_VERSION_SUFFIX "${CMAKE_MATCH_1}")
+else()
+ set(CMake_VERSION_SUFFIX "")
+endif()
+if(CMake_VERSION_IS_DIRTY)
+ set(CMake_VERSION ${CMake_VERSION}-dirty)
+endif()
diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake
deleted file mode 100644
index 72a580058..000000000
--- a/Source/CMakeVersionCompute.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# Load version number components.
-include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake)
-
-# Releases define a small patch level.
-if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000)
- set(CMake_VERSION_IS_DIRTY 0)
- set(CMake_VERSION_IS_RELEASE 1)
- set(CMake_VERSION_SOURCE "")
-else()
- set(CMake_VERSION_IS_DIRTY 0) # may be set to 1 by CMakeVersionSource
- set(CMake_VERSION_IS_RELEASE 0)
- include(${CMake_SOURCE_DIR}/Source/CMakeVersionSource.cmake)
-endif()
-
-# Compute the full version string.
-set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
-if(CMake_VERSION_SOURCE)
- set(CMake_VERSION_SUFFIX "${CMake_VERSION_SOURCE}")
-elseif(CMake_VERSION_RC)
- set(CMake_VERSION_SUFFIX "rc${CMake_VERSION_RC}")
-else()
- set(CMake_VERSION_SUFFIX "")
-endif()
-if(CMake_VERSION_SUFFIX)
- set(CMake_VERSION ${CMake_VERSION}-${CMake_VERSION_SUFFIX})
-endif()
-if(CMake_VERSION_IS_DIRTY)
- set(CMake_VERSION ${CMake_VERSION}-dirty)
-endif()
-
-# Compute the binary version that appears in the RC file. Version
-# components in the RC file are 16-bit integers so we may have to
-# split the patch component.
-if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$")
- set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}")
- set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}")
- string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}")
- set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY})
- unset(CMake_RCVERSION_MONTH_DAY)
- unset(CMake_RCVERSION_YEAR)
-else()
- set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH})
-endif()
-set(CMake_RCVERSION_STR ${CMake_VERSION})
diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake
deleted file mode 100644
index 5ea1de3f4..000000000
--- a/Source/CMakeVersionSource.cmake
+++ /dev/null
@@ -1,30 +0,0 @@
-# Try to identify the current development source version.
-set(CMake_VERSION_SOURCE "")
-if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD)
- find_program(GIT_EXECUTABLE NAMES git git.cmd)
- mark_as_advanced(GIT_EXECUTABLE)
- if(GIT_EXECUTABLE)
- execute_process(
- COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD
- OUTPUT_VARIABLE head
- OUTPUT_STRIP_TRAILING_WHITESPACE
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- if(head)
- set(CMake_VERSION_SOURCE "g${head}")
- execute_process(
- COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- execute_process(
- COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
- OUTPUT_VARIABLE dirty
- OUTPUT_STRIP_TRAILING_WHITESPACE
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- if(dirty)
- set(CMake_VERSION_IS_DIRTY 1)
- endif()
- endif()
- endif()
-endif()
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 1e7264156..9fa74be76 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWCommon.h"
+#include <cstddef>
+#include <sstream>
+#include <utility>
+#include <vector>
+
#include "cmCPackGenerator.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackLog.h" // IWYU pragma: keep
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmVersionConfig.h"
#include "cmXMLWriter.h"
-#include <sstream>
-#include <utility>
-#include <vector>
-
cmCPackIFWCommon::cmCPackIFWCommon()
: Generator(nullptr)
{
@@ -77,8 +79,7 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version)
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::map<std::string, std::string>& argsOut)
{
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(arg, args, false);
+ std::vector<std::string> args = cmExpandedList(arg, false);
if (args.empty()) {
return;
}
@@ -99,8 +100,7 @@ void cmCPackIFWCommon::ExpandListArgument(
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::multimap<std::string, std::string>& argsOut)
{
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(arg, args, false);
+ std::vector<std::string> args = cmExpandedList(arg, false);
if (args.empty()) {
return;
}
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index c1b6eea9a..509ac6507 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWGenerator.h"
+#include <sstream>
+#include <utility>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackIFWCommon.h"
@@ -11,11 +14,9 @@
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <sstream>
-#include <utility>
-
cmCPackIFWGenerator::cmCPackIFWGenerator()
{
this->Generator = this;
@@ -34,29 +35,35 @@ int cmCPackIFWGenerator::PackageFiles()
this->Installer.GeneratePackageFiles();
std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- std::string ifwTmpFile = ifwTLD;
- ifwTmpFile += "/IFWOutput.log";
+ std::string ifwTmpFile = cmStrCat(ifwTLD, "/IFWOutput.log");
// Run repogen
if (!this->Installer.RemoteRepositories.empty()) {
- std::string ifwCmd = this->RepoGen;
+ std::vector<std::string> ifwCmd;
+ std::string ifwArg;
+
+ ifwCmd.emplace_back(this->RepoGen);
if (this->IsVersionLess("2.0.0")) {
- ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ ifwCmd.emplace_back("-c");
+ ifwCmd.emplace_back(this->toplevel + "/config/config.xml");
}
- ifwCmd += " -p " + this->toplevel + "/packages";
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(this->toplevel + "/packages");
if (!this->PkgsDirsVector.empty()) {
for (std::string const& it : this->PkgsDirsVector) {
- ifwCmd += " -p " + it;
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(it);
}
}
if (!this->RepoDirsVector.empty()) {
if (!this->IsVersionLess("3.1")) {
for (std::string const& rd : this->RepoDirsVector) {
- ifwCmd += " --repository " + rd;
+ ifwCmd.emplace_back("--repository");
+ ifwCmd.emplace_back(rd);
}
} else {
cmCPackIFWLogger(WARNING,
@@ -69,18 +76,20 @@ int cmCPackIFWGenerator::PackageFiles()
}
if (!this->OnlineOnly && !this->DownloadedPackages.empty()) {
- ifwCmd += " -i ";
- std::set<cmCPackIFWPackage*>::iterator it =
- this->DownloadedPackages.begin();
- ifwCmd += (*it)->Name;
+ ifwCmd.emplace_back("-i");
+ auto it = this->DownloadedPackages.begin();
+ ifwArg = (*it)->Name;
++it;
while (it != this->DownloadedPackages.end()) {
- ifwCmd += "," + (*it)->Name;
+ ifwArg += "," + (*it)->Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
- ifwCmd += " " + this->toplevel + "/repository";
- cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
+ ifwCmd.emplace_back(this->toplevel + "/repository");
+ cmCPackIFWLogger(VERBOSE,
+ "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl);
std::string output;
int retVal = 1;
cmCPackIFWLogger(OUTPUT, "- Generate repository" << std::endl);
@@ -89,14 +98,15 @@ int cmCPackIFWGenerator::PackageFiles()
cmDuration::zero());
if (!res || retVal) {
cmGeneratedFileStream ofs(ifwTmpFile);
- ofs << "# Run command: " << ifwCmd << std::endl
+ ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl
<< "# Output:" << std::endl
<< output << std::endl;
- cmCPackIFWLogger(ERROR,
- "Problem running IFW command: "
- << ifwCmd << std::endl
- << "Please check " << ifwTmpFile << " for errors"
- << std::endl);
+ cmCPackIFWLogger(
+ ERROR,
+ "Problem running IFW command: "
+ << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl
+ << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl);
return 0;
}
@@ -104,46 +114,54 @@ int cmCPackIFWGenerator::PackageFiles()
!this->Repository.PatchUpdatesXml()) {
cmCPackIFWLogger(WARNING,
"Problem patch IFW \"Updates\" "
- << "file: "
- << this->toplevel + "/repository/Updates.xml"
- << std::endl);
+ << "file: \"" << this->toplevel
+ << "/repository/Updates.xml\"" << std::endl);
}
cmCPackIFWLogger(OUTPUT,
- "- repository: " << this->toplevel
- << "/repository generated" << std::endl);
+ "- repository: \"" << this->toplevel
+ << "/repository\" generated"
+ << std::endl);
}
// Run binary creator
{
- std::string ifwCmd = this->BinCreator;
- ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ std::vector<std::string> ifwCmd;
+ std::string ifwArg;
+
+ ifwCmd.emplace_back(this->BinCreator);
+
+ ifwCmd.emplace_back("-c");
+ ifwCmd.emplace_back(this->toplevel + "/config/config.xml");
if (!this->Installer.Resources.empty()) {
- ifwCmd += " -r ";
- std::vector<std::string>::iterator it =
- this->Installer.Resources.begin();
+ ifwCmd.emplace_back("-r");
+ auto it = this->Installer.Resources.begin();
std::string path = this->toplevel + "/resources/";
- ifwCmd += path + *it;
+ ifwArg = path + *it;
++it;
while (it != this->Installer.Resources.end()) {
- ifwCmd += "," + path + *it;
+ ifwArg += "," + path + *it;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
- ifwCmd += " -p " + this->toplevel + "/packages";
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(this->toplevel + "/packages");
if (!this->PkgsDirsVector.empty()) {
for (std::string const& it : this->PkgsDirsVector) {
- ifwCmd += " -p " + it;
+ ifwCmd.emplace_back("-p");
+ ifwCmd.emplace_back(it);
}
}
if (!this->RepoDirsVector.empty()) {
if (!this->IsVersionLess("3.1")) {
for (std::string const& rd : this->RepoDirsVector) {
- ifwCmd += " --repository " + rd;
+ ifwCmd.emplace_back("--repository");
+ ifwCmd.emplace_back(rd);
}
} else {
cmCPackIFWLogger(WARNING,
@@ -156,44 +174,46 @@ int cmCPackIFWGenerator::PackageFiles()
}
if (this->OnlineOnly) {
- ifwCmd += " --online-only";
+ ifwCmd.emplace_back("--online-only");
} else if (!this->DownloadedPackages.empty() &&
!this->Installer.RemoteRepositories.empty()) {
- ifwCmd += " -e ";
- std::set<cmCPackIFWPackage*>::iterator it =
- this->DownloadedPackages.begin();
- ifwCmd += (*it)->Name;
+ ifwCmd.emplace_back("-e");
+ auto it = this->DownloadedPackages.begin();
+ ifwArg = (*it)->Name;
++it;
while (it != this->DownloadedPackages.end()) {
- ifwCmd += "," + (*it)->Name;
+ ifwArg += "," + (*it)->Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
} else if (!this->DependentPackages.empty()) {
- ifwCmd += " -i ";
+ ifwCmd.emplace_back("-i");
+ ifwArg.clear();
// Binary
- std::set<cmCPackIFWPackage*>::iterator bit =
- this->BinaryPackages.begin();
+ auto bit = this->BinaryPackages.begin();
while (bit != this->BinaryPackages.end()) {
- ifwCmd += (*bit)->Name + ",";
+ ifwArg += (*bit)->Name + ",";
++bit;
}
// Depend
- DependenceMap::iterator it = this->DependentPackages.begin();
- ifwCmd += it->second.Name;
+ auto it = this->DependentPackages.begin();
+ ifwArg += it->second.Name;
++it;
while (it != this->DependentPackages.end()) {
- ifwCmd += "," + it->second.Name;
+ ifwArg += "," + it->second.Name;
++it;
}
+ ifwCmd.emplace_back(ifwArg);
}
// TODO: set correct name for multipackages
if (!this->packageFileNames.empty()) {
- ifwCmd += " " + this->packageFileNames[0];
+ ifwCmd.emplace_back(this->packageFileNames[0]);
} else {
- ifwCmd += " installer";
- ifwCmd += this->OutputExtension;
+ ifwCmd.emplace_back("installer" + this->OutputExtension);
}
- cmCPackIFWLogger(VERBOSE, "Execute: " << ifwCmd << std::endl);
+ cmCPackIFWLogger(VERBOSE,
+ "Execute: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl);
std::string output;
int retVal = 1;
cmCPackIFWLogger(OUTPUT, "- Generate package" << std::endl);
@@ -202,14 +222,15 @@ int cmCPackIFWGenerator::PackageFiles()
cmDuration::zero());
if (!res || retVal) {
cmGeneratedFileStream ofs(ifwTmpFile);
- ofs << "# Run command: " << ifwCmd << std::endl
+ ofs << "# Run command: " << cmSystemTools::PrintSingleCommand(ifwCmd)
+ << std::endl
<< "# Output:" << std::endl
<< output << std::endl;
- cmCPackIFWLogger(ERROR,
- "Problem running IFW command: "
- << ifwCmd << std::endl
- << "Please check " << ifwTmpFile << " for errors"
- << std::endl);
+ cmCPackIFWLogger(
+ ERROR,
+ "Problem running IFW command: "
+ << cmSystemTools::PrintSingleCommand(ifwCmd) << std::endl
+ << "Please check \"" << ifwTmpFile << "\" for errors" << std::endl);
return 0;
}
}
@@ -253,7 +274,7 @@ int cmCPackIFWGenerator::InitializeInternal()
// Look 'binarycreator' executable (needs)
const char* BinCreatorStr = this->GetOption(BinCreatorOpt);
- if (!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr)) {
+ if (!BinCreatorStr || cmIsNOTFOUND(BinCreatorStr)) {
this->BinCreator.clear();
} else {
this->BinCreator = BinCreatorStr;
@@ -270,7 +291,7 @@ int cmCPackIFWGenerator::InitializeInternal()
// Look 'repogen' executable (optional)
const char* RepoGenStr = this->GetOption(RepoGenOpt);
- if (!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr)) {
+ if (!RepoGenStr || cmIsNOTFOUND(RepoGenStr)) {
this->RepoGen.clear();
} else {
this->RepoGen = RepoGenStr;
@@ -292,14 +313,14 @@ int cmCPackIFWGenerator::InitializeInternal()
// Additional packages dirs
this->PkgsDirsVector.clear();
if (const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) {
- cmSystemTools::ExpandListArgument(dirs, this->PkgsDirsVector);
+ cmExpandList(dirs, this->PkgsDirsVector);
}
// Additional repositories dirs
this->RepoDirsVector.clear();
if (const char* dirs =
this->GetOption("CPACK_IFW_REPOSITORIES_DIRECTORIES")) {
- cmSystemTools::ExpandListArgument(dirs, this->RepoDirsVector);
+ cmExpandList(dirs, this->RepoDirsVector);
}
// Installer
@@ -316,18 +337,17 @@ int cmCPackIFWGenerator::InitializeInternal()
// Repositories
if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
- std::vector<std::string> RepoAllVector;
- cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector);
+ std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr);
for (std::string const& r : RepoAllVector) {
this->GetRepository(r);
}
}
if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) {
- this->OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
+ this->OnlineOnly = cmIsOn(ifwDownloadAll);
} else if (const char* cpackDownloadAll =
this->GetOption("CPACK_DOWNLOAD_ALL")) {
- this->OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
+ this->OnlineOnly = cmIsOn(cpackDownloadAll);
} else {
this->OnlineOnly = false;
}
@@ -386,7 +406,7 @@ std::string cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(
cmCPackComponent* cmCPackIFWGenerator::GetComponent(
const std::string& projectName, const std::string& componentName)
{
- ComponentsMap::iterator cit = this->Components.find(componentName);
+ auto cit = this->Components.find(componentName);
if (cit != this->Components.end()) {
return &(cit->second);
}
@@ -398,7 +418,7 @@ cmCPackComponent* cmCPackIFWGenerator::GetComponent(
}
std::string name = this->GetComponentPackageName(component);
- PackagesMap::iterator pit = this->Packages.find(name);
+ auto pit = this->Packages.find(name);
if (pit != this->Packages.end()) {
return component;
}
@@ -438,7 +458,7 @@ cmCPackComponentGroup* cmCPackIFWGenerator::GetComponentGroup(
}
std::string name = this->GetGroupPackageName(group);
- PackagesMap::iterator pit = this->Packages.find(name);
+ auto pit = this->Packages.find(name);
if (pit != this->Packages.end()) {
return group;
}
@@ -569,23 +589,21 @@ std::string cmCPackIFWGenerator::GetComponentPackageName(
cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage(
cmCPackComponentGroup* group) const
{
- std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit =
- this->GroupPackages.find(group);
+ auto pit = this->GroupPackages.find(group);
return pit != this->GroupPackages.end() ? pit->second : nullptr;
}
cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
cmCPackComponent* component) const
{
- std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit =
- this->ComponentPackages.find(component);
+ auto pit = this->ComponentPackages.find(component);
return pit != this->ComponentPackages.end() ? pit->second : nullptr;
}
cmCPackIFWRepository* cmCPackIFWGenerator::GetRepository(
const std::string& repositoryName)
{
- RepositoriesMap::iterator rit = this->Repositories.find(repositoryName);
+ auto rit = this->Repositories.find(repositoryName);
if (rit != this->Repositories.end()) {
return &(rit->second);
}
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h
index 0430122c9..86a73c83f 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.h
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.h
@@ -5,6 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackIFWCommon.h"
@@ -12,11 +17,6 @@
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
/** \class cmCPackIFWGenerator
* \brief A generator for Qt Installer Framework tools
*
@@ -29,12 +29,12 @@ class cmCPackIFWGenerator
public:
cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator);
- typedef std::map<std::string, cmCPackIFWPackage> PackagesMap;
- typedef std::map<std::string, cmCPackIFWRepository> RepositoriesMap;
- typedef std::map<std::string, cmCPackComponent> ComponentsMap;
- typedef std::map<std::string, cmCPackComponentGroup> ComponentGoupsMap;
- typedef std::map<std::string, cmCPackIFWPackage::DependenceStruct>
- DependenceMap;
+ using PackagesMap = std::map<std::string, cmCPackIFWPackage>;
+ using RepositoriesMap = std::map<std::string, cmCPackIFWRepository>;
+ using ComponentsMap = std::map<std::string, cmCPackComponent>;
+ using ComponentGoupsMap = std::map<std::string, cmCPackComponentGroup>;
+ using DependenceMap =
+ std::map<std::string, cmCPackIFWPackage::DependenceStruct>;
using cmCPackIFWCommon::GetOption;
using cmCPackIFWCommon::IsOn;
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index a075a17e3..4bad598e9 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -2,20 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWInstaller.h"
+#include <cstddef>
+#include <sstream>
+#include <utility>
+
#include "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"
-#include <sstream>
-#include <stddef.h>
-#include <utility>
-
cmCPackIFWInstaller::cmCPackIFWInstaller() = default;
void cmCPackIFWInstaller::printSkippedOptionWarning(
@@ -192,8 +193,8 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
this->TargetDir = optIFW_TARGET_DIRECTORY;
} else if (const char* optPACKAGE_INSTALL_DIRECTORY =
this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) {
- this->TargetDir = "@ApplicationsDir@/";
- this->TargetDir += optPACKAGE_INSTALL_DIRECTORY;
+ this->TargetDir =
+ cmStrCat("@ApplicationsDir@/", optPACKAGE_INSTALL_DIRECTORY);
} else {
this->TargetDir = "@RootDir@/usr/local";
}
@@ -244,8 +245,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
if (const char* optIFW_PACKAGE_RESOURCES =
this->GetOption("CPACK_IFW_PACKAGE_RESOURCES")) {
this->Resources.clear();
- cmSystemTools::ExpandListArgument(optIFW_PACKAGE_RESOURCES,
- this->Resources);
+ cmExpandList(optIFW_PACKAGE_RESOURCES, this->Resources);
}
}
@@ -292,7 +292,7 @@ protected:
{
if (this->file) {
std::string content(data, data + length);
- content = cmSystemTools::TrimWhitespace(content);
+ content = cmTrimWhitespace(content);
std::string source = this->basePath + "/" + content;
std::string destination = this->path + "/" + content;
if (!cmSystemTools::CopyFileIfDifferent(source, destination)) {
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
index be51fa5fb..8b3f96af8 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.h
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackIFWCommon.h"
-
#include <map>
#include <string>
#include <vector>
+#include "cmCPackIFWCommon.h"
+
class cmCPackIFWPackage;
class cmCPackIFWRepository;
@@ -22,8 +22,8 @@ class cmCPackIFWInstaller : public cmCPackIFWCommon
public:
// Types
- typedef std::map<std::string, cmCPackIFWPackage*> PackagesMap;
- typedef std::vector<cmCPackIFWRepository*> RepositoriesVector;
+ using PackagesMap = std::map<std::string, cmCPackIFWPackage*>;
+ using RepositoriesVector = std::vector<cmCPackIFWRepository*>;
public:
// Constructor
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index a1a52b185..9a9cd5678 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -2,21 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWPackage.h"
+#include <cstddef>
+#include <map>
+#include <sstream>
+#include <utility>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackIFWCommon.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWInstaller.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmXMLWriter.h"
-#include <map>
-#include <sstream>
-#include <stddef.h>
-#include <utility>
-
//---------------------------------------------------------- CompareStruct ---
cmCPackIFWPackage::CompareStruct::CompareStruct()
: Type(cmCPackIFWPackage::CompareNone)
@@ -196,7 +197,7 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
// User interfaces
if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
this->UserInterfaces.clear();
- cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
+ cmExpandList(option, this->UserInterfaces);
}
// CMake dependencies
@@ -209,7 +210,7 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
// Licenses
if (const char* option = this->GetOption(prefix + "LICENSES")) {
this->Licenses.clear();
- cmSystemTools::ExpandListArgument(option, this->Licenses);
+ cmExpandList(option, this->Licenses);
if (this->Licenses.size() % 2 != 0) {
cmCPackIFWLogger(
WARNING,
@@ -281,13 +282,13 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group)
// User interfaces
if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
this->UserInterfaces.clear();
- cmSystemTools::ExpandListArgument(option, this->UserInterfaces);
+ cmExpandList(option, this->UserInterfaces);
}
// Licenses
if (const char* option = this->GetOption(prefix + "LICENSES")) {
this->Licenses.clear();
- cmSystemTools::ExpandListArgument(option, this->Licenses);
+ cmExpandList(option, this->Licenses);
if (this->Licenses.size() % 2 != 0) {
cmCPackIFWLogger(
WARNING,
@@ -398,18 +399,18 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
this->Translations.clear();
} else if (const char* value = this->GetOption(option)) {
this->Translations.clear();
- cmSystemTools::ExpandListArgument(value, this->Translations);
+ cmExpandList(value, this->Translations);
}
// QtIFW dependencies
std::vector<std::string> deps;
option = prefix + "DEPENDS";
if (const char* value = this->GetOption(option)) {
- cmSystemTools::ExpandListArgument(value, deps);
+ cmExpandList(value, deps);
}
option = prefix + "DEPENDENCIES";
if (const char* value = this->GetOption(option)) {
- cmSystemTools::ExpandListArgument(value, deps);
+ cmExpandList(value, deps);
}
for (std::string const& d : deps) {
DependenceStruct dep(d);
@@ -430,8 +431,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
if (this->IsSetToEmpty(option)) {
this->AlienAutoDependOn.clear();
} else if (const char* value = this->GetOption(option)) {
- std::vector<std::string> depsOn;
- cmSystemTools::ExpandListArgument(value, depsOn);
+ std::vector<std::string> depsOn = cmExpandedList(value);
for (std::string const& d : depsOn) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
@@ -488,7 +488,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
this->Replaces.clear();
} else if (const char* value = this->GetOption(option)) {
this->Replaces.clear();
- cmSystemTools::ExpandListArgument(value, this->Replaces);
+ cmExpandList(value, this->Replaces);
}
// Requires admin rights
@@ -620,7 +620,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
// Write dependencies
if (!compDepSet.empty()) {
std::ostringstream dependencies;
- std::set<DependenceStruct>::iterator it = compDepSet.begin();
+ auto it = compDepSet.begin();
dependencies << it->NameWithCompare();
++it;
while (it != compDepSet.end()) {
@@ -638,7 +638,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
// Write automatic dependency on
if (!compAutoDepSet.empty()) {
std::ostringstream dependencies;
- std::set<DependenceStruct>::iterator it = compAutoDepSet.begin();
+ auto it = compAutoDepSet.begin();
dependencies << it->NameWithCompare();
++it;
while (it != compAutoDepSet.end()) {
@@ -674,7 +674,7 @@ void cmCPackIFWPackage::GeneratePackageFile()
// Replaces
if (!this->Replaces.empty()) {
std::ostringstream replaces;
- std::vector<std::string>::iterator it = this->Replaces.begin();
+ auto it = this->Replaces.begin();
replaces << *it;
++it;
while (it != this->Replaces.end()) {
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h
index ae411462a..6a4a170a5 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.h
+++ b/Source/CPack/IFW/cmCPackIFWPackage.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackIFWCommon.h"
-
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmCPackIFWCommon.h"
+
class cmCPackComponent;
class cmCPackComponentGroup;
class cmCPackIFWInstaller;
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index 8042167ed..a6965491e 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -2,14 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWRepository.h"
+#include <cstddef>
+
#include "cmCPackIFWGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"
-#include <stddef.h>
-
cmCPackIFWRepository::cmCPackIFWRepository()
: Update(cmCPackIFWRepository::None)
{
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.h b/Source/CPack/IFW/cmCPackIFWRepository.h
index 227cfae7a..c29398124 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.h
+++ b/Source/CPack/IFW/cmCPackIFWRepository.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackIFWCommon.h"
-
#include <string>
#include <vector>
+#include "cmCPackIFWCommon.h"
+
class cmXMLWriter;
/** \class cmCPackIFWRepository
@@ -28,7 +28,7 @@ public:
Replace
};
- typedef std::vector<cmCPackIFWRepository*> RepositoriesVector;
+ using RepositoriesVector = std::vector<cmCPackIFWRepository*>;
public:
// Constructor
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 00d272c83..21d27a02d 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -1,15 +1,16 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
-#include "cmsys/SystemTools.hxx"
+#include <cstddef>
#include <iostream>
-#include <stddef.h>
#include <string>
#include <vector>
#include <CoreFoundation/CoreFoundation.h>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
+#include "cmsys/SystemTools.hxx"
+
// For the PATH_MAX constant
#include <sys/syslimits.h>
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.cxx b/Source/CPack/WiX/cmCMakeToWixPath.cxx
index b3889cf2e..87385011a 100644
--- a/Source/CPack/WiX/cmCMakeToWixPath.cxx
+++ b/Source/CPack/WiX/cmCMakeToWixPath.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeToWixPath.h"
-#include "cmSystemTools.h"
-
#include <string>
#include <vector>
+#include "cmStringAlgorithms.h"
+
#ifdef __CYGWIN__
# include <sys/cygwin.h>
std::string CMakeToWixPath(const std::string& cygpath)
@@ -29,7 +29,7 @@ std::string CMakeToWixPath(const std::string& cygpath)
return cygpath;
}
- return cmSystemTools::TrimWhitespace(winpath_chars.data());
+ return cmTrimWhitespace(winpath_chars.data());
}
#else
std::string CMakeToWixPath(const std::string& path)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 045d93d87..e71a38fd2 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -2,26 +2,30 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackWIXGenerator.h"
+#include <algorithm>
+
+#include <cm/string_view>
+
+#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"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUuid.h"
-#include <algorithm>
-
#include "cmWIXDirectoriesSourceWriter.h"
#include "cmWIXFeaturesSourceWriter.h"
#include "cmWIXFilesSourceWriter.h"
#include "cmWIXRichTextFormatWriter.h"
#include "cmWIXSourceWriter.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/Encoding.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/SystemTools.hxx"
-
#ifdef _WIN32
# include <rpc.h> // for GUID generation (windows only)
#else
@@ -225,8 +229,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if (patchFilePath) {
- std::vector<std::string> patchFilePaths;
- cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);
+ std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath);
for (std::string const& p : patchFilePaths) {
if (!this->Patch->LoadFragments(p)) {
@@ -237,7 +240,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
// if install folder is supposed to be set absolutely, the default
// component guid "*" cannot be used
- if (cmSystemTools::IsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
+ if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
this->ComponentGuidType = cmWIXSourceWriter::CMAKE_GENERATED_GUID;
}
@@ -300,7 +303,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
if (!cpackWixExtraSources)
return;
- cmSystemTools::ExpandListArgument(cpackWixExtraSources, this->WixSources);
+ cmExpandList(cpackWixExtraSources, this->WixSources);
}
void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
@@ -309,10 +312,8 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
if (!cpackWixExtraObjects)
return;
- std::vector<std::string> expandedExtraObjects;
-
- cmSystemTools::ExpandListArgument(cpackWixExtraObjects,
- expandedExtraObjects);
+ std::vector<std::string> expandedExtraObjects =
+ cmExpandedList(cpackWixExtraObjects);
for (std::string const& obj : expandedExtraObjects) {
stream << " " << QuotePath(obj);
@@ -518,9 +519,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
for (auto const& i : this->Components) {
cmCPackComponent const& component = i.second;
- std::string componentPath = toplevel;
- componentPath += "/";
- componentPath += component.Name;
+ std::string componentPath = cmStrCat(toplevel, '/', component.Name);
std::string const componentFeatureId = "CM_C_" + component.Name;
@@ -539,9 +538,16 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
}
}
- bool emitUninstallShortcut =
- emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
- emittedShortcutTypes.end();
+ bool emitUninstallShortcut = true;
+ const char* cpackWixProgramMenuFolder =
+ GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
+ if (cpackWixProgramMenuFolder &&
+ cm::string_view(cpackWixProgramMenuFolder) == ".") {
+ emitUninstallShortcut = false;
+ } else if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) ==
+ emittedShortcutTypes.end()) {
+ emitUninstallShortcut = false;
+ }
if (!CreateShortcuts(std::string(), "ProductFeature", globalShortcuts,
emitUninstallShortcut, fileDefinitions,
@@ -582,7 +588,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
std::string cmCPackWIXGenerator::GetRootFolderId() const
{
- if (cmSystemTools::IsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
+ if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) {
return "";
}
@@ -664,8 +670,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
std::vector<std::string> cpackPackageExecutablesList;
const char* cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
if (cpackPackageExecutables) {
- cmSystemTools::ExpandListArgument(cpackPackageExecutables,
- cpackPackageExecutablesList);
+ cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList);
if (cpackPackageExecutablesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -680,8 +685,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
const char* cpackPackageDesktopLinks =
GetOption("CPACK_CREATE_DESKTOP_LINKS");
if (cpackPackageDesktopLinks) {
- cmSystemTools::ExpandListArgument(cpackPackageDesktopLinks,
- cpackPackageDesktopLinksList);
+ cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList);
}
AddDirectoryAndFileDefinitions(
@@ -737,9 +741,16 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
{
std::string directoryId;
switch (type) {
- case cmWIXShortcuts::START_MENU:
- directoryId = "PROGRAM_MENU_FOLDER";
- break;
+ case cmWIXShortcuts::START_MENU: {
+ const char* cpackWixProgramMenuFolder =
+ GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
+ if (cpackWixProgramMenuFolder &&
+ cm::string_view(cpackWixProgramMenuFolder) == ".") {
+ directoryId = "ProgramMenuFolder";
+ } else {
+ directoryId = "PROGRAM_MENU_FOLDER";
+ }
+ } break;
case cmWIXShortcuts::DESKTOP:
directoryId = "DesktopFolder";
break;
@@ -793,8 +804,13 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
fileDefinitions);
if (type == cmWIXShortcuts::START_MENU) {
- fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" +
- idSuffix);
+ const char* cpackWixProgramMenuFolder =
+ GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
+ if (cpackWixProgramMenuFolder &&
+ cm::string_view(cpackWixProgramMenuFolder) != ".") {
+ fileDefinitions.EmitRemoveFolder("CM_REMOVE_PROGRAM_MENU_FOLDER" +
+ idSuffix);
+ }
}
if (emitUninstallShortcut) {
@@ -944,9 +960,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
shortcut.workingDirectoryId = directoryId;
shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
- if (!desktopExecutables.empty() &&
- std::find(desktopExecutables.begin(), desktopExecutables.end(),
- executableName) != desktopExecutables.end()) {
+ if (cmContains(desktopExecutables, executableName)) {
shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
}
}
@@ -1090,8 +1104,7 @@ std::string cmCPackWIXGenerator::CreateHashedId(
cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
std::string const hash = sha1.HashString(path);
- std::string identifier;
- identifier += hash.substr(0, 7) + "_";
+ std::string identifier = cmStrCat(cm::string_view(hash).substr(0, 7), '_');
const size_t maxFileNameLength = 52;
if (normalizedFilename.length() > maxFileNameLength) {
@@ -1136,8 +1149,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(variableContent, list);
+ std::vector<std::string> list = cmExpandedList(variableContent);
extensions.insert(list.begin(), list.end());
}
@@ -1148,8 +1160,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(variableContent, list);
+ std::vector<std::string> list = cmExpandedList(variableContent);
for (std::string const& i : list) {
stream << " " << QuotePath(i);
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index f8c76449b..d1933483f 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -3,14 +3,13 @@
#ifndef cmCPackWIXGenerator_h
#define cmCPackWIXGenerator_h
-#include "cmCPackGenerator.h"
+#include <map>
+#include <string>
+#include "cmCPackGenerator.h"
#include "cmWIXPatch.h"
#include "cmWIXShortcut.h"
-#include <map>
-#include <string>
-
class cmWIXSourceWriter;
class cmWIXDirectoriesSourceWriter;
class cmWIXFilesSourceWriter;
@@ -44,9 +43,9 @@ protected:
bool SupportsComponentInstallation() const override { return true; }
private:
- typedef std::map<std::string, std::string> id_map_t;
- typedef std::map<std::string, size_t> ambiguity_map_t;
- typedef std::set<std::string> extension_set_t;
+ using id_map_t = std::map<std::string, std::string>;
+ using ambiguity_map_t = std::map<std::string, size_t>;
+ using extension_set_t = std::set<std::string>;
enum class DefinitionType
{
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 563de02ae..3668b4613 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -3,7 +3,7 @@
#include "cmWIXAccessControlList.h"
#include "cmCPackGenerator.h"
-
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmWIXAccessControlList::cmWIXAccessControlList(
@@ -48,8 +48,7 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
user = user_and_domain;
}
- std::vector<std::string> permissions =
- cmSystemTools::tokenize(permission_string, ",");
+ std::vector<std::string> permissions = cmTokenize(permission_string, ",");
this->SourceWriter.BeginElement("Permission");
this->SourceWriter.AddAttribute("User", user);
@@ -57,8 +56,7 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
this->SourceWriter.AddAttribute("Domain", domain);
}
for (std::string const& permission : permissions) {
- this->EmitBooleanAttribute(entry,
- cmSystemTools::TrimWhitespace(permission));
+ this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
}
this->SourceWriter.EndElement("Permission");
}
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.h b/Source/CPack/WiX/cmWIXAccessControlList.h
index 2a23f2f37..64f9a1382 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.h
+++ b/Source/CPack/WiX/cmWIXAccessControlList.h
@@ -3,10 +3,9 @@
#ifndef cmWIXAccessControlList_h
#define cmWIXAccessControlList_h
-#include "cmWIXSourceWriter.h"
-
#include "cmCPackLog.h"
#include "cmInstalledFile.h"
+#include "cmWIXSourceWriter.h"
class cmWIXAccessControlList
{
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
index 975dffb4f..0a83ca2c0 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -14,10 +14,12 @@ void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
BeginElement("Directory");
AddAttribute("Id", "ProgramMenuFolder");
- BeginElement("Directory");
- AddAttribute("Id", "PROGRAM_MENU_FOLDER");
- AddAttribute("Name", startMenuFolder);
- EndElement("Directory");
+ if (startMenuFolder != ".") {
+ BeginElement("Directory");
+ AddAttribute("Id", "PROGRAM_MENU_FOLDER");
+ AddAttribute("Name", startMenuFolder);
+ EndElement("Directory");
+ }
EndElement("Directory");
}
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
index 8233331a3..a907d6d18 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
@@ -3,11 +3,10 @@
#ifndef cmWIXDirectoriesSourceWriter_h
#define cmWIXDirectoriesSourceWriter_h
-#include "cmWIXSourceWriter.h"
+#include <string>
#include "cmCPackGenerator.h"
-
-#include <string>
+#include "cmWIXSourceWriter.h"
/** \class cmWIXDirectoriesSourceWriter
* \brief Helper class to generate directories.wxs
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
index e751ca719..e03e87bad 100644
--- a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
@@ -3,11 +3,10 @@
#ifndef cmWIXFeaturesSourceWriter_h
#define cmWIXFeaturesSourceWriter_h
+#include "cmCPackGenerator.h"
#include "cmWIXPatch.h"
#include "cmWIXSourceWriter.h"
-#include "cmCPackGenerator.h"
-
/** \class cmWIXFeaturesSourceWriter
* \brief Helper class to generate features.wxs
*/
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index dd3caf9d3..c0d879a0c 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -2,16 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXFilesSourceWriter.h"
-#include "cmWIXAccessControlList.h"
+#include "cm_sys_stat.h"
+#include "cmCMakeToWixPath.h"
#include "cmInstalledFile.h"
-
#include "cmSystemTools.h"
#include "cmUuid.h"
-
-#include "cm_sys_stat.h"
-
-#include "cmCMakeToWixPath.h"
+#include "cmWIXAccessControlList.h"
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
std::string const& filename,
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
index dc9c636d3..8cc98f52b 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -3,12 +3,10 @@
#ifndef cmWIXFilesSourceWriter_h
#define cmWIXFilesSourceWriter_h
-#include "cmWIXSourceWriter.h"
-
+#include "cmCPackGenerator.h"
#include "cmWIXPatch.h"
#include "cmWIXShortcut.h"
-
-#include "cmCPackGenerator.h"
+#include "cmWIXSourceWriter.h"
/** \class cmWIXFilesSourceWriter
* \brief Helper class to generate files.wxs
diff --git a/Source/CPack/WiX/cmWIXPatch.h b/Source/CPack/WiX/cmWIXPatch.h
index a4c9e714d..31a60f4e8 100644
--- a/Source/CPack/WiX/cmWIXPatch.h
+++ b/Source/CPack/WiX/cmWIXPatch.h
@@ -3,11 +3,11 @@
#ifndef cmWIXPatch_h
#define cmWIXPatch_h
+#include <string>
+
#include "cmWIXPatchParser.h"
#include "cmWIXSourceWriter.h"
-#include <string>
-
/** \class cmWIXPatch
* \brief Class that maintains and applies patch fragments
*/
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index c6ca9441a..fd9103bc1 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXPatchParser.h"
-#include "cmCPackGenerator.h"
-
#include "cm_expat.h"
+#include "cmCPackGenerator.h"
+
cmWIXPatchNode::Type cmWIXPatchText::type()
{
return cmWIXPatchNode::TEXT;
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index 52c7e3524..87dd89288 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -3,13 +3,12 @@
#ifndef cmCPackWIXPatchParser_h
#define cmCPackWIXPatchParser_h
-#include "cmCPackLog.h"
-
-#include "cmXMLParser.h"
-
#include <map>
#include <vector>
+#include "cmCPackLog.h"
+#include "cmXMLParser.h"
+
struct cmWIXPatchNode
{
enum Type
@@ -36,8 +35,8 @@ struct cmWIXPatchElement : cmWIXPatchNode
~cmWIXPatchElement();
- typedef std::vector<cmWIXPatchNode*> child_list_t;
- typedef std::map<std::string, std::string> attributes_t;
+ using child_list_t = std::vector<cmWIXPatchNode*>;
+ using attributes_t = std::map<std::string, std::string>;
std::string name;
child_list_t children;
@@ -50,7 +49,7 @@ struct cmWIXPatchElement : cmWIXPatchNode
class cmWIXPatchParser : public cmXMLParser
{
public:
- typedef std::map<std::string, cmWIXPatchElement> fragment_map_t;
+ using fragment_map_t = std::map<std::string, cmWIXPatchElement>;
cmWIXPatchParser(fragment_map_t& Fragments, cmCPackLog* logger);
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
index 2c99a2284..751f7dc3a 100644
--- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
@@ -25,7 +25,7 @@ cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
void cmWIXRichTextFormatWriter::AddText(std::string const& text)
{
- typedef unsigned char rtf_byte_t;
+ using rtf_byte_t = unsigned char;
for (size_t i = 0; i < text.size(); ++i) {
rtf_byte_t c = rtf_byte_t(text[i]);
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
index 21be8ee66..a879f3da9 100644
--- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
@@ -5,9 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/FStream.hxx"
#include <string>
+#include "cmsys/FStream.hxx"
+
/** \class cmWIXRichtTextFormatWriter
* \brief Helper class to generate Rich Text Format (RTF) documents
* from plain text (e.g. for license and welcome text)
diff --git a/Source/CPack/WiX/cmWIXShortcut.h b/Source/CPack/WiX/cmWIXShortcut.h
index 23ddc6a3f..c67baf369 100644
--- a/Source/CPack/WiX/cmWIXShortcut.h
+++ b/Source/CPack/WiX/cmWIXShortcut.h
@@ -3,13 +3,13 @@
#ifndef cmWIXShortcut_h
#define cmWIXShortcut_h
-#include "cmInstalledFile.h"
-
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmInstalledFile.h"
+
class cmWIXFilesSourceWriter;
struct cmWIXShortcut
@@ -28,8 +28,8 @@ public:
STARTUP
};
- typedef std::vector<cmWIXShortcut> shortcut_list_t;
- typedef std::map<std::string, shortcut_list_t> shortcut_id_map_t;
+ using shortcut_list_t = std::vector<cmWIXShortcut>;
+ using shortcut_id_map_t = std::map<std::string, shortcut_list_t>;
void insert(Type type, std::string const& id, cmWIXShortcut const& shortcut);
@@ -46,7 +46,7 @@ public:
cmInstalledFile const& installedFile);
private:
- typedef std::map<Type, shortcut_id_map_t> shortcut_type_map_t;
+ using shortcut_type_map_t = std::map<Type, shortcut_id_map_t>;
void CreateFromProperty(std::string const& propertyName, Type type,
std::string const& id,
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 6adf80bac..8e9bfdf3f 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -2,12 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXSourceWriter.h"
-#include "cmCPackGenerator.h"
+#include <windows.h>
+#include "cmCPackGenerator.h"
#include "cmUuid.h"
-#include <windows.h>
-
cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
std::string const& filename,
GuidType componentGuidType,
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 4af1ed6ed..8cc2070a8 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -3,12 +3,12 @@
#ifndef cmWIXSourceWriter_h
#define cmWIXSourceWriter_h
-#include "cmCPackLog.h"
+#include <string>
+#include <vector>
#include "cmsys/FStream.hxx"
-#include <string>
-#include <vector>
+#include "cmCPackLog.h"
/** \class cmWIXSourceWriter
* \brief Helper class to generate XML WiX source files
diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx
deleted file mode 100644
index 741377012..000000000
--- a/Source/CPack/cmCPack7zGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPack7zGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPack7zGenerator::cmCPack7zGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip")
-{
-}
-
-cmCPack7zGenerator::~cmCPack7zGenerator() = default;
diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h
deleted file mode 100644
index 8af4c4a4d..000000000
--- a/Source/CPack/cmCPack7zGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPack7zGenerator_h
-#define cmCPack7zGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPack7zGenerator
- * \brief A generator for 7z files
- */
-class cmCPack7zGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPack7zGenerator, cmCPackArchiveGenerator);
-
- /**
- * Construct generator
- */
- cmCPack7zGenerator();
- ~cmCPack7zGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".7z"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 98fb29d14..43f2946bd 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -2,24 +2,68 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackArchiveGenerator.h"
+#include <cstring>
+#include <map>
+#include <ostream>
+#include <utility>
+#include <vector>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
-#include <cstring>
-#include <map>
-#include <ostream>
-#include <utility>
-#include <vector>
+cmCPackGenerator* cmCPackArchiveGenerator::Create7ZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip",
+ ".7z");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTBZ2Generator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr",
+ ".tar.bz2");
+}
-cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t,
- std::string const& format)
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTGZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr",
+ ".tar.gz");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTXZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr",
+ ".tar.xz");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr",
+ ".tar.Z");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTZSTGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressZstd, "paxr",
+ ".tar.zst");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateZIPGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip",
+ ".zip");
+}
+
+cmCPackArchiveGenerator::cmCPackArchiveGenerator(
+ cmArchiveWrite::Compress compress, std::string format, std::string extension)
+ : Compress(compress)
+ , ArchiveFormat(std::move(format))
+ , OutputExtension(std::move(extension))
{
- this->Compress = t;
- this->ArchiveFormat = format;
}
cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default;
@@ -71,8 +115,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
}
std::string filePrefix;
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
- filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
- filePrefix += "/";
+ filePrefix = cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), '/');
}
const char* installPrefix =
this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 998385432..8d677208f 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmArchiveWrite.h"
-#include "cmCPackGenerator.h"
-
#include <iosfwd>
#include <string>
+#include "cmArchiveWrite.h"
+#include "cmCPackGenerator.h"
+
class cmCPackComponent;
/** \class cmCPackArchiveGenerator
@@ -22,12 +22,21 @@ class cmCPackComponent;
class cmCPackArchiveGenerator : public cmCPackGenerator
{
public:
- typedef cmCPackGenerator Superclass;
+ using Superclass = cmCPackGenerator;
+
+ static cmCPackGenerator* Create7ZGenerator();
+ static cmCPackGenerator* CreateTBZ2Generator();
+ static cmCPackGenerator* CreateTGZGenerator();
+ static cmCPackGenerator* CreateTXZGenerator();
+ static cmCPackGenerator* CreateTZGenerator();
+ static cmCPackGenerator* CreateTZSTGenerator();
+ static cmCPackGenerator* CreateZIPGenerator();
/**
* Construct generator
*/
- cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format);
+ cmCPackArchiveGenerator(cmArchiveWrite::Compress t, std::string format,
+ std::string extension);
~cmCPackArchiveGenerator() override;
// Used to add a header to the archive
virtual int GenerateHeader(std::ostream* os);
@@ -68,9 +77,19 @@ protected:
* components will be put in a single installer.
*/
int PackageComponentsAllInOne();
- const char* GetOutputExtension() override = 0;
+
+private:
+ const char* GetNameOfClass() override { return "cmCPackArchiveGenerator"; }
+
+ const char* GetOutputExtension() override
+ {
+ return this->OutputExtension.c_str();
+ }
+
+private:
cmArchiveWrite::Compress Compress;
std::string ArchiveFormat;
+ std::string OutputExtension;
};
#endif
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index 3a476f44b..4d5f43f9e 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -6,6 +6,7 @@
#include <vector>
#include "cmCPackLog.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmCPackBundleGenerator::cmCPackBundleGenerator() = default;
@@ -40,9 +41,8 @@ int cmCPackBundleGenerator::InitializeInternal()
const char* cmCPackBundleGenerator::GetPackagingInstallPrefix()
{
- this->InstallPrefix = "/";
- this->InstallPrefix += this->GetOption("CPACK_BUNDLE_NAME");
- this->InstallPrefix += ".app/Contents/Resources";
+ this->InstallPrefix = cmStrCat('/', this->GetOption("CPACK_BUNDLE_NAME"),
+ ".app/Contents/Resources");
return this->InstallPrefix.c_str();
}
@@ -89,11 +89,10 @@ int cmCPackBundleGenerator::ConstructBundle()
// The staging directory contains everything that will end-up inside the
// final disk image ...
- std::ostringstream staging;
- staging << toplevel;
+ std::string const staging = toplevel;
std::ostringstream contents;
- contents << staging.str() << "/" << cpack_bundle_name << ".app/"
+ contents << staging << "/" << cpack_bundle_name << ".app/"
<< "Contents";
std::ostringstream application;
@@ -190,9 +189,8 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
if (!cpack_apple_cert_app.empty()) {
std::string output;
std::string bundle_path;
- bundle_path = src_dir + "/";
- bundle_path += this->GetOption("CPACK_BUNDLE_NAME");
- bundle_path += ".app";
+ bundle_path =
+ cmStrCat(src_dir, '/', this->GetOption("CPACK_BUNDLE_NAME"), ".app");
// A list of additional files to sign, ie. frameworks and plugins.
const std::string sign_parameter =
@@ -205,8 +203,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES")
: "";
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(sign_files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(sign_files);
// sign the files supplied by the user, ie. frameworks.
for (auto const& file : relFiles) {
diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx
index f888a5f5d..d40e5fcf8 100644
--- a/Source/CPack/cmCPackComponentGroup.cxx
+++ b/Source/CPack/cmCPackComponentGroup.cxx
@@ -2,10 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackComponentGroup.h"
-#include "cmSystemTools.h"
-
#include <string>
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
unsigned long cmCPackComponent::GetInstalledSize(
const std::string& installDir) const
{
@@ -14,9 +15,7 @@ unsigned long cmCPackComponent::GetInstalledSize(
}
for (std::string const& file : this->Files) {
- std::string path = installDir;
- path += '/';
- path += file;
+ std::string path = cmStrCat(installDir, '/', file);
this->TotalSize += cmSystemTools::FileLength(path);
}
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
index 49a9f15c3..b5abd5a6b 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackCygwinBinaryGenerator.h"
+#include "cmsys/SystemTools.hxx"
+
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
@@ -9,9 +11,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cmsys/SystemTools.hxx"
-
cmCPackCygwinBinaryGenerator::cmCPackCygwinBinaryGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2")
{
}
@@ -28,13 +29,11 @@ int cmCPackCygwinBinaryGenerator::InitializeInternal()
int cmCPackCygwinBinaryGenerator::PackageFiles()
{
- std::string packageName = this->GetOption("CPACK_PACKAGE_NAME");
- packageName += "-";
- packageName += this->GetOption("CPACK_PACKAGE_VERSION");
+ std::string packageName =
+ cmStrCat(this->GetOption("CPACK_PACKAGE_NAME"), '-',
+ this->GetOption("CPACK_PACKAGE_VERSION"));
packageName = cmsys::SystemTools::LowerCase(packageName);
- std::string manifest = "/usr/share/doc/";
- manifest += packageName;
- manifest += "/MANIFEST";
+ std::string manifest = cmStrCat("/usr/share/doc/", packageName, "/MANIFEST");
std::string manifestFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
// Create a MANIFEST file that contains all of the files in
// the tar file
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h
index f87a1343b..47bd41e13 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.h
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h
@@ -3,15 +3,15 @@
#ifndef cmCPackCygwinBinaryGenerator_h
#define cmCPackCygwinBinaryGenerator_h
-#include "cmCPackTarBZip2Generator.h"
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackCygwinBinaryGenerator
* \brief A generator for TarBZip2 files
*/
-class cmCPackCygwinBinaryGenerator : public cmCPackTarBZip2Generator
+class cmCPackCygwinBinaryGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackTarBZip2Generator);
+ cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
index 889f29a59..64a88eba4 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackCygwinSourceGenerator.h"
+#include "cmsys/SystemTools.hxx"
+
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
@@ -9,17 +11,17 @@
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cmsys/SystemTools.hxx"
-
// Includes needed for implementation of RenameFile. This is not in
// system tools because it is not implemented robustly enough to move
// files across directories.
#ifdef _WIN32
-# include "cm_sys_stat.h"
# include <windows.h>
+
+# include "cm_sys_stat.h"
#endif
cmCPackCygwinSourceGenerator::cmCPackCygwinSourceGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2")
{
}
@@ -37,15 +39,11 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
{
// Create a tar file of the sources
std::string packageDirFileName =
- this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- packageDirFileName += ".tar.bz2";
+ cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".tar.bz2");
packageFileNames[0] = packageDirFileName;
std::string output;
- // skip one parent up to the cmCPackTarBZip2Generator
- // to create tar.bz2 file with the list of source
- // files
- this->Compress = cmArchiveWrite::CompressBZip2;
- if (!this->cmCPackTarBZip2Generator::PackageFiles()) {
+ // create tar.bz2 file with the list of source files
+ if (!this->cmCPackArchiveGenerator::PackageFiles()) {
return 0;
}
// Now create a tar file that contains the above .tar.bz2 file
@@ -94,8 +92,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
<< this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n");
return 0;
}
- std::string outerTarFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- outerTarFile += "-";
+ std::string outerTarFile =
+ cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '-');
const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
if (!patch) {
cmCPackLogger(cmCPackLog::LOG_WARNING,
@@ -106,19 +104,18 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
outerTarFile += patch;
outerTarFile += "-src.tar.bz2";
std::string tmpDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- std::string buildScript = tmpDir;
- buildScript += "/";
- buildScript += cmSystemTools::GetFilenameName(
- this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"));
- std::string patchFile = tmpDir;
- patchFile += "/";
- patchFile +=
- cmSystemTools::GetFilenameName(this->GetOption("CPACK_CYGWIN_PATCH_FILE"));
+ std::string buildScript =
+ cmStrCat(tmpDir, '/',
+ cmSystemTools::GetFilenameName(
+ this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT")));
+ std::string patchFile =
+ cmStrCat(tmpDir, '/',
+ cmSystemTools::GetFilenameName(
+ this->GetOption("CPACK_CYGWIN_PATCH_FILE")));
std::string file = cmSystemTools::GetFilenameName(compressOutFile);
- std::string sourceTar = cmSystemTools::GetFilenamePath(compressOutFile);
- sourceTar += "/";
- sourceTar += file;
+ std::string sourceTar =
+ cmStrCat(cmSystemTools::GetFilenamePath(compressOutFile), '/', file);
/* reset list of file to be packaged */
files.clear();
// a source release in cygwin should have the build script used
@@ -132,7 +129,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
packageFileNames[0] = outerTarFile;
/* update the toplevel dir */
toplevel = tmpDir;
- if (!this->cmCPackTarBZip2Generator::PackageFiles()) {
+ if (!this->cmCPackArchiveGenerator::PackageFiles()) {
return 0;
}
return 1;
@@ -140,8 +137,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix()
{
- this->InstallPrefix = "/";
- this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ this->InstallPrefix =
+ cmStrCat('/', this->GetOption("CPACK_PACKAGE_FILE_NAME"));
return this->InstallPrefix.c_str();
}
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h
index a909b1595..98d8f0ab7 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.h
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.h
@@ -3,15 +3,15 @@
#ifndef cmCPackCygwinSourceGenerator_h
#define cmCPackCygwinSourceGenerator_h
-#include "cmCPackTarBZip2Generator.h"
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackCygwinSourceGenerator
* \brief A generator for cygwin source files
*/
-class cmCPackCygwinSourceGenerator : public cmCPackTarBZip2Generator
+class cmCPackCygwinSourceGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackTarBZip2Generator);
+ cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index cfb5efd0e..5b7d8fb68 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -2,21 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackDebGenerator.h"
+#include <cstring>
+#include <map>
+#include <ostream>
+#include <set>
+#include <utility>
+
+#include "cmsys/Glob.hxx"
+
+#include "cm_sys_stat.h"
+
#include "cmArchiveWrite.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cm_sys_stat.h"
-
-#include "cmsys/Glob.hxx"
-#include <map>
-#include <ostream>
-#include <set>
-#include <string.h>
-#include <utility>
namespace {
@@ -148,8 +151,7 @@ void DebGenerator::generateControlFile() const
unsigned long totalSize = 0;
{
- std::string dirName = TemporaryDir;
- dirName += '/';
+ std::string dirName = cmStrCat(TemporaryDir, '/');
for (std::string const& file : PackageFiles) {
totalSize += cmSystemTools::FileLength(file);
}
@@ -247,8 +249,7 @@ std::string DebGenerator::generateMD5File() const
cmGeneratedFileStream out(md5filename);
- std::string topLevelWithTrailingSlash = TemporaryDir;
- topLevelWithTrailingSlash += '/';
+ std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/');
for (std::string const& file : PackageFiles) {
// hash only regular files
if (cmSystemTools::FileIsDirectory(file) ||
@@ -377,8 +378,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// default
control_tar.ClearPermissions();
- std::vector<std::string> controlExtraList;
- cmSystemTools::ExpandListArgument(ControlExtra, controlExtraList);
+ std::vector<std::string> controlExtraList = cmExpandedList(ControlExtra);
for (std::string const& i : controlExtraList) {
std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
std::string localcopy = WorkDir + "/" + filenamename;
@@ -439,7 +439,7 @@ cmCPackDebGenerator::~cmCPackDebGenerator() = default;
int cmCPackDebGenerator::InitializeInternal()
{
this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
- if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
+ if (cmIsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
this->SetOption("CPACK_SET_DESTDIR", "I_ON");
}
return this->Superclass::InitializeInternal();
@@ -468,8 +468,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
// Tell CPackDeb.cmake the name of the component GROUP.
this->SetOption("CPACK_DEB_PACKAGE_COMPONENT", packageName.c_str());
// Tell CPackDeb.cmake the path where the component is.
- std::string component_path = "/";
- component_path += packageName;
+ std::string component_path = cmStrCat('/', packageName);
this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
component_path.c_str());
if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) {
@@ -499,9 +498,8 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
retval = 0;
}
// add the generated package to package file names list
- packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- packageFileName += "/";
- packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
+ packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
+ this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
packageFileNames.push_back(std::move(packageFileName));
if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE")) {
@@ -523,9 +521,9 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
retval = 0;
}
// add the generated package to package file names list
- packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- packageFileName += "/";
- packageFileName += this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME");
+ packageFileName =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
+ this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"));
packageFileNames.push_back(std::move(packageFileName));
}
@@ -613,8 +611,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
if (!compInstDirName.empty()) {
// Tell CPackDeb.cmake the path where the component is.
- std::string component_path = "/";
- component_path += compInstDirName;
+ std::string component_path = cmStrCat('/', compInstDirName);
this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
component_path.c_str());
}
@@ -643,9 +640,8 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
retval = 0;
}
// add the generated package to package file names list
- packageFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- packageFileName += "/";
- packageFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
+ packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
+ this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
packageFileNames.push_back(std::move(packageFileName));
return retval;
}
diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h
index 2244fe72e..ce77e0804 100644
--- a/Source/CPack/cmCPackDebGenerator.h
+++ b/Source/CPack/cmCPackDebGenerator.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackGenerator.h"
-
#include <string>
#include <vector>
+#include "cmCPackGenerator.h"
+
/** \class cmCPackDebGenerator
* \brief A generator for Debian packages
*
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 7a3742b55..ea7100708 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -2,21 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackDragNDropGenerator.h"
-#include "cmCPackGenerator.h"
-#include "cmCPackLog.h"
-#include "cmDuration.h"
-#include "cmGeneratedFileStream.h"
-#include "cmSystemTools.h"
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include <cstdlib>
#include <iomanip>
#include <map>
-#include <stdlib.h>
#include <CoreFoundation/CoreFoundation.h>
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCPackGenerator.h"
+#include "cmCPackLog.h"
+#include "cmDuration.h"
+#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
#ifdef HAVE_CoreServices
// For the old LocaleStringToLangAndRegionCodes() function, to convert
// to the old Script Manager RegionCode values needed for the 'LPic' data
@@ -127,9 +129,8 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
- std::vector<std::string> languages;
- cmSystemTools::ExpandListArgument(
- this->GetOption("CPACK_DMG_SLA_LANGUAGES"), languages);
+ std::vector<std::string> languages =
+ cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"));
if (languages.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
@@ -196,9 +197,7 @@ int cmCPackDragNDropGenerator::PackageFiles()
full_package_name += std::string(GetOutputExtension());
packageFileNames.push_back(full_package_name);
- std::string src_dir = toplevel;
- src_dir += "/";
- src_dir += package_file;
+ std::string src_dir = cmStrCat(toplevel, '/', package_file);
if (0 == this->CreateDMG(src_dir, full_package_name)) {
return 0;
@@ -409,8 +408,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// Create a temporary read-write disk image ...
- std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- temp_image += "/temp.dmg";
+ std::string temp_image =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg");
std::string create_error;
std::ostringstream temp_image_command;
@@ -522,12 +521,12 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
if (!cpack_license_file.empty() || !slaDirectory.empty()) {
// Use old hardcoded style if sla_dir is not set
bool oldStyle = slaDirectory.empty();
- std::string sla_r = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- sla_r += "/sla.r";
+ std::string sla_r =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.r");
std::vector<std::string> languages;
if (!oldStyle) {
- cmSystemTools::ExpandListArgument(cpack_dmg_languages, languages);
+ cmExpandList(cpack_dmg_languages, languages);
}
cmGeneratedFileStream ofs(sla_r);
@@ -649,8 +648,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
if (temp_image_format != "UDZO") {
temp_image_format = "UDZO";
// convert to UDZO to enable unflatten/flatten
- std::string temp_udzo = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- temp_udzo += "/temp-udzo.dmg";
+ std::string temp_udzo = cmStrCat(
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp-udzo.dmg");
std::ostringstream udco_image_command;
udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index d8c5c8337..f8c86c06d 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -6,10 +6,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <sstream>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
#include "cmCPackGenerator.h"
class cmGeneratedFileStream;
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 9dc985331..142eb6fbf 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -2,20 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackExternalGenerator.h"
-#include "cmAlgorithms.h"
-#include "cmCPackComponentGroup.h"
-#include "cmCPackLog.h"
-#include "cmMakefile.h"
-#include "cmSystemTools.h"
+#include <map>
+#include <utility>
+#include <vector>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm/memory>
#include "cmsys/FStream.hxx"
-#include <map>
-#include <utility>
-#include <vector>
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
+
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
int cmCPackExternalGenerator::InitializeInternal()
{
@@ -148,8 +150,7 @@ int cmCPackExternalGenerator::InstallCMakeProject(
bool cmCPackExternalGenerator::StagingEnabled() const
{
- return !cmSystemTools::IsOff(
- this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING"));
+ return !cmIsOff(this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING"));
}
cmCPackExternalGenerator::cmCPackExternalVersionGenerator::
@@ -207,8 +208,7 @@ int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON(
if (defaultDirectoryPermissions && *defaultDirectoryPermissions) {
root["defaultDirectoryPermissions"] = defaultDirectoryPermissions;
}
- if (cmSystemTools::IsInternallyOn(
- this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
+ if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
root["setDestdir"] = true;
root["packagingInstallPrefix"] =
this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
@@ -216,8 +216,7 @@ int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON(
root["setDestdir"] = false;
}
- root["stripFiles"] =
- !cmSystemTools::IsOff(this->Parent->GetOption("CPACK_STRIP_FILES"));
+ root["stripFiles"] = !cmIsOff(this->Parent->GetOption("CPACK_STRIP_FILES"));
root["warnOnAbsoluteInstallDestination"] =
this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION");
root["errorOnAbsoluteInstallDestination"] =
diff --git a/Source/CPack/cmCPackExternalGenerator.h b/Source/CPack/cmCPackExternalGenerator.h
index 176d6a9d9..80011fddd 100644
--- a/Source/CPack/cmCPackExternalGenerator.h
+++ b/Source/CPack/cmCPackExternalGenerator.h
@@ -3,12 +3,13 @@
#ifndef cmCPackExternalGenerator_h
#define cmCPackExternalGenerator_h
-#include "cmCPackGenerator.h"
-#include "cm_sys_stat.h"
-
#include <memory>
#include <string>
+#include "cm_sys_stat.h"
+
+#include "cmCPackGenerator.h"
+
class cmGlobalGenerator;
namespace Json {
class Value;
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index 9fdafa47b..e3cc352fb 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -6,21 +6,22 @@
#include "cmCPackArchiveGenerator.h"
#include "cmCPackLog.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// Needed for ::open() and ::stat()
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
+#include <algorithm>
+#include <ostream>
+#include <utility>
+#include <vector>
+#include <fcntl.h>
#include <pkg.h>
-#include <algorithm>
-#include <utility>
+#include <sys/stat.h>
cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr")
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", ".txz")
{
}
@@ -130,7 +131,7 @@ public:
class ManifestKeyListValue : public ManifestKey
{
public:
- typedef std::vector<std::string> VList;
+ using VList = std::vector<std::string>;
VList value;
ManifestKeyListValue(const std::string& k)
@@ -227,9 +228,8 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
manifest << ManifestKeyValue(
"desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION"));
manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW"));
- std::vector<std::string> licenses;
- cmSystemTools::ExpandListArgument(
- var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"), licenses);
+ std::vector<std::string> licenses =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"));
std::string licenselogic("single");
if (licenses.empty()) {
cmSystemTools::SetFatalErrorOccured();
@@ -238,14 +238,12 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
}
manifest << ManifestKeyValue("licenselogic", licenselogic);
manifest << (ManifestKeyListValue("licenses") << licenses);
- std::vector<std::string> categories;
- cmSystemTools::ExpandListArgument(
- var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"), categories);
+ std::vector<std::string> categories =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"));
manifest << (ManifestKeyListValue("categories") << categories);
manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX"));
- std::vector<std::string> deps;
- cmSystemTools::ExpandListArgument(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"),
- deps);
+ std::vector<std::string> deps =
+ cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"));
if (!deps.empty()) {
manifest << (ManifestKeyDepsValue("deps") << deps);
}
@@ -278,12 +276,6 @@ void write_manifest_files(cmGeneratedFileStream& s,
s << " },\n";
}
-static bool has_suffix(const std::string& str, const std::string& suffix)
-{
- return str.size() >= suffix.size() &&
- str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
int cmCPackFreeBSDGenerator::PackageFiles()
{
if (!this->ReadListFile("Internal/CPack/CPackFreeBSD.cmake")) {
@@ -329,13 +321,13 @@ int cmCPackFreeBSDGenerator::PackageFiles()
pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(),
manifestname.c_str(), nullptr);
- std::string broken_suffix = std::string("-") +
- var_lookup("CPACK_TOPLEVEL_TAG") + std::string(GetOutputExtension());
+ std::string broken_suffix =
+ cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), ".txz");
for (std::string& name : packageFileNames) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << name << std::endl);
- if (has_suffix(name, broken_suffix)) {
+ if (cmHasSuffix(name, broken_suffix)) {
name.replace(name.size() - broken_suffix.size(), std::string::npos,
- GetOutputExtension());
+ ".txz");
break;
}
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.h b/Source/CPack/cmCPackFreeBSDGenerator.h
index 99d2e2421..a18b72f62 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.h
+++ b/Source/CPack/cmCPackFreeBSDGenerator.h
@@ -3,7 +3,9 @@
#ifndef cmCPackFreeBSDGenerator_h
#define cmCPackFreeBSDGenerator_h
-#include <cmConfigure.h>
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
#include "cmCPackArchiveGenerator.h"
#include "cmCPackGenerator.h"
@@ -28,8 +30,6 @@ public:
int PackageFiles() override;
protected:
- const char* GetOutputExtension() override { return ".txz"; }
-
std::string var_lookup(const char* var_name);
void write_manifest_fields(cmGeneratedFileStream&);
};
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 7e07ff488..953022764 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -2,14 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackGenerator.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <cstring>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <utility>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
@@ -21,6 +22,8 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmWorkingDirectory.h"
#include "cmXMLSafe.h"
@@ -72,8 +75,8 @@ int cmCPackGenerator::PrepareNames()
}
}
- std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
- tempDirectory += "/_CPack_Packages/";
+ std::string tempDirectory =
+ cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/_CPack_Packages/");
const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG");
if (toplevelTag) {
tempDirectory += toplevelTag;
@@ -179,8 +182,8 @@ int cmCPackGenerator::InstallProject()
std::string bareTempInstallDirectory =
this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
std::string tempInstallDirectoryStr = bareTempInstallDirectory;
- bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR")) |
- cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"));
+ bool setDestDir = cmIsOn(this->GetOption("CPACK_SET_DESTDIR")) |
+ cmIsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"));
if (!setDestDir) {
tempInstallDirectoryStr += this->GetPackagingInstallPrefix();
}
@@ -196,8 +199,7 @@ int cmCPackGenerator::InstallProject()
}
if (setDestDir) {
- std::string destDir = "DESTDIR=";
- destDir += tempInstallDirectory;
+ std::string destDir = cmStrCat("DESTDIR=", tempInstallDirectory);
cmSystemTools::PutEnv(destDir);
} else {
// Make sure there is no destdir
@@ -210,8 +212,8 @@ int cmCPackGenerator::InstallProject()
const char* default_dir_install_permissions =
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (default_dir_install_permissions && *default_dir_install_permissions) {
- std::vector<std::string> items;
- cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
+ std::vector<std::string> items =
+ cmExpandedList(default_dir_install_permissions);
for (const auto& arg : items) {
if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -235,7 +237,7 @@ int cmCPackGenerator::InstallProject()
return 0;
}
- // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
+ // If the CPackConfig file sets CPACK_INSTALL_SCRIPT(S) then run them
// as listed
if (!this->InstallProjectViaInstallScript(setDestDir,
tempInstallDirectory)) {
@@ -270,11 +272,11 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
(void)setDestDir;
const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
if (installCommands && *installCommands) {
- std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX=";
- tempInstallDirectoryEnv += tempInstallDirectory;
+ std::string tempInstallDirectoryEnv =
+ cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
cmSystemTools::PutEnv(tempInstallDirectoryEnv);
- std::vector<std::string> installCommandsVector;
- cmSystemTools::ExpandListArgument(installCommands, installCommandsVector);
+ std::vector<std::string> installCommandsVector =
+ cmExpandedList(installCommands);
for (std::string const& ic : installCommandsVector) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl);
std::string output;
@@ -283,8 +285,8 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
ic, &output, &output, &retVal, nullptr, this->GeneratorVerbose,
cmDuration::zero());
if (!resB || retVal) {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/InstallOutput.log";
+ std::string tmpFile = cmStrCat(
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/InstallOutput.log");
cmGeneratedFileStream ofs(tmpFile);
ofs << "# Run command: " << ic << std::endl
<< "# Output:" << std::endl
@@ -310,9 +312,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::vector<cmsys::RegularExpression> ignoreFilesRegex;
const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
if (cpackIgnoreFiles) {
- std::vector<std::string> ignoreFilesRegexString;
- cmSystemTools::ExpandListArgument(cpackIgnoreFiles,
- ignoreFilesRegexString);
+ std::vector<std::string> ignoreFilesRegexString =
+ cmExpandedList(cpackIgnoreFiles);
for (std::string const& ifr : ignoreFilesRegexString) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Create ignore files regex for: " << ifr << std::endl);
@@ -322,9 +323,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
const char* installDirectories =
this->GetOption("CPACK_INSTALLED_DIRECTORIES");
if (installDirectories && *installDirectories) {
- std::vector<std::string> installDirectoriesVector;
- cmSystemTools::ExpandListArgument(installDirectories,
- installDirectoriesVector);
+ std::vector<std::string> installDirectoriesVector =
+ cmExpandedList(installDirectories);
if (installDirectoriesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -344,8 +344,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::string top = *it;
it++;
std::string subdir = *it;
- std::string findExpr = top;
- findExpr += "/*";
+ std::string findExpr = cmStrCat(top, "/*");
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install directory: " << top << std::endl);
gl.RecurseOn();
@@ -373,8 +372,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
if (skip) {
continue;
}
- std::string filePath = tempDir;
- filePath += "/" + subdir + "/" + cmSystemTools::RelativePath(top, gf);
+ std::string filePath = cmStrCat(tempDir, '/', subdir, '/',
+ cmSystemTools::RelativePath(top, gf));
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Copy file: " << inFile << " -> " << filePath
<< std::endl);
@@ -399,8 +398,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
/* rebuild symlinks in the installed tree */
if (!symlinkedFiles.empty()) {
std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
- std::string goToDir = tempDir;
- goToDir += "/" + subdir;
+ std::string goToDir = cmStrCat(tempDir, '/', subdir);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Change dir to: " << goToDir << std::endl);
cmWorkingDirectory workdir(goToDir);
@@ -448,12 +446,23 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
int cmCPackGenerator::InstallProjectViaInstallScript(
bool setDestDir, const std::string& tempInstallDirectory)
{
- const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPT");
+ const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS");
+ {
+ const char* const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT");
+ if (cmakeScript && cmakeScripts) {
+ cmCPackLogger(
+ cmCPackLog::LOG_WARNING,
+ "Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, "
+ "the latter will be ignored."
+ << std::endl);
+ } else if (cmakeScript && !cmakeScripts) {
+ cmakeScripts = cmakeScript;
+ }
+ }
if (cmakeScripts && *cmakeScripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install scripts: " << cmakeScripts << std::endl);
- std::vector<std::string> cmakeScriptsVector;
- cmSystemTools::ExpandListArgument(cmakeScripts, cmakeScriptsVector);
+ std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts);
for (std::string const& installScript : cmakeScriptsVector) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
@@ -517,8 +526,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< std::endl);
return 0;
}
- std::vector<std::string> cmakeProjectsVector;
- cmSystemTools::ExpandListArgument(cmakeProjects, cmakeProjectsVector);
+ std::vector<std::string> cmakeProjectsVector =
+ cmExpandedList(cmakeProjects);
std::vector<std::string>::iterator it;
for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end();
++it) {
@@ -562,8 +571,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
const char* installTypes = this->GetOption(installTypesVar);
if (installTypes && *installTypes) {
- std::vector<std::string> installTypesVector;
- cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
+ std::vector<std::string> installTypesVector =
+ cmExpandedList(installTypes);
for (std::string const& installType : installTypesVector) {
project.InstallationTypes.push_back(
this->GetInstallationType(project.ProjectName, installType));
@@ -575,7 +584,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
"CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
const char* components = this->GetOption(componentsVar);
if (components && *components) {
- cmSystemTools::ExpandListArgument(components, componentsVector);
+ cmExpandList(components, componentsVector);
for (std::string const& comp : componentsVector) {
project.Components.push_back(
this->GetComponent(project.ProjectName, comp));
@@ -587,11 +596,29 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
componentsVector.push_back(project.Component);
}
- const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG");
- std::string buildConfig = buildConfigCstr ? buildConfigCstr : "";
- cmGlobalGenerator* globalGenerator =
+ std::vector<std::string> buildConfigs;
+
+ // Try get configuration names given via `-C` CLI option
+ {
+ const char* const buildConfigCstr =
+ this->GetOption("CPACK_BUILD_CONFIG");
+ auto buildConfig = buildConfigCstr ? buildConfigCstr : std::string{};
+ cmExpandList(buildConfig, buildConfigs);
+ }
+
+ // Remove duplicates
+ std::sort(buildConfigs.begin(), buildConfigs.end());
+ buildConfigs.erase(std::unique(buildConfigs.begin(), buildConfigs.end()),
+ buildConfigs.end());
+
+ // Ensure we have at least one configuration.
+ if (buildConfigs.empty()) {
+ buildConfigs.emplace_back();
+ }
+
+ std::unique_ptr<cmGlobalGenerator> globalGenerator(
this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
- cmakeGenerator);
+ cmakeGenerator));
if (!globalGenerator) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Specified package generator not found. "
@@ -604,27 +631,29 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
// on windows.
cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
- if (!this->RunPreinstallTarget(project.ProjectName, project.Directory,
- globalGenerator, buildConfig)) {
- return 0;
- }
-
- delete globalGenerator;
-
- cmCPackLogger(cmCPackLog::LOG_OUTPUT,
- "- Install project: " << project.ProjectName << std::endl);
-
- // Run the installation for each component
- for (std::string const& component : componentsVector) {
- if (!this->InstallCMakeProject(
- setDestDir, project.Directory, baseTempInstallDirectory,
- default_dir_mode, component, componentInstall,
- project.SubDirectory, buildConfig, absoluteDestFiles)) {
+ // Run the installation for the selected build configurations
+ for (auto const& buildConfig : buildConfigs) {
+ if (!this->RunPreinstallTarget(project.ProjectName, project.Directory,
+ globalGenerator.get(), buildConfig)) {
return 0;
}
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install project: " << project.ProjectName << " ["
+ << buildConfig << ']'
+ << std::endl);
+ // Run the installation for each component
+ for (std::string const& component : componentsVector) {
+ if (!this->InstallCMakeProject(
+ setDestDir, project.Directory, baseTempInstallDirectory,
+ default_dir_mode, component, componentInstall,
+ project.SubDirectory, buildConfig, absoluteDestFiles)) {
+ return 0;
+ }
+ }
}
- this->CMakeProjects.push_back(project);
+ this->CMakeProjects.emplace_back(std::move(project));
}
}
this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",
@@ -651,8 +680,8 @@ int cmCPackGenerator::RunPreinstallTarget(
buildCommand, &output, &output, &retVal, installDirectory.c_str(),
this->GeneratorVerbose, cmDuration::zero());
if (!resB || retVal) {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/PreinstallOutput.log";
+ std::string tmpFile = cmStrCat(
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/PreinstallOutput.log");
cmGeneratedFileStream ofs(tmpFile);
ofs << "# Run command: " << buildCommand << std::endl
<< "# Directory: " << installDirectory << std::endl
@@ -739,7 +768,7 @@ int cmCPackGenerator::InstallCMakeProject(
// CPACK_PACKAGING_INSTALL_PREFIX
// I know this is tricky and awkward but it's the price for
// CPACK_SET_DESTDIR backward compatibility.
- if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) {
+ if (cmIsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) {
this->SetOption("CPACK_INSTALL_PREFIX",
this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
}
@@ -747,7 +776,7 @@ int cmCPackGenerator::InstallCMakeProject(
if (this->GetOption("CPACK_INSTALL_PREFIX")) {
dir += this->GetOption("CPACK_INSTALL_PREFIX");
}
- mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
+ mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir);
cmCPackLogger(
cmCPackLog::LOG_DEBUG,
@@ -760,7 +789,7 @@ int cmCPackGenerator::InstallCMakeProject(
// Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
// exists:
//
- if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) {
+ if (cmHasLiteralPrefix(dir, "/")) {
dir = tempInstallDirectory + dir;
} else {
dir = tempInstallDirectory + "/" + dir;
@@ -787,7 +816,7 @@ int cmCPackGenerator::InstallCMakeProject(
return 0;
}
} else {
- mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str());
+ mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory,
default_dir_mode)) {
@@ -806,16 +835,16 @@ int cmCPackGenerator::InstallCMakeProject(
}
if (!buildConfig.empty()) {
- mf.AddDefinition("BUILD_TYPE", buildConfig.c_str());
+ mf.AddDefinition("BUILD_TYPE", buildConfig);
}
std::string installComponentLowerCase = cmSystemTools::LowerCase(component);
if (installComponentLowerCase != "all") {
- mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component.c_str());
+ mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component);
}
// strip on TRUE, ON, 1, one or several file names, but not on
// FALSE, OFF, 0 and an empty string
- if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) {
+ if (!cmIsOff(this->GetOption("CPACK_STRIP_FILES"))) {
mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
}
// Remember the list of files before installation
@@ -851,9 +880,8 @@ int cmCPackGenerator::InstallCMakeProject(
// forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
// to CPack (may be used by generators like CPack RPM or DEB)
// in order to transparently handle ABSOLUTE PATH
- if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
- mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES",
- mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
+ if (const char* def = mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
+ mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", def);
}
// Now rebuild the list of files after installation
@@ -901,10 +929,8 @@ int cmCPackGenerator::InstallCMakeProject(
GetComponentInstallDirNameSuffix(component);
if (nullptr != this->GetOption(absoluteDestFileComponent)) {
std::string absoluteDestFilesListComponent =
- this->GetOption(absoluteDestFileComponent);
- absoluteDestFilesListComponent += ";";
- absoluteDestFilesListComponent +=
- mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+ cmStrCat(this->GetOption(absoluteDestFileComponent), ';',
+ mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
this->SetOption(absoluteDestFileComponent,
absoluteDestFilesListComponent.c_str());
} else {
@@ -967,8 +993,7 @@ int cmCPackGenerator::DoPackage()
return 0;
}
- if (cmSystemTools::IsOn(
- this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY"))) {
+ if (cmIsOn(this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY"))) {
const char* toplevelDirectory =
this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
if (cmSystemTools::FileExists(toplevelDirectory)) {
@@ -997,8 +1022,7 @@ int cmCPackGenerator::DoPackage()
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
cmsys::Glob gl;
- std::string findExpr = tempDirectory;
- findExpr += "/*";
+ std::string findExpr = cmStrCat(tempDirectory, "/*");
gl.RecurseOn();
gl.SetRecurseListDirs(true);
gl.SetRecurseThroughSymlinks(false);
@@ -1018,8 +1042,7 @@ int cmCPackGenerator::DoPackage()
"Remove old package file" << std::endl);
cmSystemTools::RemoveFile(tempPackageFileName);
}
- if (cmSystemTools::IsOn(
- this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
+ if (cmIsOn(this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
}
@@ -1143,14 +1166,14 @@ bool cmCPackGenerator::IsSet(const std::string& name) const
bool cmCPackGenerator::IsOn(const std::string& name) const
{
- return cmSystemTools::IsOn(GetOption(name));
+ return cmIsOn(GetOption(name));
}
bool cmCPackGenerator::IsSetToOff(const std::string& op) const
{
const char* ret = this->MakefileMap->GetDefinition(op);
if (ret && *ret) {
- return cmSystemTools::IsOff(ret);
+ return cmIsOff(ret);
}
return false;
}
@@ -1195,8 +1218,7 @@ const char* cmCPackGenerator::GetInstallPath()
if (cmsys::SystemTools::GetEnv("ProgramFiles", prgfiles)) {
this->InstallPath = prgfiles;
} else if (cmsys::SystemTools::GetEnv("SystemDrive", sysDrive)) {
- this->InstallPath = sysDrive;
- this->InstallPath += "/Program Files";
+ this->InstallPath = cmStrCat(sysDrive, "/Program Files");
} else {
this->InstallPath = "c:/Program Files";
}
@@ -1233,7 +1255,17 @@ std::string cmCPackGenerator::FindTemplate(const char* name)
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Look for template: " << (name ? name : "(NULL)")
<< std::endl);
+ // Search CMAKE_MODULE_PATH for a custom template.
std::string ffile = this->MakefileMap->GetModulesFile(name);
+ if (ffile.empty()) {
+ // Fall back to our internal builtin default.
+ ffile = cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/Internal/CPack/",
+ name);
+ cmSystemTools::ConvertToUnixSlashes(ffile);
+ if (!cmSystemTools::FileExists(ffile)) {
+ ffile.clear();
+ }
+ }
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Found template: " << ffile << std::endl);
return ffile;
@@ -1464,7 +1496,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
component->IsRequired = this->IsOn(macroPrefix + "_REQUIRED");
component->IsDisabledByDefault = this->IsOn(macroPrefix + "_DISABLED");
component->IsDownloaded = this->IsOn(macroPrefix + "_DOWNLOADED") ||
- cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
+ cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE");
if (archiveFile && *archiveFile) {
@@ -1492,8 +1524,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the installation types.
const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
if (installTypes && *installTypes) {
- std::vector<std::string> installTypesVector;
- cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
+ std::vector<std::string> installTypesVector =
+ cmExpandedList(installTypes);
for (std::string const& installType : installTypesVector) {
component->InstallationTypes.push_back(
this->GetInstallationType(projectName, installType));
@@ -1503,8 +1535,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the component dependencies.
const char* depends = this->GetOption(macroPrefix + "_DEPENDS");
if (depends && *depends) {
- std::vector<std::string> dependsVector;
- cmSystemTools::ExpandListArgument(depends, dependsVector);
+ std::vector<std::string> dependsVector = cmExpandedList(depends);
for (std::string const& depend : dependsVector) {
cmCPackComponent* child = GetComponent(projectName, depend);
component->Dependencies.push_back(child);
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 3c06d4196..33026c1d9 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -10,9 +10,10 @@
#include <string>
#include <vector>
+#include "cm_sys_stat.h"
+
#include "cmCPackComponentGroup.h"
#include "cmSystemTools.h"
-#include "cm_sys_stat.h"
class cmCPackLog;
class cmGlobalGenerator;
@@ -326,7 +327,7 @@ protected:
};
#define cmCPackTypeMacro(klass, superclass) \
- typedef superclass Superclass; \
+ using Superclass = superclass; \
const char* GetNameOfClass() override { return #klass; } \
static cmCPackGenerator* CreateGenerator() { return new klass; } \
class cmCPackTypeMacro_UseTrailingSemicolon
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 2c5ab4d78..79e344be7 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -6,11 +6,10 @@
#include <utility>
#include "IFW/cmCPackIFWGenerator.h"
-#include "cmAlgorithms.h"
-#include "cmCPack7zGenerator.h"
#ifdef HAVE_FREEBSD_PKG
# include "cmCPackFreeBSDGenerator.h"
#endif
+#include "cmCPackArchiveGenerator.h"
#include "cmCPackDebGenerator.h"
#include "cmCPackExternalGenerator.h"
#include "cmCPackGenerator.h"
@@ -18,11 +17,6 @@
#include "cmCPackNSISGenerator.h"
#include "cmCPackNuGetGenerator.h"
#include "cmCPackSTGZGenerator.h"
-#include "cmCPackTGZGenerator.h"
-#include "cmCPackTXZGenerator.h"
-#include "cmCPackTarBZip2Generator.h"
-#include "cmCPackTarCompressGenerator.h"
-#include "cmCPackZIPGenerator.h"
#ifdef __APPLE__
# include "cmCPackBundleGenerator.h"
@@ -48,13 +42,21 @@
cmCPackGeneratorFactory::cmCPackGeneratorFactory()
{
- if (cmCPackTGZGenerator::CanGenerate()) {
+ if (cmCPackArchiveGenerator::CanGenerate()) {
+ this->RegisterGenerator("7Z", "7-Zip file format",
+ cmCPackArchiveGenerator::Create7ZGenerator);
+ this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
+ cmCPackArchiveGenerator::CreateTBZ2Generator);
this->RegisterGenerator("TGZ", "Tar GZip compression",
- cmCPackTGZGenerator::CreateGenerator);
- }
- if (cmCPackTXZGenerator::CanGenerate()) {
+ cmCPackArchiveGenerator::CreateTGZGenerator);
this->RegisterGenerator("TXZ", "Tar XZ compression",
- cmCPackTXZGenerator::CreateGenerator);
+ cmCPackArchiveGenerator::CreateTXZGenerator);
+ this->RegisterGenerator("TZ", "Tar Compress compression",
+ cmCPackArchiveGenerator::CreateTZGenerator);
+ this->RegisterGenerator("TZST", "Tar Zstandard compression",
+ cmCPackArchiveGenerator::CreateTZSTGenerator);
+ this->RegisterGenerator("ZIP", "ZIP file format",
+ cmCPackArchiveGenerator::CreateZIPGenerator);
}
if (cmCPackSTGZGenerator::CanGenerate()) {
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
@@ -80,29 +82,12 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
cmCPackCygwinSourceGenerator::CreateGenerator);
}
#endif
-
- if (cmCPackZIPGenerator::CanGenerate()) {
- this->RegisterGenerator("ZIP", "ZIP file format",
- cmCPackZIPGenerator::CreateGenerator);
- }
- if (cmCPack7zGenerator::CanGenerate()) {
- this->RegisterGenerator("7Z", "7-Zip file format",
- cmCPack7zGenerator::CreateGenerator);
- }
#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
if (cmCPackWIXGenerator::CanGenerate()) {
this->RegisterGenerator("WIX", "MSI file format via WiX tools",
cmCPackWIXGenerator::CreateGenerator);
}
#endif
- if (cmCPackTarBZip2Generator::CanGenerate()) {
- this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
- cmCPackTarBZip2Generator::CreateGenerator);
- }
- if (cmCPackTarCompressGenerator::CanGenerate()) {
- this->RegisterGenerator("TZ", "Tar Compress compression",
- cmCPackTarCompressGenerator::CreateGenerator);
- }
if (cmCPackDebGenerator::CanGenerate()) {
this->RegisterGenerator("DEB", "Debian packages",
cmCPackDebGenerator::CreateGenerator);
@@ -152,34 +137,21 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
#endif
}
-cmCPackGeneratorFactory::~cmCPackGeneratorFactory()
-{
- cmDeleteAll(this->Generators);
-}
-
-cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(
+std::unique_ptr<cmCPackGenerator> cmCPackGeneratorFactory::NewGenerator(
const std::string& name)
{
- cmCPackGenerator* gen = this->NewGeneratorInternal(name);
+ auto it = this->GeneratorCreators.find(name);
+ if (it == this->GeneratorCreators.end()) {
+ return nullptr;
+ }
+ std::unique_ptr<cmCPackGenerator> gen(it->second());
if (!gen) {
return nullptr;
}
- this->Generators.push_back(gen);
gen->SetLogger(this->Logger);
return gen;
}
-cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal(
- const std::string& name)
-{
- cmCPackGeneratorFactory::t_GeneratorCreatorsMap::iterator it =
- this->GeneratorCreators.find(name);
- if (it == this->GeneratorCreators.end()) {
- return nullptr;
- }
- return (it->second)();
-}
-
void cmCPackGeneratorFactory::RegisterGenerator(
const std::string& name, const char* generatorDescription,
CreateGeneratorCall* createGenerator)
diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h
index 972f0f73c..62b748423 100644
--- a/Source/CPack/cmCPackGeneratorFactory.h
+++ b/Source/CPack/cmCPackGeneratorFactory.h
@@ -6,8 +6,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <string>
-#include <vector>
class cmCPackGenerator;
class cmCPackLog;
@@ -20,16 +20,11 @@ class cmCPackGeneratorFactory
{
public:
cmCPackGeneratorFactory();
- ~cmCPackGeneratorFactory();
-
- cmCPackGeneratorFactory(const cmCPackGeneratorFactory&) = delete;
- cmCPackGeneratorFactory& operator=(const cmCPackGeneratorFactory&) = delete;
//! Get the generator
- cmCPackGenerator* NewGenerator(const std::string& name);
- void DeleteGenerator(cmCPackGenerator* gen);
+ std::unique_ptr<cmCPackGenerator> NewGenerator(const std::string& name);
- typedef cmCPackGenerator* CreateGeneratorCall();
+ using CreateGeneratorCall = cmCPackGenerator*();
void RegisterGenerator(const std::string& name,
const char* generatorDescription,
@@ -37,17 +32,14 @@ public:
void SetLogger(cmCPackLog* logger) { this->Logger = logger; }
- typedef std::map<std::string, std::string> DescriptionsMap;
+ using DescriptionsMap = std::map<std::string, std::string>;
const DescriptionsMap& GetGeneratorsList() const
{
return this->GeneratorDescriptions;
}
private:
- cmCPackGenerator* NewGeneratorInternal(const std::string& name);
- std::vector<cmCPackGenerator*> Generators;
-
- typedef std::map<std::string, CreateGeneratorCall*> t_GeneratorCreatorsMap;
+ using t_GeneratorCreatorsMap = std::map<std::string, CreateGeneratorCall*>;
t_GeneratorCreatorsMap GeneratorCreators;
DescriptionsMap GeneratorDescriptions;
cmCPackLog* Logger;
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index a3ca4b590..ca675fdc8 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -83,7 +83,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "VERBOSE";
+ tagString += "VERBOSE";
}
}
if (tag & LOG_WARNING) {
@@ -93,7 +93,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "WARNING";
+ tagString += "WARNING";
}
}
if (tag & LOG_ERROR) {
@@ -103,7 +103,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "ERROR";
+ tagString += "ERROR";
}
}
if (tag & LOG_DEBUG && this->Debug) {
@@ -113,7 +113,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "DEBUG";
+ tagString += "DEBUG";
}
useFileAndLine = true;
}
@@ -124,7 +124,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
if (!tagString.empty()) {
tagString += ",";
}
- tagString = "VERBOSE";
+ tagString += "VERBOSE";
}
}
if (this->Quiet) {
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 65281e3d8..1cb16433c 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -6,9 +6,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <ostream>
-#include <string.h>
#include <string>
+#include <string.h>
+
#define cmCPack_Log(ctSelf, logType, msg) \
do { \
std::ostringstream cmCPackLog_msg; \
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index e2020c5ae..9bf72dfb8 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -2,22 +2,25 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackNSISGenerator.h"
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <sstream>
+#include <utility>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/RegularExpression.hxx"
-#include <algorithm>
-#include <map>
-#include <sstream>
-#include <stdlib.h>
-#include <string.h>
-#include <utility>
-
/* NSIS uses different command line syntax on Windows and others */
#ifdef _WIN32
# define NSIS_OPT "/"
@@ -53,8 +56,7 @@ int cmCPackNSISGenerator::PackageFiles()
}
std::string nsisFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- std::string tmpFile = nsisFileName;
- tmpFile += "/NSISOutput.log";
+ std::string tmpFile = cmStrCat(nsisFileName, "/NSISOutput.log");
std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
nsisFileName += "/project.nsi";
std::ostringstream str;
@@ -139,39 +141,34 @@ int cmCPackNSISGenerator::PackageFiles()
installerIconCode.c_str());
}
if (this->IsSet("CPACK_PACKAGE_ICON")) {
- std::string installerIconCode = "!define MUI_HEADERIMAGE_BITMAP \"";
- installerIconCode += this->GetOption("CPACK_PACKAGE_ICON");
- installerIconCode += "\"\n";
+ std::string installerIconCode =
+ cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"",
+ this->GetOption("CPACK_PACKAGE_ICON"), "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
installerIconCode.c_str());
}
if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP")) {
- std::string installerBitmapCode =
- "!define MUI_WELCOMEFINISHPAGE_BITMAP \"";
- installerBitmapCode +=
- this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP");
- installerBitmapCode += "\"\n";
+ std::string installerBitmapCode = cmStrCat(
+ "!define MUI_WELCOMEFINISHPAGE_BITMAP \"",
+ this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"), "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE",
installerBitmapCode.c_str());
}
if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP")) {
- std::string installerBitmapCode =
- "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"";
- installerBitmapCode +=
- this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP");
- installerBitmapCode += "\"\n";
+ std::string installerBitmapCode = cmStrCat(
+ "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"",
+ this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"), "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE",
installerBitmapCode.c_str());
}
if (this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN")) {
- std::string installerRunCode = "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\";
- installerRunCode += this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY");
- installerRunCode += "\\";
- installerRunCode += this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN");
- installerRunCode += "\"\n";
+ std::string installerRunCode =
+ cmStrCat("!define MUI_FINISHPAGE_RUN \"$INSTDIR\\",
+ this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY"), '\\',
+ this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN"), "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE",
installerRunCode.c_str());
}
@@ -273,7 +270,7 @@ int cmCPackNSISGenerator::PackageFiles()
if (anyDownloadedComponents) {
defines += "!define CPACK_USES_DOWNLOAD\n";
- if (cmSystemTools::IsOn(this->GetOption("CPACK_ADD_REMOVE"))) {
+ if (cmIsOn(this->GetOption("CPACK_ADD_REMOVE"))) {
defines += "!define CPACK_NSIS_ADD_REMOVE\n";
}
}
@@ -294,9 +291,9 @@ int cmCPackNSISGenerator::PackageFiles()
this->ConfigureFile(nsisInInstallOptions, nsisInstallOptions);
this->ConfigureFile(nsisInFileName, nsisFileName);
- std::string nsisCmd = "\"";
- nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM");
- nsisCmd += "\" \"" + nsisFileName + "\"";
+ std::string nsisCmd =
+ cmStrCat('"', this->GetOption("CPACK_INSTALLER_PROGRAM"), "\" \"",
+ nsisFileName, '"');
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd << std::endl);
std::string output;
int retVal = 1;
@@ -320,8 +317,7 @@ int cmCPackNSISGenerator::PackageFiles()
int cmCPackNSISGenerator::InitializeInternal()
{
- if (cmSystemTools::IsOn(
- this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
+ if (cmIsOn(this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
cmCPackLogger(
cmCPackLog::LOG_WARNING,
"NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. "
@@ -413,8 +409,7 @@ int cmCPackNSISGenerator::InitializeInternal()
if (!resS || retVal ||
(!versionRex.find(output) && !versionRexCVS.find(output))) {
const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- std::string tmpFile = topDir ? topDir : ".";
- tmpFile += "/NSISOutput.log";
+ std::string tmpFile = cmStrCat(topDir ? topDir : ".", "/NSISOutput.log");
cmGeneratedFileStream ofs(tmpFile);
ofs << "# Run command: " << nsisCmd << std::endl
<< "# Output:" << std::endl
@@ -458,8 +453,7 @@ int cmCPackNSISGenerator::InitializeInternal()
"CPACK_CREATE_DESKTOP_LINKS: " << cpackPackageDeskTopLinks
<< std::endl);
- cmSystemTools::ExpandListArgument(cpackPackageDeskTopLinks,
- cpackPackageDesktopLinksVector);
+ cmExpandList(cpackPackageDeskTopLinks, cpackPackageDesktopLinksVector);
for (std::string const& cpdl : cpackPackageDesktopLinksVector) {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"CPACK_CREATE_DESKTOP_LINKS: " << cpdl << std::endl);
@@ -477,9 +471,8 @@ int cmCPackNSISGenerator::InitializeInternal()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackPackageExecutables: " << cpackPackageExecutables
<< "." << std::endl);
- std::vector<std::string> cpackPackageExecutablesVector;
- cmSystemTools::ExpandListArgument(cpackPackageExecutables,
- cpackPackageExecutablesVector);
+ std::vector<std::string> cpackPackageExecutablesVector =
+ cmExpandedList(cpackPackageExecutables);
if (cpackPackageExecutablesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -501,10 +494,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (!cpackPackageDesktopLinksVector.empty() &&
- std::find(cpackPackageDesktopLinksVector.begin(),
- cpackPackageDesktopLinksVector.end(),
- execName) != cpackPackageDesktopLinksVector.end()) {
+ if (cmContains(cpackPackageDesktopLinksVector, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -534,8 +524,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl);
- std::vector<std::string> cpackMenuLinksVector;
- cmSystemTools::ExpandListArgument(cpackMenuLinks, cpackMenuLinksVector);
+ std::vector<std::string> cpackMenuLinksVector =
+ cmExpandedList(cpackMenuLinks);
if (cpackMenuLinksVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -576,8 +566,7 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
}
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";
- desktop += linkName;
+ std::string desktop = cmStrCat("CPACK_CREATE_DESKTOP_LINK_", linkName);
if (this->IsSet(desktop)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
@@ -659,8 +648,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
if (component->IsDownloaded) {
if (component->ArchiveFile.empty()) {
// Compute the name of the archive.
- std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- packagesDir += ".dummy";
+ std::string packagesDir =
+ cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy");
std::ostringstream out;
out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-"
<< component->Name << ".zip";
@@ -674,8 +663,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
if (userUploadDirectory && *userUploadDirectory) {
uploadDirectory = userUploadDirectory;
} else {
- uploadDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
- uploadDirectory += "/CPackUploads";
+ uploadDirectory =
+ cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
}
if (!cmSystemTools::FileExists(uploadDirectory)) {
if (!cmSystemTools::MakeDirectory(uploadDirectory)) {
@@ -712,17 +701,14 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
}
// The directory where this component's files reside
- std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- dirName += '/';
- dirName += component->Name;
- dirName += '/';
+ std::string dirName = cmStrCat(
+ this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component->Name, '/');
// Build the list of files to go into this archive, and determine the
// size of the installed component.
- std::string zipListFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- zipListFileName += "/winZip.filelist";
- bool needQuotesInFile =
- cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES"));
+ std::string zipListFileName = cmStrCat(
+ this->GetOption("CPACK_TEMPORARY_DIRECTORY"), "/winZip.filelist");
+ bool needQuotesInFile = cmIsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES"));
unsigned long totalSize = 0;
{ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(zipListFileName);
@@ -751,8 +737,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
cmd, &output, &output, &retVal, dirName.c_str(),
cmSystemTools::OUTPUT_NONE, cmDuration::zero());
if (!res || retVal) {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/CompressZip.log";
+ std::string tmpFile = cmStrCat(
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/CompressZip.log");
cmGeneratedFileStream ofs(tmpFile);
ofs << "# Run command: " << cmd << std::endl
<< "# Output:" << std::endl
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index fc9ad9ace..0af37af50 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackGenerator.h"
-
#include <iosfwd>
#include <set>
#include <string>
#include <vector>
+#include "cmCPackGenerator.h"
+
class cmCPackComponent;
class cmCPackComponentGroup;
diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx
index 76f06992b..60faecd0b 100644
--- a/Source/CPack/cmCPackNuGetGenerator.cxx
+++ b/Source/CPack/cmCPackNuGetGenerator.cxx
@@ -2,11 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackNuGetGenerator.h"
-#include "cmAlgorithms.h"
-#include "cmCPackComponentGroup.h"
-#include "cmCPackLog.h"
-#include "cmSystemTools.h"
-
#include <algorithm>
#include <iterator>
#include <map>
@@ -15,6 +10,11 @@
#include <utility>
#include <vector>
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
bool cmCPackNuGetGenerator::SupportsComponentInstallation() const
{
return IsOn("CPACK_NUGET_COMPONENT_INSTALL");
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 90e0afe7f..951c65f4d 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -4,12 +4,14 @@
#include <sstream>
+#include "cm_sys_stat.h"
+
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cm_sys_stat.h"
cmCPackOSXX11Generator::cmCPackOSXX11Generator() = default;
@@ -28,9 +30,8 @@ int cmCPackOSXX11Generator::PackageFiles()
<< "." << std::endl);
std::ostringstream str;
std::ostringstream deleteStr;
- std::vector<std::string> cpackPackageExecutablesVector;
- cmSystemTools::ExpandListArgument(cpackPackageExecutables,
- cpackPackageExecutablesVector);
+ std::vector<std::string> cpackPackageExecutablesVector =
+ cmExpandedList(cpackPackageExecutables);
if (cpackPackageExecutablesVector.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -55,16 +56,14 @@ int cmCPackOSXX11Generator::PackageFiles()
diskImageDirectory + "/.background";
// App bundle directories
- std::string packageDirFileName = toplevel;
- packageDirFileName += "/";
- packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
- packageDirFileName += ".app";
+ std::string packageDirFileName = cmStrCat(
+ toplevel, '/', this->GetOption("CPACK_PACKAGE_FILE_NAME"), ".app");
std::string contentsDirectory = packageDirFileName + "/Contents";
std::string resourcesDirectory = contentsDirectory + "/Resources";
std::string appDirectory = contentsDirectory + "/MacOS";
std::string scriptDirectory = resourcesDirectory + "/Scripts";
- std::string resourceFileName = this->GetOption("CPACK_PACKAGE_FILE_NAME");
- resourceFileName += ".rsrc";
+ std::string resourceFileName =
+ cmStrCat(this->GetOption("CPACK_PACKAGE_FILE_NAME"), ".rsrc");
const char* dir = resourcesDirectory.c_str();
const char* appdir = appDirectory.c_str();
@@ -113,13 +112,10 @@ int cmCPackOSXX11Generator::PackageFiles()
}
// Two of the files need to have execute permission, so ensure they do:
- std::string runTimeScript = dir;
- runTimeScript += "/";
- runTimeScript += "RuntimeScript";
+ std::string runTimeScript = cmStrCat(dir, "/RuntimeScript");
- std::string appScriptName = appdir;
- appScriptName += "/";
- appScriptName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ std::string appScriptName =
+ cmStrCat(appdir, '/', this->GetOption("CPACK_PACKAGE_FILE_NAME"));
mode_t mode;
if (cmsys::SystemTools::GetPermissions(runTimeScript.c_str(), mode)) {
@@ -139,8 +135,8 @@ int cmCPackOSXX11Generator::PackageFiles()
}
std::string output;
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/hdiutilOutput.log";
+ std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
+ "/hdiutilOutput.log");
std::ostringstream dmgCmd;
dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
<< "\" create -ov -fs HFS+ -format UDZO -srcfolder \""
@@ -228,9 +224,8 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const std::string& name)
return false;
}
- std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- destFileName += "/Resources/";
- destFileName += name + ext;
+ std::string destFileName = cmStrCat(
+this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources/", name, ext );
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
@@ -245,9 +240,7 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile(
const std::string& name, const std::string& dir,
const char* outputFileName /* = 0 */, bool copyOnly /* = false */)
{
- std::string inFName = "CPack.";
- inFName += name;
- inFName += ".in";
+ std::string inFName = cmStrCat("CPack.", name, ".in");
std::string inFileName = this->FindTemplate(inFName.c_str());
if (inFileName.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -259,9 +252,7 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile(
outputFileName = name.c_str();
}
- std::string destFileName = dir;
- destFileName += "/";
- destFileName += outputFileName;
+ std::string destFileName = cmStrCat(dir, '/', outputFileName);
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Configure file: " << inFileName << " to " << destFileName
@@ -272,8 +263,8 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile(
const char* cmCPackOSXX11Generator::GetPackagingInstallPrefix()
{
- this->InstallPrefix = "/";
- this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
- this->InstallPrefix += ".app/Contents/Resources";
+ this->InstallPrefix =
+ cmStrCat('/', this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ ".app/Contents/Resources");
return this->InstallPrefix.c_str();
}
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 8c22c65b0..dae5ec9d4 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -7,6 +7,7 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -34,8 +35,8 @@ std::string cmCPackPKGGenerator::GetPackageName(
const cmCPackComponent& component)
{
if (component.ArchiveFile.empty()) {
- std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- packagesDir += ".dummy";
+ std::string packagesDir =
+ cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy");
std::ostringstream out;
out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-"
<< component.Name << ".pkg";
@@ -56,8 +57,8 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
return;
}
- std::string distributionFile = metapackageFile;
- distributionFile += "/Contents/distribution.dist";
+ std::string distributionFile =
+ cmStrCat(metapackageFile, "/Contents/distribution.dist");
// Create the choice outline, which provides a tree-based view of
// the components in their groups.
@@ -144,12 +145,9 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group,
void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
cmXMLWriter& xout)
{
- std::string packageId = "com.";
- packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
- packageId += '.';
- packageId += this->GetOption("CPACK_PACKAGE_NAME");
- packageId += '.';
- packageId += component.Name;
+ std::string packageId =
+ cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.',
+ this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name);
xout.StartElement("choice");
xout.Attribute("id", component.Name + "Choice");
@@ -192,14 +190,13 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
// Create a description of the package associated with this
// component.
- std::string relativePackageLocation = "Contents/Packages/";
- relativePackageLocation += this->GetPackageName(component);
+ std::string relativePackageLocation =
+ cmStrCat("Contents/Packages/", this->GetPackageName(component));
// Determine the installed size of the package.
- std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- dirName += '/';
- dirName += component.Name;
- dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
+ std::string dirName =
+ cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component.Name,
+ this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
unsigned long installedSize = component.GetInstalledSizeInKbytes(dirName);
xout.StartElement("pkg-ref");
@@ -282,9 +279,7 @@ bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
return false;
}
- std::string destFileName = dirName;
- destFileName += '/';
- destFileName += name + ext;
+ std::string destFileName = cmStrCat(dirName, '/', name, ext);
// Set this so that distribution.dist gets the right name (without
// the path).
@@ -305,9 +300,7 @@ bool cmCPackPKGGenerator::CopyResourcePlistFile(const std::string& name,
outName = name.c_str();
}
- std::string inFName = "CPack.";
- inFName += name;
- inFName += ".in";
+ std::string inFName = cmStrCat("CPack.", name, ".in");
std::string inFileName = this->FindTemplate(inFName.c_str());
if (inFileName.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -315,9 +308,8 @@ bool cmCPackPKGGenerator::CopyResourcePlistFile(const std::string& name,
return false;
}
- std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- destFileName += "/";
- destFileName += outName;
+ std::string destFileName =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', outName);
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Configure file: " << inFileName << " to " << destFileName
@@ -330,9 +322,7 @@ int cmCPackPKGGenerator::CopyInstallScript(const std::string& resdir,
const std::string& script,
const std::string& name)
{
- std::string dst = resdir;
- dst += "/";
- dst += name;
+ std::string dst = cmStrCat(resdir, '/', name);
cmSystemTools::CopyFileAlways(script, dst);
cmSystemTools::SetPermissions(dst.c_str(), 0777);
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index 3d93c48f1..c5ba726d5 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -2,19 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackPackageMakerGenerator.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
#include <map>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
#include <string>
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -47,8 +49,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
this->GetOption("CPACK_TEMPORARY_DIRECTORY");
if (this->Components.empty()) {
packageDirFileName += ".pkg";
- resDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- resDir += "/Resources";
+ resDir =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources");
} else {
packageDirFileName += ".mpkg";
if (!cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str())) {
@@ -58,8 +60,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
return 0;
}
- resDir = packageDirFileName;
- resDir += "/Contents";
+ resDir = cmStrCat(packageDirFileName, "/Contents");
if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"unable to create package subdirectory " << resDir
@@ -155,8 +156,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
if (!this->Components.empty()) {
// Create the directory where component packages will be built.
- std::string basePackageDir = packageDirFileName;
- basePackageDir += "/Contents/Packages";
+ std::string basePackageDir =
+ cmStrCat(packageDirFileName, "/Contents/Packages");
if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating component packages directory: "
@@ -172,8 +173,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
if (userUploadDirectory && *userUploadDirectory) {
uploadDirectory = userUploadDirectory;
} else {
- uploadDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
- uploadDirectory += "/CPackUploads";
+ uploadDirectory =
+ cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
}
// Create packages for each component
@@ -232,9 +233,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
packageFile += '/';
packageFile += GetPackageName(compIt->second);
- std::string packageDir = toplevel;
- packageDir += '/';
- packageDir += compIt->first;
+ std::string packageDir = cmStrCat(toplevel, '/', compIt->first);
if (!this->GenerateComponentPackage(
packageFile.c_str(), packageDir.c_str(), compIt->second)) {
return 0;
@@ -283,8 +282,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
WriteDistributionFile(packageDirFileName.c_str());
}
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/hdiutilOutput.log";
+ std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
+ "/hdiutilOutput.log");
std::ostringstream dmgCmd;
dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
<< "\" create -ov -fs HFS+ -format UDZO -srcfolder \""
@@ -461,8 +460,8 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command,
const char* packageFile)
{
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/PackageMakerOutput.log";
+ std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
+ "/PackageMakerOutput.log");
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
std::string output;
@@ -517,8 +516,9 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
this->PackageMakerVersion < 3.0) {
// Create Description.plist and Info.plist files for normal Mac OS
// X packages, which work on Mac OS X 10.3 and newer.
- std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- descriptionFile += '/' + component.Name + "-Description.plist";
+ std::string descriptionFile =
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
+ component.Name, "-Description.plist");
cmsys::ofstream out(descriptionFile.c_str());
cmXMLWriter xout(out);
xout.StartDocument();
@@ -539,12 +539,10 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
out.close();
// Create the Info.plist file for this component
- std::string moduleVersionSuffix = ".";
- moduleVersionSuffix += component.Name;
+ std::string moduleVersionSuffix = cmStrCat('.', component.Name);
this->SetOption("CPACK_MODULE_VERSION_SUFFIX",
moduleVersionSuffix.c_str());
- std::string infoFileName = component.Name;
- infoFileName += "-Info.plist";
+ std::string infoFileName = cmStrCat(component.Name, "-Info.plist");
if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str())) {
return false;
}
@@ -561,12 +559,9 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
// like normal packages, and can be downloaded by the installer
// on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create
// flat packages when the packages will be downloaded on the fly.
- std::string pkgId = "com.";
- pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
- pkgId += '.';
- pkgId += this->GetOption("CPACK_PACKAGE_NAME");
- pkgId += '.';
- pkgId += component.Name;
+ std::string pkgId =
+ cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.',
+ this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name);
pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
<< "\" --root \"" << packageDir << "\""
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index 94b5b5f7e..dae268c5c 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -2,14 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackProductBuildGenerator.h"
+#include <cstddef>
#include <map>
#include <sstream>
-#include <stddef.h>
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmCPackProductBuildGenerator::cmCPackProductBuildGenerator()
@@ -28,8 +29,8 @@ int cmCPackProductBuildGenerator::PackageFiles()
this->GetOption("CPACK_TEMPORARY_DIRECTORY");
// Create the directory where component packages will be built.
- std::string basePackageDir = packageDirFileName;
- basePackageDir += "/Contents/Packages";
+ std::string basePackageDir =
+ cmStrCat(packageDirFileName, "/Contents/Packages");
if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating component packages directory: "
@@ -41,9 +42,7 @@ int cmCPackProductBuildGenerator::PackageFiles()
std::map<std::string, cmCPackComponent>::iterator compIt;
for (compIt = this->Components.begin(); compIt != this->Components.end();
++compIt) {
- std::string packageDir = toplevel;
- packageDir += '/';
- packageDir += compIt->first;
+ std::string packageDir = cmStrCat(toplevel, '/', compIt->first);
if (!this->GenerateComponentPackage(basePackageDir,
GetPackageName(compIt->second),
packageDir, &compIt->second)) {
@@ -138,8 +137,8 @@ int cmCPackProductBuildGenerator::InitializeInternal()
bool cmCPackProductBuildGenerator::RunProductBuild(const std::string& command)
{
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/ProductBuildOutput.log";
+ std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
+ "/ProductBuildOutput.log");
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
std::string output;
@@ -166,9 +165,7 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
const std::string& packageFileDir, const std::string& packageFileName,
const std::string& packageDir, const cmCPackComponent* component)
{
- std::string packageFile = packageFileDir;
- packageFile += '/';
- packageFile += packageFileName;
+ std::string packageFile = cmStrCat(packageFileDir, '/', packageFileName);
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Building component package: " << packageFile
@@ -206,10 +203,8 @@ bool cmCPackProductBuildGenerator::GenerateComponentPackage(
// The command that will be used to run ProductBuild
std::ostringstream pkgCmd;
- std::string pkgId = "com.";
- pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
- pkgId += '.';
- pkgId += this->GetOption("CPACK_PACKAGE_NAME");
+ std::string pkgId = cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"),
+ '.', this->GetOption("CPACK_PACKAGE_NAME"));
if (component) {
pkgId += '.';
pkgId += component->Name;
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 33ab62bdf..0c1cecf39 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -3,7 +3,7 @@
#include "cmCPackRPMGenerator.h"
#include <algorithm>
-#include <ctype.h>
+#include <cctype>
#include <map>
#include <ostream>
#include <utility>
@@ -12,6 +12,7 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmCPackRPMGenerator::cmCPackRPMGenerator() = default;
@@ -21,7 +22,7 @@ cmCPackRPMGenerator::~cmCPackRPMGenerator() = default;
int cmCPackRPMGenerator::InitializeInternal()
{
this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
- if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
+ if (cmIsOff(this->GetOption("CPACK_SET_DESTDIR"))) {
this->SetOption("CPACK_SET_DESTDIR", "I_ON");
}
/* Replace space in CPACK_PACKAGE_NAME in order to avoid
@@ -81,8 +82,7 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel,
// Tell CPackRPM.cmake the name of the component NAME.
this->SetOption("CPACK_RPM_PACKAGE_COMPONENT", packageName.c_str());
// Tell CPackRPM.cmake the path where the component is.
- std::string component_path = "/";
- component_path += packageName;
+ std::string component_path = cmStrCat('/', packageName);
this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
component_path.c_str());
if (!this->ReadListFile("Internal/CPack/CPackRPM.cmake")) {
@@ -184,8 +184,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
// The default behavior is to have one package by component group
// unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
if (!ignoreGroup) {
- std::map<std::string, cmCPackComponentGroup>::iterator mainCompGIt =
- this->ComponentGroups.end();
+ auto mainCompGIt = this->ComponentGroups.end();
std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
for (compGIt = this->ComponentGroups.begin();
@@ -206,8 +205,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
retval &= PackageOnePack(initialTopLevel, compGIt->first);
}
// Handle Orphan components (components not belonging to any groups)
- std::map<std::string, cmCPackComponent>::iterator mainCompIt =
- this->Components.end();
+ auto mainCompIt = this->Components.end();
std::map<std::string, cmCPackComponent>::iterator compIt;
for (compIt = this->Components.begin(); compIt != this->Components.end();
++compIt) {
@@ -251,8 +249,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
// CPACK_COMPONENTS_IGNORE_GROUPS is set
// We build 1 package per component
else {
- std::map<std::string, cmCPackComponent>::iterator mainCompIt =
- this->Components.end();
+ auto mainCompIt = this->Components.end();
std::map<std::string, cmCPackComponent>::iterator compIt;
for (compIt = this->Components.begin(); compIt != this->Components.end();
@@ -375,8 +372,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
if (!compInstDirName.empty()) {
// Tell CPackRPM.cmake the path where the component is.
- std::string component_path = "/";
- component_path += compInstDirName;
+ std::string component_path = cmStrCat('/', compInstDirName);
this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
component_path.c_str());
}
diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h
index 27d3b6339..075ce8458 100644
--- a/Source/CPack/cmCPackRPMGenerator.h
+++ b/Source/CPack/cmCPackRPMGenerator.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackGenerator.h"
-
#include <string>
+#include "cmCPackGenerator.h"
+
/** \class cmCPackRPMGenerator
* \brief A generator for RPM packages
* The idea of the CPack RPM generator is to use
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index aba15d239..a4a5e6fcd 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -2,18 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackSTGZGenerator.h"
-#include "cmsys/FStream.hxx"
+#include <cstdio>
#include <sstream>
-#include <stdio.h>
#include <string>
#include <vector>
+#include "cmsys/FStream.hxx"
+
+#include "cm_sys_stat.h"
+
+#include "cmArchiveWrite.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmSystemTools.h"
-#include "cm_sys_stat.h"
-cmCPackSTGZGenerator::cmCPackSTGZGenerator() = default;
+cmCPackSTGZGenerator::cmCPackSTGZGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh")
+{
+}
cmCPackSTGZGenerator::~cmCPackSTGZGenerator() = default;
diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h
index 9cf184b19..79d7035e1 100644
--- a/Source/CPack/cmCPackSTGZGenerator.h
+++ b/Source/CPack/cmCPackSTGZGenerator.h
@@ -5,19 +5,19 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCPackGenerator.h"
-#include "cmCPackTGZGenerator.h"
-
#include <iosfwd>
+#include "cmCPackArchiveGenerator.h"
+#include "cmCPackGenerator.h"
+
/** \class cmCPackSTGZGenerator
* \brief A generator for Self extractable TGZ files
*
*/
-class cmCPackSTGZGenerator : public cmCPackTGZGenerator
+class cmCPackSTGZGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackTGZGenerator);
+ cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
@@ -29,7 +29,6 @@ protected:
int PackageFiles() override;
int InitializeInternal() override;
int GenerateHeader(std::ostream* os) override;
- const char* GetOutputExtension() override { return ".sh"; }
};
#endif
diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx
deleted file mode 100644
index 6f4676ef9..000000000
--- a/Source/CPack/cmCPackTGZGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTGZGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTGZGenerator::cmCPackTGZGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr")
-{
-}
-
-cmCPackTGZGenerator::~cmCPackTGZGenerator() = default;
diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h
deleted file mode 100644
index 7be3d9d33..000000000
--- a/Source/CPack/cmCPackTGZGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTGZGenerator_h
-#define cmCPackTGZGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTGZGenerator
- * \brief A generator for TGZ files
- *
- */
-class cmCPackTGZGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTGZGenerator();
- ~cmCPackTGZGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.gz"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx
deleted file mode 100644
index ccbccde95..000000000
--- a/Source/CPack/cmCPackTXZGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTXZGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTXZGenerator::cmCPackTXZGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr")
-{
-}
-
-cmCPackTXZGenerator::~cmCPackTXZGenerator() = default;
diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h
deleted file mode 100644
index 4aa59730e..000000000
--- a/Source/CPack/cmCPackTXZGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTXZGenerator_h
-#define cmCPackTXZGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTXZGenerator
- * \brief A generator for TXZ files
- *
- */
-class cmCPackTXZGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTXZGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTXZGenerator();
- ~cmCPackTXZGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.xz"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx
deleted file mode 100644
index 85abeb1ca..000000000
--- a/Source/CPack/cmCPackTarBZip2Generator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTarBZip2Generator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr")
-{
-}
-
-cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator() = default;
diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h
deleted file mode 100644
index 7975ddaee..000000000
--- a/Source/CPack/cmCPackTarBZip2Generator.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTarBZip2Generator_h
-#define cmCPackTarBZip2Generator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTarBZip2Generator
- * \brief A generator for TarBZip2 files
- */
-class cmCPackTarBZip2Generator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTarBZip2Generator();
- ~cmCPackTarBZip2Generator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.bz2"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx
deleted file mode 100644
index 55a6de53c..000000000
--- a/Source/CPack/cmCPackTarCompressGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTarCompressGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr")
-{
-}
-
-cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator() = default;
diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h
deleted file mode 100644
index 37c7f48c8..000000000
--- a/Source/CPack/cmCPackTarCompressGenerator.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTarCompressGenerator_h
-#define cmCPackTarCompressGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTarCompressGenerator
- * \brief A generator for TarCompress files
- */
-class cmCPackTarCompressGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTarCompressGenerator();
- ~cmCPackTarCompressGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.Z"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx
deleted file mode 100644
index f06494c44..000000000
--- a/Source/CPack/cmCPackZIPGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackZIPGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackZIPGenerator::cmCPackZIPGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip")
-{
-}
-
-cmCPackZIPGenerator::~cmCPackZIPGenerator() = default;
diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h
deleted file mode 100644
index 58ec79ef1..000000000
--- a/Source/CPack/cmCPackZIPGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackZIPGenerator_h
-#define cmCPackZIPGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackZIPGenerator
- * \brief A generator for ZIP files
- */
-class cmCPackZIPGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackArchiveGenerator);
-
- /**
- * Construct generator
- */
- cmCPackZIPGenerator();
- ~cmCPackZIPGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".zip"; }
-};
-
-#endif
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 58b9e70fa..58956522f 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -3,18 +3,6 @@
#include "cmsys/CommandLineArguments.hxx"
#include "cmsys/Encoding.hxx"
-#include <iostream>
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <sstream>
-#include <stddef.h>
-#include <string>
-#include <utility>
-#include <vector>
-
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
-# include "cmsys/ConsoleBuf.hxx"
-#endif
#include "cmCPackGenerator.h"
#include "cmCPackGeneratorFactory.h"
@@ -26,22 +14,37 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-static const char* cmDocumentationName[][2] = {
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+# include "cmsys/ConsoleBuf.hxx"
+#endif
+
+#include <cstddef>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace {
+const char* cmDocumentationName[][2] = {
{ nullptr, " cpack - Packaging driver provided by CMake." },
{ nullptr, nullptr }
};
-static const char* cmDocumentationUsage[][2] = {
+const char* cmDocumentationUsage[][2] = {
// clang-format off
{ nullptr, " cpack [options]" },
{ nullptr, nullptr }
// clang-format on
};
-static const char* cmDocumentationOptions[][2] = {
+const char* cmDocumentationOptions[][2] = {
{ "-G <generators>", "Override/define CPACK_GENERATOR" },
{ "-C <Configuration>", "Specify the project configuration" },
{ "-D <var>=<value>", "Set a CPack variable." },
@@ -64,7 +67,7 @@ int cpackUnknownArgument(const char* /*unused*/, void* /*unused*/)
struct cpackDefinitions
{
- typedef std::map<std::string, std::string> MapType;
+ using MapType = std::map<std::string, std::string>;
MapType Map;
cmCPackLog* Log;
};
@@ -90,16 +93,17 @@ int cpackDefinitionArgument(const char* argument, const char* cValue,
return 1;
}
-static void cpackProgressCallback(const std::string& message, float /*unused*/)
+void cpackProgressCallback(const std::string& message, float /*unused*/)
{
std::cout << "-- " << message << std::endl;
}
+} // namespace
// this is CPack.
int main(int argc, char const* const* argv)
{
cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we can output Unicode to console
cmsys::ConsoleBuf::Manager consoleOut(std::cout);
consoleOut.SetUTF8Pipes();
@@ -154,7 +158,7 @@ int main(int argc, char const* const* argv)
cmsys::CommandLineArguments arg;
arg.Initialize(argc, argv);
- typedef cmsys::CommandLineArguments argT;
+ using argT = cmsys::CommandLineArguments;
// Help arguments
arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
@@ -227,14 +231,13 @@ int main(int argc, char const* const* argv)
bool cpackConfigFileSpecified = true;
if (cpackConfigFile.empty()) {
- cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory();
- cpackConfigFile += "/CPackConfig.cmake";
+ cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
+ "/CPackConfig.cmake");
cpackConfigFileSpecified = false;
}
cmCPackGeneratorFactory generators;
generators.SetLogger(&log);
- cmCPackGenerator* cpackGenerator = nullptr;
cmDocumentation doc;
doc.addCPackStandardDocSections();
@@ -269,7 +272,7 @@ int main(int argc, char const* const* argv)
}
if (!cpackBuildConfig.empty()) {
- globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
+ globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig);
}
if (cmSystemTools::FileExists(cpackConfigFile)) {
@@ -291,24 +294,21 @@ int main(int argc, char const* const* argv)
}
if (!generator.empty()) {
- globalMF.AddDefinition("CPACK_GENERATOR", generator.c_str());
+ globalMF.AddDefinition("CPACK_GENERATOR", generator);
}
if (!cpackProjectName.empty()) {
- globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
+ globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName);
}
if (!cpackProjectVersion.empty()) {
- globalMF.AddDefinition("CPACK_PACKAGE_VERSION",
- cpackProjectVersion.c_str());
+ globalMF.AddDefinition("CPACK_PACKAGE_VERSION", cpackProjectVersion);
}
if (!cpackProjectVendor.empty()) {
- globalMF.AddDefinition("CPACK_PACKAGE_VENDOR",
- cpackProjectVendor.c_str());
+ globalMF.AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor);
}
// if this is not empty it has been set on the command line
// go for it. Command line override values set in config file.
if (!cpackProjectDirectory.empty()) {
- globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
- cpackProjectDirectory.c_str());
+ globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
}
// The value has not been set on the command line
else {
@@ -317,11 +317,11 @@ int main(int argc, char const* const* argv)
// use default value iff no value has been provided by the config file
if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
- cpackProjectDirectory.c_str());
+ cpackProjectDirectory);
}
}
for (auto const& cd : definitions.Map) {
- globalMF.AddDefinition(cd.first, cd.second.c_str());
+ globalMF.AddDefinition(cd.first, cd.second);
}
const char* cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH");
@@ -333,8 +333,7 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified" << std::endl);
} else {
- std::vector<std::string> generatorsVector;
- cmSystemTools::ExpandListArgument(genList, generatorsVector);
+ std::vector<std::string> generatorsVector = cmExpandedList(genList);
for (std::string const& gen : generatorsVector) {
cmMakefile::ScopePushPop raii(&globalMF);
cmMakefile* mf = &globalMF;
@@ -361,7 +360,8 @@ int main(int argc, char const* const* argv)
parsed = 0;
}
if (parsed) {
- cpackGenerator = generators.NewGenerator(gen);
+ std::unique_ptr<cmCPackGenerator> cpackGenerator =
+ generators.NewGenerator(gen);
if (cpackGenerator) {
cpackGenerator->SetTrace(trace);
cpackGenerator->SetTraceExpand(traceExpand);
@@ -425,7 +425,7 @@ int main(int argc, char const* const* argv)
std::ostringstream ostr;
ostr << projVersionMajor << "." << projVersionMinor << "."
<< projVersionPatch;
- mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str().c_str());
+ mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str());
}
int res = cpackGenerator->DoPackage();
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index b957856e8..8640c46f8 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -2,6 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestBZR.h"
+#include <cstdlib>
+#include <list>
+#include <map>
+#include <ostream>
+#include <vector>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_expat.h"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
@@ -9,14 +19,6 @@
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cm_expat.h"
-#include "cmsys/RegularExpression.hxx"
-#include <list>
-#include <map>
-#include <ostream>
-#include <stdlib.h>
-#include <vector>
-
extern "C" int cmBZRXMLParserUnknownEncodingHandler(void* /*unused*/,
const XML_Char* name,
XML_Encoding* info)
@@ -200,8 +202,8 @@ public:
private:
cmCTestBZR* BZR;
- typedef cmCTestBZR::Revision Revision;
- typedef cmCTestBZR::Change Change;
+ using Revision = cmCTestBZR::Revision;
+ using Change = cmCTestBZR::Change;
Revision Rev;
std::vector<Change> Changes;
Change CurChange;
diff --git a/Source/CTest/cmCTestBZR.h b/Source/CTest/cmCTestBZR.h
index d5c78c760..d7c632128 100644
--- a/Source/CTest/cmCTestBZR.h
+++ b/Source/CTest/cmCTestBZR.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGlobalVC.h"
-
#include <iosfwd>
#include <string>
+#include "cmCTestGlobalVC.h"
+
class cmCTest;
/** \class cmCTestBZR
diff --git a/Source/CTest/cmCTestBinPacker.cxx b/Source/CTest/cmCTestBinPacker.cxx
new file mode 100644
index 000000000..e21b14dd7
--- /dev/null
+++ b/Source/CTest/cmCTestBinPacker.cxx
@@ -0,0 +1,203 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestBinPacker.h"
+
+#include <algorithm>
+#include <utility>
+
+bool cmCTestBinPackerAllocation::operator==(
+ const cmCTestBinPackerAllocation& other) const
+{
+ return this->ProcessIndex == other.ProcessIndex &&
+ this->SlotsNeeded == other.SlotsNeeded && this->Id == other.Id;
+}
+
+bool cmCTestBinPackerAllocation::operator!=(
+ const cmCTestBinPackerAllocation& other) const
+{
+ return !(*this == other);
+}
+
+namespace {
+
+/*
+ * The following algorithm is used to do two things:
+ *
+ * 1) Determine if a test's resource requirements can fit within the resources
+ * present on the system, and
+ * 2) Do the actual allocation
+ *
+ * This algorithm performs a recursive search, looking for a bin pack that will
+ * fit the specified requirements. It has a template to specify different
+ * optimization strategies. If it ever runs out of room, it backtracks as far
+ * down the stack as it needs to and tries a different combination until no
+ * more combinations can be tried.
+ */
+template <typename AllocationStrategy>
+static bool AllocateCTestResources(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ const std::vector<std::string>& resourcesSorted, std::size_t currentIndex,
+ std::vector<cmCTestBinPackerAllocation*>& allocations)
+{
+ // Iterate through all large enough resources until we find a solution
+ std::size_t resourceIndex = 0;
+ while (resourceIndex < resourcesSorted.size()) {
+ auto const& resource = resources.at(resourcesSorted[resourceIndex]);
+ if (resource.Free() >=
+ static_cast<unsigned int>(allocations[currentIndex]->SlotsNeeded)) {
+ // Preemptively allocate the resource
+ allocations[currentIndex]->Id = resourcesSorted[resourceIndex];
+ if (currentIndex + 1 >= allocations.size()) {
+ // We have a solution
+ return true;
+ }
+
+ // Move the resource up the list until it is sorted again
+ auto resources2 = resources;
+ auto resourcesSorted2 = resourcesSorted;
+ resources2[resourcesSorted2[resourceIndex]].Locked +=
+ allocations[currentIndex]->SlotsNeeded;
+ AllocationStrategy::IncrementalSort(resources2, resourcesSorted2,
+ resourceIndex);
+
+ // Recurse one level deeper
+ if (AllocateCTestResources<AllocationStrategy>(
+ resources2, resourcesSorted2, currentIndex + 1, allocations)) {
+ return true;
+ }
+ }
+
+ // No solution found here, deallocate the resource and try the next one
+ allocations[currentIndex]->Id.clear();
+ auto freeSlots = resources.at(resourcesSorted.at(resourceIndex)).Free();
+ do {
+ ++resourceIndex;
+ } while (resourceIndex < resourcesSorted.size() &&
+ resources.at(resourcesSorted.at(resourceIndex)).Free() ==
+ freeSlots);
+ }
+
+ // No solution was found
+ return false;
+}
+
+template <typename AllocationStrategy>
+static bool AllocateCTestResources(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<cmCTestBinPackerAllocation>& allocations)
+{
+ // Sort the resource requirements in descending order by slots needed
+ std::vector<cmCTestBinPackerAllocation*> allocationsPtr;
+ allocationsPtr.reserve(allocations.size());
+ for (auto& allocation : allocations) {
+ allocationsPtr.push_back(&allocation);
+ }
+ std::stable_sort(
+ allocationsPtr.rbegin(), allocationsPtr.rend(),
+ [](cmCTestBinPackerAllocation* a1, cmCTestBinPackerAllocation* a2) {
+ return a1->SlotsNeeded < a2->SlotsNeeded;
+ });
+
+ // Sort the resources according to sort strategy
+ std::vector<std::string> resourcesSorted;
+ resourcesSorted.reserve(resources.size());
+ for (auto const& res : resources) {
+ resourcesSorted.push_back(res.first);
+ }
+ AllocationStrategy::InitialSort(resources, resourcesSorted);
+
+ // Do the actual allocation
+ return AllocateCTestResources<AllocationStrategy>(
+ resources, resourcesSorted, std::size_t(0), allocationsPtr);
+}
+
+class RoundRobinAllocationStrategy
+{
+public:
+ static void InitialSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted);
+
+ static void IncrementalSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex);
+};
+
+void RoundRobinAllocationStrategy::InitialSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted)
+{
+ std::stable_sort(
+ resourcesSorted.rbegin(), resourcesSorted.rend(),
+ [&resources](const std::string& id1, const std::string& id2) {
+ return resources.at(id1).Free() < resources.at(id2).Free();
+ });
+}
+
+void RoundRobinAllocationStrategy::IncrementalSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex)
+{
+ auto tmp = resourcesSorted[lastAllocatedIndex];
+ std::size_t i = lastAllocatedIndex;
+ while (i < resourcesSorted.size() - 1 &&
+ resources.at(resourcesSorted[i + 1]).Free() >
+ resources.at(tmp).Free()) {
+ resourcesSorted[i] = resourcesSorted[i + 1];
+ ++i;
+ }
+ resourcesSorted[i] = tmp;
+}
+
+class BlockAllocationStrategy
+{
+public:
+ static void InitialSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted);
+
+ static void IncrementalSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex);
+};
+
+void BlockAllocationStrategy::InitialSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<std::string>& resourcesSorted)
+{
+ std::stable_sort(
+ resourcesSorted.rbegin(), resourcesSorted.rend(),
+ [&resources](const std::string& id1, const std::string& id2) {
+ return resources.at(id1).Free() < resources.at(id2).Free();
+ });
+}
+
+void BlockAllocationStrategy::IncrementalSort(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>&,
+ std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex)
+{
+ auto tmp = resourcesSorted[lastAllocatedIndex];
+ std::size_t i = lastAllocatedIndex;
+ while (i > 0) {
+ resourcesSorted[i] = resourcesSorted[i - 1];
+ --i;
+ }
+ resourcesSorted[i] = tmp;
+}
+}
+
+bool cmAllocateCTestResourcesRoundRobin(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<cmCTestBinPackerAllocation>& allocations)
+{
+ return AllocateCTestResources<RoundRobinAllocationStrategy>(resources,
+ allocations);
+}
+
+bool cmAllocateCTestResourcesBlock(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<cmCTestBinPackerAllocation>& allocations)
+{
+ return AllocateCTestResources<BlockAllocationStrategy>(resources,
+ allocations);
+}
diff --git a/Source/CTest/cmCTestBinPacker.h b/Source/CTest/cmCTestBinPacker.h
new file mode 100644
index 000000000..ff02b8565
--- /dev/null
+++ b/Source/CTest/cmCTestBinPacker.h
@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestBinPacker_h
+#define cmCTestBinPacker_h
+
+#include <cstddef>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "cmCTestResourceAllocator.h"
+
+struct cmCTestBinPackerAllocation
+{
+ std::size_t ProcessIndex;
+ int SlotsNeeded;
+ std::string Id;
+
+ bool operator==(const cmCTestBinPackerAllocation& other) const;
+ bool operator!=(const cmCTestBinPackerAllocation& other) const;
+};
+
+bool cmAllocateCTestResourcesRoundRobin(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<cmCTestBinPackerAllocation>& allocations);
+
+bool cmAllocateCTestResourcesBlock(
+ const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
+ std::vector<cmCTestBinPackerAllocation>& allocations);
+
+#endif
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 9ad96699b..2ad661cf0 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -2,21 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestBuildAndTestHandler.h"
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <ratio>
+
+#include "cmsys/Process.h"
+
#include "cmCTest.h"
#include "cmCTestTestHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmake.h"
-#include "cmsys/Process.h"
-#include <chrono>
-#include <cstring>
-#include <ratio>
-#include <stdlib.h>
-
cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
{
this->BuildTwoConfig = false;
@@ -76,6 +78,11 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
if (config) {
args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config));
}
+ if (!this->BuildMakeProgram.empty() &&
+ (this->BuildGenerator.find("Make") != std::string::npos ||
+ this->BuildGenerator.find("Ninja") != std::string::npos)) {
+ args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram);
+ }
for (std::string const& opt : this->BuildOptions) {
args.push_back(opt);
@@ -284,9 +291,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
std::vector<std::string> extraPaths;
// if this->ExecutableDirectory is set try that as well
if (!this->ExecutableDirectory.empty()) {
- std::string tempPath = this->ExecutableDirectory;
- tempPath += "/";
- tempPath += this->TestCommand;
+ std::string tempPath =
+ cmStrCat(this->ExecutableDirectory, '/', this->TestCommand);
extraPaths.push_back(tempPath);
}
std::vector<std::string> failed;
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
index 2d47b1580..0c8a04079 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -5,14 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-#include "cmDuration.h"
-
#include <sstream>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
+#include "cmCTestGenericHandler.h"
+#include "cmDuration.h"
+
class cmake;
/** \class cmCTestBuildAndTestHandler
@@ -22,7 +23,7 @@ class cmake;
class cmCTestBuildAndTestHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/*
* The main entry point for this class
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 2eacaf144..18df2141e 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -2,30 +2,31 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestBuildCommand.h"
+#include <cstring>
+#include <sstream>
+
+#include "cm_static_string_view.hxx"
+
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <sstream>
-#include <string.h>
-
class cmExecutionStatus;
-cmCTestBuildCommand::cmCTestBuildCommand()
+void cmCTestBuildCommand::BindArguments()
{
- this->GlobalGenerator = nullptr;
- this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
- this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
- this->Arguments[ctb_TARGET] = "TARGET";
- this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
- this->Arguments[ctb_FLAGS] = "FLAGS";
- this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
- this->Arguments[ctb_LAST] = nullptr;
- this->Last = ctb_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("NUMBER_ERRORS"_s, this->NumberErrors);
+ this->Bind("NUMBER_WARNINGS"_s, this->NumberWarnings);
+ this->Bind("TARGET"_s, this->Target);
+ this->Bind("CONFIGURATION"_s, this->Configuration);
+ this->Bind("FLAGS"_s, this->Flags);
+ this->Bind("PROJECT_NAME"_s, this->ProjectName);
}
cmCTestBuildCommand::~cmCTestBuildCommand()
@@ -59,20 +60,17 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
//
const char* ctestBuildConfiguration =
this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
- const char* cmakeBuildConfiguration =
- (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
- ? this->Values[ctb_CONFIGURATION]
+ const char* cmakeBuildConfiguration = !this->Configuration.empty()
+ ? this->Configuration.c_str()
: ((ctestBuildConfiguration && *ctestBuildConfiguration)
? ctestBuildConfiguration
: this->CTest->GetConfigType().c_str());
- const char* cmakeBuildAdditionalFlags =
- (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
- ? this->Values[ctb_FLAGS]
+ const char* cmakeBuildAdditionalFlags = !this->Flags.empty()
+ ? this->Flags.c_str()
: this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
- const char* cmakeBuildTarget =
- (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
- ? this->Values[ctb_TARGET]
+ const char* cmakeBuildTarget = !this->Target.empty()
+ ? this->Target.c_str()
: this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
if (cmakeGeneratorName && *cmakeGeneratorName) {
@@ -90,9 +88,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
cmakeGeneratorName);
if (!this->GlobalGenerator) {
- std::string e = "could not create generator named \"";
- e += cmakeGeneratorName;
- e += "\"";
+ std::string e = cmStrCat("could not create generator named \"",
+ cmakeGeneratorName, '"');
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
cmSystemTools::SetFatalErrorOccured();
return nullptr;
@@ -153,18 +150,13 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
bool ret = cmCTestHandlerCommand::InitialPass(args, status);
- if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
- std::ostringstream str;
- str << this->Handler->GetTotalErrors();
- this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS],
- str.str().c_str());
+ if (!this->NumberErrors.empty()) {
+ this->Makefile->AddDefinition(
+ this->NumberErrors, std::to_string(this->Handler->GetTotalErrors()));
}
- if (this->Values[ctb_NUMBER_WARNINGS] &&
- *this->Values[ctb_NUMBER_WARNINGS]) {
- std::ostringstream str;
- str << this->Handler->GetTotalWarnings();
- this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS],
- str.str().c_str());
+ if (!this->NumberWarnings.empty()) {
+ this->Makefile->AddDefinition(
+ this->NumberWarnings, std::to_string(this->Handler->GetTotalWarnings()));
}
return ret;
}
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index 77b05498d..da00a43c6 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -5,14 +5,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
#include <string>
+#include <utility>
#include <vector>
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
+
class cmCTestBuildHandler;
class cmCTestGenericHandler;
-class cmCommand;
class cmExecutionStatus;
class cmGlobalGenerator;
@@ -24,18 +27,17 @@ class cmGlobalGenerator;
class cmCTestBuildCommand : public cmCTestHandlerCommand
{
public:
- cmCTestBuildCommand();
~cmCTestBuildCommand() override;
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestBuildCommand* ni = new cmCTestBuildCommand;
+ auto ni = cm::make_unique<cmCTestBuildCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
@@ -46,23 +48,19 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator* GlobalGenerator = nullptr;
protected:
cmCTestBuildHandler* Handler;
- enum
- {
- ctb_BUILD = ct_LAST,
- ctb_NUMBER_ERRORS,
- ctb_NUMBER_WARNINGS,
- ctb_TARGET,
- ctb_CONFIGURATION,
- ctb_FLAGS,
- ctb_PROJECT_NAME,
- ctb_LAST
- };
-
+ void BindArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
+
+ std::string NumberErrors;
+ std::string NumberWarnings;
+ std::string Target;
+ std::string Configuration;
+ std::string Flags;
+ std::string ProjectName;
};
#endif
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index c8e4fa1b4..9cb5449d9 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -2,6 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestBuildHandler.h"
+#include <cstdlib>
+#include <cstring>
+#include <set>
+#include <utility>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
@@ -9,17 +18,11 @@
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
-#include <set>
-#include <stdlib.h>
-#include <string.h>
-#include <utility>
-
static const char* cmCTestErrorMatches[] = {
"^[Bb]us [Ee]rror",
"^[Ss]egmentation [Vv]iolation",
@@ -246,13 +249,11 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile* mf)
// Record the user-specified custom warning rules.
if (const char* customWarningMatchers =
mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH")) {
- cmSystemTools::ExpandListArgument(customWarningMatchers,
- this->ReallyCustomWarningMatches);
+ cmExpandList(customWarningMatchers, this->ReallyCustomWarningMatches);
}
if (const char* customWarningExceptions =
mf->GetDefinition("CTEST_CUSTOM_WARNING_EXCEPTION")) {
- cmSystemTools::ExpandListArgument(customWarningExceptions,
- this->ReallyCustomWarningExceptions);
+ cmExpandList(customWarningExceptions, this->ReallyCustomWarningExceptions);
}
}
@@ -327,7 +328,7 @@ int cmCTestBuildHandler::ProcessHandler()
std::string const& useLaunchers =
this->CTest->GetCTestConfiguration("UseLaunchers");
- this->UseCTestLaunch = cmSystemTools::IsOn(useLaunchers);
+ this->UseCTestLaunch = cmIsOn(useLaunchers);
// Create a last build log
cmGeneratedFileStream ofs;
@@ -384,11 +385,8 @@ int cmCTestBuildHandler::ProcessHandler()
if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
std::string srcdir =
this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
- std::string srcdirrep;
for (cc = srcdir.size() - 2; cc > 0; cc--) {
if (srcdir[cc] == '/') {
- srcdirrep = srcdir.substr(cc);
- srcdirrep = "/..." + srcdirrep;
srcdir = srcdir.substr(0, cc + 1);
break;
}
@@ -398,11 +396,8 @@ int cmCTestBuildHandler::ProcessHandler()
if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
std::string bindir =
this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
- std::string bindirrep;
for (cc = bindir.size() - 2; cc > 0; cc--) {
if (bindir[cc] == '/') {
- bindirrep = bindir.substr(cc);
- bindirrep = "/..." + bindirrep;
bindir = bindir.substr(0, cc + 1);
break;
}
@@ -415,6 +410,9 @@ int cmCTestBuildHandler::ProcessHandler()
// Remember start build time
this->StartBuild = this->CTest->CurrentTime();
this->StartBuildTime = std::chrono::system_clock::now();
+
+ cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr);
+ this->ColorRemover = &colorRemover;
int retVal = 0;
int res = cmsysProcess_State_Exited;
if (!this->CTest->GetShowOnly()) {
@@ -532,7 +530,7 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
// Sort XML fragments in chronological order.
cmFileTimeCache ftc;
FragmentCompare fragmentCompare(&ftc);
- typedef std::set<std::string, FragmentCompare> Fragments;
+ using Fragments = std::set<std::string, FragmentCompare>;
Fragments fragments(fragmentCompare);
// only report the first 50 warnings and first 50 errors
@@ -572,8 +570,7 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml)
std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
// make sure the source dir is in the correct case on windows
// via a call to collapse full path.
- srcdir = cmSystemTools::CollapseFullPath(srcdir);
- srcdir += "/";
+ srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/');
for (it = ew.begin();
it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) {
cmCTestBuildErrorWarning* cm = &(*it);
@@ -704,10 +701,8 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler)
} else {
// Compute a directory in which to store launcher fragments.
std::string& launchDir = this->Handler->CTestLaunchDir;
- launchDir = this->CTest->GetBinaryDir();
- launchDir += "/Testing/";
- launchDir += tag;
- launchDir += "/Build";
+ launchDir =
+ cmStrCat(this->CTest->GetBinaryDir(), "/Testing/", tag, "/Build");
// Clean out any existing launcher fragments.
cmSystemTools::RemoveADirectory(launchDir);
@@ -716,8 +711,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler)
// Enable launcher fragments.
cmSystemTools::MakeDirectory(launchDir);
this->WriteLauncherConfig();
- std::string launchEnv = "CTEST_LAUNCH_LOGS=";
- launchEnv += launchDir;
+ std::string launchEnv = cmStrCat("CTEST_LAUNCH_LOGS=", launchDir);
cmSystemTools::PutEnv(launchEnv);
}
}
@@ -743,8 +737,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteLauncherConfig()
this->Handler->ReallyCustomWarningExceptions);
// Give some testing configuration information to the launcher.
- std::string fname = this->Handler->CTestLaunchDir;
- fname += "/CTestLaunchConfig.cmake";
+ std::string fname =
+ cmStrCat(this->Handler->CTestLaunchDir, "/CTestLaunchConfig.cmake");
cmGeneratedFileStream fout(fname);
std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
fout << "set(CTEST_SOURCE_DIRECTORY \"" << srcdir << "\")\n";
@@ -756,10 +750,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteScrapeMatchers(
if (matchers.empty()) {
return;
}
- std::string fname = this->Handler->CTestLaunchDir;
- fname += "/Custom";
- fname += purpose;
- fname += ".txt";
+ std::string fname =
+ cmStrCat(this->Handler->CTestLaunchDir, "/Custom", purpose, ".txt");
cmGeneratedFileStream fout(fname);
for (std::string const& m : matchers) {
fout << m << "\n";
@@ -898,9 +890,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
// dashboard.
cmCTestBuildErrorWarning errorwarning;
errorwarning.LogLine = 1;
- errorwarning.Text =
- "*** WARNING non-zero return value in ctest from: ";
- errorwarning.Text += argv[0];
+ errorwarning.Text = cmStrCat(
+ "*** WARNING non-zero return value in ctest from: ", argv[0]);
errorwarning.PreContext.clear();
errorwarning.PostContext.clear();
errorwarning.Error = false;
@@ -922,8 +913,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command,
// If there was an error running command, report that on the dashboard.
cmCTestBuildErrorWarning errorwarning;
errorwarning.LogLine = 1;
- errorwarning.Text = "*** ERROR executing: ";
- errorwarning.Text += cmsysProcess_GetErrorString(cp);
+ errorwarning.Text =
+ cmStrCat("*** ERROR executing: ", cmsysProcess_GetErrorString(cp));
errorwarning.PreContext.clear();
errorwarning.PostContext.clear();
errorwarning.Error = true;
@@ -1084,7 +1075,12 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
return b_REGULAR_LINE;
}
- cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl,
+ // Ignore ANSI color codes when checking for errors and warnings.
+ std::string input(data);
+ std::string line;
+ this->ColorRemover->Replace(input, line);
+
+ cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << line << "]" << std::endl,
this->Quiet);
int warningLine = 0;
@@ -1096,10 +1092,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Errors
int wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->ErrorMatchRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
errorLine = 1;
cmCTestOptionalLog(this->CTest, DEBUG,
- " Error Line: " << data << " (matches: "
+ " Error Line: " << line << " (matches: "
<< this->CustomErrorMatches[wrxCnt]
<< ")" << std::endl,
this->Quiet);
@@ -1110,11 +1106,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Error exceptions
wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->ErrorExceptionRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
errorLine = 0;
cmCTestOptionalLog(this->CTest, DEBUG,
" Not an error Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomErrorExceptions[wrxCnt] << ")"
<< std::endl,
this->Quiet);
@@ -1127,11 +1123,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
// Warnings
int wrxCnt = 0;
for (cmsys::RegularExpression& rx : this->WarningMatchRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
warningLine = 1;
cmCTestOptionalLog(this->CTest, DEBUG,
" Warning Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomWarningMatches[wrxCnt] << ")"
<< std::endl,
this->Quiet);
@@ -1143,11 +1139,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
wrxCnt = 0;
// Warning exceptions
for (cmsys::RegularExpression& rx : this->WarningExceptionRegex) {
- if (rx.find(data)) {
+ if (rx.find(line.c_str())) {
warningLine = 0;
cmCTestOptionalLog(this->CTest, DEBUG,
" Not a warning Line: "
- << data << " (matches: "
+ << line << " (matches: "
<< this->CustomWarningExceptions[wrxCnt] << ")"
<< std::endl,
this->Quiet);
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 722c59009..a5193f6e5 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -5,19 +5,22 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-
-#include "cmDuration.h"
-#include "cmProcessOutput.h"
-#include "cmsys/RegularExpression.hxx"
#include <chrono>
#include <deque>
#include <iosfwd>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCTestGenericHandler.h"
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
+
class cmMakefile;
+class cmStringReplaceHelper;
class cmXMLWriter;
/** \class cmCTestBuildHandler
@@ -27,8 +30,8 @@ class cmXMLWriter;
class cmCTestBuildHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
- typedef cmProcessOutput::Encoding Encoding;
+ using Superclass = cmCTestGenericHandler;
+ using Encoding = cmProcessOutput::Encoding;
/*
* The main entry point for this class
@@ -110,7 +113,7 @@ private:
std::vector<cmsys::RegularExpression> WarningMatchRegex;
std::vector<cmsys::RegularExpression> WarningExceptionRegex;
- typedef std::deque<char> t_BuildProcessingQueueType;
+ using t_BuildProcessingQueueType = std::deque<char>;
void ProcessBuffer(const char* data, size_t length, size_t& tick,
size_t tick_len, std::ostream& ofs,
@@ -125,7 +128,7 @@ private:
std::string SimplifySourceDir;
std::string SimplifyBuildDir;
size_t OutputLineCounter;
- typedef std::vector<cmCTestBuildErrorWarning> t_ErrorsAndWarningsVector;
+ using t_ErrorsAndWarningsVector = std::vector<cmCTestBuildErrorWarning>;
t_ErrorsAndWarningsVector ErrorsAndWarnings;
t_ErrorsAndWarningsVector::iterator LastErrorOrWarning;
size_t PostContextCount;
@@ -143,6 +146,9 @@ private:
int MaxErrors;
int MaxWarnings;
+ // Used to remove ANSI color codes before checking for errors and warnings.
+ cmStringReplaceHelper* ColorRemover;
+
bool UseCTestLaunch;
std::string CTestLaunchDir;
class LaunchHelper;
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 9c038399e..45ec39066 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -2,15 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestCVS.h"
+#include <utility>
+
+#include <cm/string_view>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCTest.h"
#include "cmProcessTools.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
-#include <utility>
-
cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log)
: cmCTestVC(ct, log)
{
@@ -103,7 +107,7 @@ bool cmCTestCVS::UpdateImpl()
class cmCTestCVS::LogParser : public cmCTestVC::LineParser
{
public:
- typedef cmCTestCVS::Revision Revision;
+ using Revision = cmCTestCVS::Revision;
LogParser(cmCTestCVS* cvs, const char* prefix, std::vector<Revision>& revs)
: CVS(cvs)
, Revisions(revs)
@@ -204,8 +208,7 @@ std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir)
if (tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) &&
tagLine.size() > 1 && tagLine[0] == 'T') {
// Use the branch specified in the tag file.
- std::string flag = "-r";
- flag += tagLine.substr(1);
+ std::string flag = cmStrCat("-r", cm::string_view(tagLine).substr(1));
return flag;
}
// Use the default branch.
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
index 77fc3cc25..7d33d8f2d 100644
--- a/Source/CTest/cmCTestCVS.h
+++ b/Source/CTest/cmCTestCVS.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestVC.h"
-
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
+#include "cmCTestVC.h"
+
class cmCTest;
class cmXMLWriter;
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 74a932a65..f2f42b4f2 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -2,30 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestConfigureCommand.h"
+#include <cstring>
+#include <sstream>
+#include <vector>
+
+#include "cm_static_string_view.hxx"
+
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <sstream>
-#include <string.h>
-#include <vector>
-
-cmCTestConfigureCommand::cmCTestConfigureCommand()
+void cmCTestConfigureCommand::BindArguments()
{
- this->Arguments[ctc_OPTIONS] = "OPTIONS";
- this->Arguments[ctc_LAST] = nullptr;
- this->Last = ctc_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("OPTIONS"_s, this->Options);
}
cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
{
std::vector<std::string> options;
- if (this->Values[ctc_OPTIONS]) {
- cmSystemTools::ExpandListArgument(this->Values[ctc_OPTIONS], options);
+ if (!this->Options.empty()) {
+ cmExpandList(this->Options, options);
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
@@ -75,9 +77,8 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
delete gg;
}
- std::string cmakeConfigureCommand = "\"";
- cmakeConfigureCommand += cmSystemTools::GetCMakeCommand();
- cmakeConfigureCommand += "\"";
+ std::string cmakeConfigureCommand =
+ cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"');
for (std::string const& option : options) {
cmakeConfigureCommand += " \"";
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index 0cbcbfaa8..3f5944af6 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
#include <string>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestConfigure
* \brief Run a ctest script
@@ -20,17 +23,15 @@ class cmCommand;
class cmCTestConfigureCommand : public cmCTestHandlerCommand
{
public:
- cmCTestConfigureCommand();
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestConfigureCommand* ni = new cmCTestConfigureCommand;
+ auto ni = cm::make_unique<cmCTestConfigureCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
@@ -39,14 +40,10 @@ public:
std::string GetName() const override { return "ctest_configure"; }
protected:
+ void BindArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
- enum
- {
- ctc_FIRST = ct_LAST,
- ctc_OPTIONS,
- ctc_LAST
- };
+ std::string Options;
};
#endif
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index 7e93189cd..914930e00 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -2,15 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestConfigureHandler.h"
+#include <chrono>
+#include <ostream>
+#include <string>
+
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmXMLWriter.h"
-#include <chrono>
-#include <ostream>
-#include <string>
-
cmCTestConfigureHandler::cmCTestConfigureHandler() = default;
void cmCTestConfigureHandler::Initialize()
diff --git a/Source/CTest/cmCTestConfigureHandler.h b/Source/CTest/cmCTestConfigureHandler.h
index 680401c84..01fe8011e 100644
--- a/Source/CTest/cmCTestConfigureHandler.h
+++ b/Source/CTest/cmCTestConfigureHandler.h
@@ -14,7 +14,7 @@
class cmCTestConfigureHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/*
* The main entry point for this class
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index 07aae768c..d6e6be395 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -2,14 +2,27 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestCoverageCommand.h"
+#include <set>
+
+#include "cm_static_string_view.hxx"
+
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
class cmCTestGenericHandler;
-cmCTestCoverageCommand::cmCTestCoverageCommand()
+void cmCTestCoverageCommand::BindArguments()
+{
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("LABELS"_s, this->Labels);
+}
+
+void cmCTestCoverageCommand::CheckArguments(
+ std::vector<std::string> const& keywords)
{
- this->LabelsMentioned = false;
+ this->LabelsMentioned =
+ !this->Labels.empty() || cmContains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
@@ -24,34 +37,10 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
// If a LABELS option was given, select only files with the labels.
if (this->LabelsMentioned) {
- handler->SetLabelFilter(this->Labels);
+ handler->SetLabelFilter(
+ std::set<std::string>(this->Labels.begin(), this->Labels.end()));
}
handler->SetQuiet(this->Quiet);
return handler;
}
-
-bool cmCTestCoverageCommand::CheckArgumentKeyword(std::string const& arg)
-{
- // Look for arguments specific to this command.
- if (arg == "LABELS") {
- this->ArgumentDoing = ArgumentDoingLabels;
- this->LabelsMentioned = true;
- return true;
- }
-
- // Look for other arguments.
- return this->Superclass::CheckArgumentKeyword(arg);
-}
-
-bool cmCTestCoverageCommand::CheckArgumentValue(std::string const& arg)
-{
- // Handle states specific to this command.
- if (this->ArgumentDoing == ArgumentDoingLabels) {
- this->Labels.insert(arg);
- return true;
- }
-
- // Look for other arguments.
- return this->Superclass::CheckArgumentValue(arg);
-}
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 1ae2d869a..76aaf46f8 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -5,13 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
-#include <set>
#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestCoverage
* \brief Run a ctest script
@@ -21,17 +24,15 @@ class cmCommand;
class cmCTestCoverageCommand : public cmCTestHandlerCommand
{
public:
- cmCTestCoverageCommand();
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestCoverageCommand* ni = new cmCTestCoverageCommand;
+ auto ni = cm::make_unique<cmCTestCoverageCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
@@ -39,22 +40,13 @@ public:
*/
std::string GetName() const override { return "ctest_coverage"; }
- typedef cmCTestHandlerCommand Superclass;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const& keywords) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingLabels = Superclass::ArgumentDoingLast1,
- ArgumentDoingLast2
- };
-
bool LabelsMentioned;
- std::set<std::string> Labels;
+ std::vector<std::string> Labels;
};
#endif
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f6028c4fc..4cd783fd6 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -2,6 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestCoverageHandler.h"
+#include <algorithm>
+#include <chrono>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <iomanip>
+#include <iterator>
+#include <sstream>
+#include <utility>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/Process.h"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
@@ -13,24 +28,11 @@
#include "cmParseGTMCoverage.h"
#include "cmParseJacocoCoverage.h"
#include "cmParsePHPCoverage.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/Process.h"
-#include "cmsys/RegularExpression.hxx"
-#include <algorithm>
-#include <chrono>
-#include <cstring>
-#include <iomanip>
-#include <iterator>
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <utility>
-
class cmMakefile;
#define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))
@@ -129,10 +131,9 @@ void cmCTestCoverageHandler::Initialize()
void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log)
{
- std::string logGlob = this->CTest->GetCTestConfiguration("BuildDirectory");
- logGlob += "/Testing/";
- logGlob += this->CTest->GetCurrentTag();
- logGlob += "/CoverageLog*";
+ std::string logGlob =
+ cmStrCat(this->CTest->GetCTestConfiguration("BuildDirectory"), "/Testing/",
+ this->CTest->GetCurrentTag(), "/CoverageLog*");
cmsys::Glob gl;
gl.FindFiles(logGlob);
std::vector<std::string> const& files = gl.GetFiles();
@@ -1181,7 +1182,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
// gcov 4.7 can have output lines saying "No executable lines" and
// "Removing 'filename.gcov'"... Don't log those as "errors."
if (line != "No executable lines" &&
- !cmSystemTools::StringStartsWith(line.c_str(), "Removing ")) {
+ !cmHasLiteralPrefix(line, "Removing ")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unknown gcov output line: [" << line << "]"
<< std::endl);
@@ -1455,8 +1456,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
std::vector<std::string> lcovFiles;
dir = this->CTest->GetBinaryDir();
std::string daGlob;
- daGlob = dir;
- daGlob += "/*.LCOV";
+ daGlob = cmStrCat(dir, "/*.LCOV");
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
" looking for LCOV files in: " << daGlob << std::endl, this->Quiet);
@@ -1597,12 +1597,10 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
cmCTestOptionalLog(
this->CTest, HANDLER_VERBOSE_OUTPUT,
" globbing for coverage in: " << lm.first << std::endl, this->Quiet);
- std::string daGlob = lm.first;
- daGlob += "/*.da";
+ std::string daGlob = cmStrCat(lm.first, "/*.da");
gl.FindFiles(daGlob);
cmAppend(files, gl.GetFiles());
- daGlob = lm.first;
- daGlob += "/*.gcda";
+ daGlob = cmStrCat(lm.first, "/*.gcda");
gl.FindFiles(daGlob);
cmAppend(files, gl.GetFiles());
}
@@ -1631,8 +1629,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
// DPI file should appear in build directory
std::string daGlob;
- daGlob = buildDir;
- daGlob += "/*.dpi";
+ daGlob = cmStrCat(buildDir, "/*.dpi");
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" looking for dpi files in: " << daGlob << std::endl,
this->Quiet);
@@ -1834,9 +1831,8 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
return 0;
}
std::map<std::string, std::string> fileMap;
- std::vector<std::string>::iterator fp = filesFullPath.begin();
- for (std::vector<std::string>::iterator f = files.begin(); f != files.end();
- ++f, ++fp) {
+ auto fp = filesFullPath.begin();
+ for (auto f = files.begin(); f != files.end(); ++f, ++fp) {
fileMap[*f] = *fp;
}
@@ -1874,7 +1870,7 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
this->StartCoverageLogXML(covLogXML);
count++; // move on one
}
- std::map<std::string, std::string>::iterator i = fileMap.find(file);
+ auto i = fileMap.find(file);
// if the file should be covered write out the header for that file
if (i != fileMap.end()) {
// we have a new file so count it in the output
@@ -1945,10 +1941,9 @@ int cmCTestCoverageHandler::RunBullseyeCommand(
cmCTestRunProcess runCoverageSrc;
runCoverageSrc.SetCommand(program.c_str());
runCoverageSrc.AddArgument(arg);
- std::string stdoutFile = cont->BinaryDir + "/Testing/Temporary/";
- stdoutFile += this->GetCTestInstance()->GetCurrentTag();
- stdoutFile += "-";
- stdoutFile += cmd;
+ std::string stdoutFile =
+ cmStrCat(cont->BinaryDir, "/Testing/Temporary/",
+ this->GetCTestInstance()->GetCurrentTag(), '-', cmd);
std::string stderrFile = stdoutFile;
stdoutFile += ".stdout";
stderrFile += ".stderr";
@@ -2037,9 +2032,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
coveredFileNames.insert(file);
if (!cmSystemTools::FileIsFullPath(sourceFile)) {
// file will be relative to the binary dir
- file = cont->BinaryDir;
- file += "/";
- file += sourceFile;
+ file = cmStrCat(cont->BinaryDir, '/', sourceFile);
}
file = cmSystemTools::CollapseFullPath(file);
bool shouldIDoCoverage =
@@ -2209,7 +2202,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine(
int cmCTestCoverageHandler::GetLabelId(std::string const& label)
{
- LabelIdMapType::iterator i = this->LabelIdMap.find(label);
+ auto i = this->LabelIdMap.find(label);
if (i == this->LabelIdMap.end()) {
int n = int(this->Labels.size());
this->Labels.push_back(label);
@@ -2221,9 +2214,8 @@ int cmCTestCoverageHandler::GetLabelId(std::string const& label)
void cmCTestCoverageHandler::LoadLabels()
{
- std::string fileList = this->CTest->GetBinaryDir();
- fileList += "/CMakeFiles";
- fileList += "/TargetDirectories.txt";
+ std::string fileList =
+ cmStrCat(this->CTest->GetBinaryDir(), "/CMakeFiles/TargetDirectories.txt");
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" target directory list [" << fileList << "]\n",
this->Quiet);
@@ -2237,8 +2229,7 @@ void cmCTestCoverageHandler::LoadLabels()
void cmCTestCoverageHandler::LoadLabels(const char* dir)
{
LabelSet& dirLabels = this->TargetDirs[dir];
- std::string fname = dir;
- fname += "/Labels.txt";
+ std::string fname = cmStrCat(dir, "/Labels.txt");
cmsys::ifstream fin(fname.c_str());
if (!fin) {
return;
@@ -2282,7 +2273,7 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir)
void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml,
std::string const& source)
{
- LabelMapType::const_iterator li = this->SourceLabels.find(source);
+ auto li = this->SourceLabels.find(source);
if (li != this->SourceLabels.end() && !li->second.empty()) {
xml.StartElement("Labels");
for (auto const& ls : li->second) {
@@ -2325,7 +2316,7 @@ bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
// The source is filtered out if it does not have any labels in
// common with the filter set.
std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
- LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc);
+ auto li = this->SourceLabels.find(shortSrc);
if (li != this->SourceLabels.end()) {
return !this->IntersectsFilter(li->second);
}
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 6492fe951..991b89d7b 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -5,15 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-
-#include "cmsys/RegularExpression.hxx"
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCTestGenericHandler.h"
+
class cmGeneratedFileStream;
class cmMakefile;
class cmXMLWriter;
@@ -24,8 +25,8 @@ public:
int Error;
std::string SourceDir;
std::string BinaryDir;
- typedef std::vector<int> SingleFileCoverageVector;
- typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap;
+ using SingleFileCoverageVector = std::vector<int>;
+ using TotalCoverageMap = std::map<std::string, SingleFileCoverageVector>;
TotalCoverageMap TotalCoverage;
std::ostream* OFS;
bool Quiet;
@@ -37,7 +38,7 @@ public:
class cmCTestCoverageHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/*
* The main entry point for this class
@@ -128,12 +129,12 @@ private:
class LabelSet : public std::set<int>
{
};
- typedef std::map<std::string, LabelSet> LabelMapType;
+ using LabelMapType = std::map<std::string, LabelSet>;
LabelMapType SourceLabels;
LabelMapType TargetDirs;
// Map from label name to label id.
- typedef std::map<std::string, int> LabelIdMapType;
+ using LabelIdMapType = std::map<std::string, int>;
LabelIdMapType LabelIdMap;
std::vector<std::string> Labels;
int GetLabelId(std::string const& label);
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index cc63e4563..ccac832f0 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -2,14 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestCurl.h"
+#include <cstdio>
+#include <ostream>
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCurl.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <ostream>
-#include <stdio.h>
-
cmCTestCurl::cmCTestCurl(cmCTest* ctest)
{
this->CTest = ctest;
@@ -127,9 +128,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file,
return false;
}
// set the url
- std::string upload_url = url;
- upload_url += "?";
- upload_url += fields;
+ std::string upload_url = cmStrCat(url, '?', fields);
::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str());
// now specify which file to upload
::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile);
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 6186af8d2..9c5ba667e 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -5,10 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_curl.h"
#include <string>
#include <vector>
+#include "cm_curl.h"
+
class cmCTest;
class cmCTestCurl
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
index f4531a1ee..051c117ca 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestEmptyBinaryDirectoryCommand.h"
-#include "cmCTestScriptHandler.h"
-
#include <sstream>
+#include "cmCTestScriptHandler.h"
+
class cmExecutionStatus;
bool cmCTestEmptyBinaryDirectoryCommand::InitialPass(
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index 9425ece95..ac96a4e30 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
#include <string>
+#include <utility>
#include <vector>
-class cmCommand;
+#include <cm/memory>
+
+#include "cmCTestCommand.h"
+#include "cmCommand.h"
+
class cmExecutionStatus;
/** \class cmCTestEmptyBinaryDirectory
@@ -27,13 +30,12 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestEmptyBinaryDirectoryCommand* ni =
- new cmCTestEmptyBinaryDirectoryCommand;
+ auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 9d9761ce2..3f3c1074f 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -2,19 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestGIT.h"
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <vector>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <vector>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
@@ -111,8 +112,8 @@ std::string cmCTestGIT::FindGitDir()
else if (git_dir[0] == '/') {
// Cygwin Git reports a full path that Cygwin understands, but we
// are a Windows application. Run "cygpath" to get Windows path.
- std::string cygpath_exe = cmSystemTools::GetFilenamePath(git);
- cygpath_exe += "/cygpath.exe";
+ std::string cygpath_exe =
+ cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe");
if (cmSystemTools::FileExists(cygpath_exe)) {
char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(),
0 };
@@ -211,8 +212,7 @@ bool cmCTestGIT::UpdateByFetchAndReset()
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
- std::vector<std::string> git_custom_command;
- cmSystemTools::ExpandListArgument(custom, git_custom_command, true);
+ std::vector<std::string> git_custom_command = cmExpandedList(custom, true);
std::vector<char const*> git_custom;
git_custom.reserve(git_custom_command.size() + 1);
for (std::string const& i : git_custom_command) {
@@ -270,7 +270,7 @@ bool cmCTestGIT::UpdateImpl()
std::string init_submodules =
this->CTest->GetCTestConfiguration("GITInitSubmodules");
- if (cmSystemTools::IsOn(init_submodules)) {
+ if (cmIsOn(init_submodules)) {
char const* git_submodule_init[] = { git, "submodule", "init", nullptr };
ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err,
top_dir.c_str());
@@ -334,7 +334,7 @@ public:
this->SetLog(&git->Log, prefix);
}
- typedef cmCTestGIT::Change Change;
+ using Change = cmCTestGIT::Change;
std::vector<Change> Changes;
protected:
@@ -457,7 +457,7 @@ public:
}
private:
- typedef cmCTestGIT::Revision Revision;
+ using Revision = cmCTestGIT::Revision;
enum SectionType
{
SectionHeader,
diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h
index ade430fae..3103d8492 100644
--- a/Source/CTest/cmCTestGIT.h
+++ b/Source/CTest/cmCTestGIT.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGlobalVC.h"
-
#include <iosfwd>
#include <string>
+#include "cmCTestGlobalVC.h"
+
class cmCTest;
/** \class cmCTestGIT
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index d3020b513..cc0b4ed0c 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -23,8 +23,7 @@ cmCTestGenericHandler::~cmCTestGenericHandler() = default;
void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
{
if (!value) {
- cmCTestGenericHandler::t_StringToString::iterator remit =
- this->Options.find(op);
+ auto remit = this->Options.find(op);
if (remit != this->Options.end()) {
this->Options.erase(remit);
}
@@ -39,8 +38,7 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
{
this->SetOption(op, value);
if (!value) {
- cmCTestGenericHandler::t_StringToString::iterator remit =
- this->PersistentOptions.find(op);
+ auto remit = this->PersistentOptions.find(op);
if (remit != this->PersistentOptions.end()) {
this->PersistentOptions.erase(remit);
}
@@ -62,8 +60,7 @@ void cmCTestGenericHandler::Initialize()
const char* cmCTestGenericHandler::GetOption(const std::string& op)
{
- cmCTestGenericHandler::t_StringToString::iterator remit =
- this->Options.find(op);
+ auto remit = this->Options.find(op);
if (remit == this->Options.end()) {
return nullptr;
}
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index cf91b4fa6..94e541865 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -6,10 +6,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
#include "cmCTest.h"
#include "cmSystemTools.h"
@@ -71,7 +72,7 @@ public:
cmCTestGenericHandler();
virtual ~cmCTestGenericHandler();
- typedef std::map<std::string, std::string> t_StringToString;
+ using t_StringToString = std::map<std::string, std::string>;
void SetPersistentOption(const std::string& op, const char* value);
void SetOption(const std::string& op, const char* value);
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
index 54ebd4f0c..5f05efb33 100644
--- a/Source/CTest/cmCTestGlobalVC.cxx
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestGlobalVC.h"
+#include <ostream>
+#include <utility>
+
#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-#include <ostream>
-#include <utility>
-
cmCTestGlobalVC::cmCTestGlobalVC(cmCTest* ct, std::ostream& log)
: cmCTestVC(ct, log)
{
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index 9c572152e..ff86591ea 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestVC.h"
-
#include <iosfwd>
#include <list>
#include <map>
#include <string>
#include <vector>
+#include "cmCTestVC.h"
+
class cmCTest;
class cmXMLWriter;
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index ba2252a30..3265498c0 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestHG.h"
+#include <ostream>
+#include <vector>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
@@ -9,10 +14,6 @@
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cmsys/RegularExpression.hxx"
-#include <ostream>
-#include <vector>
-
cmCTestHG::cmCTestHG(cmCTest* ct, std::ostream& log)
: cmCTestGlobalVC(ct, log)
{
@@ -174,8 +175,8 @@ public:
private:
cmCTestHG* HG;
- typedef cmCTestHG::Revision Revision;
- typedef cmCTestHG::Change Change;
+ using Revision = cmCTestHG::Revision;
+ using Change = cmCTestHG::Change;
Revision Rev;
std::vector<Change> Changes;
Change CurChange;
diff --git a/Source/CTest/cmCTestHG.h b/Source/CTest/cmCTestHG.h
index c12d61887..2900139b4 100644
--- a/Source/CTest/cmCTestHG.h
+++ b/Source/CTest/cmCTestHG.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGlobalVC.h"
-
#include <iosfwd>
#include <string>
+#include "cmCTestGlobalVC.h"
+
class cmCTest;
/** \class cmCTestHG
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index adf955399..b1034c9ff 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -2,37 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestHandlerCommand.h"
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include "cm_static_string_view.hxx"
+
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
-#include <cstring>
-#include <sstream>
-#include <stdlib.h>
-
-class cmExecutionStatus;
-
-cmCTestHandlerCommand::cmCTestHandlerCommand()
-{
- const size_t INIT_SIZE = 100;
- size_t cc;
- this->Arguments.reserve(INIT_SIZE);
- for (cc = 0; cc < INIT_SIZE; ++cc) {
- this->Arguments.push_back(nullptr);
- }
- this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
- this->Arguments[ct_CAPTURE_CMAKE_ERROR] = "CAPTURE_CMAKE_ERROR";
- this->Arguments[ct_SOURCE] = "SOURCE";
- this->Arguments[ct_BUILD] = "BUILD";
- this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
- this->Last = ct_LAST;
- this->AppendXML = false;
- this->Quiet = false;
-}
-
namespace {
// class to save and restore the error state for ctest_* commands
// if a ctest_* command has a CAPTURE_CMAKE_ERROR then put the error
@@ -86,47 +71,46 @@ private:
}
bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+ cmExecutionStatus& status)
{
// save error state and restore it if needed
SaveRestoreErrorState errorState;
// Allocate space for argument values.
- this->Values.clear();
- this->Values.resize(this->Last, nullptr);
+ this->BindArguments();
// Process input arguments.
- this->ArgumentDoing = ArgumentDoingNone;
- // look at all arguments and do not short circuit on the first
- // bad one so that CAPTURE_CMAKE_ERROR can override setting the
- // global error state
- bool foundBadArgument = false;
- for (std::string const& arg : args) {
- // Check this argument.
- if (!this->CheckArgumentKeyword(arg) && !this->CheckArgumentValue(arg)) {
- std::ostringstream e;
- e << "called with unknown argument \"" << arg << "\".";
- this->SetError(e.str());
- foundBadArgument = true;
- }
- // note bad argument
- if (this->ArgumentDoing == ArgumentDoingError) {
- foundBadArgument = true;
- }
+ std::vector<std::string> unparsedArguments;
+ std::vector<std::string> keywordsMissingValue;
+ std::vector<std::string> parsedKeywords;
+ this->Parse(args, &unparsedArguments, &keywordsMissingValue,
+ &parsedKeywords);
+ this->CheckArguments(keywordsMissingValue);
+
+ std::sort(parsedKeywords.begin(), parsedKeywords.end());
+ auto it = std::adjacent_find(parsedKeywords.begin(), parsedKeywords.end());
+ if (it != parsedKeywords.end()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Called with more than one value for ", *it));
+ }
+
+ bool const foundBadArgument = !unparsedArguments.empty();
+ if (foundBadArgument) {
+ this->SetError(cmStrCat("called with unknown argument \"",
+ unparsedArguments.front(), "\"."));
}
- bool capureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] &&
- *this->Values[ct_CAPTURE_CMAKE_ERROR]);
+ bool const captureCMakeError = !this->CaptureCMakeError.empty();
// now that arguments are parsed check to see if there is a
// CAPTURE_CMAKE_ERROR specified let the errorState object know.
- if (capureCMakeError) {
+ if (captureCMakeError) {
errorState.CaptureCMakeError();
}
// if we found a bad argument then exit before running command
if (foundBadArgument) {
// store the cmake error
- if (capureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
- std::string const err = this->GetName() + " " + this->GetError();
+ if (captureCMakeError) {
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
+ std::string const err = this->GetName() + " " + status.GetError();
if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
}
@@ -147,10 +131,9 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->CTest->SetConfigType(ctestConfigType);
}
- if (this->Values[ct_BUILD]) {
+ if (!this->Build.empty()) {
this->CTest->SetCTestConfiguration(
- "BuildDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(),
+ "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(),
this->Quiet);
} else {
std::string const& bdir =
@@ -164,13 +147,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
"CTEST_BINARY_DIRECTORY not set" << std::endl;);
}
}
- if (this->Values[ct_SOURCE]) {
+ if (!this->Source.empty()) {
cmCTestLog(this->CTest, DEBUG,
- "Set source directory to: " << this->Values[ct_SOURCE]
- << std::endl);
+ "Set source directory to: " << this->Source << std::endl);
this->CTest->SetCTestConfiguration(
- "SourceDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
+ "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
this->Quiet);
} else {
this->CTest->SetCTestConfiguration(
@@ -192,11 +173,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot instantiate test handler " << this->GetName()
<< std::endl);
- if (capureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
- const char* err = this->GetError();
- if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+ if (captureCMakeError) {
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
+ std::string const& err = status.GetError();
+ if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
}
return true;
@@ -204,11 +184,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
- handler->SetAppendXML(this->AppendXML);
+ handler->SetAppendXML(this->Append);
handler->PopulateCustomVectors(this->Makefile);
- if (this->Values[ct_SUBMIT_INDEX]) {
- handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
+ if (!this->SubmitIndex.empty()) {
+ handler->SetSubmitIndex(atoi(this->SubmitIndex.c_str()));
}
cmWorkingDirectory workdir(
this->CTest->GetCTestConfiguration("BuildDirectory"));
@@ -216,11 +196,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->SetError("failed to change directory to " +
this->CTest->GetCTestConfiguration("BuildDirectory") +
" : " + std::strerror(workdir.GetLastResult()));
- if (capureCMakeError) {
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- "-1");
+ if (captureCMakeError) {
+ this->Makefile->AddDefinition(this->CaptureCMakeError, "-1");
cmCTestLog(this->CTest, ERROR_MESSAGE,
- this->GetName() << " " << this->GetError() << "\n");
+ this->GetName() << " " << status.GetError() << "\n");
// return success because failure is recorded in CAPTURE_CMAKE_ERROR
return true;
}
@@ -228,28 +207,24 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
}
int res = handler->ProcessHandler();
- if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
- std::ostringstream str;
- str << res;
- this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
- str.str().c_str());
+ if (!this->ReturnValue.empty()) {
+ this->Makefile->AddDefinition(this->ReturnValue, std::to_string(res));
}
this->ProcessAdditionalValues(handler);
// log the error message if there was an error
- if (capureCMakeError) {
+ if (captureCMakeError) {
const char* returnString = "0";
if (cmSystemTools::GetErrorOccuredFlag()) {
returnString = "-1";
- const char* err = this->GetError();
+ std::string const& err = status.GetError();
// print out the error if it is not "unknown error" which means
// there was no message
- if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+ if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
cmCTestLog(this->CTest, ERROR_MESSAGE, err);
}
}
// store the captured cmake error state 0 or -1
- this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
- returnString);
+ this->Makefile->AddDefinition(this->CaptureCMakeError, returnString);
}
return true;
}
@@ -258,47 +233,17 @@ void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
{
}
-bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestHandlerCommand::BindArguments()
{
- // Look for non-value arguments common to all commands.
- if (arg == "APPEND") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->AppendXML = true;
- return true;
- }
- if (arg == "QUIET") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->Quiet = true;
- return true;
- }
-
- // Check for a keyword in our argument/value table.
- for (unsigned int k = 0; k < this->Arguments.size(); ++k) {
- if (this->Arguments[k] && arg == this->Arguments[k]) {
- this->ArgumentDoing = ArgumentDoingKeyword;
- this->ArgumentIndex = k;
- return true;
- }
- }
- return false;
+ this->Bind("APPEND"_s, this->Append);
+ this->Bind("QUIET"_s, this->Quiet);
+ this->Bind("RETURN_VALUE"_s, this->ReturnValue);
+ this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
+ this->Bind("SOURCE"_s, this->Source);
+ this->Bind("BUILD"_s, this->Build);
+ this->Bind("SUBMIT_INDEX"_s, this->SubmitIndex);
}
-bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestHandlerCommand::CheckArguments(std::vector<std::string> const&)
{
- if (this->ArgumentDoing == ArgumentDoingKeyword) {
- this->ArgumentDoing = ArgumentDoingNone;
- unsigned int k = this->ArgumentIndex;
- if (this->Values[k]) {
- std::ostringstream e;
- e << "Called with more than one value for " << this->Arguments[k];
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
- return true;
- }
- this->Values[k] = arg.c_str();
- cmCTestLog(this->CTest, DEBUG,
- "Set " << this->Arguments[k] << " to " << arg << "\n");
- return true;
- }
- return false;
}
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index 79d61f3c7..a20d607e2 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
-#include <stddef.h>
#include <string>
#include <vector>
+#include "cmArgumentParser.h"
+#include "cmCTestCommand.h"
+
class cmCTestGenericHandler;
class cmExecutionStatus;
@@ -19,11 +19,11 @@ class cmExecutionStatus;
*
* cmCTestHandlerCommand defineds the command to test the project.
*/
-class cmCTestHandlerCommand : public cmCTestCommand
+class cmCTestHandlerCommand
+ : public cmCTestCommand
+ , public cmArgumentParser<void>
{
public:
- cmCTestHandlerCommand();
-
/**
* The name of the command as specified in CMakeList.txt.
*/
@@ -36,42 +36,22 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- enum
- {
- ct_NONE,
- ct_RETURN_VALUE,
- ct_CAPTURE_CMAKE_ERROR,
- ct_BUILD,
- ct_SOURCE,
- ct_SUBMIT_INDEX,
- ct_LAST
- };
-
protected:
virtual cmCTestGenericHandler* InitializeHandler() = 0;
virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler);
// Command argument handling.
- virtual bool CheckArgumentKeyword(std::string const& arg);
- virtual bool CheckArgumentValue(std::string const& arg);
- enum
- {
- ArgumentDoingNone,
- ArgumentDoingError,
- ArgumentDoingKeyword,
- ArgumentDoingLast1
- };
- int ArgumentDoing;
- unsigned int ArgumentIndex;
-
- bool AppendXML;
- bool Quiet;
-
- std::string ReturnVariable;
- std::vector<const char*> Arguments;
- std::vector<const char*> Values;
- size_t Last;
+ virtual void BindArguments();
+ virtual void CheckArguments(std::vector<std::string> const& keywords);
+
+ bool Append = false;
+ bool Quiet = false;
+ std::string CaptureCMakeError;
+ std::string ReturnValue;
+ std::string Build;
+ std::string Source;
+ std::string SubmitIndex;
};
#define CTEST_COMMAND_APPEND_OPTION_DOCS \
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index a96513e8c..647f5fff9 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestLaunch.h"
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
-#include <iostream>
-#include <memory> // IWYU pragma: keep
-#include <stdlib.h>
-#include <string.h>
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
@@ -17,6 +17,7 @@
#include "cmProcessOutput.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -176,14 +177,8 @@ void cmCTestLaunch::ComputeFileNames()
this->LogHash = md5.FinalizeHex();
// We store stdout and stderr in temporary log files.
- this->LogOut = this->LogDir;
- this->LogOut += "launch-";
- this->LogOut += this->LogHash;
- this->LogOut += "-out.txt";
- this->LogErr = this->LogDir;
- this->LogErr += "launch-";
- this->LogErr += this->LogHash;
- this->LogErr += "-err.txt";
+ this->LogOut = cmStrCat(this->LogDir, "launch-", this->LogHash, "-out.txt");
+ this->LogErr = cmStrCat(this->LogDir, "launch-", this->LogHash, "-err.txt");
}
void cmCTestLaunch::RunChild()
@@ -282,11 +277,8 @@ void cmCTestLaunch::LoadLabels()
}
// Labels are listed in per-target files.
- std::string fname = this->OptionBuildDir;
- fname += "/CMakeFiles";
- fname += "/";
- fname += this->OptionTargetName;
- fname += ".dir/Labels.txt";
+ std::string fname = cmStrCat(this->OptionBuildDir, "/CMakeFiles/",
+ this->OptionTargetName, ".dir/Labels.txt");
// We are interested in per-target labels for this source file.
std::string source = this->OptionSource;
@@ -340,10 +332,9 @@ bool cmCTestLaunch::IsError() const
void cmCTestLaunch::WriteXML()
{
// Name the xml file.
- std::string logXML = this->LogDir;
- logXML += this->IsError() ? "error-" : "warning-";
- logXML += this->LogHash;
- logXML += ".xml";
+ std::string logXML =
+ cmStrCat(this->LogDir, this->IsError() ? "error-" : "warning-",
+ this->LogHash, ".xml");
// Use cmGeneratedFileStream to atomically create the report file.
cmGeneratedFileStream fxml(logXML);
@@ -494,9 +485,9 @@ void cmCTestLaunch::DumpFileToXML(cmXMLElement& e3, const char* tag,
continue;
}
if (this->Match(line, this->RegexWarningSuppress)) {
- line = "[CTest: warning suppressed] " + line;
+ line = cmStrCat("[CTest: warning suppressed] ", line);
} else if (this->Match(line, this->RegexWarning)) {
- line = "[CTest: warning matched] " + line;
+ line = cmStrCat("[CTest: warning matched] ", line);
}
e4.Content(sep);
e4.Content(line);
@@ -546,10 +537,7 @@ void cmCTestLaunch::LoadScrapeRules()
void cmCTestLaunch::LoadScrapeRules(
const char* purpose, std::vector<cmsys::RegularExpression>& regexps)
{
- std::string fname = this->LogDir;
- fname += "Custom";
- fname += purpose;
- fname += ".txt";
+ std::string fname = cmStrCat(this->LogDir, "Custom", purpose, ".txt");
cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
cmsys::RegularExpression rex;
@@ -595,7 +583,7 @@ bool cmCTestLaunch::Match(std::string const& line,
bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const
{
return !this->OptionFilterPrefix.empty() &&
- cmSystemTools::StringStartsWith(line, this->OptionFilterPrefix.c_str());
+ cmHasPrefix(line, this->OptionFilterPrefix);
}
int cmCTestLaunch::Main(int argc, const char* const argv[])
@@ -617,8 +605,7 @@ void cmCTestLaunch::LoadConfig()
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
- std::string fname = this->LogDir;
- fname += "CTestLaunchConfig.cmake";
+ std::string fname = cmStrCat(this->LogDir, "CTestLaunchConfig.cmake");
if (cmSystemTools::FileExists(fname) && mf.ReadListFile(fname)) {
this->SourceDir = mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
cmSystemTools::ConvertToUnixSlashes(this->SourceDir);
diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h
index 107fd6174..79a7712aa 100644
--- a/Source/CTest/cmCTestLaunch.h
+++ b/Source/CTest/cmCTestLaunch.h
@@ -5,11 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
#include <set>
#include <string>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
class cmXMLElement;
/** \class cmCTestLaunch
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 7dad1cec5..39dec6d87 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,19 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include <sstream>
-#include <string>
-#include <vector>
+#include "cm_static_string_view.hxx"
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
#include "cmMakefile.h"
-cmCTestMemCheckCommand::cmCTestMemCheckCommand()
+void cmCTestMemCheckCommand::BindArguments()
{
- this->Arguments[ctm_DEFECT_COUNT] = "DEFECT_COUNT";
- this->Arguments[ctm_LAST] = nullptr;
- this->Last = ctm_LAST;
+ this->cmCTestTestCommand::BindArguments();
+ this->Bind("DEFECT_COUNT"_s, this->DefectCount);
}
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
@@ -44,10 +41,10 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
void cmCTestMemCheckCommand::ProcessAdditionalValues(
cmCTestGenericHandler* handler)
{
- if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) {
- std::ostringstream str;
- str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount();
- this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT],
- str.str().c_str());
+ if (!this->DefectCount.empty()) {
+ this->Makefile->AddDefinition(
+ this->DefectCount,
+ std::to_string(
+ static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount()));
}
}
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index b6b3c4028..8f4ffb89a 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -5,10 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+#include <utility>
+
+#include <cm/memory>
+
#include "cmCTestTestCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestMemCheck
* \brief Run a ctest script
@@ -18,29 +23,25 @@ class cmCommand;
class cmCTestMemCheckCommand : public cmCTestTestCommand
{
public:
- cmCTestMemCheckCommand();
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand;
+ auto ni = cm::make_unique<cmCTestMemCheckCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
protected:
+ void BindArguments() override;
+
cmCTestGenericHandler* InitializeActualHandler() override;
void ProcessAdditionalValues(cmCTestGenericHandler* handler) override;
- enum
- {
- ctm_DEFECT_COUNT = ctt_LAST,
- ctm_LAST
- };
+ std::string DefectCount;
};
#endif
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index b09e7bb22..a5ec1ae81 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -2,21 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckHandler.h"
+#include <chrono>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <utility>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-#include <chrono>
-#include <iostream>
-#include <sstream>
-#include <string.h>
-#include <utility>
-
struct CatToErrorType
{
const char* ErrorCategory;
@@ -1074,10 +1075,7 @@ void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
void cmCTestMemCheckHandler::TestOutputFileNames(
int test, std::vector<std::string>& files)
{
- std::string index;
- std::ostringstream stream;
- stream << test;
- index = stream.str();
+ std::string index = std::to_string(test);
std::string ofile = this->MemoryTesterOutputFile;
std::string::size_type pos = ofile.find("??");
ofile.replace(pos, 2, index);
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 746d72c01..eda65f7b9 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestTestHandler.h"
-
#include <string>
#include <vector>
+#include "cmCTestTestHandler.h"
+
class cmMakefile;
class cmXMLWriter;
@@ -22,7 +22,7 @@ class cmCTestMemCheckHandler : public cmCTestTestHandler
friend class cmCTestRunTest;
public:
- typedef cmCTestTestHandler Superclass;
+ using Superclass = cmCTestTestHandler;
void PopulateCustomVectors(cmMakefile* mf) override;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 1b71f2ab6..02d396ebd 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -2,38 +2,43 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMultiProcessHandler.h"
-#include "cmAffinity.h"
-#include "cmAlgorithms.h"
-#include "cmCTest.h"
-#include "cmCTestRunTest.h"
-#include "cmCTestTestHandler.h"
-#include "cmDuration.h"
-#include "cmListFileCache.h"
-#include "cmRange.h"
-#include "cmSystemTools.h"
-#include "cmWorkingDirectory.h"
-
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#include "cm_uv.h"
-
-#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/SystemInformation.hxx"
-
#include <algorithm>
+#include <cassert>
#include <chrono>
+#include <cmath>
+#include <cstddef>
+#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
-#include <math.h>
+#include <memory>
#include <sstream>
#include <stack>
-#include <stdlib.h>
#include <unordered_map>
#include <utility>
+#include <vector>
+
+#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"
+#include "cmCTestTestHandler.h"
+#include "cmDuration.h"
+#include "cmListFileCache.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
+#include "cmWorkingDirectory.h"
namespace cmsys {
class RegularExpression;
@@ -108,8 +113,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
std::string fake_load_value;
if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING",
fake_load_value)) {
- if (!cmSystemTools::StringToULong(fake_load_value.c_str(),
- &this->FakeLoadForTesting)) {
+ if (!cmStrToULong(fake_load_value, &this->FakeLoadForTesting)) {
cmSystemTools::Error("Failed to parse fake load value: " +
fake_load_value);
}
@@ -132,6 +136,12 @@ void cmCTestMultiProcessHandler::RunTests()
uv_run(&this->Loop, UV_RUN_DEFAULT);
uv_loop_close(&this->Loop);
+ if (!this->StopTimePassed) {
+ assert(this->Completed == this->Total);
+ assert(this->Tests.empty());
+ }
+ assert(this->AllResourcesAvailable());
+
this->MarkFinished();
this->UpdateCostData();
}
@@ -167,12 +177,15 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
+ if (this->TestHandler->UseResourceSpec) {
+ testRun->SetUseAllocatedResources(true);
+ testRun->SetAllocatedResources(this->AllocatedResources[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 (this->Properties[test]->RequireSuccessDepends.find(f) !=
- this->Properties[test]->RequireSuccessDepends.end()) {
+ if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
testRun->AddFailedDependency(f);
}
}
@@ -181,6 +194,12 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// working directory because FinishTestProcess() will try to unlock them
this->LockResources(test);
+ if (!this->TestsHaveSufficientResources[test]) {
+ testRun->StartFailure("Insufficient resources");
+ this->FinishTestProcess(testRun, false);
+ return false;
+ }
+
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
testRun->StartFailure("Failed to change working directory to " +
@@ -188,14 +207,121 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
std::strerror(workdir.GetLastResult()));
} 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;
}
}
+ // Pass ownership of 'testRun'.
this->FinishTestProcess(testRun, false);
return false;
}
+bool cmCTestMultiProcessHandler::AllocateResources(int index)
+{
+ if (!this->TestHandler->UseResourceSpec) {
+ return true;
+ }
+
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations;
+ if (!this->TryAllocateResources(index, allocations)) {
+ return false;
+ }
+
+ auto& allocatedResources = this->AllocatedResources[index];
+ allocatedResources.resize(this->Properties[index]->ResourceGroups.size());
+ for (auto const& it : allocations) {
+ for (auto const& alloc : it.second) {
+ bool result = this->ResourceAllocator.AllocateResource(
+ it.first, alloc.Id, alloc.SlotsNeeded);
+ (void)result;
+ assert(result);
+ allocatedResources[alloc.ProcessIndex][it.first].push_back(
+ { alloc.Id, static_cast<unsigned int>(alloc.SlotsNeeded) });
+ }
+ }
+
+ return true;
+}
+
+bool cmCTestMultiProcessHandler::TryAllocateResources(
+ int index,
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations)
+{
+ allocations.clear();
+
+ std::size_t processIndex = 0;
+ for (auto const& process : this->Properties[index]->ResourceGroups) {
+ for (auto const& requirement : process) {
+ for (int i = 0; i < requirement.UnitsNeeded; ++i) {
+ allocations[requirement.ResourceType].push_back(
+ { processIndex, requirement.SlotsNeeded, "" });
+ }
+ }
+ ++processIndex;
+ }
+
+ auto const& availableResources = this->ResourceAllocator.GetResources();
+ for (auto& it : allocations) {
+ if (!availableResources.count(it.first)) {
+ return false;
+ }
+ if (!cmAllocateCTestResourcesRoundRobin(availableResources.at(it.first),
+ it.second)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void cmCTestMultiProcessHandler::DeallocateResources(int index)
+{
+ if (!this->TestHandler->UseResourceSpec) {
+ return;
+ }
+
+ {
+ auto& allocatedResources = this->AllocatedResources[index];
+ for (auto const& processAlloc : allocatedResources) {
+ for (auto const& it : processAlloc) {
+ auto resourceType = it.first;
+ for (auto const& it2 : it.second) {
+ bool success = this->ResourceAllocator.DeallocateResource(
+ resourceType, it2.Id, it2.Slots);
+ (void)success;
+ assert(success);
+ }
+ }
+ }
+ }
+ this->AllocatedResources.erase(index);
+}
+
+bool cmCTestMultiProcessHandler::AllResourcesAvailable()
+{
+ for (auto const& it : this->ResourceAllocator.GetResources()) {
+ for (auto const& it2 : it.second) {
+ if (it2.second.Locked != 0) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void cmCTestMultiProcessHandler::CheckResourcesAvailable()
+{
+ for (auto test : this->SortedTests) {
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations;
+ this->TestsHaveSufficientResources[test] =
+ !this->TestHandler->UseResourceSpec ||
+ this->TryAllocateResources(test, allocations);
+ }
+}
+
bool cmCTestMultiProcessHandler::CheckStopTimePassed()
{
if (!this->StopTimePassed) {
@@ -273,17 +399,25 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
{
// Check for locked resources
for (std::string const& i : this->Properties[test]->LockedResources) {
- if (this->LockedResources.find(i) != this->LockedResources.end()) {
+ if (cmContains(this->LockedResources, i)) {
return false;
}
}
+ // Allocate resources
+ if (this->TestsHaveSufficientResources[test] &&
+ !this->AllocateResources(test)) {
+ this->DeallocateResources(test);
+ return false;
+ }
+
// if there are no depends left then run this test
if (this->Tests[test].empty()) {
return this->StartTestProcess(test);
}
// This test was not able to start because it is waiting
// on depends to run
+ this->DeallocateResources(test);
return false;
}
@@ -468,6 +602,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->TestFinishMap[test] = true;
this->TestRunningMap[test] = false;
this->WriteCheckpoint(test);
+ this->DeallocateResources(test);
this->UnlockResources(test);
this->RunningCount -= GetProcessorsUsed(test);
@@ -619,9 +754,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 (std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(),
- this->Properties[t.first]->Name) !=
- this->LastTestsFailed.end()) {
+ if (cmContains(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);
@@ -660,7 +793,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
TestComparator(this));
for (auto const& j : sortedCopy) {
- if (alreadySortedTests.find(j) == alreadySortedTests.end()) {
+ if (!cmContains(alreadySortedTests, j)) {
this->SortedTests.push_back(j);
alreadySortedTests.insert(j);
}
@@ -692,7 +825,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
TestSet alreadySortedTests;
for (int test : presortedList) {
- if (alreadySortedTests.find(test) != alreadySortedTests.end()) {
+ if (cmContains(alreadySortedTests, test)) {
continue;
}
@@ -700,8 +833,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
- if (alreadySortedTests.find(testDependency) ==
- alreadySortedTests.end()) {
+ if (!cmContains(alreadySortedTests, testDependency)) {
alreadySortedTests.insert(testDependency);
this->SortedTests.push_back(testDependency);
}
@@ -780,6 +912,28 @@ static Json::Value DumpTimeoutAfterMatch(
return timeoutAfterMatch;
}
+static Json::Value DumpResourceGroupsToJsonArray(
+ const std::vector<
+ std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
+ resourceGroups)
+{
+ Json::Value jsonResourceGroups = Json::arrayValue;
+ for (auto const& it : resourceGroups) {
+ Json::Value jsonResourceGroup = Json::objectValue;
+ Json::Value requirements = Json::arrayValue;
+ for (auto const& it2 : it) {
+ Json::Value res = Json::objectValue;
+ res[".type"] = it2.ResourceType;
+ // res[".units"] = it2.UnitsNeeded; // Intentionally commented out
+ res["slots"] = it2.SlotsNeeded;
+ requirements.append(res);
+ }
+ jsonResourceGroup["requirements"] = requirements;
+ jsonResourceGroups.append(jsonResourceGroup);
+ }
+ return jsonResourceGroups;
+}
+
static Json::Value DumpCTestProperty(std::string const& name,
Json::Value value)
{
@@ -821,6 +975,11 @@ static Json::Value DumpCTestProperties(
"FAIL_REGULAR_EXPRESSION",
DumpRegExToJsonArray(testProperties.ErrorRegularExpressions)));
}
+ if (!testProperties.SkipRegularExpressions.empty()) {
+ properties.append(DumpCTestProperty(
+ "SKIP_REGULAR_EXPRESSION",
+ DumpRegExToJsonArray(testProperties.SkipRegularExpressions)));
+ }
if (!testProperties.FixturesCleanup.empty()) {
properties.append(DumpCTestProperty(
"FIXTURES_CLEANUP", DumpToJsonArray(testProperties.FixturesCleanup)));
@@ -846,6 +1005,11 @@ static Json::Value DumpCTestProperties(
"PASS_REGULAR_EXPRESSION",
DumpRegExToJsonArray(testProperties.RequiredRegularExpressions)));
}
+ if (!testProperties.ResourceGroups.empty()) {
+ properties.append(DumpCTestProperty(
+ "RESOURCE_GROUPS",
+ DumpResourceGroupsToJsonArray(testProperties.ResourceGroups)));
+ }
if (testProperties.WantAffinity) {
properties.append(
DumpCTestProperty("PROCESSOR_AFFINITY", testProperties.WantAffinity));
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 93bb880fe..1db4bfdd1 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -5,17 +5,22 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestTestHandler.h"
#include <map>
#include <set>
-#include <stddef.h>
#include <string>
#include <vector>
-#include "cmUVHandlePtr.h"
+#include <stddef.h>
+
#include "cm_uv.h"
+#include "cmCTestResourceAllocator.h"
+#include "cmCTestTestHandler.h"
+#include "cmUVHandlePtr.h"
+
class cmCTest;
+struct cmCTestBinPackerAllocation;
+class cmCTestResourceSpec;
class cmCTestRunTest;
/** \class cmCTestMultiProcessHandler
@@ -42,6 +47,11 @@ public:
: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
{
};
+ struct ResourceAllocation
+ {
+ std::string Id;
+ unsigned int Slots;
+ };
cmCTestMultiProcessHandler();
virtual ~cmCTestMultiProcessHandler();
@@ -77,6 +87,13 @@ public:
void SetQuiet(bool b) { this->Quiet = b; }
+ void InitResourceAllocator(const cmCTestResourceSpec& spec)
+ {
+ this->ResourceAllocator.InitializeFromResourceSpec(spec);
+ }
+
+ void CheckResourcesAvailable();
+
protected:
// Start the next test or tests as many as are allowed by
// ParallelLevel
@@ -119,6 +136,15 @@ protected:
void LockResources(int index);
void UnlockResources(int index);
+
+ bool AllocateResources(int index);
+ bool TryAllocateResources(
+ int index,
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
+ allocations);
+ void DeallocateResources(int index);
+ bool AllResourcesAvailable();
+
// map from test number to set of depend tests
TestMap Tests;
TestList SortedTests;
@@ -139,6 +165,11 @@ protected:
std::vector<std::string>* Failed;
std::vector<std::string> LastTestsFailed;
std::set<std::string> LockedResources;
+ std::map<int,
+ std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
+ AllocatedResources;
+ std::map<int, bool> TestsHaveSufficientResources;
+ cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
unsigned long TestLoad;
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 2eb8dba29..e2063e178 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -2,19 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestP4.h"
+#include <algorithm>
+#include <ctime>
+#include <ostream>
+#include <utility>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmsys/RegularExpression.hxx"
-#include <algorithm>
-#include <ostream>
-#include <time.h>
-#include <utility>
-
cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log)
: cmCTestGlobalVC(ct, log)
{
@@ -145,8 +147,7 @@ private:
cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
{
- std::map<std::string, cmCTestP4::User>::const_iterator it =
- Users.find(username);
+ auto it = Users.find(username);
if (it == Users.end()) {
std::vector<char const*> p4_users;
@@ -203,8 +204,8 @@ private:
cmsys::RegularExpression RegexDiff;
cmCTestP4* P4;
- typedef cmCTestP4::Revision Revision;
- typedef cmCTestP4::Change Change;
+ using Revision = cmCTestP4::Revision;
+ using Change = cmCTestP4::Change;
std::vector<Change> Changes;
enum SectionType
{
@@ -459,8 +460,7 @@ bool cmCTestP4::LoadModifications()
bool cmCTestP4::UpdateCustom(const std::string& custom)
{
- std::vector<std::string> p4_custom_command;
- cmSystemTools::ExpandListArgument(custom, p4_custom_command, true);
+ std::vector<std::string> p4_custom_command = cmExpandedList(custom, true);
std::vector<char const*> p4_custom;
p4_custom.reserve(p4_custom_command.size() + 1);
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
index b14edf7e9..e19472ee8 100644
--- a/Source/CTest/cmCTestP4.h
+++ b/Source/CTest/cmCTestP4.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGlobalVC.h"
-
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
+#include "cmCTestGlobalVC.h"
+
class cmCTest;
/** \class cmCTestP4
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index ba25c516c..cbb939030 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
#include <string>
+#include <utility>
#include <vector>
-class cmCommand;
+#include <cm/memory>
+
+#include "cmCTestCommand.h"
+#include "cmCommand.h"
+
class cmExecutionStatus;
/** \class cmCTestReadCustomFiles
@@ -27,11 +30,11 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand;
+ auto ni = cm::make_unique<cmCTestReadCustomFilesCommand>();
ni->CTest = this->CTest;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestResourceAllocator.cxx b/Source/CTest/cmCTestResourceAllocator.cxx
new file mode 100644
index 000000000..9d468a7f0
--- /dev/null
+++ b/Source/CTest/cmCTestResourceAllocator.cxx
@@ -0,0 +1,86 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCTestResourceAllocator.h"
+
+#include <utility>
+#include <vector>
+
+#include "cmCTestResourceSpec.h"
+
+void cmCTestResourceAllocator::InitializeFromResourceSpec(
+ const cmCTestResourceSpec& spec)
+{
+ this->Resources.clear();
+
+ for (auto const& it : spec.LocalSocket.Resources) {
+ auto& res = this->Resources[it.first];
+ for (auto const& specRes : it.second) {
+ res[specRes.Id].Total = specRes.Capacity;
+ res[specRes.Id].Locked = 0;
+ }
+ }
+}
+
+const std::map<std::string,
+ std::map<std::string, cmCTestResourceAllocator::Resource>>&
+cmCTestResourceAllocator::GetResources() const
+{
+ return this->Resources;
+}
+
+bool cmCTestResourceAllocator::AllocateResource(const std::string& name,
+ const std::string& id,
+ unsigned int slots)
+{
+ auto it = this->Resources.find(name);
+ if (it == this->Resources.end()) {
+ return false;
+ }
+
+ auto resIt = it->second.find(id);
+ if (resIt == it->second.end()) {
+ return false;
+ }
+
+ if (resIt->second.Total < resIt->second.Locked + slots) {
+ return false;
+ }
+
+ resIt->second.Locked += slots;
+ return true;
+}
+
+bool cmCTestResourceAllocator::DeallocateResource(const std::string& name,
+ const std::string& id,
+ unsigned int slots)
+{
+ auto it = this->Resources.find(name);
+ if (it == this->Resources.end()) {
+ return false;
+ }
+
+ auto resIt = it->second.find(id);
+ if (resIt == it->second.end()) {
+ return false;
+ }
+
+ if (resIt->second.Locked < slots) {
+ return false;
+ }
+
+ resIt->second.Locked -= slots;
+ return true;
+}
+
+bool cmCTestResourceAllocator::Resource::operator==(
+ const Resource& other) const
+{
+ return this->Total == other.Total && this->Locked == other.Locked;
+}
+
+bool cmCTestResourceAllocator::Resource::operator!=(
+ const Resource& other) const
+{
+ return !(*this == other);
+}
diff --git a/Source/CTest/cmCTestResourceAllocator.h b/Source/CTest/cmCTestResourceAllocator.h
new file mode 100644
index 000000000..9f0b9c95a
--- /dev/null
+++ b/Source/CTest/cmCTestResourceAllocator.h
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestResourceAllocator_h
+#define cmCTestResourceAllocator_h
+
+#include <map>
+#include <string>
+
+class cmCTestResourceSpec;
+
+class cmCTestResourceAllocator
+{
+public:
+ struct Resource
+ {
+ unsigned int Total;
+ unsigned int Locked;
+
+ unsigned int Free() const { return this->Total - this->Locked; }
+
+ bool operator==(const Resource& other) const;
+ bool operator!=(const Resource& other) const;
+ };
+
+ void InitializeFromResourceSpec(const cmCTestResourceSpec& spec);
+
+ const std::map<std::string, std::map<std::string, Resource>>& GetResources()
+ const;
+
+ bool AllocateResource(const std::string& name, const std::string& id,
+ unsigned int slots);
+ bool DeallocateResource(const std::string& name, const std::string& id,
+ unsigned int slots);
+
+private:
+ std::map<std::string, std::map<std::string, Resource>> Resources;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestResourceGroupsLexerHelper.cxx b/Source/CTest/cmCTestResourceGroupsLexerHelper.cxx
new file mode 100644
index 000000000..072af42f0
--- /dev/null
+++ b/Source/CTest/cmCTestResourceGroupsLexerHelper.cxx
@@ -0,0 +1,55 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestResourceGroupsLexerHelper.h"
+
+#include "cmCTestResourceGroupsLexer.h"
+#include "cmCTestTestHandler.h"
+
+cmCTestResourceGroupsLexerHelper::cmCTestResourceGroupsLexerHelper(
+ std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
+ output)
+ : Output(output)
+{
+}
+
+bool cmCTestResourceGroupsLexerHelper::ParseString(const std::string& value)
+{
+ yyscan_t lexer;
+ cmCTestResourceGroups_yylex_init_extra(this, &lexer);
+
+ auto state = cmCTestResourceGroups_yy_scan_string(value.c_str(), lexer);
+ int retval = cmCTestResourceGroups_yylex(lexer);
+ cmCTestResourceGroups_yy_delete_buffer(state, lexer);
+
+ cmCTestResourceGroups_yylex_destroy(lexer);
+ return retval == 0;
+}
+
+void cmCTestResourceGroupsLexerHelper::SetProcessCount(unsigned int count)
+{
+ this->ProcessCount = count;
+}
+
+void cmCTestResourceGroupsLexerHelper::SetResourceType(const std::string& type)
+{
+ this->ResourceType = type;
+}
+
+void cmCTestResourceGroupsLexerHelper::SetNeededSlots(int count)
+{
+ this->NeededSlots = count;
+}
+
+void cmCTestResourceGroupsLexerHelper::WriteRequirement()
+{
+ this->Process.push_back({ this->ResourceType, this->NeededSlots, 1 });
+}
+
+void cmCTestResourceGroupsLexerHelper::WriteProcess()
+{
+ for (unsigned int i = 0; i < this->ProcessCount; ++i) {
+ this->Output.push_back(this->Process);
+ }
+ this->Process.clear();
+ this->ProcessCount = 1;
+}
diff --git a/Source/CTest/cmCTestResourceGroupsLexerHelper.h b/Source/CTest/cmCTestResourceGroupsLexerHelper.h
new file mode 100644
index 000000000..2cb6cb1c5
--- /dev/null
+++ b/Source/CTest/cmCTestResourceGroupsLexerHelper.h
@@ -0,0 +1,44 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestResourceGroupsLexerHelper_h
+#define cmCTestResourceGroupsLexerHelper_h
+
+#include <string>
+#include <vector>
+
+#include "cmCTestTestHandler.h"
+
+class cmCTestResourceGroupsLexerHelper
+{
+public:
+ struct ParserType
+ {
+ };
+
+ cmCTestResourceGroupsLexerHelper(
+ std::vector<
+ std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
+ output);
+ ~cmCTestResourceGroupsLexerHelper() = default;
+
+ bool ParseString(const std::string& value);
+
+ void SetProcessCount(unsigned int count);
+ void SetResourceType(const std::string& type);
+ void SetNeededSlots(int count);
+ void WriteRequirement();
+ void WriteProcess();
+
+private:
+ std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
+ Output;
+
+ unsigned int ProcessCount = 1;
+ std::string ResourceType;
+ int NeededSlots;
+ std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement> Process;
+};
+
+#define YY_EXTRA_TYPE cmCTestResourceGroupsLexerHelper*
+
+#endif
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
new file mode 100644
index 000000000..237a745c9
--- /dev/null
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -0,0 +1,159 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestResourceSpec.h"
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#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_]+$" };
+
+bool cmCTestResourceSpec::ReadFromJSONFile(const std::string& filename)
+{
+ cmsys::ifstream fin(filename.c_str());
+ if (!fin) {
+ return false;
+ }
+
+ Json::Value root;
+ Json::CharReaderBuilder builder;
+ if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
+ return false;
+ }
+
+ if (!root.isObject()) {
+ return false;
+ }
+
+ int majorVersion = 1;
+ int minorVersion = 0;
+ if (root.isMember("version")) {
+ auto const& version = root["version"];
+ if (version.isObject()) {
+ if (!version.isMember("major") || !version.isMember("minor")) {
+ return false;
+ }
+ auto const& major = version["major"];
+ auto const& minor = version["minor"];
+ if (!major.isInt() || !minor.isInt()) {
+ return false;
+ }
+ majorVersion = major.asInt();
+ minorVersion = minor.asInt();
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ if (majorVersion != 1 || minorVersion != 0) {
+ return false;
+ }
+
+ auto const& local = root["local"];
+ if (!local.isArray()) {
+ return false;
+ }
+ if (local.size() > 1) {
+ return false;
+ }
+
+ if (local.empty()) {
+ this->LocalSocket.Resources.clear();
+ return true;
+ }
+
+ auto const& localSocket = local[0];
+ if (!localSocket.isObject()) {
+ return false;
+ }
+ std::map<std::string, std::vector<cmCTestResourceSpec::Resource>> resources;
+ cmsys::RegularExpressionMatch match;
+ for (auto const& key : localSocket.getMemberNames()) {
+ if (IdentifierRegex.find(key.c_str(), match)) {
+ auto const& value = localSocket[key];
+ auto& r = resources[key];
+ if (value.isArray()) {
+ for (auto const& item : value) {
+ if (item.isObject()) {
+ cmCTestResourceSpec::Resource resource;
+
+ if (!item.isMember("id")) {
+ return false;
+ }
+ auto const& id = item["id"];
+ if (!id.isString()) {
+ return false;
+ }
+ resource.Id = id.asString();
+ if (!IdRegex.find(resource.Id.c_str(), match)) {
+ return false;
+ }
+
+ if (item.isMember("slots")) {
+ auto const& capacity = item["slots"];
+ if (!capacity.isConvertibleTo(Json::uintValue)) {
+ return false;
+ }
+ resource.Capacity = capacity.asUInt();
+ } else {
+ resource.Capacity = 1;
+ }
+
+ r.push_back(resource);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this->LocalSocket.Resources = std::move(resources);
+ return true;
+}
+
+bool cmCTestResourceSpec::operator==(const cmCTestResourceSpec& other) const
+{
+ return this->LocalSocket == other.LocalSocket;
+}
+
+bool cmCTestResourceSpec::operator!=(const cmCTestResourceSpec& other) const
+{
+ return !(*this == other);
+}
+
+bool cmCTestResourceSpec::Socket::operator==(
+ const cmCTestResourceSpec::Socket& other) const
+{
+ return this->Resources == other.Resources;
+}
+
+bool cmCTestResourceSpec::Socket::operator!=(
+ const cmCTestResourceSpec::Socket& other) const
+{
+ return !(*this == other);
+}
+
+bool cmCTestResourceSpec::Resource::operator==(
+ const cmCTestResourceSpec::Resource& other) const
+{
+ return this->Id == other.Id && this->Capacity == other.Capacity;
+}
+
+bool cmCTestResourceSpec::Resource::operator!=(
+ const cmCTestResourceSpec::Resource& other) const
+{
+ return !(*this == other);
+}
diff --git a/Source/CTest/cmCTestResourceSpec.h b/Source/CTest/cmCTestResourceSpec.h
new file mode 100644
index 000000000..4646db84c
--- /dev/null
+++ b/Source/CTest/cmCTestResourceSpec.h
@@ -0,0 +1,40 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestResourceSpec_h
+#define cmCTestResourceSpec_h
+
+#include <map>
+#include <string>
+#include <vector>
+
+class cmCTestResourceSpec
+{
+public:
+ class Resource
+ {
+ public:
+ std::string Id;
+ unsigned int Capacity;
+
+ bool operator==(const Resource& other) const;
+ bool operator!=(const Resource& other) const;
+ };
+
+ class Socket
+ {
+ public:
+ std::map<std::string, std::vector<Resource>> Resources;
+
+ bool operator==(const Socket& other) const;
+ bool operator!=(const Socket& other) const;
+ };
+
+ Socket LocalSocket;
+
+ bool ReadFromJSONFile(const std::string& filename);
+
+ bool operator==(const cmCTestResourceSpec& other) const;
+ bool operator!=(const cmCTestResourceSpec& other) const;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index a7e47d35c..f59ca57de 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -5,8 +5,6 @@
#include "cmCTestScriptHandler.h"
#include "cmMakefile.h"
-#include <sstream>
-
class cmExecutionStatus;
bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
@@ -41,9 +39,7 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
int ret;
cmCTestScriptHandler::RunScript(this->CTest, this->Makefile,
args[i].c_str(), !np, &ret);
- std::ostringstream str;
- str << ret;
- this->Makefile->AddDefinition(returnVariable, str.str().c_str());
+ this->Makefile->AddDefinition(returnVariable, std::to_string(ret));
}
}
return true;
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 9d8b4b587..2d8bde19d 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
#include <string>
+#include <utility>
#include <vector>
-class cmCommand;
+#include <cm/memory>
+
+#include "cmCTestCommand.h"
+#include "cmCommand.h"
+
class cmExecutionStatus;
/** \class cmCTestRunScript
@@ -27,12 +30,12 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand;
+ auto ni = cm::make_unique<cmCTestRunScriptCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 31976b994..3091050f3 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -2,24 +2,28 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestRunTest.h"
-#include "cmCTest.h"
-#include "cmCTestMemCheckHandler.h"
-#include "cmCTestMultiProcessHandler.h"
-#include "cmProcess.h"
-#include "cmSystemTools.h"
-#include "cmWorkingDirectory.h"
-
-#include "cmsys/RegularExpression.hxx"
#include <chrono>
-#include <cmAlgorithms.h>
+#include <cstddef>
#include <cstdint>
+#include <cstdio>
#include <cstring>
#include <iomanip>
#include <ratio>
#include <sstream>
-#include <stdio.h>
#include <utility>
+#include <cm/memory>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCTest.h"
+#include "cmCTestMemCheckHandler.h"
+#include "cmCTestMultiProcessHandler.h"
+#include "cmProcess.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
+
cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler)
: MultiTestHandler(multiHandler)
{
@@ -76,6 +80,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
std::int64_t retVal = this->TestProcess->GetExitValue();
bool forceFail = false;
+ bool forceSkip = false;
bool skipped = false;
bool outputTestErrorsToConsole = false;
if (!this->TestProperties->RequiredRegularExpressions.empty() &&
@@ -84,49 +89,62 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
for (auto& pass : this->TestProperties->RequiredRegularExpressions) {
if (pass.first.find(this->ProcessOutput)) {
found = true;
- reason = "Required regular expression found.";
+ reason = cmStrCat("Required regular expression found. Regex=[",
+ pass.second, ']');
break;
}
}
if (!found) {
- reason = "Required regular expression not found.";
+ reason = "Required regular expression not found. Regex=[";
+ for (auto& pass : this->TestProperties->RequiredRegularExpressions) {
+ reason += pass.second;
+ reason += "\n";
+ }
+ reason += "]";
forceFail = true;
}
- reason += "Regex=[";
- for (auto& pass : this->TestProperties->RequiredRegularExpressions) {
- reason += pass.second;
- reason += "\n";
- }
- reason += "]";
}
if (!this->TestProperties->ErrorRegularExpressions.empty() &&
this->FailedDependencies.empty()) {
- for (auto& pass : this->TestProperties->ErrorRegularExpressions) {
- if (pass.first.find(this->ProcessOutput)) {
- reason = "Error regular expression found in output.";
- reason += " Regex=[";
- reason += pass.second;
- reason += "]";
+ for (auto& fail : this->TestProperties->ErrorRegularExpressions) {
+ if (fail.first.find(this->ProcessOutput)) {
+ reason = cmStrCat("Error regular expression found in output. Regex=[",
+ fail.second, ']');
forceFail = true;
break;
}
}
}
+ if (!this->TestProperties->SkipRegularExpressions.empty() &&
+ this->FailedDependencies.empty()) {
+ for (auto& skip : this->TestProperties->SkipRegularExpressions) {
+ if (skip.first.find(this->ProcessOutput)) {
+ reason = cmStrCat("Skip regular expression found in output. Regex=[",
+ skip.second, ']');
+ forceSkip = true;
+ break;
+ }
+ }
+ }
std::ostringstream outputStream;
if (res == cmProcess::State::Exited) {
bool success = !forceFail &&
(retVal == 0 ||
!this->TestProperties->RequiredRegularExpressions.empty());
- if (this->TestProperties->SkipReturnCode >= 0 &&
- this->TestProperties->SkipReturnCode == retVal) {
+ if ((this->TestProperties->SkipReturnCode >= 0 &&
+ this->TestProperties->SkipReturnCode == retVal) ||
+ forceSkip) {
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
std::ostringstream s;
- s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
+ if (forceSkip) {
+ s << "SKIP_REGULAR_EXPRESSION_MATCHED";
+ } else {
+ s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
+ }
this->TestResult.CompletionStatus = s.str();
cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
skipped = true;
- } else if ((success && !this->TestProperties->WillFail) ||
- (!success && this->TestProperties->WillFail)) {
+ } else if (success != this->TestProperties->WillFail) {
this->TestResult.Status = cmCTestTestHandler::COMPLETED;
outputStream << " Passed ";
} else {
@@ -481,12 +499,11 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
- msg = "Test not available without configuration.";
- msg += " (Missing \"-C <config>\"?)";
+ msg = "Test not available without configuration. (Missing \"-C "
+ "<config>\"?)";
} else {
- msg = "Test not available in configuration \"";
- msg += this->CTest->GetConfigType();
- msg += "\".";
+ msg = cmStrCat("Test not available in configuration \"",
+ this->CTest->GetConfigType(), "\".");
}
*this->TestHandler->LogFile << msg << std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
@@ -556,8 +573,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
void cmCTestRunTest::ComputeArguments()
{
this->Arguments.clear(); // reset because this might be a rerun
- std::vector<std::string>::const_iterator j =
- this->TestProperties->Args.begin();
+ auto j = this->TestProperties->Args.begin();
++j; // skip test name
// find the test executable
if (this->TestHandler->MemCheck) {
@@ -666,7 +682,7 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
this->TestProcess->SetTimeout(timeout);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::SaveRestoreEnvironment sre;
#endif
@@ -674,10 +690,52 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
cmSystemTools::AppendEnv(*environment);
}
+ if (this->UseAllocatedResources) {
+ this->SetupResourcesEnvironment();
+ } else {
+ cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT");
+ }
+
return this->TestProcess->StartProcess(this->MultiTestHandler.Loop,
affinity);
}
+void cmCTestRunTest::SetupResourcesEnvironment()
+{
+ std::string processCount = "CTEST_RESOURCE_GROUP_COUNT=";
+ processCount += std::to_string(this->AllocatedResources.size());
+ cmSystemTools::PutEnv(processCount);
+
+ std::size_t i = 0;
+ for (auto const& process : this->AllocatedResources) {
+ std::string prefix = "CTEST_RESOURCE_GROUP_";
+ prefix += std::to_string(i);
+ std::string resourceList = prefix + '=';
+ prefix += '_';
+ bool firstType = true;
+ for (auto const& it : process) {
+ if (!firstType) {
+ resourceList += ',';
+ }
+ firstType = false;
+ auto resourceType = it.first;
+ resourceList += resourceType;
+ std::string var = prefix + cmSystemTools::UpperCase(resourceType) + '=';
+ bool firstName = true;
+ for (auto const& it2 : it.second) {
+ if (!firstName) {
+ var += ';';
+ }
+ firstName = false;
+ var += "id:" + it2.Id + ",slots:" + std::to_string(it2.Slots);
+ }
+ cmSystemTools::PutEnv(var);
+ }
+ cmSystemTools::PutEnv(resourceList);
+ ++i;
+ }
+}
+
void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
{
std::ostringstream outputStream;
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 38cc417e5..f781c7ab0 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -5,17 +5,20 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
+#include <memory>
#include <set>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
+#include "cmCTestMultiProcessHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
-#include "cmProcess.h" // IWYU pragma: keep (for unique_ptr)
+#include "cmProcess.h"
class cmCTest;
-class cmCTestMultiProcessHandler;
/** \class cmRunTest
* \brief represents a single test to be run
@@ -81,6 +84,19 @@ public:
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
+ void SetUseAllocatedResources(bool use)
+ {
+ this->UseAllocatedResources = use;
+ }
+ void SetAllocatedResources(
+ const std::vector<
+ std::map<std::string,
+ std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>&
+ resources)
+ {
+ this->AllocatedResources = resources;
+ }
+
private:
bool NeedsToRerun();
void DartProcessing();
@@ -92,6 +108,8 @@ private:
// Run post processing of the process output for MemCheck
void MemCheckPostProcess();
+ void SetupResourcesEnvironment();
+
// Returns "completed/total Test #Index: "
std::string GetTestPrefix(size_t completed, size_t total) const;
@@ -110,6 +128,10 @@ private:
std::string StartTime;
std::string ActualCommand;
std::vector<std::string> Arguments;
+ bool UseAllocatedResources = false;
+ std::vector<std::map<
+ std::string, std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>
+ AllocatedResources;
bool RunUntilFail;
int NumberOfRunsLeft;
bool RunAgain;
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index c834686d7..34395c9fe 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -2,20 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSVN.h"
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <ostream>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"
-#include "cmsys/RegularExpression.hxx"
-#include <map>
-#include <ostream>
-#include <stdlib.h>
-#include <string.h>
-
struct cmCTestSVN::Revision : public cmCTestVC::Revision
{
cmCTestSVN::SVNInfo* SVNInfo;
@@ -143,9 +145,8 @@ bool cmCTestSVN::NoteNewRevision()
// the repository root.
if (!svninfo.Root.empty() &&
cmCTestSVNPathStarts(svninfo.URL, svninfo.Root)) {
- svninfo.Base =
- cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size()));
- svninfo.Base += "/";
+ svninfo.Base = cmStrCat(
+ cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size())), '/');
}
this->Log << "Repository '" << svninfo.LocalPath
<< "' Base = " << svninfo.Base << "\n";
@@ -169,7 +170,7 @@ void cmCTestSVN::GuessBase(SVNInfo& svninfo,
slash = svninfo.URL.find('/', slash + 1)) {
// If the URL suffix is a prefix of at least one path then it is the base.
std::string base = cmCTest::DecodeURL(svninfo.URL.substr(slash));
- for (std::vector<Change>::const_iterator ci = changes.begin();
+ for (auto ci = changes.begin();
svninfo.Base.empty() && ci != changes.end(); ++ci) {
if (cmCTestSVNPathStarts(ci->Path, base)) {
svninfo.Base = base;
@@ -307,8 +308,8 @@ private:
cmCTestSVN* SVN;
cmCTestSVN::SVNInfo& SVNRepo;
- typedef cmCTestSVN::Revision Revision;
- typedef cmCTestSVN::Change Change;
+ using Revision = cmCTestSVN::Revision;
+ using Change = cmCTestSVN::Change;
Revision Rev;
std::vector<Change> Changes;
Change CurChange;
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 5c8505d49..b74dc12b0 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGlobalVC.h"
-
#include <iosfwd>
#include <list>
#include <string>
#include <vector>
+#include "cmCTestGlobalVC.h"
+
class cmCTest;
class cmXMLWriter;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index a739f440c..60facbdf5 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -2,16 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestScriptHandler.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/Process.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <map>
+#include <memory>
#include <ratio>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <utility>
+#include <cm/memory>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/Process.h"
+
#include "cmCTest.h"
#include "cmCTestBuildCommand.h"
#include "cmCTestCommand.h"
@@ -27,14 +31,15 @@
#include "cmCTestTestCommand.h"
#include "cmCTestUpdateCommand.h"
#include "cmCTestUploadCommand.h"
+#include "cmCommand.h"
#include "cmDuration.h"
-#include "cmFunctionBlocker.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -44,32 +49,8 @@
# include <unistd.h>
#endif
-class cmExecutionStatus;
-struct cmListFileFunction;
-
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
-// used to keep elapsed time up to date
-class cmCTestScriptFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus& /*status*/) override;
- // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
- // virtual void ScopeEnded(cmMakefile &mf);
-
- cmCTestScriptHandler* CTestScriptHandler;
-};
-
-// simply update the time and don't block anything
-bool cmCTestScriptFunctionBlocker::IsFunctionBlocked(
- const cmListFileFunction& /*lff*/, cmMakefile& /*mf*/,
- cmExecutionStatus& /*status*/)
-{
- this->CTestScriptHandler->UpdateElapsedTime();
- return false;
-}
-
cmCTestScriptHandler::cmCTestScriptHandler()
{
this->Backup = false;
@@ -163,16 +144,16 @@ void cmCTestScriptHandler::UpdateElapsedTime()
auto itime = cmDurationTo<unsigned int>(std::chrono::steady_clock::now() -
this->ScriptStartTime);
auto timeString = std::to_string(itime);
- this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString.c_str());
+ this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString);
}
}
-void cmCTestScriptHandler::AddCTestCommand(std::string const& name,
- cmCTestCommand* command)
+void cmCTestScriptHandler::AddCTestCommand(
+ std::string const& name, std::unique_ptr<cmCTestCommand> command)
{
command->CTest = this->CTest;
command->CTestScriptHandler = this;
- this->CMake->GetState()->AddBuiltinCommand(name, command);
+ this->CMake->GetState()->AddBuiltinCommand(name, std::move(command));
}
int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
@@ -295,21 +276,28 @@ void cmCTestScriptHandler::CreateCMake()
}
});
- this->AddCTestCommand("ctest_build", new cmCTestBuildCommand);
- this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand);
- this->AddCTestCommand("ctest_coverage", new cmCTestCoverageCommand);
+ this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>());
+ this->AddCTestCommand("ctest_configure",
+ cm::make_unique<cmCTestConfigureCommand>());
+ this->AddCTestCommand("ctest_coverage",
+ cm::make_unique<cmCTestCoverageCommand>());
this->AddCTestCommand("ctest_empty_binary_directory",
- new cmCTestEmptyBinaryDirectoryCommand);
- this->AddCTestCommand("ctest_memcheck", new cmCTestMemCheckCommand);
+ cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>());
+ this->AddCTestCommand("ctest_memcheck",
+ cm::make_unique<cmCTestMemCheckCommand>());
this->AddCTestCommand("ctest_read_custom_files",
- new cmCTestReadCustomFilesCommand);
- this->AddCTestCommand("ctest_run_script", new cmCTestRunScriptCommand);
- this->AddCTestCommand("ctest_sleep", new cmCTestSleepCommand);
- this->AddCTestCommand("ctest_start", new cmCTestStartCommand);
- this->AddCTestCommand("ctest_submit", new cmCTestSubmitCommand);
- this->AddCTestCommand("ctest_test", new cmCTestTestCommand);
- this->AddCTestCommand("ctest_update", new cmCTestUpdateCommand);
- this->AddCTestCommand("ctest_upload", new cmCTestUploadCommand);
+ cm::make_unique<cmCTestReadCustomFilesCommand>());
+ this->AddCTestCommand("ctest_run_script",
+ cm::make_unique<cmCTestRunScriptCommand>());
+ this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>());
+ this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>());
+ this->AddCTestCommand("ctest_submit",
+ cm::make_unique<cmCTestSubmitCommand>());
+ this->AddCTestCommand("ctest_test", cm::make_unique<cmCTestTestCommand>());
+ this->AddCTestCommand("ctest_update",
+ cm::make_unique<cmCTestUpdateCommand>());
+ this->AddCTestCommand("ctest_upload",
+ cm::make_unique<cmCTestUploadCommand>());
}
// this sets up some variables for the script to use, creates the required
@@ -340,31 +328,29 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
this->CreateCMake();
// set a variable with the path to the current script
- this->Makefile->AddDefinition(
- "CTEST_SCRIPT_DIRECTORY", cmSystemTools::GetFilenamePath(script).c_str());
- this->Makefile->AddDefinition(
- "CTEST_SCRIPT_NAME", cmSystemTools::GetFilenameName(script).c_str());
+ this->Makefile->AddDefinition("CTEST_SCRIPT_DIRECTORY",
+ cmSystemTools::GetFilenamePath(script));
+ this->Makefile->AddDefinition("CTEST_SCRIPT_NAME",
+ cmSystemTools::GetFilenameName(script));
this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME",
- cmSystemTools::GetCTestCommand().c_str());
+ cmSystemTools::GetCTestCommand());
this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME",
- cmSystemTools::GetCMakeCommand().c_str());
- this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true);
+ cmSystemTools::GetCMakeCommand());
+ this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true);
this->SetRunCurrentScript(true);
this->UpdateElapsedTime();
// add the script arg if defined
if (!script_arg.empty()) {
- this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str());
+ this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg);
}
#if defined(__CYGWIN__)
this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
#endif
- // always add a function blocker to update the elapsed time
- cmCTestScriptFunctionBlocker* f = new cmCTestScriptFunctionBlocker();
- f->CTestScriptHandler = this;
- this->Makefile->AddFunctionBlocker(f);
+ // set a callback function to update the elapsed time
+ this->Makefile->OnExecuteCommand([this] { this->UpdateElapsedTime(); });
/* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and
CMakeSystemSpecificInformation, so
@@ -384,7 +370,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
const std::map<std::string, std::string>& defs =
this->CTest->GetDefinitions();
for (auto const& d : defs) {
- this->Makefile->AddDefinition(d.first, d.second.c_str());
+ this->Makefile->AddDefinition(d.first, d.second);
}
// finally read in the script
@@ -465,12 +451,13 @@ int cmCTestScriptHandler::ExtractVariables()
// make sure the required info is here
if (this->SourceDir.empty() || this->BinaryDir.empty() ||
this->CTestCmd.empty()) {
- std::string msg = "CTEST_SOURCE_DIRECTORY = ";
- msg += (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)";
- msg += "\nCTEST_BINARY_DIRECTORY = ";
- msg += (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)";
- msg += "\nCTEST_COMMAND = ";
- msg += (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)";
+ std::string msg =
+ cmStrCat("CTEST_SOURCE_DIRECTORY = ",
+ (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)",
+ "\nCTEST_BINARY_DIRECTORY = ",
+ (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)",
+ "\nCTEST_COMMAND = ",
+ (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)");
cmSystemTools::Error(
"Some required settings in the configuration file were missing:\n" +
msg);
@@ -509,7 +496,7 @@ void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait)
int cmCTestScriptHandler::RunConfigurationScript(
const std::string& total_script_arg, bool pscope)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::SaveRestoreEnvironment sre;
#endif
@@ -557,8 +544,7 @@ int cmCTestScriptHandler::RunCurrentScript()
// set any environment variables
if (!this->CTestEnv.empty()) {
- std::vector<std::string> envArgs;
- cmSystemTools::ExpandListArgument(this->CTestEnv, envArgs);
+ std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv);
cmSystemTools::AppendEnv(envArgs);
}
@@ -624,10 +610,8 @@ int cmCTestScriptHandler::BackupDirectories()
int retVal;
// compute the backup names
- this->BackupSourceDir = this->SourceDir;
- this->BackupSourceDir += "_CMakeBackup";
- this->BackupBinaryDir = this->BinaryDir;
- this->BackupBinaryDir += "_CMakeBackup";
+ this->BackupSourceDir = cmStrCat(this->SourceDir, "_CMakeBackup");
+ this->BackupBinaryDir = cmStrCat(this->BinaryDir, "_CMakeBackup");
// backup the binary and src directories if requested
if (this->Backup) {
@@ -664,12 +648,9 @@ int cmCTestScriptHandler::PerformExtraUpdates()
// do an initial cvs update as required
command = this->UpdateCmd;
for (std::string const& eu : this->ExtraUpdates) {
- std::vector<std::string> cvsArgs;
- cmSystemTools::ExpandListArgument(eu, cvsArgs);
+ std::vector<std::string> cvsArgs = cmExpandedList(eu);
if (cvsArgs.size() == 2) {
- std::string fullCommand = command;
- fullCommand += " update ";
- fullCommand += cvsArgs[1];
+ std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]);
output.clear();
retVal = 0;
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -678,8 +659,8 @@ int cmCTestScriptHandler::PerformExtraUpdates()
fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(),
this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
if (!res || retVal != 0) {
- cmSystemTools::Error("Unable to perform extra updates:\n" + eu +
- "\nWith output:\n" + output);
+ cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu,
+ "\nWith output:\n", output));
return 0;
}
}
@@ -770,9 +751,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
int cmakeFailed = 0;
std::string cmakeFailedOuput;
if (!this->CMakeCmd.empty()) {
- command = this->CMakeCmd;
- command += " \"";
- command += this->SourceDir;
+ command = cmStrCat(this->CMakeCmd, " \"", this->SourceDir);
output.clear();
command += "\"";
retVal = 0;
@@ -808,8 +787,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
}
// run ctest, it may be more than one command in here
- std::vector<std::string> ctestCommands;
- cmSystemTools::ExpandListArgument(this->CTestCmd, ctestCommands);
+ std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd);
// for each variable/argument do a putenv
for (std::string const& ctestCommand : ctestCommands) {
command = ctestCommand;
@@ -853,8 +831,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
bool cmCTestScriptHandler::WriteInitialCache(const char* directory,
const char* text)
{
- std::string cacheFile = directory;
- cacheFile += "/CMakeCache.txt";
+ std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt");
cmGeneratedFileStream fout(cacheFile);
if (!fout) {
return false;
@@ -919,8 +896,7 @@ bool cmCTestScriptHandler::EmptyBinaryDirectory(const char* sname)
}
// try to avoid deleting directories that we shouldn't
- std::string check = sname;
- check += "/CMakeCache.txt";
+ std::string check = cmStrCat(sname, "/CMakeCache.txt");
if (!cmSystemTools::FileExists(check)) {
return false;
@@ -949,7 +925,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
continue;
}
- std::string fullPath = directoryPath + std::string("/") + path;
+ std::string fullPath = cmStrCat(directoryPath, "/", path);
bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
!cmSystemTools::FileIsSymlink(fullPath);
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d93b5f8e7..d0031990b 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -5,13 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-#include "cmDuration.h"
-
#include <chrono>
+#include <memory>
#include <string>
#include <vector>
+#include "cmCTestGenericHandler.h"
+#include "cmDuration.h"
+
class cmCTest;
class cmCTestCommand;
class cmGlobalGenerator;
@@ -57,7 +58,7 @@ class cmake;
class cmCTestScriptHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/**
* Add a script to run, and if is should run in the current process
@@ -131,7 +132,8 @@ private:
int RunConfigurationDashboard();
// Add ctest command
- void AddCTestCommand(std::string const& name, cmCTestCommand* command);
+ void AddCTestCommand(std::string const& name,
+ std::unique_ptr<cmCTestCommand> command);
// Try to remove the binary directory once
static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath);
diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx
index 2752cd370..623d3b69c 100644
--- a/Source/CTest/cmCTestSleepCommand.cxx
+++ b/Source/CTest/cmCTestSleepCommand.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSleepCommand.h"
-#include "cmCTestScriptHandler.h"
+#include <cstdlib>
-#include <stdlib.h>
+#include "cmCTestScriptHandler.h"
class cmExecutionStatus;
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index 5cd185a81..1c3b8a1e1 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
#include <string>
+#include <utility>
#include <vector>
-class cmCommand;
+#include <cm/memory>
+
+#include "cmCTestCommand.h"
+#include "cmCommand.h"
+
class cmExecutionStatus;
/** \class cmCTestSleep
@@ -27,12 +30,12 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestSleepCommand* ni = new cmCTestSleepCommand;
+ auto ni = cm::make_unique<cmCTestSleepCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index 67ff2db05..fe684062d 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -2,15 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestStartCommand.h"
+#include <cstddef>
+#include <sstream>
+
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include <sstream>
-#include <stddef.h>
-
class cmExecutionStatus;
cmCTestStartCommand::cmCTestStartCommand()
@@ -33,14 +33,16 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
const char* bld_dir = nullptr;
while (cnt < args.size()) {
- if (args[cnt] == "TRACK") {
+ if (args[cnt] == "GROUP" || args[cnt] == "TRACK") {
cnt++;
if (cnt >= args.size() || args[cnt] == "APPEND" ||
args[cnt] == "QUIET") {
- this->SetError("TRACK argument missing track name");
+ std::ostringstream e;
+ e << args[cnt - 1] << " argument missing group name";
+ this->SetError(e.str());
return false;
}
- this->CTest->SetSpecificTrack(args[cnt].c_str());
+ this->CTest->SetSpecificGroup(args[cnt].c_str());
cnt++;
} else if (args[cnt] == "APPEND") {
cnt++;
@@ -113,10 +115,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
<< " Build directory: " << bld_dir << std::endl,
this->Quiet);
}
- const char* track = this->CTest->GetSpecificTrack();
- if (track) {
+ const char* group = this->CTest->GetSpecificGroup();
+ if (group) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Track: " << track << std::endl, this->Quiet);
+ " Group: " << group << std::endl, this->Quiet);
}
// Log startup actions.
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 542f27c13..b30b1bb44 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -5,13 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestCommand.h"
-
#include <iosfwd>
#include <string>
+#include <utility>
#include <vector>
-class cmCommand;
+#include <cm/memory>
+
+#include "cmCTestCommand.h"
+#include "cmCommand.h"
+
class cmExecutionStatus;
/** \class cmCTestStart
@@ -27,14 +30,14 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestStartCommand* ni = new cmCTestStartCommand;
+ auto ni = cm::make_unique<cmCTestStartCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
ni->CreateNewTag = this->CreateNewTag;
ni->Quiet = this->Quiet;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index afc3e67d9..46b00b168 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -2,37 +2,35 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSubmitCommand.h"
+#include <set>
+#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cm_static_string_view.hxx"
+
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
+#include "cmCommand.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <sstream>
-
class cmExecutionStatus;
-cmCTestSubmitCommand::cmCTestSubmitCommand()
-{
- this->PartsMentioned = false;
- this->FilesMentioned = false;
- this->InternalTest = false;
- this->RetryCount = "";
- this->RetryDelay = "";
- this->CDashUpload = false;
- this->Arguments[cts_BUILD_ID] = "BUILD_ID";
- this->Last = cts_LAST;
-}
-
/**
* This is a virtual constructor for the command.
*/
-cmCommand* cmCTestSubmitCommand::Clone()
+std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone()
{
- cmCTestSubmitCommand* ni = new cmCTestSubmitCommand;
+ auto ni = cm::make_unique<cmCTestSubmitCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
@@ -63,16 +61,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
const char* notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
- std::vector<std::string> notesFiles;
- cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles);
+ std::vector<std::string> notesFiles = cmExpandedList(notesFilesVariable);
this->CTest->GenerateNotesFile(notesFiles);
}
const char* extraFilesVariable =
this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
- std::vector<std::string> extraFiles;
- cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles);
+ std::vector<std::string> extraFiles = cmExpandedList(extraFilesVariable);
if (!this->CTest->SubmitExtraFiles(extraFiles)) {
this->SetError("problem submitting extra files.");
return nullptr;
@@ -103,13 +99,18 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// without any of the default parts.
//
handler->SelectParts(std::set<cmCTest::Part>());
- handler->SelectFiles(this->Files);
+ handler->SelectFiles(
+ std::set<std::string>(this->Files.begin(), this->Files.end()));
}
// If a PARTS option was given, select only the named parts for submission.
//
if (this->PartsMentioned) {
- handler->SelectParts(this->Parts);
+ auto parts =
+ cmMakeRange(this->Parts).transform([this](std::string const& arg) {
+ return this->CTest->GetPartFromName(arg.c_str());
+ });
+ handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
}
// Pass along any HTTPHEADER to the handler if this option was given.
@@ -137,133 +138,61 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
- if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) {
- this->Makefile->AddDefinition(this->Values[cts_BUILD_ID],
- this->CTest->GetBuildID().c_str());
+ if (!this->BuildID.empty()) {
+ this->Makefile->AddDefinition(this->BuildID, this->CTest->GetBuildID());
}
return ret;
}
-bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestSubmitCommand::BindArguments()
{
if (this->CDashUpload) {
// Arguments specific to the CDASH_UPLOAD signature.
- if (arg == "CDASH_UPLOAD") {
- this->ArgumentDoing = ArgumentDoingCDashUpload;
- return true;
- }
-
- if (arg == "CDASH_UPLOAD_TYPE") {
- this->ArgumentDoing = ArgumentDoingCDashUploadType;
- return true;
- }
+ this->Bind("CDASH_UPLOAD", this->CDashUploadFile);
+ this->Bind("CDASH_UPLOAD_TYPE", this->CDashUploadType);
} else {
// Arguments that cannot be used with CDASH_UPLOAD.
- if (arg == "PARTS") {
- this->ArgumentDoing = ArgumentDoingParts;
- this->PartsMentioned = true;
- return true;
- }
-
- if (arg == "FILES") {
- this->ArgumentDoing = ArgumentDoingFiles;
- this->FilesMentioned = true;
- return true;
- }
+ this->Bind("PARTS"_s, this->Parts);
+ this->Bind("FILES"_s, this->Files);
}
// Arguments used by both modes.
- if (arg == "HTTPHEADER") {
- this->ArgumentDoing = ArgumentDoingHttpHeader;
- return true;
- }
-
- if (arg == "RETRY_COUNT") {
- this->ArgumentDoing = ArgumentDoingRetryCount;
- return true;
- }
-
- if (arg == "RETRY_DELAY") {
- this->ArgumentDoing = ArgumentDoingRetryDelay;
- return true;
- }
-
- if (arg == "SUBMIT_URL") {
- this->ArgumentDoing = ArgumentDoingSubmitURL;
- return true;
- }
-
- if (arg == "INTERNAL_TEST_CHECKSUM") {
- this->InternalTest = true;
- return true;
- }
+ this->Bind("BUILD_ID"_s, this->BuildID);
+ this->Bind("HTTPHEADER"_s, this->HttpHeaders);
+ this->Bind("RETRY_COUNT"_s, this->RetryCount);
+ this->Bind("RETRY_DELAY"_s, this->RetryDelay);
+ this->Bind("SUBMIT_URL"_s, this->SubmitURL);
+ this->Bind("INTERNAL_TEST_CHECKSUM", this->InternalTest);
// Look for other arguments.
- return this->Superclass::CheckArgumentKeyword(arg);
+ this->cmCTestHandlerCommand::BindArguments();
}
-bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestSubmitCommand::CheckArguments(
+ std::vector<std::string> const& keywords)
{
- // Handle states specific to this command.
- if (this->ArgumentDoing == ArgumentDoingParts) {
+ this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
+ this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+
+ cmEraseIf(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
- if (p != cmCTest::PartCount) {
- this->Parts.insert(p);
- } else {
+ if (p == cmCTest::PartCount) {
std::ostringstream e;
e << "Part name \"" << arg << "\" is invalid.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
+ return true;
}
- return true;
- }
+ return false;
+ });
- if (this->ArgumentDoing == ArgumentDoingFiles) {
- if (cmSystemTools::FileExists(arg)) {
- this->Files.insert(arg);
- } else {
+ cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
<< "a non-existent file.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
+ return true;
}
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
- this->HttpHeaders.push_back(arg);
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingRetryCount) {
- this->RetryCount = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingRetryDelay) {
- this->RetryDelay = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingCDashUpload) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->CDashUploadFile = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingCDashUploadType) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->CDashUploadType = arg;
- return true;
- }
-
- if (this->ArgumentDoing == ArgumentDoingSubmitURL) {
- this->ArgumentDoing = ArgumentDoingNone;
- this->SubmitURL = arg;
- return true;
- }
-
- // Look for other arguments.
- return this->Superclass::CheckArgumentValue(arg);
+ return false;
+ });
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 1e270466d..90607713b 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -5,15 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTest.h"
-#include "cmCTestHandlerCommand.h"
-
-#include <set>
+#include <memory>
#include <string>
#include <vector>
-class cmCTestGenericHandler;
+#include "cmCTestHandlerCommand.h"
+
class cmCommand;
+class cmCTestGenericHandler;
class cmExecutionStatus;
/** \class cmCTestSubmit
@@ -25,8 +24,7 @@ class cmExecutionStatus;
class cmCTestSubmitCommand : public cmCTestHandlerCommand
{
public:
- cmCTestSubmitCommand();
- cmCommand* Clone() override;
+ std::unique_ptr<cmCommand> Clone() override;
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
@@ -36,45 +34,26 @@ public:
*/
std::string GetName() const override { return "ctest_submit"; }
- typedef cmCTestHandlerCommand Superclass;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const& keywords) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingParts = Superclass::ArgumentDoingLast1,
- ArgumentDoingFiles,
- ArgumentDoingRetryDelay,
- ArgumentDoingRetryCount,
- ArgumentDoingCDashUpload,
- ArgumentDoingCDashUploadType,
- ArgumentDoingHttpHeader,
- ArgumentDoingSubmitURL,
- ArgumentDoingLast2
- };
+ bool CDashUpload = false;
+ bool FilesMentioned = false;
+ bool InternalTest = false;
+ bool PartsMentioned = false;
- enum
- {
- cts_BUILD_ID = ct_LAST,
- cts_LAST
- };
-
- bool PartsMentioned;
- std::set<cmCTest::Part> Parts;
- bool FilesMentioned;
- bool InternalTest;
- std::set<std::string> Files;
- std::string RetryCount;
- std::string RetryDelay;
- bool CDashUpload;
+ std::string BuildID;
std::string CDashUploadFile;
std::string CDashUploadType;
- std::vector<std::string> HttpHeaders;
+ std::string RetryCount;
+ std::string RetryDelay;
std::string SubmitURL;
+
+ std::vector<std::string> Files;
+ std::vector<std::string> HttpHeaders;
+ std::vector<std::string> Parts;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 54c4bae08..2ac5af691 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -2,13 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestSubmitHandler.h"
+#include <chrono>
+#include <cstdio>
+#include <cstdlib>
+#include <sstream>
+
#include "cm_curl.h"
#include "cm_jsoncpp_reader.h"
#include "cm_jsoncpp_value.h"
-#include <chrono>
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
#include "cmAlgorithms.h"
#include "cmCTest.h"
@@ -19,13 +20,14 @@
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmake.h"
#define SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT 120
-typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
+using cmCTestSubmitHandlerVectorOfChar = std::vector<char>;
class cmCTestSubmitHandler::ResponseParser : public cmXMLParser
{
@@ -154,8 +156,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(curlopt, args);
+ std::vector<std::string> args = cmExpandedList(curlopt);
bool verifyPeerOff = false;
bool verifyHostOff = false;
for (std::string const& arg : args) {
@@ -224,7 +225,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
std::string local_file = file;
bool initialize_cdash_buildid = false;
if (!cmSystemTools::FileExists(local_file)) {
- local_file = localprefix + "/" + file;
+ local_file = cmStrCat(localprefix, "/", file);
// If this file exists within the local Testing directory we assume
// that it will be associated with the current build in CDash.
initialize_cdash_buildid = true;
@@ -236,9 +237,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
<< remote_file << std::endl;
std::string ofile = cmSystemTools::EncodeURL(remote_file);
- std::string upload_as = url +
- ((url.find('?') == std::string::npos) ? '?' : '&') +
- "FileName=" + ofile;
+ std::string upload_as =
+ cmStrCat(url, ((url.find('?') == std::string::npos) ? '?' : '&'),
+ "FileName=", ofile);
if (initialize_cdash_buildid) {
// Provide extra arguments to CDash so that it can initialize and
@@ -279,7 +280,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
upload_as += "&MD5=";
- if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) {
+ if (cmIsOn(this->GetOption("InternalTest"))) {
upload_as += "bad_md5sum";
} else {
upload_as +=
@@ -498,8 +499,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
cmCTestCurl curl(this->CTest);
curl.SetQuiet(this->Quiet);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(curlopt, args);
+ std::vector<std::string> args = cmExpandedList(curlopt);
curl.SetCurlOptions(args);
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
@@ -516,7 +516,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
}
- bool internalTest = cmSystemTools::IsOn(this->GetOption("InternalTest"));
+ bool internalTest = cmIsOn(this->GetOption("InternalTest"));
// Get RETRY_COUNT and RETRY_DELAY values if they were set.
std::string retryDelayString = this->GetOption("RetryDelay") == nullptr
@@ -528,8 +528,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
auto retryDelay = std::chrono::seconds(0);
if (!retryDelayString.empty()) {
unsigned long retryDelayValue = 0;
- if (!cmSystemTools::StringToULong(retryDelayString.c_str(),
- &retryDelayValue)) {
+ if (!cmStrToULong(retryDelayString, &retryDelayValue)) {
cmCTestLog(this->CTest, WARNING,
"Invalid value for 'RETRY_DELAY' : " << retryDelayString
<< std::endl);
@@ -539,7 +538,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
}
unsigned long retryCount = 0;
if (!retryCountString.empty()) {
- if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) {
+ if (!cmStrToULong(retryCountString, &retryCount)) {
cmCTestLog(this->CTest, WARNING,
"Invalid value for 'RETRY_DELAY' : " << retryCountString
<< std::endl);
@@ -569,6 +568,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
<< curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&"
<< "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site"))
<< "&"
+ << "group=" << curl.Escape(this->CTest->GetTestModelString())
+ << "&"
+ // For now, we send both "track" and "group" to CDash in case we're
+ // submitting to an older instance that still expects the prior
+ // terminology.
<< "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&"
<< "starttime=" << timeNow << "&"
<< "endtime=" << timeNow << "&"
@@ -837,10 +841,10 @@ int cmCTestSubmitHandler::ProcessHandler()
}
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n",
this->Quiet);
- const char* specificTrack = this->CTest->GetSpecificTrack();
- if (specificTrack) {
+ const char* specificGroup = this->CTest->GetSpecificGroup();
+ if (specificGroup) {
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- " Send to track: " << specificTrack << std::endl,
+ " Send to group: " << specificGroup << std::endl,
this->Quiet);
}
this->SetLogFile(&ofs);
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index e0fed10e0..304daaa98 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTest.h"
-#include "cmCTestGenericHandler.h"
-
#include <iosfwd>
#include <set>
#include <string>
#include <vector>
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
/** \class cmCTestSubmitHandler
* \brief Helper class for CTest
*
@@ -22,7 +22,7 @@
class cmCTestSubmitHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
cmCTestSubmitHandler();
~cmCTestSubmitHandler() override { this->LogFile = nullptr; }
@@ -59,7 +59,7 @@ private:
const std::string& remoteprefix,
const std::string& url);
- typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
+ using cmCTestSubmitHandlerVectorOfChar = std::vector<char>;
void ParseResponse(cmCTestSubmitHandlerVectorOfChar chunk);
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index cfd5e3dd2..978421405 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -2,36 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestTestCommand.h"
+#include <chrono>
+#include <cstdlib>
+#include <sstream>
+
+#include "cm_static_string_view.hxx"
+
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
#include "cmMakefile.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
-#include <chrono>
-#include <sstream>
-#include <stdlib.h>
-#include <vector>
-
-cmCTestTestCommand::cmCTestTestCommand()
+void cmCTestTestCommand::BindArguments()
{
- this->Arguments[ctt_START] = "START";
- this->Arguments[ctt_END] = "END";
- this->Arguments[ctt_STRIDE] = "STRIDE";
- this->Arguments[ctt_EXCLUDE] = "EXCLUDE";
- this->Arguments[ctt_INCLUDE] = "INCLUDE";
- this->Arguments[ctt_EXCLUDE_LABEL] = "EXCLUDE_LABEL";
- this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL";
- this->Arguments[ctt_EXCLUDE_FIXTURE] = "EXCLUDE_FIXTURE";
- this->Arguments[ctt_EXCLUDE_FIXTURE_SETUP] = "EXCLUDE_FIXTURE_SETUP";
- this->Arguments[ctt_EXCLUDE_FIXTURE_CLEANUP] = "EXCLUDE_FIXTURE_CLEANUP";
- this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
- this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
- this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
- this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD";
- this->Arguments[ctt_LAST] = nullptr;
- this->Last = ctt_LAST;
+ this->cmCTestHandlerCommand::BindArguments();
+ this->Bind("START"_s, this->Start);
+ this->Bind("END"_s, this->End);
+ this->Bind("STRIDE"_s, this->Stride);
+ this->Bind("EXCLUDE"_s, this->Exclude);
+ this->Bind("INCLUDE"_s, this->Include);
+ this->Bind("EXCLUDE_LABEL"_s, this->ExcludeLabel);
+ this->Bind("INCLUDE_LABEL"_s, this->IncludeLabel);
+ this->Bind("EXCLUDE_FIXTURE"_s, this->ExcludeFixture);
+ this->Bind("EXCLUDE_FIXTURE_SETUP"_s, this->ExcludeFixtureSetup);
+ this->Bind("EXCLUDE_FIXTURE_CLEANUP"_s, this->ExcludeFixtureCleanup);
+ this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
+ this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
+ this->Bind("STOP_TIME"_s, this->StopTime);
+ this->Bind("TEST_LOAD"_s, this->TestLoad);
+ this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -51,57 +52,47 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
}
this->CTest->SetTimeOut(timeout);
cmCTestGenericHandler* handler = this->InitializeActualHandler();
- if (this->Values[ctt_START] || this->Values[ctt_END] ||
- this->Values[ctt_STRIDE]) {
- std::ostringstream testsToRunString;
- if (this->Values[ctt_START]) {
- testsToRunString << this->Values[ctt_START];
- }
- testsToRunString << ",";
- if (this->Values[ctt_END]) {
- testsToRunString << this->Values[ctt_END];
- }
- testsToRunString << ",";
- if (this->Values[ctt_STRIDE]) {
- testsToRunString << this->Values[ctt_STRIDE];
- }
- handler->SetOption("TestsToRunInformation",
- testsToRunString.str().c_str());
+ if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
+ handler->SetOption(
+ "TestsToRunInformation",
+ cmStrCat(this->Start, ',', this->End, ',', this->Stride).c_str());
}
- if (this->Values[ctt_EXCLUDE]) {
- handler->SetOption("ExcludeRegularExpression", this->Values[ctt_EXCLUDE]);
+ if (!this->Exclude.empty()) {
+ handler->SetOption("ExcludeRegularExpression", this->Exclude.c_str());
}
- if (this->Values[ctt_INCLUDE]) {
- handler->SetOption("IncludeRegularExpression", this->Values[ctt_INCLUDE]);
+ if (!this->Include.empty()) {
+ handler->SetOption("IncludeRegularExpression", this->Include.c_str());
}
- if (this->Values[ctt_EXCLUDE_LABEL]) {
+ if (!this->ExcludeLabel.empty()) {
handler->SetOption("ExcludeLabelRegularExpression",
- this->Values[ctt_EXCLUDE_LABEL]);
+ this->ExcludeLabel.c_str());
}
- if (this->Values[ctt_INCLUDE_LABEL]) {
- handler->SetOption("LabelRegularExpression",
- this->Values[ctt_INCLUDE_LABEL]);
+ if (!this->IncludeLabel.empty()) {
+ handler->SetOption("LabelRegularExpression", this->IncludeLabel.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE]) {
+ if (!this->ExcludeFixture.empty()) {
handler->SetOption("ExcludeFixtureRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE]);
+ this->ExcludeFixture.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE_SETUP]) {
+ if (!this->ExcludeFixtureSetup.empty()) {
handler->SetOption("ExcludeFixtureSetupRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE_SETUP]);
+ this->ExcludeFixtureSetup.c_str());
}
- if (this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]) {
+ if (!this->ExcludeFixtureCleanup.empty()) {
handler->SetOption("ExcludeFixtureCleanupRegularExpression",
- this->Values[ctt_EXCLUDE_FIXTURE_CLEANUP]);
+ this->ExcludeFixtureCleanup.c_str());
+ }
+ if (!this->ParallelLevel.empty()) {
+ handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
- if (this->Values[ctt_PARALLEL_LEVEL]) {
- handler->SetOption("ParallelLevel", this->Values[ctt_PARALLEL_LEVEL]);
+ if (!this->ScheduleRandom.empty()) {
+ handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str());
}
- if (this->Values[ctt_SCHEDULE_RANDOM]) {
- handler->SetOption("ScheduleRandom", this->Values[ctt_SCHEDULE_RANDOM]);
+ if (!this->ResourceSpecFile.empty()) {
+ handler->SetOption("ResourceSpecFile", this->ResourceSpecFile.c_str());
}
- if (this->Values[ctt_STOP_TIME]) {
- this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
+ if (!this->StopTime.empty()) {
+ this->CTest->SetStopTime(this->StopTime);
}
// Test load is determined by: TEST_LOAD argument,
@@ -109,16 +100,15 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
// command line argument... in that order.
unsigned long testLoad;
const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
- if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) {
- if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD],
- &testLoad)) {
+ if (!this->TestLoad.empty()) {
+ if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) {
testLoad = 0;
cmCTestLog(this->CTest, WARNING,
- "Invalid value for 'TEST_LOAD' : "
- << this->Values[ctt_TEST_LOAD] << std::endl);
+ "Invalid value for 'TEST_LOAD' : " << this->TestLoad
+ << std::endl);
}
} else if (ctestTestLoad && *ctestTestLoad) {
- if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) {
+ if (!cmStrToULong(ctestTestLoad, &testLoad)) {
testLoad = 0;
cmCTestLog(this->CTest, WARNING,
"Invalid value for 'CTEST_TEST_LOAD' : " << ctestTestLoad
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 11c0db955..4019694b2 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
#include <string>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestTest
* \brief Run a ctest script
@@ -20,17 +23,15 @@ class cmCommand;
class cmCTestTestCommand : public cmCTestHandlerCommand
{
public:
- cmCTestTestCommand();
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestTestCommand* ni = new cmCTestTestCommand;
+ auto ni = cm::make_unique<cmCTestTestCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
@@ -39,29 +40,25 @@ public:
std::string GetName() const override { return "ctest_test"; }
protected:
+ void BindArguments() override;
virtual cmCTestGenericHandler* InitializeActualHandler();
cmCTestGenericHandler* InitializeHandler() override;
- enum
- {
- ctt_BUILD = ct_LAST,
- ctt_RETURN_VALUE,
- ctt_START,
- ctt_END,
- ctt_STRIDE,
- ctt_EXCLUDE,
- ctt_INCLUDE,
- ctt_EXCLUDE_LABEL,
- ctt_INCLUDE_LABEL,
- ctt_EXCLUDE_FIXTURE,
- ctt_EXCLUDE_FIXTURE_SETUP,
- ctt_EXCLUDE_FIXTURE_CLEANUP,
- ctt_PARALLEL_LEVEL,
- ctt_SCHEDULE_RANDOM,
- ctt_STOP_TIME,
- ctt_TEST_LOAD,
- ctt_LAST
- };
+ std::string Start;
+ std::string End;
+ std::string Stride;
+ std::string Exclude;
+ std::string Include;
+ std::string ExcludeLabel;
+ std::string IncludeLabel;
+ std::string ExcludeFixture;
+ std::string ExcludeFixtureSetup;
+ std::string ExcludeFixtureCleanup;
+ std::string ParallelLevel;
+ std::string ScheduleRandom;
+ std::string StopTime;
+ std::string TestLoad;
+ std::string ResourceSpecFile;
};
#endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 0ed56c850..8e3ac2263 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1,70 +1,84 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestTestHandler.h"
+
#include <algorithm>
#include <chrono>
#include <cmath>
-#include <cmsys/Base64.h>
-#include <cmsys/Directory.hxx>
-#include <cmsys/RegularExpression.hxx>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
#include <cstring>
+#include <ctime>
#include <functional>
#include <iomanip>
#include <iterator>
-#include <memory> // IWYU pragma: keep
#include <set>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+#include <cmsys/Base64.h>
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#include "cm_utf8.h"
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
-#include "cmCommand.h"
+#include "cmCTestResourceGroupsLexerHelper.h"
#include "cmDuration.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
-#include "cm_utf8.h"
#include "cmake.h"
-#include "cmsys/FStream.hxx"
-class cmExecutionStatus;
+namespace {
-class cmCTestSubdirCommand : public cmCommand
+class cmCTestCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
+ cmCTestCommand(cmCTestTestHandler* testHandler)
+ : TestHandler(testHandler)
{
- cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
- c->TestHandler = this->TestHandler;
- return c;
}
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/) override;
+ virtual ~cmCTestCommand() = default;
+
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status)
+ {
+ cmMakefile& mf = status.GetMakefile();
+ std::vector<std::string> expandedArguments;
+ if (!mf.ExpandArguments(args, expandedArguments)) {
+ // There was an error expanding arguments. It was already
+ // reported, so we can skip this command without error.
+ return true;
+ }
+ return this->InitialPass(expandedArguments, status);
+ }
+
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status) = 0;
cmCTestTestHandler* TestHandler;
};
-bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+bool cmCTestSubdirCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
@@ -74,9 +88,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
if (cmSystemTools::FileIsFullPath(arg)) {
fname = arg;
} else {
- fname = cwd;
- fname += "/";
- fname += arg;
+ fname = cmStrCat(cwd, '/', arg);
}
if (!cmSystemTools::FileIsDirectory(fname)) {
@@ -87,8 +99,8 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
{
cmWorkingDirectory workdir(fname);
if (workdir.Failed()) {
- this->SetError("Failed to change directory to " + fname + " : " +
- std::strerror(workdir.GetLastResult()));
+ status.SetError("Failed to change directory to " + fname + " : " +
+ std::strerror(workdir.GetLastResult()));
return false;
}
const char* testFilename;
@@ -104,52 +116,26 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args,
}
fname += "/";
fname += testFilename;
- readit = this->Makefile->ReadDependentFile(fname);
+ readit = status.GetMakefile().ReadDependentFile(fname);
}
if (!readit) {
- std::string m = "Could not find include file: ";
- m += fname;
- this->SetError(m);
+ status.SetError(cmStrCat("Could not find include file: ", fname));
return false;
}
}
return true;
}
-class cmCTestAddSubdirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
- c->TestHandler = this->TestHandler;
- return c;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/) override;
-
- cmCTestTestHandler* TestHandler;
-};
-
-bool cmCTestAddSubdirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus& /*unused*/)
+bool cmCTestAddSubdirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- std::string fname = cmSystemTools::GetCurrentWorkingDirectory();
- fname += "/";
- fname += args[0];
+ std::string fname =
+ cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]);
if (!cmSystemTools::FileExists(fname)) {
// No subdirectory? So what...
@@ -170,29 +156,19 @@ bool cmCTestAddSubdirectoryCommand::InitialPass(
}
fname += "/";
fname += testFilename;
- readit = this->Makefile->ReadDependentFile(fname);
+ readit = status.GetMakefile().ReadDependentFile(fname);
}
if (!readit) {
- std::string m = "Could not find include file: ";
- m += fname;
- this->SetError(m);
+ status.SetError(cmStrCat("Could not find include file: ", fname));
return false;
}
return true;
}
-class cmCTestAddTestCommand : public cmCommand
+class cmCTestAddTestCommand : public cmCTestCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
- c->TestHandler = this->TestHandler;
- return c;
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
@@ -200,32 +176,22 @@ public:
*/
bool InitialPass(std::vector<std::string> const& /*args*/,
cmExecutionStatus& /*unused*/) override;
-
- cmCTestTestHandler* TestHandler;
};
bool cmCTestAddTestCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& /*unused*/)
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
return this->TestHandler->AddTest(args);
}
-class cmCTestSetTestsPropertiesCommand : public cmCommand
+class cmCTestSetTestsPropertiesCommand : public cmCTestCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand;
- c->TestHandler = this->TestHandler;
- return c;
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
@@ -233,8 +199,6 @@ public:
*/
bool InitialPass(std::vector<std::string> const& /*args*/,
cmExecutionStatus& /*unused*/) override;
-
- cmCTestTestHandler* TestHandler;
};
bool cmCTestSetTestsPropertiesCommand::InitialPass(
@@ -243,19 +207,10 @@ bool cmCTestSetTestsPropertiesCommand::InitialPass(
return this->TestHandler->SetTestsProperties(args);
}
-class cmCTestSetDirectoryPropertiesCommand : public cmCommand
+class cmCTestSetDirectoryPropertiesCommand : public cmCTestCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmCTestSetDirectoryPropertiesCommand* c =
- new cmCTestSetDirectoryPropertiesCommand;
- c->TestHandler = this->TestHandler;
- return c;
- }
+ using cmCTestCommand::cmCTestCommand;
/**
* This is called when the command is first encountered in
@@ -263,8 +218,6 @@ public:
*/
bool InitialPass(std::vector<std::string> const& /*unused*/,
cmExecutionStatus& /*unused*/) override;
-
- cmCTestTestHandler* TestHandler;
};
bool cmCTestSetDirectoryPropertiesCommand::InitialPass(
@@ -325,6 +278,8 @@ inline int GetNextRealNumber(std::string const& in, double& val,
return 0;
}
+} // namespace
+
cmCTestTestHandler::cmCTestTestHandler()
{
this->UseUnion = false;
@@ -334,6 +289,7 @@ cmCTestTestHandler::cmCTestTestHandler()
this->UseIncludeRegExpFlag = false;
this->UseExcludeRegExpFlag = false;
this->UseExcludeRegExpFirst = false;
+ this->UseResourceSpec = false;
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
@@ -422,54 +378,11 @@ int cmCTestTestHandler::PostProcessHandler()
return 1;
}
-// clearly it would be nice if this were broken up into a few smaller
-// functions and commented...
int cmCTestTestHandler::ProcessHandler()
{
- // Update internal data structure from generic one
- this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
- this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
- if (cmSystemTools::IsOn(this->GetOption("ScheduleRandom"))) {
- this->CTest->SetScheduleType("Random");
- }
- if (this->GetOption("ParallelLevel")) {
- this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
- }
-
- const char* val;
- val = this->GetOption("LabelRegularExpression");
- if (val) {
- this->UseIncludeLabelRegExpFlag = true;
- this->IncludeLabelRegExp = val;
- }
- val = this->GetOption("ExcludeLabelRegularExpression");
- if (val) {
- this->UseExcludeLabelRegExpFlag = true;
- this->ExcludeLabelRegExp = val;
- }
- val = this->GetOption("IncludeRegularExpression");
- if (val) {
- this->UseIncludeRegExp();
- this->SetIncludeRegExp(val);
- }
- val = this->GetOption("ExcludeRegularExpression");
- if (val) {
- this->UseExcludeRegExp();
- this->SetExcludeRegExp(val);
- }
- val = this->GetOption("ExcludeFixtureRegularExpression");
- if (val) {
- this->ExcludeFixtureRegExp = val;
- }
- val = this->GetOption("ExcludeFixtureSetupRegularExpression");
- if (val) {
- this->ExcludeFixtureSetupRegExp = val;
- }
- val = this->GetOption("ExcludeFixtureCleanupRegularExpression");
- if (val) {
- this->ExcludeFixtureCleanupRegExp = val;
+ if (!this->ProcessOptions()) {
+ return -1;
}
- this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));
this->TestResults.clear();
@@ -489,7 +402,6 @@ int cmCTestTestHandler::ProcessHandler()
std::vector<std::string> passed;
std::vector<std::string> failed;
- int total;
// start the real time clock
auto clock_start = std::chrono::steady_clock::now();
@@ -498,9 +410,7 @@ int cmCTestTestHandler::ProcessHandler()
auto clock_finish = std::chrono::steady_clock::now();
- total = int(passed.size()) + int(failed.size());
-
- if (total == 0) {
+ if (passed.size() + failed.size() == 0) {
if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"No tests were found!!!" << std::endl);
@@ -518,105 +428,202 @@ int cmCTestTestHandler::ProcessHandler()
}
}
- typedef std::set<cmCTestTestHandler::cmCTestTestResult,
- cmCTestTestResultLess>
- SetOfTests;
SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests;
for (cmCTestTestResult const& ft : resultsSet) {
- if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") ||
+ if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") ||
ft.CompletionStatus == "Disabled") {
disabledTests.push_back(ft);
}
}
- float percent = float(passed.size()) * 100.0f / float(total);
- if (!failed.empty() && percent > 99) {
- percent = 99;
- }
+ cmDuration durationInSecs = clock_finish - clock_start;
+ this->LogTestSummary(passed, failed, durationInSecs);
- std::string passColorCode;
- std::string failedColorCode;
- if (failed.empty()) {
- passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
- } else {
- failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
+ this->LogDisabledTests(disabledTests);
+
+ this->LogFailedTests(failed, resultsSet);
+ }
+
+ if (!this->GenerateXML()) {
+ return 1;
+ }
+
+ if (!this->PostProcessHandler()) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+
+ if (!failed.empty()) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+ this->LogFile = nullptr;
+ return 0;
+}
+
+bool cmCTestTestHandler::ProcessOptions()
+{
+ // Update internal data structure from generic one
+ this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
+ this->SetUseUnion(cmIsOn(this->GetOption("UseUnion")));
+ if (cmIsOn(this->GetOption("ScheduleRandom"))) {
+ this->CTest->SetScheduleType("Random");
+ }
+ if (this->GetOption("ParallelLevel")) {
+ this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
+ }
+
+ const char* val;
+ val = this->GetOption("LabelRegularExpression");
+ if (val) {
+ this->UseIncludeLabelRegExpFlag = true;
+ this->IncludeLabelRegExp = val;
+ }
+ val = this->GetOption("ExcludeLabelRegularExpression");
+ if (val) {
+ this->UseExcludeLabelRegExpFlag = true;
+ this->ExcludeLabelRegExp = val;
+ }
+ val = this->GetOption("IncludeRegularExpression");
+ if (val) {
+ this->UseIncludeRegExp();
+ this->SetIncludeRegExp(val);
+ }
+ val = this->GetOption("ExcludeRegularExpression");
+ if (val) {
+ this->UseExcludeRegExp();
+ this->SetExcludeRegExp(val);
+ }
+ val = this->GetOption("ExcludeFixtureRegularExpression");
+ if (val) {
+ this->ExcludeFixtureRegExp = val;
+ }
+ val = this->GetOption("ExcludeFixtureSetupRegularExpression");
+ if (val) {
+ this->ExcludeFixtureSetupRegExp = val;
+ }
+ val = this->GetOption("ExcludeFixtureCleanupRegularExpression");
+ if (val) {
+ this->ExcludeFixtureCleanupRegExp = val;
+ }
+ this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
+
+ val = this->GetOption("ResourceSpecFile");
+ if (val) {
+ this->UseResourceSpec = true;
+ if (!this->ResourceSpec.ReadFromJSONFile(val)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not read resource spec file: " << val << std::endl);
+ return false;
}
+ }
+
+ return true;
+}
+
+void cmCTestTestHandler::LogTestSummary(const std::vector<std::string>& passed,
+ const std::vector<std::string>& failed,
+ const cmDuration& durationInSecs)
+{
+ std::size_t total = passed.size() + failed.size();
+
+ float percent = float(passed.size()) * 100.0f / float(total);
+ if (!failed.empty() && percent > 99) {
+ percent = 99;
+ }
+
+ std::string passColorCode;
+ std::string failedColorCode;
+ if (failed.empty()) {
+ passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
+ } else {
+ failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ std::endl
+ << passColorCode << std::lround(percent) << "% tests passed"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << ", " << failedColorCode << failed.size() << " tests failed"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << " out of " << total << std::endl);
+ if ((!this->CTest->GetLabelsForSubprojects().empty() &&
+ this->CTest->GetSubprojectSummary())) {
+ this->PrintLabelOrSubprojectSummary(true);
+ }
+ if (this->CTest->GetLabelSummary()) {
+ this->PrintLabelOrSubprojectSummary(false);
+ }
+ char realBuf[1024];
+ sprintf(realBuf, "%6.2f sec", durationInSecs.count());
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "\nTotal Test time (real) = " << realBuf << "\n",
+ this->Quiet);
+}
+
+void cmCTestTestHandler::LogDisabledTests(
+ const std::vector<cmCTestTestResult>& disabledTests)
+{
+ if (!disabledTests.empty()) {
+ cmGeneratedFileStream ofs;
cmCTestLog(this->CTest, HANDLER_OUTPUT,
std::endl
- << passColorCode << std::lround(percent) << "% tests passed"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << ", " << failedColorCode << failed.size() << " tests failed"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << " out of " << total << std::endl);
- if ((!this->CTest->GetLabelsForSubprojects().empty() &&
- this->CTest->GetSubprojectSummary())) {
- this->PrintLabelOrSubprojectSummary(true);
- }
- if (this->CTest->GetLabelSummary()) {
- this->PrintLabelOrSubprojectSummary(false);
- }
- char realBuf[1024];
- cmDuration durationInSecs = clock_finish - clock_start;
- sprintf(realBuf, "%6.2f sec", durationInSecs.count());
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- "\nTotal Test time (real) = " << realBuf << "\n",
- this->Quiet);
-
- if (!disabledTests.empty()) {
- cmGeneratedFileStream ofs;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- std::endl
- << "The following tests did not run:" << std::endl);
- this->StartLogFile("TestsDisabled", ofs);
+ << "The following tests did not run:" << std::endl);
+ this->StartLogFile("TestsDisabled", ofs);
- const char* disabled_reason;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetColorCode(cmCTest::Color::BLUE));
- for (cmCTestTestResult const& dt : disabledTests) {
- ofs << dt.TestCount << ":" << dt.Name << std::endl;
- if (dt.CompletionStatus == "Disabled") {
- disabled_reason = "Disabled";
- } else {
- disabled_reason = "Skipped";
- }
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
- << " (" << disabled_reason << ")" << std::endl);
+ const char* disabled_reason;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetColorCode(cmCTest::Color::BLUE));
+ for (cmCTestTestResult const& dt : disabledTests) {
+ ofs << dt.TestCount << ":" << dt.Name << std::endl;
+ if (dt.CompletionStatus == "Disabled") {
+ disabled_reason = "Disabled";
+ } else {
+ disabled_reason = "Skipped";
}
cmCTestLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+ "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
+ << " (" << disabled_reason << ")" << std::endl);
}
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+ }
+}
- if (!failed.empty()) {
- cmGeneratedFileStream ofs;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- std::endl
- << "The following tests FAILED:" << std::endl);
- this->StartLogFile("TestsFailed", ofs);
-
- for (cmCTestTestResult const& ft : resultsSet) {
- if (ft.Status != cmCTestTestHandler::COMPLETED &&
- !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") &&
- ft.CompletionStatus != "Disabled") {
- ofs << ft.TestCount << ":" << ft.Name << std::endl;
- auto testColor = cmCTest::Color::RED;
- if (this->GetTestStatus(ft) == "Not Run") {
- testColor = cmCTest::Color::YELLOW;
- }
- cmCTestLog(
- this->CTest, HANDLER_OUTPUT,
- "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
- << ft.TestCount << " - " << ft.Name << " ("
- << this->GetTestStatus(ft) << ")"
- << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
- << std::endl);
+void cmCTestTestHandler::LogFailedTests(const std::vector<std::string>& failed,
+ const SetOfTests& resultsSet)
+{
+ if (!failed.empty()) {
+ cmGeneratedFileStream ofs;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ std::endl
+ << "The following tests FAILED:" << std::endl);
+ this->StartLogFile("TestsFailed", ofs);
+
+ for (cmCTestTestResult const& ft : resultsSet) {
+ if (ft.Status != cmCTestTestHandler::COMPLETED &&
+ !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") &&
+ ft.CompletionStatus != "Disabled") {
+ ofs << ft.TestCount << ":" << ft.Name << std::endl;
+ auto testColor = cmCTest::Color::RED;
+ if (this->GetTestStatus(ft) == "Not Run") {
+ testColor = cmCTest::Color::YELLOW;
}
+ cmCTestLog(
+ this->CTest, HANDLER_OUTPUT,
+ "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
+ << ft.TestCount << " - " << ft.Name << " ("
+ << this->GetTestStatus(ft) << ")"
+ << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+ << std::endl);
}
}
}
+}
+bool cmCTestTestHandler::GenerateXML()
+{
if (this->CTest->GetProduceXML()) {
cmGeneratedFileStream xmlfile;
if (!this->StartResultingXML(
@@ -627,23 +634,13 @@ int cmCTestTestHandler::ProcessHandler()
<< (this->MemCheck ? "memory check" : "testing")
<< " XML file" << std::endl);
this->LogFile = nullptr;
- return 1;
+ return false;
}
cmXMLWriter xml(xmlfile);
this->GenerateDartOutput(xml);
}
- if (!this->PostProcessHandler()) {
- this->LogFile = nullptr;
- return -1;
- }
-
- if (!failed.empty()) {
- this->LogFile = nullptr;
- return -1;
- }
- this->LogFile = nullptr;
- return 0;
+ return true;
}
void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
@@ -660,15 +657,13 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
for (std::string const& l : p.Labels) {
// first check to see if the current label is a subproject label
bool isSubprojectLabel = false;
- std::vector<std::string>::iterator subproject =
- std::find(subprojects.begin(), subprojects.end(), l);
+ auto subproject = std::find(subprojects.begin(), subprojects.end(), l);
if (subproject != subprojects.end()) {
isSubprojectLabel = true;
}
// if we are doing sub projects and this label is one, then use it
// if we are not doing sub projects and the label is not one use it
- if ((doSubProject && isSubprojectLabel) ||
- (!doSubProject && !isSubprojectLabel)) {
+ if (doSubProject == isSubprojectLabel) {
if (l.size() > maxlen) {
maxlen = l.size();
}
@@ -683,7 +678,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestTestProperties& p = *result.Properties;
for (std::string const& l : p.Labels) {
// only use labels found in labels
- if (labels.find(l) != labels.end()) {
+ if (cmContains(labels, l)) {
labelTimes[l] +=
result.ExecutionTime.count() * result.Properties->Processors;
++labelCounts[l];
@@ -825,17 +820,14 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion) {
// if it is not in the list and not in the regexp then skip
- if ((!this->TestsToRun.empty() &&
- std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) ==
- this->TestsToRun.end()) &&
+ if ((!this->TestsToRun.empty() && !cmContains(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() &&
- std::find(this->TestsToRun.begin(), this->TestsToRun.end(),
- inREcnt) == this->TestsToRun.end()) ||
+ !cmContains(this->TestsToRun, inREcnt)) ||
!tp.IsInBasedOnREOptions) {
continue;
}
@@ -864,9 +856,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if ((!this->TestsToRun.empty() &&
- std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) ==
- this->TestsToRun.end())) {
+ if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
continue;
}
@@ -915,14 +905,13 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
// Prepare some maps to help us find setup and cleanup tests for
// any given fixture
- typedef ListOfTests::const_iterator TestIterator;
- typedef std::multimap<std::string, TestIterator> FixtureDependencies;
- typedef FixtureDependencies::const_iterator FixtureDepsIterator;
+ using TestIterator = ListOfTests::const_iterator;
+ using FixtureDependencies = std::multimap<std::string, TestIterator>;
+ using FixtureDepsIterator = FixtureDependencies::const_iterator;
FixtureDependencies fixtureSetups;
FixtureDependencies fixtureCleanups;
- for (ListOfTests::const_iterator it = this->TestList.begin();
- it != this->TestList.end(); ++it) {
+ for (auto it = this->TestList.begin(); it != this->TestList.end(); ++it) {
const cmCTestTestProperties& p = *it;
for (std::string const& deps : p.FixturesSetup) {
@@ -983,12 +972,10 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
// cleanup tests depend on this test case later.
std::pair<FixtureDepsIterator, FixtureDepsIterator> setupRange =
fixtureSetups.equal_range(requiredFixtureName);
- for (FixtureDepsIterator sIt = setupRange.first;
- sIt != setupRange.second; ++sIt) {
+ for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
const std::string& setupTestName = sIt->second->Name;
tests[i].RequireSuccessDepends.insert(setupTestName);
- if (std::find(tests[i].Depends.begin(), tests[i].Depends.end(),
- setupTestName) == tests[i].Depends.end()) {
+ if (!cmContains(tests[i].Depends, setupTestName)) {
tests[i].Depends.push_back(setupTestName);
}
}
@@ -1008,8 +995,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
!excludeSetupRegex.find(requiredFixtureName)) {
std::pair<FixtureDepsIterator, FixtureDepsIterator> fixtureRange =
fixtureSetups.equal_range(requiredFixtureName);
- for (FixtureDepsIterator it = fixtureRange.first;
- it != fixtureRange.second; ++it) {
+ for (auto it = fixtureRange.first; it != fixtureRange.second; ++it) {
ListOfTests::const_iterator lotIt = it->second;
const cmCTestTestProperties& p = *lotIt;
@@ -1040,8 +1026,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
!excludeCleanupRegex.find(requiredFixtureName)) {
std::pair<FixtureDepsIterator, FixtureDepsIterator> fixtureRange =
fixtureCleanups.equal_range(requiredFixtureName);
- for (FixtureDepsIterator it = fixtureRange.first;
- it != fixtureRange.second; ++it) {
+ for (auto it = fixtureRange.first; it != fixtureRange.second; ++it) {
ListOfTests::const_iterator lotIt = it->second;
const cmCTestTestProperties& p = *lotIt;
@@ -1089,14 +1074,12 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
// This cleanup test could be part of the original test list that was
// passed in. It is then possible that no other test requires the
// fIt fixture, so we have to check for this.
- std::map<std::string, std::vector<size_t>>::const_iterator cIt =
- fixtureRequirements.find(fixture);
+ auto cIt = fixtureRequirements.find(fixture);
if (cIt != fixtureRequirements.end()) {
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& reqTestName = tests[index].Name;
- if (std::find(p.Depends.begin(), p.Depends.end(), reqTestName) ==
- p.Depends.end()) {
+ if (!cmContains(p.Depends, reqTestName)) {
p.Depends.push_back(reqTestName);
}
}
@@ -1109,8 +1092,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 (std::find(p.Depends.begin(), p.Depends.end(), setupTestName) ==
- p.Depends.end()) {
+ if (!cmContains(p.Depends, setupTestName)) {
p.Depends.push_back(setupTestName);
}
}
@@ -1255,6 +1237,9 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
+ if (this->UseResourceSpec) {
+ parallel->InitResourceAllocator(this->ResourceSpec);
+ }
*this->LogFile
<< "Start testing: " << this->CTest->CurrentTime() << std::endl
@@ -1298,6 +1283,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
parallel->SetPassFailVectors(&passed, &failed);
this->TestResults.clear();
parallel->SetTestResults(&this->TestResults);
+ parallel->CheckResourcesAvailable();
if (this->CTest->ShouldPrintLabels()) {
parallel->PrintLabels();
@@ -1527,50 +1513,32 @@ void cmCTestTestHandler::AddConfigurations(
attemptedConfigs.emplace_back();
if (!ctest->GetConfigType().empty()) {
- tempPath = filepath;
- tempPath += ctest->GetConfigType();
- tempPath += "/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, ctest->GetConfigType(), '/', filename);
attempted.push_back(tempPath);
attemptedConfigs.push_back(ctest->GetConfigType());
// If the file is an OSX bundle then the configtype
// will be at the start of the path
- tempPath = ctest->GetConfigType();
- tempPath += "/";
- tempPath += filepath;
- tempPath += filename;
+ tempPath = cmStrCat(ctest->GetConfigType(), '/', filepath, filename);
attempted.push_back(tempPath);
attemptedConfigs.push_back(ctest->GetConfigType());
} else {
// no config specified - try some options...
- tempPath = filepath;
- tempPath += "Release/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "Release/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("Release");
- tempPath = filepath;
- tempPath += "Debug/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "Debug/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("Debug");
- tempPath = filepath;
- tempPath += "MinSizeRel/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "MinSizeRel/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("MinSizeRel");
- tempPath = filepath;
- tempPath += "RelWithDebInfo/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "RelWithDebInfo/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("RelWithDebInfo");
- tempPath = filepath;
- tempPath += "Deployment/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "Deployment/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("Deployment");
- tempPath = filepath;
- tempPath += "Development/";
- tempPath += filename;
+ tempPath = cmStrCat(filepath, "Development/", filename);
attempted.push_back(tempPath);
attemptedConfigs.emplace_back("Deployment");
}
@@ -1624,8 +1592,8 @@ std::string cmCTestTestHandler::FindExecutable(
// then try with the exe extension
else {
failed.push_back(attempted[ai]);
- tempPath = attempted[ai];
- tempPath += cmSystemTools::GetExecutableExtension();
+ tempPath =
+ cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension());
if (cmSystemTools::FileExists(tempPath) &&
!cmSystemTools::FileIsDirectory(tempPath)) {
fullPath = cmSystemTools::CollapseFullPath(tempPath);
@@ -1658,6 +1626,14 @@ std::string cmCTestTestHandler::FindExecutable(
return fullPath;
}
+bool cmCTestTestHandler::ParseResourceGroupsProperty(
+ const std::string& val,
+ std::vector<std::vector<cmCTestTestResourceRequirement>>& resourceGroups)
+{
+ cmCTestResourceGroupsLexerHelper lexer(resourceGroups);
+ return lexer.ParseString(val);
+}
+
void cmCTestTestHandler::GetListOfTests()
{
if (!this->IncludeLabelRegExp.empty()) {
@@ -1682,36 +1658,26 @@ void cmCTestTestHandler::GetListOfTests()
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmGlobalGenerator gg(&cm);
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
- mf.AddDefinition("CTEST_CONFIGURATION_TYPE",
- this->CTest->GetConfigType().c_str());
+ mf.AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType());
// Add handler for ADD_TEST
- cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand;
- newCom1->TestHandler = this;
- cm.GetState()->AddBuiltinCommand("add_test", newCom1);
+ cm.GetState()->AddBuiltinCommand("add_test", cmCTestAddTestCommand(this));
// Add handler for SUBDIRS
- cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand;
- newCom2->TestHandler = this;
- cm.GetState()->AddBuiltinCommand("subdirs", newCom2);
+ cm.GetState()->AddBuiltinCommand("subdirs", cmCTestSubdirCommand);
// Add handler for ADD_SUBDIRECTORY
- cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand;
- newCom3->TestHandler = this;
- cm.GetState()->AddBuiltinCommand("add_subdirectory", newCom3);
+ cm.GetState()->AddBuiltinCommand("add_subdirectory",
+ cmCTestAddSubdirectoryCommand);
// Add handler for SET_TESTS_PROPERTIES
- cmCTestSetTestsPropertiesCommand* newCom4 =
- new cmCTestSetTestsPropertiesCommand;
- newCom4->TestHandler = this;
- cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4);
+ cm.GetState()->AddBuiltinCommand("set_tests_properties",
+ cmCTestSetTestsPropertiesCommand(this));
// Add handler for SET_DIRECTORY_PROPERTIES
cm.GetState()->RemoveBuiltinCommand("set_directory_properties");
- cmCTestSetDirectoryPropertiesCommand* newCom5 =
- new cmCTestSetDirectoryPropertiesCommand;
- newCom5->TestHandler = this;
- cm.GetState()->AddBuiltinCommand("set_directory_properties", newCom5);
+ cm.GetState()->AddBuiltinCommand("set_directory_properties",
+ cmCTestSetDirectoryPropertiesCommand(this));
const char* testFilename;
if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
@@ -1818,8 +1784,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformation(size_t numTests)
std::sort(this->TestsToRun.begin(), this->TestsToRun.end(),
std::less<int>());
// remove duplicates
- std::vector<int>::iterator new_end =
- std::unique(this->TestsToRun.begin(), this->TestsToRun.end());
+ auto new_end = std::unique(this->TestsToRun.begin(), this->TestsToRun.end());
this->TestsToRun.erase(new_end, this->TestsToRun.end());
}
@@ -2150,7 +2115,7 @@ bool cmCTestTestHandler::SetTestsProperties(
if (key == "_BACKTRACE_TRIPLES") {
std::vector<std::string> triples;
// allow empty args in the triples
- cmSystemTools::ExpandListArgument(val, triples, true);
+ cmExpandList(val, triples, true);
// Ensure we have complete triples otherwise the data is corrupt.
if (triples.size() % 3 == 0) {
@@ -2163,8 +2128,7 @@ bool cmCTestTestHandler::SetTestsProperties(
cmListFileContext fc;
fc.FilePath = triples[i - 3];
long line = 0;
- if (!cmSystemTools::StringToLong(triples[i - 2].c_str(),
- &line)) {
+ if (!cmStrToLong(triples[i - 2], &line)) {
line = 0;
}
fc.Line = line;
@@ -2174,38 +2138,34 @@ bool cmCTestTestHandler::SetTestsProperties(
}
}
if (key == "WILL_FAIL") {
- rt.WillFail = cmSystemTools::IsOn(val);
+ rt.WillFail = cmIsOn(val);
}
if (key == "DISABLED") {
- rt.Disabled = cmSystemTools::IsOn(val);
+ rt.Disabled = cmIsOn(val);
}
if (key == "ATTACHED_FILES") {
- cmSystemTools::ExpandListArgument(val, rt.AttachedFiles);
+ cmExpandList(val, rt.AttachedFiles);
}
if (key == "ATTACHED_FILES_ON_FAIL") {
- cmSystemTools::ExpandListArgument(val, rt.AttachOnFail);
+ cmExpandList(val, rt.AttachOnFail);
}
if (key == "RESOURCE_LOCK") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.LockedResources.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_SETUP") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesSetup.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_CLEANUP") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesCleanup.insert(lval.begin(), lval.end());
}
if (key == "FIXTURES_REQUIRED") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesRequired.insert(lval.begin(), lval.end());
}
@@ -2217,18 +2177,23 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Cost = static_cast<float>(atof(val.c_str()));
}
if (key == "REQUIRED_FILES") {
- cmSystemTools::ExpandListArgument(val, rt.RequiredFiles);
+ cmExpandList(val, rt.RequiredFiles);
}
if (key == "RUN_SERIAL") {
- rt.RunSerial = cmSystemTools::IsOn(val);
+ rt.RunSerial = cmIsOn(val);
}
if (key == "FAIL_REGULAR_EXPRESSION") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
}
+ if (key == "SKIP_REGULAR_EXPRESSION") {
+ std::vector<std::string> lval = cmExpandedList(val);
+ for (std::string const& cr : lval) {
+ rt.SkipRegularExpressions.emplace_back(cr, cr);
+ }
+ }
if (key == "PROCESSORS") {
rt.Processors = atoi(val.c_str());
if (rt.Processors < 1) {
@@ -2236,7 +2201,12 @@ bool cmCTestTestHandler::SetTestsProperties(
}
}
if (key == "PROCESSOR_AFFINITY") {
- rt.WantAffinity = cmSystemTools::IsOn(val);
+ rt.WantAffinity = cmIsOn(val);
+ }
+ if (key == "RESOURCE_GROUPS") {
+ if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
+ return false;
+ }
}
if (key == "SKIP_RETURN_CODE") {
rt.SkipReturnCode = atoi(val.c_str());
@@ -2245,20 +2215,18 @@ bool cmCTestTestHandler::SetTestsProperties(
}
}
if (key == "DEPENDS") {
- cmSystemTools::ExpandListArgument(val, rt.Depends);
+ cmExpandList(val, rt.Depends);
}
if (key == "ENVIRONMENT") {
- cmSystemTools::ExpandListArgument(val, rt.Environment);
+ cmExpandList(val, rt.Environment);
}
if (key == "LABELS") {
- std::vector<std::string> Labels;
- cmSystemTools::ExpandListArgument(val, Labels);
+ std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
std::sort(rt.Labels.begin(), rt.Labels.end());
// remove duplicates
- std::vector<std::string>::iterator new_end =
- std::unique(rt.Labels.begin(), rt.Labels.end());
+ auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
rt.Labels.erase(new_end, rt.Labels.end());
}
if (key == "MEASUREMENT") {
@@ -2272,8 +2240,7 @@ bool cmCTestTestHandler::SetTestsProperties(
}
}
if (key == "PASS_REGULAR_EXPRESSION") {
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val, lval);
+ std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
@@ -2282,16 +2249,14 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Directory = val;
}
if (key == "TIMEOUT_AFTER_MATCH") {
- std::vector<std::string> propArgs;
- cmSystemTools::ExpandListArgument(val, propArgs);
+ std::vector<std::string> propArgs = cmExpandedList(val);
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
"TIMEOUT_AFTER_MATCH expects two arguments, found "
<< propArgs.size() << std::endl);
} else {
rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str()));
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(propArgs[1], lval);
+ std::vector<std::string> lval = cmExpandedList(propArgs[1]);
for (std::string const& cr : lval) {
rt.TimeoutRegularExpressions.emplace_back(cr, cr);
}
@@ -2333,16 +2298,14 @@ bool cmCTestTestHandler::SetDirectoryProperties(
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
if (key == "LABELS") {
- std::vector<std::string> DirectoryLabels;
- cmSystemTools::ExpandListArgument(val, DirectoryLabels);
+ std::vector<std::string> DirectoryLabels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
// sort the array
std::sort(rt.Labels.begin(), rt.Labels.end());
// remove duplicates
- std::vector<std::string>::iterator new_end =
- std::unique(rt.Labels.begin(), rt.Labels.end());
+ auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
rt.Labels.erase(new_end, rt.Labels.end());
}
}
@@ -2422,3 +2385,17 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
this->TestList.push_back(test);
return true;
}
+
+bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator==(
+ const cmCTestTestResourceRequirement& other) const
+{
+ return this->ResourceType == other.ResourceType &&
+ this->SlotsNeeded == other.SlotsNeeded &&
+ this->UnitsNeeded == other.UnitsNeeded;
+}
+
+bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator!=(
+ const cmCTestTestResourceRequirement& other) const
+{
+ return !(*this == other);
+}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 7f3f5e4f8..eab75d0eb 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -5,21 +5,24 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-#include "cmDuration.h"
-#include "cmListFileCache.h"
-
-#include "cmsys/RegularExpression.hxx"
#include <chrono>
#include <cstdint>
#include <iosfwd>
#include <map>
#include <set>
-#include <stddef.h>
#include <string>
#include <utility>
#include <vector>
+#include <stddef.h>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCTestGenericHandler.h"
+#include "cmCTestResourceSpec.h"
+#include "cmDuration.h"
+#include "cmListFileCache.h"
+
class cmCTest;
class cmMakefile;
class cmXMLWriter;
@@ -34,7 +37,7 @@ class cmCTestTestHandler : public cmCTestGenericHandler
friend class cmCTestMultiProcessHandler;
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/**
* The main entry point for this class
@@ -100,6 +103,16 @@ public:
void Initialize() override;
+ struct cmCTestTestResourceRequirement
+ {
+ std::string ResourceType;
+ int SlotsNeeded;
+ int UnitsNeeded;
+
+ bool operator==(const cmCTestTestResourceRequirement& other) const;
+ bool operator!=(const cmCTestTestResourceRequirement& other) const;
+ };
+
// NOTE: This struct is Saved/Restored
// in cmCTestTestHandler, if you add to this class
// then you must add the new members to that code or
@@ -118,6 +131,8 @@ public:
std::vector<std::pair<cmsys::RegularExpression, std::string>>
RequiredRegularExpressions;
std::vector<std::pair<cmsys::RegularExpression, std::string>>
+ SkipRegularExpressions;
+ std::vector<std::pair<cmsys::RegularExpression, std::string>>
TimeoutRegularExpressions;
std::map<std::string, std::string> Measurements;
bool IsInBasedOnREOptions;
@@ -143,6 +158,7 @@ public:
std::set<std::string> FixturesCleanup;
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
+ std::vector<std::vector<cmCTestTestResourceRequirement>> ResourceGroups;
// Private test generator properties used to track backtraces
cmListFileBacktrace Backtrace;
};
@@ -186,15 +202,31 @@ public:
std::vector<std::string>& extraPaths,
std::vector<std::string>& failed);
- typedef std::vector<cmCTestTestProperties> ListOfTests;
+ static bool ParseResourceGroupsProperty(
+ const std::string& val,
+ std::vector<std::vector<cmCTestTestResourceRequirement>>& resourceGroups);
+
+ using ListOfTests = std::vector<cmCTestTestProperties>;
protected:
+ using SetOfTests =
+ std::set<cmCTestTestHandler::cmCTestTestResult, cmCTestTestResultLess>;
+
// compute a final test list
virtual int PreProcessHandler();
virtual int PostProcessHandler();
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
int ExecuteCommands(std::vector<std::string>& vec);
+ bool ProcessOptions();
+ void LogTestSummary(const std::vector<std::string>& passed,
+ const std::vector<std::string>& failed,
+ const cmDuration& durationInSecs);
+ void LogDisabledTests(const std::vector<cmCTestTestResult>& disabledTests);
+ void LogFailedTests(const std::vector<std::string>& failed,
+ const SetOfTests& resultsSet);
+ bool GenerateXML();
+
void WriteTestResultHeader(cmXMLWriter& xml,
cmCTestTestResult const& result);
void WriteTestResultFooter(cmXMLWriter& xml,
@@ -207,7 +239,7 @@ protected:
cmDuration ElapsedTestingTime;
- typedef std::vector<cmCTestTestResult> TestResultsVector;
+ using TestResultsVector = std::vector<cmCTestTestResult>;
TestResultsVector TestResults;
std::vector<std::string> CustomTestsIgnore;
@@ -304,6 +336,9 @@ private:
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
+ bool UseResourceSpec;
+ cmCTestResourceSpec ResourceSpec;
+
void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
cmsys::RegularExpression DartStuff1;
void CheckLabelFilter(cmCTestTestProperties& it);
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 65dc9211a..673eb9ac1 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -7,14 +7,11 @@
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include <vector>
-
cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
{
- if (this->Values[ct_SOURCE]) {
+ if (!this->Source.empty()) {
this->CTest->SetCTestConfiguration(
- "SourceDirectory",
- cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
+ "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
this->Quiet);
} else {
this->CTest->SetCTestConfiguration(
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index 3b2f3e102..5555c1637 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
#include <string>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestUpdate
* \brief Run a ctest script
@@ -20,17 +23,15 @@ class cmCommand;
class cmCTestUpdateCommand : public cmCTestHandlerCommand
{
public:
- cmCTestUpdateCommand() {}
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestUpdateCommand* ni = new cmCTestUpdateCommand;
+ auto ni = cm::make_unique<cmCTestUpdateCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 5cfc4a7cd..f30ba2bd2 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -2,7 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUpdateHandler.h"
-#include "cmAlgorithms.h"
+#include <chrono>
+#include <sstream>
+
+#include <cm/memory>
+
#include "cmCLocaleEnvironmentScope.h"
#include "cmCTest.h"
#include "cmCTestBZR.h"
@@ -13,14 +17,11 @@
#include "cmCTestSVN.h"
#include "cmCTestVC.h"
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmXMLWriter.h"
-#include <chrono>
-#include <memory> // IWYU pragma: keep
-#include <sstream>
-
static const char* cmCTestUpdateHandlerUpdateStrings[] = {
"Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4"
};
@@ -266,33 +267,27 @@ int cmCTestUpdateHandler::DetectVCS(const char* dir)
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_SVN;
}
- sourceDirectory = dir;
- sourceDirectory += "/CVS";
+ sourceDirectory = cmStrCat(dir, "/CVS");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_CVS;
}
- sourceDirectory = dir;
- sourceDirectory += "/.bzr";
+ sourceDirectory = cmStrCat(dir, "/.bzr");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_BZR;
}
- sourceDirectory = dir;
- sourceDirectory += "/.git";
+ sourceDirectory = cmStrCat(dir, "/.git");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_GIT;
}
- sourceDirectory = dir;
- sourceDirectory += "/.hg";
+ sourceDirectory = cmStrCat(dir, "/.hg");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_HG;
}
- sourceDirectory = dir;
- sourceDirectory += "/.p4";
+ sourceDirectory = cmStrCat(dir, "/.p4");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_P4;
}
- sourceDirectory = dir;
- sourceDirectory += "/.p4config";
+ sourceDirectory = cmStrCat(dir, "/.p4config");
if (cmSystemTools::FileExists(sourceDirectory)) {
return cmCTestUpdateHandler::e_P4;
}
diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h
index 0f51d3f3e..afc0e3d80 100644
--- a/Source/CTest/cmCTestUpdateHandler.h
+++ b/Source/CTest/cmCTestUpdateHandler.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-
#include <string>
#include <utility>
#include <vector>
+#include "cmCTestGenericHandler.h"
+
/** \class cmCTestUpdateHandler
* \brief A class that handles ctest -S invocations
*
@@ -18,7 +18,7 @@
class cmCTestUpdateHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
/*
* The main entry point for this class
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index 59fbf371c..d0e3848a0 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -2,61 +2,46 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUploadCommand.h"
+#include <set>
#include <sstream>
#include <vector>
+#include "cm_static_string_view.hxx"
+
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
-cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
-{
- cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
- handler->Initialize();
- handler->SetFiles(this->Files);
- handler->SetQuiet(this->Quiet);
- return handler;
-}
-
-bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
+void cmCTestUploadCommand::BindArguments()
{
- if (arg == "FILES") {
- this->ArgumentDoing = ArgumentDoingFiles;
- return true;
- }
- if (arg == "QUIET") {
- this->ArgumentDoing = ArgumentDoingNone;
- this->Quiet = true;
- return true;
- }
- if (arg == "CAPTURE_CMAKE_ERROR") {
- this->ArgumentDoing = ArgumentDoingCaptureCMakeError;
- return true;
- }
- return false;
+ this->Bind("FILES"_s, this->Files);
+ this->Bind("QUIET"_s, this->Quiet);
+ this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
}
-bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
+void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
{
- if (this->ArgumentDoing == ArgumentDoingCaptureCMakeError) {
- this->Values[ct_CAPTURE_CMAKE_ERROR] = arg.c_str();
- return true;
- }
- if (this->ArgumentDoing == ArgumentDoingFiles) {
- if (cmSystemTools::FileExists(arg)) {
- this->Files.insert(arg);
+ cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ if (!cmSystemTools::FileExists(arg)) {
+ std::ostringstream e;
+ e << "File \"" << arg << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return true;
}
- std::ostringstream e;
- e << "File \"" << arg << "\" does not exist. Cannot submit "
- << "a non-existent file.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- this->ArgumentDoing = ArgumentDoingError;
return false;
- }
+ });
+}
- // Look for other arguments.
- return this->Superclass::CheckArgumentValue(arg);
+cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+{
+ cmCTestUploadHandler* handler = this->CTest->GetUploadHandler();
+ handler->Initialize();
+ handler->SetFiles(
+ std::set<std::string>(this->Files.begin(), this->Files.end()));
+ handler->SetQuiet(this->Quiet);
+ return handler;
}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index 0d3b06e43..8334a9e08 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -5,13 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestHandlerCommand.h"
-
-#include <set>
#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
class cmCTestGenericHandler;
-class cmCommand;
/** \class cmCTestUpload
* \brief Run a ctest script
@@ -25,12 +28,12 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmCTestUploadCommand* ni = new cmCTestUploadCommand;
+ auto ni = cm::make_unique<cmCTestUploadCommand>();
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
- return ni;
+ return std::unique_ptr<cmCommand>(std::move(ni));
}
/**
@@ -38,22 +41,12 @@ public:
*/
std::string GetName() const override { return "ctest_upload"; }
- typedef cmCTestHandlerCommand Superclass;
-
protected:
+ void BindArguments() override;
+ void CheckArguments(std::vector<std::string> const&) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool CheckArgumentKeyword(std::string const& arg) override;
- bool CheckArgumentValue(std::string const& arg) override;
-
- enum
- {
- ArgumentDoingFiles = Superclass::ArgumentDoingLast1,
- ArgumentDoingCaptureCMakeError,
- ArgumentDoingLast2
- };
-
- std::set<std::string> Files;
+ std::vector<std::string> Files;
};
#endif
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
index 9efdf70b8..9d92aad03 100644
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -2,14 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestUploadHandler.h"
+#include <ostream>
+#include <string>
+
#include "cmCTest.h"
#include "cmGeneratedFileStream.h"
#include "cmVersion.h"
#include "cmXMLWriter.h"
-#include <ostream>
-#include <string>
-
cmCTestUploadHandler::cmCTestUploadHandler()
{
this->Initialize();
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
index 4d8fab487..dde14df16 100644
--- a/Source/CTest/cmCTestUploadHandler.h
+++ b/Source/CTest/cmCTestUploadHandler.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCTestGenericHandler.h"
-
#include <set>
#include <string>
+#include "cmCTestGenericHandler.h"
+
/** \class cmCTestUploadHandler
* \brief Helper class for CTest
*
@@ -19,7 +19,7 @@
class cmCTestUploadHandler : public cmCTestGenericHandler
{
public:
- typedef cmCTestGenericHandler Superclass;
+ using Superclass = cmCTestGenericHandler;
cmCTestUploadHandler();
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index eea41cf74..6026c69bb 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -2,16 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestVC.h"
+#include <cstdio>
+#include <ctime>
+#include <sstream>
+#include <vector>
+
+#include "cmsys/Process.h"
+
#include "cmCTest.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
-#include "cmsys/Process.h"
-#include <sstream>
-#include <stdio.h>
-#include <time.h>
-#include <vector>
-
cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log)
: CTest(ct)
, Log(log)
@@ -152,8 +154,7 @@ bool cmCTestVC::Update()
// if update version only is on then do not actually update,
// just note the current version and finish
- if (!cmSystemTools::IsOn(
- this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) {
+ if (!cmIsOn(this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) {
result = this->NoteOldRevision() && result;
this->Log << "--- Begin Update ---\n";
result = this->UpdateImpl() && result;
diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx
index 63d6a15d8..409025f80 100644
--- a/Source/CTest/cmParseBlanketJSCoverage.cxx
+++ b/Source/CTest/cmParseBlanketJSCoverage.cxx
@@ -2,19 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmParseBlanketJSCoverage.h"
+#include <cstdio>
+#include <cstdlib>
+
+#include "cmsys/FStream.hxx"
+
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
#include "cmSystemTools.h"
-#include "cmsys/FStream.hxx"
-#include <stdio.h>
-#include <stdlib.h>
-
class cmParseBlanketJSCoverage::JSONParser
{
public:
- typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
- FileLinesType;
+ using FileLinesType =
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector;
JSONParser(cmCTestCoverageHandlerContainer& cont)
: Coverage(cont)
{
@@ -110,7 +111,8 @@ cmParseBlanketJSCoverage::cmParseBlanketJSCoverage(
{
}
-bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files)
+bool cmParseBlanketJSCoverage::LoadCoverageData(
+ std::vector<std::string> const& files)
{
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Found " << files.size() << " Files" << std::endl,
diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h
index 696121f21..cd1b225e5 100644
--- a/Source/CTest/cmParseBlanketJSCoverage.h
+++ b/Source/CTest/cmParseBlanketJSCoverage.h
@@ -29,7 +29,7 @@ class cmParseBlanketJSCoverage
public:
cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont,
cmCTest* ctest);
- bool LoadCoverageData(std::vector<std::string> files);
+ bool LoadCoverageData(std::vector<std::string> const& files);
// Read the JSON output
bool ReadJSONFile(std::string const& file);
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index ca1fe70e4..8c4da7577 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -1,15 +1,17 @@
#include "cmParseCacheCoverage.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <utility>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include <map>
-#include <stdio.h>
-#include <stdlib.h>
-#include <utility>
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
cmParseCacheCoverage::cmParseCacheCoverage(
cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
@@ -30,9 +32,7 @@ bool cmParseCacheCoverage::LoadCoverageData(const char* d)
for (i = 0; i < numf; i++) {
std::string file = dir.GetFile(i);
if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) {
- std::string path = d;
- path += "/";
- path += file;
+ std::string path = cmStrCat(d, '/', file);
if (cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") {
if (!this->ReadCMCovFile(path.c_str())) {
return false;
@@ -48,8 +48,7 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles()
{
// loop over the coverage data computed and remove all files
// that only have -1 or 0 for the lines.
- cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator ci =
- this->Coverage.TotalCoverage.begin();
+ auto ci = this->Coverage.TotalCoverage.begin();
while (ci != this->Coverage.TotalCoverage.end()) {
cmCTestCoverageHandlerContainer::SingleFileCoverageVector& v = ci->second;
bool nothing = true;
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index 081f5fa13..e89b9e454 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmParseMumpsCoverage.h"
-
#include <string>
#include <vector>
+#include "cmParseMumpsCoverage.h"
+
class cmCTest;
class cmCTestCoverageHandlerContainer;
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 848a034c9..05da84e2e 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -1,14 +1,16 @@
#include "cmParseCoberturaCoverage.h"
+#include <cstdlib>
+#include <cstring>
+
+#include "cmsys/FStream.hxx"
+
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cmsys/FStream.hxx"
-#include <stdlib.h>
-#include <string.h>
-
class cmParseCoberturaCoverage::XMLParser : public cmXMLParser
{
public:
@@ -75,7 +77,7 @@ protected:
// Check if this is a path that is relative to our source or
// binary directories.
for (std::string const& filePath : FilePaths) {
- finalpath = filePath + "/" + filename;
+ finalpath = cmStrCat(filePath, "/", filename);
if (cmSystemTools::FileExists(finalpath)) {
this->CurFileName = finalpath;
break;
@@ -86,7 +88,7 @@ protected:
cmsys::ifstream fin(this->CurFileName.c_str());
if (this->CurFileName.empty() || !fin) {
this->CurFileName =
- this->Coverage.BinaryDir + "/" + atts[tagCount + 1];
+ cmStrCat(this->Coverage.BinaryDir, "/", atts[tagCount + 1]);
fin.open(this->CurFileName.c_str());
if (!fin) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -141,8 +143,8 @@ private:
bool InSource = false;
bool SkipThisClass = false;
std::vector<std::string> FilePaths;
- typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
- FileLinesType;
+ using FileLinesType =
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector;
cmCTest* CTest;
cmCTestCoverageHandlerContainer& Coverage;
std::string CurFileName;
diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx
index 9eda6f8f3..016e90c02 100644
--- a/Source/CTest/cmParseDelphiCoverage.cxx
+++ b/Source/CTest/cmParseDelphiCoverage.cxx
@@ -1,19 +1,20 @@
#include "cmParseDelphiCoverage.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
+#include <cstdio>
+#include <cstdlib>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
-#include <stdio.h>
-#include <stdlib.h>
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmSystemTools.h"
class cmParseDelphiCoverage::HTMLParser
{
public:
- typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
- FileLinesType;
+ using FileLinesType =
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector;
HTMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
: CTest(ctest)
, Coverage(cont)
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 072275372..1dc5b7038 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -1,16 +1,17 @@
#include "cmParseGTMCoverage.h"
-#include "cmAlgorithms.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <vector>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include <map>
-#include <stdio.h>
-#include <stdlib.h>
-#include <vector>
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
cmCTest* ctest)
@@ -31,9 +32,7 @@ bool cmParseGTMCoverage::LoadCoverageData(const char* d)
for (i = 0; i < numf; i++) {
std::string file = dir.GetFile(i);
if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) {
- std::string path = d;
- path += "/";
- path += file;
+ std::string path = cmStrCat(d, '/', file);
if (cmSystemTools::GetFilenameLastExtension(path) == ".mcov") {
if (!this->ReadMCovFile(path.c_str())) {
return false;
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index 13afbbc26..fe0ae0bfd 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmParseMumpsCoverage.h"
-
#include <string>
+#include "cmParseMumpsCoverage.h"
+
class cmCTest;
class cmCTestCoverageHandlerContainer;
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
index b78142a81..9cf30dfcb 100644
--- a/Source/CTest/cmParseJacocoCoverage.cxx
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -1,15 +1,17 @@
#include "cmParseJacocoCoverage.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
-#include "cmXMLParser.h"
+#include <cstdlib>
+#include <cstring>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
-#include <stdlib.h>
-#include <string.h>
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
class cmParseJacocoCoverage::XMLParser : public cmXMLParser
{
@@ -103,9 +105,7 @@ protected:
std::string const& baseDir)
{
// Search for the file in the baseDir and its subdirectories.
- std::string packageGlob = baseDir;
- packageGlob += "/";
- packageGlob += fileName;
+ std::string packageGlob = cmStrCat(baseDir, '/', fileName);
cmsys::Glob gl;
gl.RecurseOn();
gl.RecurseThroughSymlinksOn();
@@ -118,7 +118,7 @@ protected:
// Check if any of the locations found match our package.
for (std::string const& f : files) {
std::string dir = cmsys::SystemTools::GetParentDirectory(f);
- if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str())) {
+ if (cmHasSuffix(dir, this->PackageName)) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Found package directory for " << fileName << ": "
<< dir << std::endl,
@@ -134,8 +134,8 @@ private:
std::string FilePath;
std::string PackagePath;
std::string PackageName;
- typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
- FileLinesType;
+ using FileLinesType =
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector;
cmCTest* CTest;
cmCTestCoverageHandlerContainer& Coverage;
};
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index 4a81ee4f7..b16f1014a 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -1,16 +1,18 @@
#include "cmParseMumpsCoverage.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
#include <map>
#include <string>
#include <utility>
#include <vector>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
cmParseMumpsCoverage::cmParseMumpsCoverage(
cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
: Coverage(cont)
@@ -107,8 +109,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
{
cmsys::Glob glob;
glob.RecurseOn();
- std::string pat = d;
- pat += "/*.m";
+ std::string pat = cmStrCat(d, "/*.m");
glob.FindFiles(pat);
for (std::string& file : glob.GetFiles()) {
std::string name = cmSystemTools::GetFilenameName(file);
@@ -123,8 +124,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine,
std::string& filepath)
{
- std::map<std::string, std::string>::iterator i =
- this->RoutineToDirectory.find(routine);
+ auto i = this->RoutineToDirectory.find(routine);
if (i != this->RoutineToDirectory.end()) {
filepath = i->second;
return true;
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index a6e65c9df..a494b92b9 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -1,13 +1,15 @@
#include "cmParsePHPCoverage.h"
-#include "cmCTest.h"
-#include "cmCTestCoverageHandler.h"
-#include "cmSystemTools.h"
+#include <cstdlib>
+#include <cstring>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
-#include <stdlib.h>
-#include <string.h>
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
/*
To setup coverage for php.
@@ -210,9 +212,7 @@ bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d)
for (i = 0; i < numf; i++) {
std::string file = dir.GetFile(i);
if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) {
- std::string path = d;
- path += "/";
- path += file;
+ std::string path = cmStrCat(d, '/', file);
if (!this->ReadPHPData(path.c_str())) {
return false;
}
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 7a3b82e61..87f7147bc 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -2,16 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcess.h"
+#include <csignal>
+#include <iostream>
+#include <string>
+
+#include "cmsys/Process.h"
+
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
#include "cmGetPipes.h"
-#include "cmsys/Process.h"
-
-#include <iostream>
-#include <signal.h>
-#include <string>
+#include "cmStringAlgorithms.h"
#if defined(_WIN32)
# include "cm_kwiml.h"
#endif
@@ -694,8 +696,7 @@ std::string cmProcess::GetExitExceptionString()
# endif
# endif
default:
- exception_str = "Signal ";
- exception_str += std::to_string(this->Signal);
+ exception_str = cmStrCat("Signal ", this->Signal);
}
#endif
return exception_str;
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index a0a4b6b20..2c24f2df0 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -4,18 +4,20 @@
#define cmProcess_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDuration.h"
-
-#include "cmProcessOutput.h"
-#include "cmUVHandlePtr.h"
-#include "cm_uv.h"
#include <chrono>
-#include <stddef.h>
-#include <stdint.h>
#include <string>
#include <vector>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "cm_uv.h"
+
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
+#include "cmUVHandlePtr.h"
+
class cmCTestRunTest;
/** \class cmProcess
diff --git a/Source/Checks/cm_cxx17_check.cpp b/Source/Checks/cm_cxx17_check.cpp
index 593d9b263..29863b136 100644
--- a/Source/Checks/cm_cxx17_check.cpp
+++ b/Source/Checks/cm_cxx17_check.cpp
@@ -1,6 +1,7 @@
#include <cstdio>
#include <iterator>
#include <memory>
+#include <optional>
#include <unordered_map>
#ifdef _MSC_VER
@@ -27,5 +28,7 @@ int main()
IDispatchPtr disp(ptr);
#endif
- return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci));
+ std::optional<int> oi = 0;
+
+ return *u + *ai + *(bi - 1) + (3 - static_cast<int>(ci)) + oi.value();
}
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index c51b0dd0e..700971751 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -1,28 +1,28 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-set( CURSES_SRCS
- CursesDialog/cmCursesOptionsWidget.cxx
- CursesDialog/cmCursesBoolWidget.cxx
- CursesDialog/cmCursesCacheEntryComposite.cxx
- CursesDialog/cmCursesDummyWidget.cxx
- CursesDialog/cmCursesFilePathWidget.cxx
- CursesDialog/cmCursesForm.cxx
- CursesDialog/cmCursesLabelWidget.cxx
- CursesDialog/cmCursesLongMessageForm.cxx
- CursesDialog/cmCursesMainForm.cxx
- CursesDialog/cmCursesPathWidget.cxx
- CursesDialog/cmCursesStringWidget.cxx
- CursesDialog/cmCursesWidget.cxx
- CursesDialog/ccmake.cxx
- )
-
-include_directories(${CURSES_INCLUDE_PATH})
-
-
-add_executable(ccmake ${CURSES_SRCS} )
+add_executable(ccmake
+ ccmake.cxx
+ cmCursesBoolWidget.cxx
+ cmCursesCacheEntryComposite.cxx
+ cmCursesDummyWidget.cxx
+ cmCursesFilePathWidget.cxx
+ cmCursesForm.cxx
+ cmCursesLabelWidget.cxx
+ cmCursesLongMessageForm.cxx
+ cmCursesMainForm.cxx
+ cmCursesOptionsWidget.cxx
+ cmCursesPathWidget.cxx
+ cmCursesStringWidget.cxx
+ cmCursesWidget.cxx
+ )
+target_include_directories(ccmake PRIVATE ${CURSES_INCLUDE_PATH})
target_link_libraries(ccmake CMakeLib)
if(CMAKE_USE_SYSTEM_FORM)
+ find_path(CURSES_FORM_INCLUDE_DIR NAMES form.h HINTS ${CURSES_INCLUDE_PATH} ${CURSES_INCLUDE_PATH}/ncurses)
+ if(CURSES_FORM_INCLUDE_DIR)
+ target_include_directories(ccmake PRIVATE ${CURSES_FORM_INCLUDE_DIR})
+ endif()
target_link_libraries(ccmake
${CURSES_FORM_LIBRARY}
${CURSES_LIBRARY}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 7caed0cd5..9e9dfbd19 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -1,6 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include <csignal>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "cmsys/Encoding.hxx"
+
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
@@ -10,13 +18,6 @@
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cmsys/Encoding.hxx"
-#include <iostream>
-#include <signal.h>
-#include <string.h>
-#include <string>
-#include <vector>
-
static const char* cmDocumentationName[][2] = {
{ nullptr, " ccmake - Curses Interface for CMake." },
{ nullptr, nullptr }
@@ -56,7 +57,8 @@ void onsig(int /*unused*/)
cbreak(); /* nl- or cr not needed */
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
refresh();
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
cmCursesForm::CurrentForm->Render(1, 1, x, y);
cmCursesForm::CurrentForm->UpdateStatusBar();
@@ -127,7 +129,8 @@ int main(int argc, char const* const* argv)
signal(SIGWINCH, onsig);
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) {
endwin();
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
index 80a5b5b9c..97b081128 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.cxx
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesBoolWidget.h"
+#include <string>
+
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
-#include <string>
-
cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, int left,
int top)
: cmCursesWidget(width, height, left, top)
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index c1dd591e0..4d3131b07 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -2,6 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesCacheEntryComposite.h"
+#include <cassert>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
#include "cmCursesBoolWidget.h"
#include "cmCursesFilePathWidget.h"
#include "cmCursesLabelWidget.h"
@@ -11,11 +17,8 @@
#include "cmCursesWidget.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmake.h"
-
-#include <assert.h>
-#include <vector>
cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
const std::string& key, int labelwidth, int entrywidth)
@@ -23,62 +26,65 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
, LabelWidth(labelwidth)
, EntryWidth(entrywidth)
{
- this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key);
- this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
- this->Entry = nullptr;
- this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
+ this->Label =
+ cm::make_unique<cmCursesLabelWidget>(this->LabelWidth, 1, 1, 1, key);
+ this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " ");
+ this->Entry =
+ cm::make_unique<cmCursesStringWidget>(this->EntryWidth, 1, 1, 1);
}
cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
- const std::string& key, cmake* cm, bool isNew, int labelwidth,
+ const std::string& key, cmState* state, bool isNew, int labelwidth,
int entrywidth)
: Key(key)
, LabelWidth(labelwidth)
, EntryWidth(entrywidth)
{
- this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key);
+ this->Label =
+ cm::make_unique<cmCursesLabelWidget>(this->LabelWidth, 1, 1, 1, key);
if (isNew) {
- this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, "*");
+ this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, "*");
} else {
- this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
+ this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " ");
}
- this->Entry = nullptr;
- const char* value = cm->GetState()->GetCacheEntryValue(key);
+ const char* value = state->GetCacheEntryValue(key);
assert(value);
- switch (cm->GetState()->GetCacheEntryType(key)) {
- case cmStateEnums::BOOL:
- this->Entry = new cmCursesBoolWidget(this->EntryWidth, 1, 1, 1);
- if (cmSystemTools::IsOn(value)) {
- static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(true);
- } else {
- static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(false);
- }
+ switch (state->GetCacheEntryType(key)) {
+ case cmStateEnums::BOOL: {
+ auto bw = cm::make_unique<cmCursesBoolWidget>(this->EntryWidth, 1, 1, 1);
+ bw->SetValueAsBool(cmIsOn(value));
+ this->Entry = std::move(bw);
break;
- case cmStateEnums::PATH:
- this->Entry = new cmCursesPathWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesPathWidget*>(this->Entry)->SetString(value);
+ }
+ case cmStateEnums::PATH: {
+ auto pw = cm::make_unique<cmCursesPathWidget>(this->EntryWidth, 1, 1, 1);
+ pw->SetString(value);
+ this->Entry = std::move(pw);
break;
- case cmStateEnums::FILEPATH:
- this->Entry = new cmCursesFilePathWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString(value);
+ }
+ case cmStateEnums::FILEPATH: {
+ auto fpw =
+ cm::make_unique<cmCursesFilePathWidget>(this->EntryWidth, 1, 1, 1);
+ fpw->SetString(value);
+ this->Entry = std::move(fpw);
break;
+ }
case cmStateEnums::STRING: {
- const char* stringsProp =
- cm->GetState()->GetCacheEntryProperty(key, "STRINGS");
+ const char* stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
if (stringsProp) {
- cmCursesOptionsWidget* ow =
- new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1);
- this->Entry = ow;
- std::vector<std::string> options;
- cmSystemTools::ExpandListArgument(stringsProp, options);
- for (auto const& opt : options) {
+ auto ow =
+ cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
+ for (std::string const& opt : cmExpandedList(stringsProp)) {
ow->AddOption(opt);
}
ow->SetOption(value);
+ this->Entry = std::move(ow);
} else {
- this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesStringWidget*>(this->Entry)->SetString(value);
+ auto sw =
+ cm::make_unique<cmCursesStringWidget>(this->EntryWidth, 1, 1, 1);
+ sw->SetString(value);
+ this->Entry = std::move(sw);
}
break;
}
@@ -91,12 +97,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
}
}
-cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite()
-{
- delete this->Label;
- delete this->IsNewLabel;
- delete this->Entry;
-}
+cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite() = default;
const char* cmCursesCacheEntryComposite::GetValue()
{
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h
index 0a69d3a9b..a71136331 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.h
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h
@@ -5,33 +5,38 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
class cmCursesLabelWidget;
class cmCursesWidget;
-class cmake;
+class cmState;
class cmCursesCacheEntryComposite
{
public:
cmCursesCacheEntryComposite(const std::string& key, int labelwidth,
int entrywidth);
- cmCursesCacheEntryComposite(const std::string& key, cmake* cm, bool isNew,
- int labelwidth, int entrywidth);
+ cmCursesCacheEntryComposite(const std::string& key, cmState* state,
+ bool isNew, int labelwidth, int entrywidth);
~cmCursesCacheEntryComposite();
cmCursesCacheEntryComposite(cmCursesCacheEntryComposite const&) = delete;
cmCursesCacheEntryComposite& operator=(cmCursesCacheEntryComposite const&) =
delete;
+ cmCursesCacheEntryComposite(cmCursesCacheEntryComposite&&) = default;
+ cmCursesCacheEntryComposite& operator=(cmCursesCacheEntryComposite&&) =
+ default;
+
const char* GetValue();
friend class cmCursesMainForm;
protected:
- cmCursesLabelWidget* Label;
- cmCursesLabelWidget* IsNewLabel;
- cmCursesWidget* Entry;
+ std::unique_ptr<cmCursesLabelWidget> Label;
+ std::unique_ptr<cmCursesLabelWidget> IsNewLabel;
+ std::unique_ptr<cmCursesWidget> Entry;
std::string Key;
int LabelWidth;
int EntryWidth;
diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h
index 78429059e..e3626e66a 100644
--- a/Source/CursesDialog/cmCursesForm.h
+++ b/Source/CursesDialog/cmCursesForm.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCursesStandardIncludes.h"
+#include <string>
#include "cmsys/FStream.hxx"
-#include <string>
+#include "cmCursesStandardIncludes.h"
class cmCursesForm
{
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
index 2ee9cfca8..9e7568187 100644
--- a/Source/CursesDialog/cmCursesLabelWidget.h
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmCursesStandardIncludes.h"
#include "cmCursesWidget.h"
-#include <string>
-
class cmCursesMainForm;
class cmCursesLabelWidget : public cmCursesWidget
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index 4e887d68f..e2d8d06b4 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -2,14 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesLongMessageForm.h"
+#include <cstdio>
+#include <cstring>
+
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmVersion.h"
-#include <stdio.h>
-#include <string.h>
-
inline int ctrl(int z)
{
return (z & 037);
@@ -38,7 +38,8 @@ cmCursesLongMessageForm::~cmCursesLongMessageForm()
void cmCursesLongMessageForm::UpdateStatusBar()
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
char bar[cmCursesMainForm::MAX_WIDTH];
@@ -81,7 +82,8 @@ void cmCursesLongMessageForm::UpdateStatusBar()
void cmCursesLongMessageForm::PrintKeys()
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) {
return;
@@ -98,7 +100,8 @@ void cmCursesLongMessageForm::PrintKeys()
void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
int /*height*/)
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
if (this->Form) {
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 466b4e1b0..42f9c710b 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCursesForm.h"
-#include "cmCursesStandardIncludes.h"
-
#include <string>
#include <vector>
+#include "cmCursesForm.h"
+#include "cmCursesStandardIncludes.h"
+
class cmCursesLongMessageForm : public cmCursesForm
{
public:
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 028e85298..6b71e8a10 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -2,7 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesMainForm.h"
-#include "cmAlgorithms.h"
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <utility>
+
+#include <cm/memory>
+
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesDummyWidget.h"
#include "cmCursesForm.h"
@@ -13,15 +19,11 @@
#include "cmCursesWidget.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmake.h"
-#include <algorithm>
-#include <stdio.h>
-#include <string.h>
-#include <utility>
-
inline int ctrl(int z)
{
return (z & 037);
@@ -33,8 +35,6 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> args,
, InitialWidth(initWidth)
{
this->NumberOfPages = 0;
- this->Fields = nullptr;
- this->Entries = nullptr;
this->AdvancedMode = false;
this->NumberOfVisibleEntries = 0;
this->OkToGenerate = false;
@@ -42,17 +42,16 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> args,
"Welcome to ccmake, curses based user interface for CMake.");
this->HelpMessage.emplace_back();
this->HelpMessage.emplace_back(s_ConstHelpMessage);
- this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
+ this->CMakeInstance =
+ cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeCursesCommand());
// create the arguments for the cmake object
- std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0]);
- whereCMake += "/cmake";
+ std::string whereCMake =
+ cmStrCat(cmSystemTools::GetProgramPath(this->Args[0]), "/cmake");
this->Args[0] = whereCMake;
this->CMakeInstance->SetArgs(this->Args);
- this->SearchString = "";
- this->OldSearchString = "";
this->SearchMode = false;
}
@@ -63,27 +62,15 @@ cmCursesMainForm::~cmCursesMainForm()
free_form(this->Form);
this->Form = nullptr;
}
- delete[] this->Fields;
-
- // Clean-up composites
- if (this->Entries) {
- cmDeleteAll(*this->Entries);
- }
- delete this->Entries;
- if (this->CMakeInstance) {
- delete this->CMakeInstance;
- this->CMakeInstance = nullptr;
- }
}
// See if a cache entry is in the list of entries in the ui.
bool cmCursesMainForm::LookForCacheEntry(const std::string& key)
{
- return this->Entries &&
- std::any_of(this->Entries->begin(), this->Entries->end(),
- [&key](cmCursesCacheEntryComposite* entry) {
- return key == entry->Key;
- });
+ return std::any_of(this->Entries.begin(), this->Entries.end(),
+ [&key](cmCursesCacheEntryComposite const& entry) {
+ return key == entry.Key;
+ });
}
// Create new cmCursesCacheEntryComposite entries from the cache
@@ -91,11 +78,10 @@ void cmCursesMainForm::InitializeUI()
{
// Create a vector of cmCursesCacheEntryComposite's
// which contain labels, entries and new entry markers
- std::vector<cmCursesCacheEntryComposite*>* newEntries =
- new std::vector<cmCursesCacheEntryComposite*>;
+ std::vector<cmCursesCacheEntryComposite> newEntries;
std::vector<std::string> cacheKeys =
this->CMakeInstance->GetState()->GetCacheEntryKeys();
- newEntries->reserve(cacheKeys.size());
+ newEntries.reserve(cacheKeys.size());
// Count non-internal and non-static entries
int count = 0;
@@ -111,13 +97,12 @@ void cmCursesMainForm::InitializeUI()
int entrywidth = this->InitialWidth - 35;
- cmCursesCacheEntryComposite* comp;
if (count == 0) {
// If cache is empty, display a label saying so and a
// dummy entry widget (does not respond to input)
- comp = new cmCursesCacheEntryComposite("EMPTY CACHE", 30, 30);
- comp->Entry = new cmCursesDummyWidget(1, 1, 1, 1);
- newEntries->push_back(comp);
+ cmCursesCacheEntryComposite comp("EMPTY CACHE", 30, 30);
+ comp.Entry = cm::make_unique<cmCursesDummyWidget>(1, 1, 1, 1);
+ newEntries.emplace_back(std::move(comp));
} else {
// Create the composites.
@@ -131,8 +116,8 @@ void cmCursesMainForm::InitializeUI()
}
if (!this->LookForCacheEntry(key)) {
- newEntries->push_back(new cmCursesCacheEntryComposite(
- key, this->CMakeInstance, true, 30, entrywidth));
+ newEntries.emplace_back(key, this->CMakeInstance->GetState(), true, 30,
+ entrywidth);
this->OkToGenerate = false;
}
}
@@ -147,18 +132,14 @@ void cmCursesMainForm::InitializeUI()
}
if (this->LookForCacheEntry(key)) {
- newEntries->push_back(new cmCursesCacheEntryComposite(
- key, this->CMakeInstance, false, 30, entrywidth));
+ newEntries.emplace_back(key, this->CMakeInstance->GetState(), false,
+ 30, entrywidth);
}
}
}
- // Clean old entries
- if (this->Entries) {
- cmDeleteAll(*this->Entries);
- }
- delete this->Entries;
- this->Entries = newEntries;
+ // Replace old entries
+ this->Entries = std::move(newEntries);
// Compute fields from composites
this->RePost();
@@ -172,18 +153,18 @@ void cmCursesMainForm::RePost()
free_form(this->Form);
this->Form = nullptr;
}
- delete[] this->Fields;
+ this->Fields.clear();
if (this->AdvancedMode) {
- this->NumberOfVisibleEntries = this->Entries->size();
+ this->NumberOfVisibleEntries = this->Entries.size();
} else {
// If normal mode, count only non-advanced entries
this->NumberOfVisibleEntries = 0;
- for (cmCursesCacheEntryComposite* entry : *this->Entries) {
+ for (cmCursesCacheEntryComposite& entry : this->Entries) {
const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(entry->GetValue());
+ this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
- entry->GetValue(), "ADVANCED");
+ entry.GetValue(), "ADVANCED");
if (!existingValue || (!this->AdvancedMode && advanced)) {
continue;
}
@@ -196,38 +177,32 @@ void cmCursesMainForm::RePost()
}
// Assign the fields: 3 for each entry: label, new entry marker
// ('*' or ' ') and entry widget
- this->Fields = new FIELD*[3 * this->NumberOfVisibleEntries + 1];
- size_t cc;
- for (cc = 0; cc < 3 * this->NumberOfVisibleEntries + 1; cc++) {
- this->Fields[cc] = nullptr;
- }
+ this->Fields.reserve(3 * this->NumberOfVisibleEntries + 1);
// Assign fields
- int j = 0;
- for (cmCursesCacheEntryComposite* entry : *this->Entries) {
+ for (cmCursesCacheEntryComposite& entry : this->Entries) {
const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(entry->GetValue());
+ this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
- entry->GetValue(), "ADVANCED");
+ entry.GetValue(), "ADVANCED");
if (!existingValue || (!this->AdvancedMode && advanced)) {
continue;
}
- this->Fields[3 * j] = entry->Label->Field;
- this->Fields[3 * j + 1] = entry->IsNewLabel->Field;
- this->Fields[3 * j + 2] = entry->Entry->Field;
- j++;
+ this->Fields.push_back(entry.Label->Field);
+ this->Fields.push_back(entry.IsNewLabel->Field);
+ this->Fields.push_back(entry.Entry->Field);
}
// if no cache entries there should still be one dummy field
- if (j == 0) {
- const auto& front = *this->Entries->front();
- this->Fields[0] = front.Label->Field;
- this->Fields[1] = front.IsNewLabel->Field;
- this->Fields[2] = front.Entry->Field;
+ if (this->Fields.empty()) {
+ const auto& front = this->Entries.front();
+ this->Fields.push_back(front.Label->Field);
+ this->Fields.push_back(front.IsNewLabel->Field);
+ this->Fields.push_back(front.Entry->Field);
this->NumberOfVisibleEntries = 1;
}
// Has to be null terminated.
- this->Fields[3 * this->NumberOfVisibleEntries] = nullptr;
+ this->Fields.push_back(nullptr);
}
void cmCursesMainForm::Render(int left, int top, int width, int height)
@@ -260,16 +235,16 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
height -= 7;
if (this->AdvancedMode) {
- this->NumberOfVisibleEntries = this->Entries->size();
+ this->NumberOfVisibleEntries = this->Entries.size();
} else {
// If normal, display only non-advanced entries
this->NumberOfVisibleEntries = 0;
- for (cmCursesCacheEntryComposite* entry : *this->Entries) {
+ for (cmCursesCacheEntryComposite& entry : this->Entries) {
const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(entry->GetValue());
+ this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
- entry->GetValue(), "ADVANCED");
+ entry.GetValue(), "ADVANCED");
if (!existingValue || (!this->AdvancedMode && advanced)) {
continue;
}
@@ -282,12 +257,12 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
if (height > 0) {
bool isNewPage;
int i = 0;
- for (cmCursesCacheEntryComposite* entry : *this->Entries) {
+ for (cmCursesCacheEntryComposite& entry : this->Entries) {
const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(entry->GetValue());
+ this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
- entry->GetValue(), "ADVANCED");
+ entry.GetValue(), "ADVANCED");
if (!existingValue || (!this->AdvancedMode && advanced)) {
continue;
}
@@ -298,16 +273,16 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
if (isNewPage) {
this->NumberOfPages++;
}
- entry->Label->Move(left, top + row - 1, isNewPage);
- entry->IsNewLabel->Move(left + 32, top + row - 1, false);
- entry->Entry->Move(left + 33, top + row - 1, false);
- entry->Entry->SetPage(this->NumberOfPages);
+ entry.Label->Move(left, top + row - 1, isNewPage);
+ entry.IsNewLabel->Move(left + 32, top + row - 1, false);
+ entry.Entry->Move(left + 33, top + row - 1, false);
+ entry.Entry->SetPage(this->NumberOfPages);
i++;
}
}
// Post the form
- this->Form = new_form(this->Fields);
+ this->Form = new_form(this->Fields.data());
post_form(this->Form);
// Update toolbar
this->UpdateStatusBar();
@@ -319,7 +294,8 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
void cmCursesMainForm::PrintKeys(int process /* = 0 */)
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
if (x < cmCursesMainForm::MIN_WIDTH || x < this->InitialWidth ||
y < cmCursesMainForm::MIN_HEIGHT) {
@@ -365,7 +341,7 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
char fmt[512] =
"Press [enter] to edit option Press [d] to delete an entry";
if (process) {
- memset(fmt, ' ', 27);
+ memset(fmt, ' ', 57);
}
printw(fmt_s, fmt);
curses_move(y - 3, 0);
@@ -390,7 +366,8 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
// on the status bar. Designed for a width of 80 chars.
void cmCursesMainForm::UpdateStatusBar(const char* message)
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
// If window size is too small, display error and return
if (x < cmCursesMainForm::MIN_WIDTH || x < this->InitialWidth ||
@@ -508,7 +485,8 @@ void cmCursesMainForm::UpdateProgress(const std::string& msg, float prog)
int cmCursesMainForm::Configure(int noconfigure)
{
- int xi, yi;
+ int xi;
+ int yi;
getmaxyx(stdscr, yi, xi);
curses_move(1, 1);
@@ -551,7 +529,8 @@ int cmCursesMainForm::Configure(int noconfigure)
if (cmSystemTools::GetErrorOccuredFlag()) {
this->OkToGenerate = false;
}
- int xx, yy;
+ int xx;
+ int yy;
getmaxyx(stdscr, yy, xx);
cmCursesLongMessageForm* msgs =
new cmCursesLongMessageForm(this->Errors,
@@ -580,7 +559,8 @@ int cmCursesMainForm::Configure(int noconfigure)
int cmCursesMainForm::Generate()
{
- int xi, yi;
+ int xi;
+ int yi;
getmaxyx(stdscr, yi, xi);
curses_move(1, 1);
@@ -609,7 +589,8 @@ int cmCursesMainForm::Generate()
}
// reset error condition
cmSystemTools::ResetErrorOccuredFlag();
- int xx, yy;
+ int xx;
+ int yy;
getmaxyx(stdscr, yy, xx);
const char* title = "Messages during last pass.";
if (cmSystemTools::GetErrorOccuredFlag()) {
@@ -648,28 +629,28 @@ void cmCursesMainForm::RemoveEntry(const char* value)
}
auto removeIt =
- std::find_if(this->Entries->begin(), this->Entries->end(),
- [value](cmCursesCacheEntryComposite* entry) -> bool {
- const char* val = entry->GetValue();
+ std::find_if(this->Entries.begin(), this->Entries.end(),
+ [value](cmCursesCacheEntryComposite& entry) -> bool {
+ const char* val = entry.GetValue();
return val != nullptr && !strcmp(value, val);
});
- if (removeIt != this->Entries->end()) {
+ if (removeIt != this->Entries.end()) {
this->CMakeInstance->UnwatchUnusedCli(value);
- this->Entries->erase(removeIt);
+ this->Entries.erase(removeIt);
}
}
// copy from the list box to the cache manager
void cmCursesMainForm::FillCacheManagerFromUI()
{
- for (cmCursesCacheEntryComposite* entry : *this->Entries) {
- const std::string& cacheKey = entry->Key;
+ for (cmCursesCacheEntryComposite& entry : this->Entries) {
+ const std::string& cacheKey = entry.Key;
const char* existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey);
if (existingValue) {
std::string oldValue = existingValue;
- std::string newValue = entry->Entry->GetValue();
+ std::string newValue = entry.Entry->GetValue();
std::string fixedOldValue;
std::string fixedNewValue;
cmStateEnums::CacheEntryType t =
@@ -696,7 +677,7 @@ void cmCursesMainForm::FixValue(cmStateEnums::CacheEntryType type,
cmSystemTools::ConvertToUnixSlashes(out);
}
if (type == cmStateEnums::BOOL) {
- if (cmSystemTools::IsOff(out)) {
+ if (cmIsOff(out)) {
out = "OFF";
} else {
out = "ON";
@@ -706,7 +687,8 @@ void cmCursesMainForm::FixValue(cmStateEnums::CacheEntryType type,
void cmCursesMainForm::HandleInput()
{
- int x = 0, y = 0;
+ int x = 0;
+ int y = 0;
if (!this->Form) {
return;
@@ -754,7 +736,7 @@ void cmCursesMainForm::HandleInput()
this->JumpToCacheEntry(this->SearchString.c_str());
this->OldSearchString = this->SearchString;
}
- this->SearchString = "";
+ this->SearchString.clear();
}
/*
else if ( key == KEY_ESCAPE )
@@ -770,7 +752,7 @@ void cmCursesMainForm::HandleInput()
}
} else if (key == ctrl('h') || key == KEY_BACKSPACE || key == KEY_DC) {
if (!this->SearchString.empty()) {
- this->SearchString.resize(this->SearchString.size() - 1);
+ this->SearchString.pop_back();
}
}
} else if (currentWidget && !this->SearchMode) {
@@ -859,17 +841,9 @@ void cmCursesMainForm::HandleInput()
curField, "HELPSTRING");
}
if (helpString) {
- char* message = new char
- [strlen(curField) + strlen(helpString) +
- strlen(
- "Current option is: \n Help string for this option is: \n") +
- 10];
- sprintf(
- message,
- "Current option is: %s\nHelp string for this option is: %s\n",
- curField, helpString);
- this->HelpMessage[1] = message;
- delete[] message;
+ this->HelpMessage[1] =
+ cmStrCat("Current option is: ", curField, '\n',
+ "Help string for this option is: ", helpString, '\n');
} else {
this->HelpMessage[1] = "";
}
@@ -965,14 +939,14 @@ void cmCursesMainForm::HandleInput()
if (nextCur) {
// make the next or prev. current field after deletion
- auto nextEntryIt =
- std::find_if(this->Entries->begin(), this->Entries->end(),
- [&nextVal](cmCursesCacheEntryComposite* entry) {
- return nextVal == entry->Key;
- });
-
- if (nextEntryIt != this->Entries->end()) {
- set_current_field(this->Form, (*nextEntryIt)->Entry->Field);
+ auto nextEntryIt = std::find_if(
+ this->Entries.begin(), this->Entries.end(),
+ [&nextVal](cmCursesCacheEntryComposite const& entry) {
+ return nextVal == entry.Key;
+ });
+
+ if (nextEntryIt != this->Entries.end()) {
+ set_current_field(this->Form, nextEntryIt->Entry->Field);
}
}
}
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index d37997581..b8769b7cf 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -5,15 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmCursesCacheEntryComposite.h"
#include "cmCursesForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmStateTypes.h"
-#include <stddef.h>
-#include <string>
-#include <vector>
-
-class cmCursesCacheEntryComposite;
class cmake;
/** \class cmCursesMainForm
@@ -122,7 +123,7 @@ protected:
void JumpToCacheEntry(const char* str);
// Copies of cache entries stored in the user interface
- std::vector<cmCursesCacheEntryComposite*>* Entries;
+ std::vector<cmCursesCacheEntryComposite> Entries;
// Errors produced during last run of cmake
std::vector<std::string> Errors;
// Command line arguments to be passed to cmake each time
@@ -136,11 +137,7 @@ protected:
static const char* s_ConstHelpMessage;
// Fields displayed. Includes labels, new entry markers, entries
- FIELD** Fields;
- // Where is source of current project
- std::string WhereSource;
- // Where is cmake executable
- std::string WhereCMake;
+ std::vector<FIELD*> Fields;
// Number of entries shown (depends on mode -normal or advanced-)
size_t NumberOfVisibleEntries;
bool AdvancedMode;
@@ -150,7 +147,7 @@ protected:
int NumberOfPages;
int InitialWidth;
- cmake* CMakeInstance;
+ std::unique_ptr<cmake> CMakeInstance;
std::string SearchString;
std::string OldSearchString;
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h
index 0128d6a42..0de8e6407 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.h
+++ b/Source/CursesDialog/cmCursesOptionsWidget.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCursesStandardIncludes.h"
-#include "cmCursesWidget.h"
-
#include <string>
#include <vector>
+#include "cmCursesStandardIncludes.h"
+#include "cmCursesWidget.h"
+
class cmCursesMainForm;
class cmCursesOptionsWidget : public cmCursesWidget
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
index 05c3279c3..bb3808e89 100644
--- a/Source/CursesDialog/cmCursesPathWidget.cxx
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesPathWidget.h"
+#include <vector>
+
#include "cmCursesMainForm.h"
#include "cmCursesStringWidget.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
-#include <vector>
-
cmCursesPathWidget::cmCursesPathWidget(int width, int height, int left,
int top)
: cmCursesStringWidget(width, height, left, top)
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
index 1eace03a6..fb365e9c5 100644
--- a/Source/CursesDialog/cmCursesPathWidget.h
+++ b/Source/CursesDialog/cmCursesPathWidget.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmCursesStandardIncludes.h"
#include "cmCursesStringWidget.h"
-#include <string>
-
class cmCursesMainForm;
class cmCursesPathWidget : public cmCursesStringWidget
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index 5e2a329d9..6296af20b 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -2,15 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesStringWidget.h"
+#include <cstdio>
+
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
-#include <stdio.h>
-#include <string.h>
-
inline int ctrl(int z)
{
return (z & 037);
@@ -35,13 +34,13 @@ void cmCursesStringWidget::OnTab(cmCursesMainForm* /*unused*/,
void cmCursesStringWidget::OnReturn(cmCursesMainForm* fm, WINDOW* /*unused*/)
{
- FORM* form = fm->GetForm();
if (this->InEdit) {
cmCursesForm::LogMessage("String widget leaving edit.");
this->InEdit = false;
fm->PrintKeys();
- delete[] this->OriginalString;
+ this->OriginalString.clear();
// trick to force forms to update the field buffer
+ FORM* form = fm->GetForm();
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_PREV_FIELD);
this->Done = true;
@@ -49,9 +48,7 @@ void cmCursesStringWidget::OnReturn(cmCursesMainForm* fm, WINDOW* /*unused*/)
cmCursesForm::LogMessage("String widget entering edit.");
this->InEdit = true;
fm->PrintKeys();
- char* buf = field_buffer(this->Field, 0);
- this->OriginalString = new char[strlen(buf) + 1];
- strcpy(this->OriginalString, buf);
+ this->OriginalString = field_buffer(this->Field, 0);
}
}
@@ -64,7 +61,8 @@ void cmCursesStringWidget::OnType(int& key, cmCursesMainForm* fm,
bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
WINDOW* w)
{
- int x, y;
+ int x;
+ int y;
FORM* form = fm->GetForm();
// when not in edit mode, edit mode is entered by pressing enter or i (vim
@@ -74,7 +72,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
return false;
}
- this->OriginalString = nullptr;
+ this->OriginalString.clear();
this->Done = false;
char debugMessage[128];
@@ -112,7 +110,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
key == ctrl('p') || key == KEY_NPAGE || key == ctrl('d') ||
key == KEY_PPAGE || key == ctrl('u')) {
this->InEdit = false;
- delete[] this->OriginalString;
+ this->OriginalString.clear();
// trick to force forms to update the field buffer
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_PREV_FIELD);
@@ -124,7 +122,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
this->InEdit = false;
fm->PrintKeys();
this->SetString(this->OriginalString);
- delete[] this->OriginalString;
+ this->OriginalString.clear();
touchwin(w);
wrefresh(w);
return true;
@@ -179,30 +177,26 @@ const char* cmCursesStringWidget::GetValue()
bool cmCursesStringWidget::PrintKeys()
{
- int x, y;
+ int x;
+ int y;
getmaxyx(stdscr, y, x);
if (x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT) {
return false;
}
if (this->InEdit) {
char fmt_s[] = "%s";
- char firstLine[512];
// Clean the toolbar
- memset(firstLine, ' ', sizeof(firstLine));
- firstLine[511] = '\0';
curses_move(y - 4, 0);
- printw(fmt_s, firstLine);
- curses_move(y - 3, 0);
- printw(fmt_s, firstLine);
- curses_move(y - 2, 0);
- printw(fmt_s, firstLine);
- curses_move(y - 1, 0);
- printw(fmt_s, firstLine);
-
+ clrtoeol();
curses_move(y - 3, 0);
printw(fmt_s, "Editing option, press [enter] to confirm");
+ clrtoeol();
curses_move(y - 2, 0);
printw(fmt_s, " press [esc] to cancel");
+ clrtoeol();
+ curses_move(y - 1, 0);
+ clrtoeol();
+
return true;
}
return false;
diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h
index 021515ba3..ce06c6da7 100644
--- a/Source/CursesDialog/cmCursesStringWidget.h
+++ b/Source/CursesDialog/cmCursesStringWidget.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmCursesStandardIncludes.h"
#include "cmCursesWidget.h"
-#include <string>
-
class cmCursesMainForm;
/** \class cmCursesStringWidget
@@ -23,9 +23,6 @@ class cmCursesStringWidget : public cmCursesWidget
public:
cmCursesStringWidget(int width, int height, int left, int top);
- cmCursesStringWidget(cmCursesStringWidget const&) = delete;
- cmCursesStringWidget& operator=(cmCursesStringWidget const&) = delete;
-
/**
* Handle user input. Called by the container of this widget
* when this widget has focus. Returns true if the input was
@@ -65,7 +62,7 @@ public:
protected:
// true if the widget is in edit mode
bool InEdit;
- char* OriginalString;
+ std::string OriginalString;
bool Done;
};
diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h
index f761f6d8a..9d03c6e42 100644
--- a/Source/CursesDialog/cmCursesWidget.h
+++ b/Source/CursesDialog/cmCursesWidget.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmCursesStandardIncludes.h"
#include "cmStateTypes.h"
-#include <string>
-
class cmCursesMainForm;
class cmCursesWidget
diff --git a/Source/LexerParser/cmCTestResourceGroupsLexer.cxx b/Source/LexerParser/cmCTestResourceGroupsLexer.cxx
new file mode 100644
index 000000000..de07c4693
--- /dev/null
+++ b/Source/LexerParser/cmCTestResourceGroupsLexer.cxx
@@ -0,0 +1,2224 @@
+#include "cmStandardLexer.h"
+
+#define FLEXINT_H 1
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+#define cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmCTestResourceGroups_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmCTestResourceGroups_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmCTestResourceGroups_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmCTestResourceGroups_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmCTestResourceGroups_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmCTestResourceGroups_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmCTestResourceGroups_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmCTestResourceGroups_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmCTestResourceGroups_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmCTestResourceGroups_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmCTestResourceGroups_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmCTestResourceGroups_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmCTestResourceGroups_yylex_ALREADY_DEFINED
+#else
+#define yylex cmCTestResourceGroups_yylex
+#endif
+
+#ifdef yyrestart
+#define cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmCTestResourceGroups_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmCTestResourceGroups_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmCTestResourceGroups_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmCTestResourceGroups_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmCTestResourceGroups_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmCTestResourceGroups_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmCTestResourceGroups_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmCTestResourceGroups_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmCTestResourceGroups_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmCTestResourceGroups_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmCTestResourceGroups_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmCTestResourceGroups_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmCTestResourceGroups_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmCTestResourceGroups_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmCTestResourceGroups_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmCTestResourceGroups_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmCTestResourceGroups_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmCTestResourceGroups_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmCTestResourceGroups_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmCTestResourceGroups_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmCTestResourceGroups_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmCTestResourceGroups_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmCTestResourceGroups_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmCTestResourceGroups_yyfree
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
+
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define cmCTestResourceGroups_yywrap(yyscanner) (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+#define YY_NUM_RULES 8
+#define YY_END_OF_BUFFER 9
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[29] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 7, 2, 5, 7, 4, 6, 3,
+ 2, 5, 0, 1, 4, 6, 3, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 1, 1, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 5, 6, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 7, 1, 7, 7, 7, 7,
+
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const YY_CHAR yy_meta[8] =
+ { 0,
+ 1, 1, 1, 2, 2, 1, 2
+ } ;
+
+static const flex_int16_t yy_base[30] =
+ { 0,
+ 0, 0, 0, 0, 7, 0, 31, 12, 17, 0,
+ 0, 0, 34, 36, 29, 26, 26, 27, 23, 24,
+ 23, 20, 20, 36, 21, 16, 13, 36, 14
+ } ;
+
+static const flex_int16_t yy_def[30] =
+ { 0,
+ 28, 1, 1, 1, 28, 5, 1, 5, 5, 9,
+ 5, 5, 28, 28, 28, 28, 29, 28, 28, 28,
+ 28, 28, 29, 28, 28, 28, 28, 0, 28
+ } ;
+
+static const flex_int16_t yy_nxt[44] =
+ { 0,
+ 14, 14, 14, 15, 14, 16, 17, 14, 14, 18,
+ 14, 14, 19, 14, 14, 23, 27, 16, 17, 14,
+ 20, 26, 14, 25, 24, 22, 21, 27, 26, 25,
+ 24, 22, 21, 28, 14, 13, 28, 28, 28, 28,
+ 28, 28, 28
+ } ;
+
+static const flex_int16_t yy_chk[44] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 5, 5, 5,
+ 5, 5, 5, 5, 8, 29, 27, 8, 8, 9,
+ 9, 26, 9, 25, 23, 22, 21, 20, 19, 18,
+ 17, 16, 15, 13, 7, 28, 28, 28, 28, 28,
+ 28, 28, 28
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+/*
+
+This file must be translated to C++ and modified to build everywhere.
+
+Run flex >= 2.6 like this:
+
+ flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestResourceGroupsLexer.h -ocmCTestResourceGroupsLexer.cxx cmCTestResourceGroupsLexer.in.l
+
+Modify cmCTestResourceGroupsLexer.cxx:
+ - remove trailing whitespace: sed -i 's/\s*$//' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
+ - remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
+ - #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestResourceGroupsLexer.cxx
+
+*/
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include "cmCTestResourceGroupsLexerHelper.h"
+
+#include <string>
+
+#include <cstddef>
+
+/*--------------------------------------------------------------------------*/
+
+#define INITIAL 0
+#define RESOURCE_GROUPS_START 1
+#define RESOURCE_GROUPS_END 2
+#define RESOURCE_START 3
+#define RESOURCE_COUNT 4
+#define RESOURCE_END 5
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals ( yyscan_t yyscanner );
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( yyscan_t yyscanner );
+
+int yyget_debug ( yyscan_t yyscanner );
+
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+
+FILE *yyget_in ( yyscan_t yyscanner );
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+char *yyget_text ( yyscan_t yyscanner );
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+int yyget_column ( yyscan_t yyscanner );
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( yyscan_t yyscanner );
+#else
+extern int yywrap ( yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( yyscan_t yyscanner );
+#else
+static int input ( yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (yyscan_t yyscanner);
+
+#define YY_DECL int yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+ }
+
+ yy_load_buffer_state( yyscanner );
+ }
+
+ {
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 29 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 36 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_COUNT);
+ yyextra->SetResourceType(std::string(yytext, yyleng - 1));
+}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_GROUPS_END);
+ std::size_t len = yyleng;
+ yyextra->SetProcessCount(std::stoll(yytext, &len, 10));
+}
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_END);
+ std::size_t len = yyleng;
+ yyextra->SetNeededSlots(std::stoll(yytext, &len, 10));
+ yyextra->WriteRequirement();
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_START);
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_GROUPS_START);
+}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+{
+ BEGIN(RESOURCE_GROUPS_START);
+ yyextra->WriteProcess();
+}
+ YY_BREAK
+case YY_STATE_EOF(RESOURCE_START):
+case YY_STATE_EOF(RESOURCE_GROUPS_END):
+case YY_STATE_EOF(RESOURCE_END):
+{
+ yyextra->WriteProcess();
+ return 0;
+}
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(RESOURCE_GROUPS_START):
+{
+ return 0;
+}
+ YY_BREAK
+case YY_STATE_EOF(RESOURCE_COUNT):
+{
+ return 1;
+}
+ YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+{
+ return 1;
+}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap( yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin , yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 29 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 29 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 28);
+
+ (void)yyg;
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
+{
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ int number_to_move = yyg->yy_n_chars + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin , yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( yyscanner ) )
+ return 0;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file , yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
+
+ yyfree( (void *) b , yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_flush_buffer( b , yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b , yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n , yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int _line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
+
+ yylineno = _line_number;
+}
+
+/** Set the current column.
+ * @param _column_no column number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int _column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "yyset_column called with no buffer" );
+
+ yycolumn = _column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = _out_str ;
+}
+
+int yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = _bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+int yylex_init(yyscan_t* ptr_yy_globals)
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = NULL;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = NULL;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack , yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree( yyg->yy_start_stack , yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+/*--------------------------------------------------------------------------*/
+
+#endif /* __clang_analyzer__ */
diff --git a/Source/LexerParser/cmCTestResourceGroupsLexer.h b/Source/LexerParser/cmCTestResourceGroupsLexer.h
new file mode 100644
index 000000000..e323a5089
--- /dev/null
+++ b/Source/LexerParser/cmCTestResourceGroupsLexer.h
@@ -0,0 +1,692 @@
+#ifndef cmCTestResourceGroups_yyHEADER_H
+#define cmCTestResourceGroups_yyHEADER_H 1
+#define cmCTestResourceGroups_yyIN_HEADER 1
+
+#define FLEXINT_H 1
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+#define cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmCTestResourceGroups_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmCTestResourceGroups_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmCTestResourceGroups_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmCTestResourceGroups_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmCTestResourceGroups_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmCTestResourceGroups_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmCTestResourceGroups_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmCTestResourceGroups_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmCTestResourceGroups_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmCTestResourceGroups_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmCTestResourceGroups_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmCTestResourceGroups_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmCTestResourceGroups_yylex_ALREADY_DEFINED
+#else
+#define yylex cmCTestResourceGroups_yylex
+#endif
+
+#ifdef yyrestart
+#define cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmCTestResourceGroups_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmCTestResourceGroups_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmCTestResourceGroups_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmCTestResourceGroups_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmCTestResourceGroups_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmCTestResourceGroups_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmCTestResourceGroups_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmCTestResourceGroups_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmCTestResourceGroups_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmCTestResourceGroups_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmCTestResourceGroups_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmCTestResourceGroups_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmCTestResourceGroups_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmCTestResourceGroups_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmCTestResourceGroups_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmCTestResourceGroups_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmCTestResourceGroups_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmCTestResourceGroups_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmCTestResourceGroups_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmCTestResourceGroups_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmCTestResourceGroups_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmCTestResourceGroups_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmCTestResourceGroups_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmCTestResourceGroups_yyfree
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmCTestResourceGroups_yywrap(yyscanner) (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define RESOURCE_GROUPS_START 1
+#define RESOURCE_GROUPS_END 2
+#define RESOURCE_START 3
+#define RESOURCE_COUNT 4
+#define RESOURCE_END 5
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( yyscan_t yyscanner );
+
+int yyget_debug ( yyscan_t yyscanner );
+
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+
+FILE *yyget_in ( yyscan_t yyscanner );
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+char *yyget_text ( yyscan_t yyscanner );
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+int yyget_column ( yyscan_t yyscanner );
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( yyscan_t yyscanner );
+#else
+extern int yywrap ( yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (yyscan_t yyscanner);
+
+#define YY_DECL int yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#ifndef cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
+#undef yy_create_buffer
+#endif
+#ifndef cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
+#undef yy_delete_buffer
+#endif
+#ifndef cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
+#undef yy_scan_buffer
+#endif
+#ifndef cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
+#undef yy_scan_string
+#endif
+#ifndef cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
+#undef yy_scan_bytes
+#endif
+#ifndef cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
+#undef yy_init_buffer
+#endif
+#ifndef cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
+#undef yy_flush_buffer
+#endif
+#ifndef cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
+#undef yy_load_buffer_state
+#endif
+#ifndef cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
+#undef yy_switch_to_buffer
+#endif
+#ifndef cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
+#undef yypush_buffer_state
+#endif
+#ifndef cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
+#undef yypop_buffer_state
+#endif
+#ifndef cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
+#undef yyensure_buffer_stack
+#endif
+#ifndef cmCTestResourceGroups_yylex_ALREADY_DEFINED
+#undef yylex
+#endif
+#ifndef cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
+#undef yyrestart
+#endif
+#ifndef cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
+#undef yylex_init
+#endif
+#ifndef cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
+#undef yylex_init_extra
+#endif
+#ifndef cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
+#undef yylex_destroy
+#endif
+#ifndef cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
+#undef yyget_debug
+#endif
+#ifndef cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
+#undef yyset_debug
+#endif
+#ifndef cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
+#undef yyget_extra
+#endif
+#ifndef cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
+#undef yyset_extra
+#endif
+#ifndef cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
+#undef yyget_in
+#endif
+#ifndef cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
+#undef yyset_in
+#endif
+#ifndef cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
+#undef yyget_out
+#endif
+#ifndef cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
+#undef yyset_out
+#endif
+#ifndef cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
+#undef yyget_leng
+#endif
+#ifndef cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
+#undef yyget_text
+#endif
+#ifndef cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
+#undef yyget_lineno
+#endif
+#ifndef cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
+#undef yyset_lineno
+#endif
+#ifndef cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
+#undef yyget_column
+#endif
+#ifndef cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
+#undef yyset_column
+#endif
+#ifndef cmCTestResourceGroups_yywrap_ALREADY_DEFINED
+#undef yywrap
+#endif
+#ifndef cmCTestResourceGroups_yyget_lval_ALREADY_DEFINED
+#undef yyget_lval
+#endif
+#ifndef cmCTestResourceGroups_yyset_lval_ALREADY_DEFINED
+#undef yyset_lval
+#endif
+#ifndef cmCTestResourceGroups_yyget_lloc_ALREADY_DEFINED
+#undef yyget_lloc
+#endif
+#ifndef cmCTestResourceGroups_yyset_lloc_ALREADY_DEFINED
+#undef yyset_lloc
+#endif
+#ifndef cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
+#undef yyalloc
+#endif
+#ifndef cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
+#undef yyrealloc
+#endif
+#ifndef cmCTestResourceGroups_yyfree_ALREADY_DEFINED
+#undef yyfree
+#endif
+#ifndef cmCTestResourceGroups_yytext_ALREADY_DEFINED
+#undef yytext
+#endif
+#ifndef cmCTestResourceGroups_yyleng_ALREADY_DEFINED
+#undef yyleng
+#endif
+#ifndef cmCTestResourceGroups_yyin_ALREADY_DEFINED
+#undef yyin
+#endif
+#ifndef cmCTestResourceGroups_yyout_ALREADY_DEFINED
+#undef yyout
+#endif
+#ifndef cmCTestResourceGroups_yy_flex_debug_ALREADY_DEFINED
+#undef yy_flex_debug
+#endif
+#ifndef cmCTestResourceGroups_yylineno_ALREADY_DEFINED
+#undef yylineno
+#endif
+#ifndef cmCTestResourceGroups_yytables_fload_ALREADY_DEFINED
+#undef yytables_fload
+#endif
+#ifndef cmCTestResourceGroups_yytables_destroy_ALREADY_DEFINED
+#undef yytables_destroy
+#endif
+#ifndef cmCTestResourceGroups_yyTABLES_NAME_ALREADY_DEFINED
+#undef yyTABLES_NAME
+#endif
+
+#undef cmCTestResourceGroups_yyIN_HEADER
+#endif /* cmCTestResourceGroups_yyHEADER_H */
diff --git a/Source/LexerParser/cmCTestResourceGroupsLexer.in.l b/Source/LexerParser/cmCTestResourceGroupsLexer.in.l
new file mode 100644
index 000000000..2aabea48d
--- /dev/null
+++ b/Source/LexerParser/cmCTestResourceGroupsLexer.in.l
@@ -0,0 +1,102 @@
+%{
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+/*
+
+This file must be translated to C++ and modified to build everywhere.
+
+Run flex >= 2.6 like this:
+
+ flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestResourceGroupsLexer.h -ocmCTestResourceGroupsLexer.cxx cmCTestResourceGroupsLexer.in.l
+
+Modify cmCTestResourceGroupsLexer.cxx:
+ - remove trailing whitespace: sed -i 's/\s*$//' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
+ - remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
+ - #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestResourceGroupsLexer.cxx
+
+*/
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include "cmCTestResourceGroupsLexerHelper.h"
+
+#include <string>
+
+#include <cstddef>
+
+/*--------------------------------------------------------------------------*/
+%}
+
+%option prefix="cmCTestResourceGroups_yy"
+
+%option reentrant
+%option noyywrap
+%option nodefault
+%pointer
+
+%s RESOURCE_GROUPS_START
+%s RESOURCE_GROUPS_END
+%s RESOURCE_START
+%s RESOURCE_COUNT
+%s RESOURCE_END
+
+NUMBER [0-9]+
+IDENTIFIER [a-z_][a-z0-9_]*
+
+%%
+
+<INITIAL,RESOURCE_GROUPS_START,RESOURCE_START>{IDENTIFIER}: {
+ BEGIN(RESOURCE_COUNT);
+ yyextra->SetResourceType(std::string(yytext, yyleng - 1));
+}
+
+<INITIAL,RESOURCE_GROUPS_START>{NUMBER} {
+ BEGIN(RESOURCE_GROUPS_END);
+ std::size_t len = yyleng;
+ yyextra->SetProcessCount(std::stoll(yytext, &len, 10));
+}
+
+<RESOURCE_COUNT>{NUMBER} {
+ BEGIN(RESOURCE_END);
+ std::size_t len = yyleng;
+ yyextra->SetNeededSlots(std::stoll(yytext, &len, 10));
+ yyextra->WriteRequirement();
+}
+
+<RESOURCE_GROUPS_END,RESOURCE_END>,+ {
+ BEGIN(RESOURCE_START);
+}
+
+<INITIAL,RESOURCE_GROUPS_START,RESOURCE_START>;+ {
+ BEGIN(RESOURCE_GROUPS_START);
+}
+
+<RESOURCE_GROUPS_END,RESOURCE_END>;+ {
+ BEGIN(RESOURCE_GROUPS_START);
+ yyextra->WriteProcess();
+}
+
+<RESOURCE_START,RESOURCE_GROUPS_END,RESOURCE_END><<EOF>> {
+ yyextra->WriteProcess();
+ return 0;
+}
+
+<INITIAL,RESOURCE_GROUPS_START><<EOF>> {
+ return 0;
+}
+
+<<EOF>> {
+ return 1;
+}
+
+.|\n {
+ return 1;
+}
+
+%%
+
+/*--------------------------------------------------------------------------*/
+
+#endif /* __clang_analyzer__ */
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index b965b32e8..ae7fb42ea 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
#define yynerrs cmCommandArgument_yynerrs
-/* Copy the first part of user declarations. */
-#line 1 "cmCommandArgumentParser.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 1 "cmCommandArgumentParser.y" /* yacc.c:337 */
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -130,13 +134,16 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 134 "cmCommandArgumentParser.cxx" /* yacc.c:339 */
-
+#line 138 "cmCommandArgumentParser.cxx" /* yacc.c:337 */
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -201,9 +208,7 @@ int cmCommandArgument_yyparse (yyscan_t yyscanner);
#endif /* !YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 207 "cmCommandArgumentParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -224,13 +229,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
-typedef short int yytype_int16;
+typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -242,7 +247,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
@@ -278,15 +283,6 @@ typedef short int yytype_int16;
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
-# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
@@ -294,7 +290,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -456,16 +452,16 @@ union yyalloc
/* YYNSTATES -- Number of states. */
#define YYNSTATES 33
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 269
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
+ as returned by yylex. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -513,7 +509,7 @@ static const yytype_uint8 yyrline[] =
static const char *const yytname[] =
{
"$end", "error", "$undefined", "cal_ENVCURLY", "cal_NCURLY",
- "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", R"("\\")",
+ "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", "\"\\\\\"",
"cal_SYMBOL", "\"@\"", "cal_ERROR", "cal_ATNAME", "$accept", "Start",
"GoalWithOptionalBackSlash", "Goal", "String", "OuterText", "Variable",
"EnvVarName", "MultipleIds", "ID", YY_NULLPTR
@@ -633,22 +629,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (yyscanner, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
/* Error token number */
#define YYTERROR 1
@@ -688,38 +684,38 @@ do { \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
YYUSE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
YYUSE (yytype);
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- YYFPRINTF (yyoutput, "%s %s (",
+ YYFPRINTF (yyo, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -753,7 +749,7 @@ do { \
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
{
- unsigned long int yylno = yyrline[yyrule];
+ unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -764,7 +760,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
+ &yyvsp[(yyi + 1) - (yynrhs)]
, yyscanner);
YYFPRINTF (stderr, "\n");
}
@@ -868,7 +864,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -886,7 +885,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres)
return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -964,10 +963,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
}
}
@@ -979,6 +978,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -990,9 +990,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
if (*yymsg_alloc < yysize)
@@ -1123,23 +1124,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
@@ -1155,14 +1164,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -1178,22 +1183,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1202,11 +1207,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -1279,7 +1284,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -1300,192 +1305,192 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 99 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 99 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
-#line 1309 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1314 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 3:
-#line 105 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 105 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1317 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1322 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 4:
-#line 108 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 108 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1325 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1330 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 5:
-#line 113 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 113 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = 0;
}
-#line 1333 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1338 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 6:
-#line 116 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 116 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1341 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1346 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 7:
-#line 121 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 121 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1349 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1354 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 8:
-#line 124 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 124 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1357 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1362 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 9:
-#line 129 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 129 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1365 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1370 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 10:
-#line 132 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 132 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1373 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1378 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 11:
-#line 135 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 135 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1381 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1386 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 12:
-#line 138 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 138 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1389 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1394 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 13:
-#line 141 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 141 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1397 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1402 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 14:
-#line 144 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 144 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1405 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1410 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 15:
-#line 149 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 149 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1413 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1418 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 16:
-#line 152 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 152 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1421 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1426 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 17:
-#line 155 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 155 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
-#line 1429 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1434 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 18:
-#line 158 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 158 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
-#line 1437 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1442 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 19:
-#line 163 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 163 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1445 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1450 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 20:
-#line 166 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 166 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[-1].str);
}
-#line 1453 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1458 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 21:
-#line 171 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 171 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = 0;
}
-#line 1461 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1466 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 22:
-#line 174 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 174 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1469 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1474 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 23:
-#line 179 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 179 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1477 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1482 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
case 24:
-#line 182 "cmCommandArgumentParser.y" /* yacc.c:1646 */
+#line 182 "cmCommandArgumentParser.y" /* yacc.c:1652 */
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1485 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1490 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
break;
-#line 1489 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */
+#line 1494 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1510,14 +1515,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -1601,12 +1605,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1669,6 +1671,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -1676,6 +1679,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
+
#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
@@ -1686,6 +1690,10 @@ yyexhaustedlab:
/* Fall through. */
#endif
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -1715,7 +1723,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 187 "cmCommandArgumentParser.y" /* yacc.c:1906 */
+#line 187 "cmCommandArgumentParser.y" /* yacc.c:1918 */
/* End of grammar */
diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h
index 3172182d7..56c9794f9 100644
--- a/Source/LexerParser/cmCommandArgumentParserTokens.h
+++ b/Source/LexerParser/cmCommandArgumentParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
#ifndef YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
# define YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
/* Debug traces. */
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index e83afa9ea..6c1fb2cb3 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
#define yynerrs cmDependsJava_yynerrs
-/* Copy the first part of user declarations. */
-#line 1 "cmDependsJavaParser.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 1 "cmDependsJavaParser.y" /* yacc.c:337 */
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -119,13 +123,16 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 123 "cmDependsJavaParser.cxx" /* yacc.c:339 */
-
+#line 127 "cmDependsJavaParser.cxx" /* yacc.c:337 */
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -372,9 +379,7 @@ int cmDependsJava_yyparse (yyscan_t yyscanner);
#endif /* !YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 378 "cmDependsJavaParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -395,13 +400,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
-typedef short int yytype_int16;
+typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -413,7 +418,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
@@ -449,15 +454,6 @@ typedef short int yytype_int16;
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
-# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
@@ -465,7 +461,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -627,16 +623,16 @@ union yyalloc
/* YYNSTATES -- Number of states. */
#define YYNSTATES 575
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 360
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
+ as returned by yylex. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -1618,22 +1614,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (yyscanner, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
/* Error token number */
#define YYTERROR 1
@@ -1673,38 +1669,38 @@ do { \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
YYUSE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
YYUSE (yytype);
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- YYFPRINTF (yyoutput, "%s %s (",
+ YYFPRINTF (yyo, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -1738,7 +1734,7 @@ do { \
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
{
- unsigned long int yylno = yyrline[yyrule];
+ unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -1749,7 +1745,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
+ &yyvsp[(yyi + 1) - (yynrhs)]
, yyscanner);
YYFPRINTF (stderr, "\n");
}
@@ -1853,7 +1849,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -1871,7 +1870,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres)
return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -1949,10 +1948,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
}
}
@@ -1964,6 +1963,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1975,9 +1975,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
if (*yymsg_alloc < yysize)
@@ -2108,23 +2109,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
@@ -2140,14 +2149,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -2163,22 +2168,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -2187,11 +2192,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -2264,7 +2269,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -2285,214 +2290,214 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 183 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 183 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 3:
-#line 192 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 192 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2307 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2312 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 4:
-#line 200 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 200 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2318 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2323 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 5:
-#line 208 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 208 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2329 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2334 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 6:
-#line 216 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 216 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2340 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2345 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 7:
-#line 224 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 224 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2351 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2356 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 8:
-#line 232 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 232 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2362 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 9:
-#line 241 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 241 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2373 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 10:
-#line 249 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 249 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2384 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2389 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 11:
-#line 258 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 258 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2395 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2400 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 12:
-#line 266 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 266 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2406 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2411 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 13:
-#line 275 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 275 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2414 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2419 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 14:
-#line 280 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 280 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2422 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2427 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 15:
-#line 285 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 285 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2430 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 16:
-#line 290 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 290 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2438 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2443 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 17:
-#line 295 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 295 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2446 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2451 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 18:
-#line 300 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 300 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2454 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2459 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 19:
-#line 305 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 305 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2462 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2467 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 20:
-#line 310 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 310 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
}
-#line 2470 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2475 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 21:
-#line 316 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 316 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2481 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2486 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 22:
-#line 324 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 324 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2492 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2497 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 23:
-#line 333 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 333 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpStoreClass((yyvsp[0].str));
@@ -2500,44 +2505,44 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2504 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 24:
-#line 343 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 343 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2515 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 25:
-#line 352 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 352 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2526 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2531 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 26:
-#line 361 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 361 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2537 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2542 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 27:
-#line 369 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 369 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpStoreClass((yyvsp[-1].str));
@@ -2545,56 +2550,56 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2549 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2554 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 28:
-#line 379 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 379 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2558 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 29:
-#line 385 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 385 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2567 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2572 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 30:
-#line 392 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 392 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2576 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2581 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 31:
-#line 399 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 399 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2585 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2590 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 32:
-#line 405 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 405 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
(yyval.str) = (yyvsp[0].str);
}
-#line 2594 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2599 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 33:
-#line 412 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 412 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2602,11 +2607,11 @@ yyreduce:
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
(yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
}
-#line 2606 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2611 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 34:
-#line 421 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 421 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2615,11 +2620,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2619 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2624 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 35:
-#line 431 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 431 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2628,118 +2633,118 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2632 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 36:
-#line 441 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 441 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2643 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2648 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 37:
-#line 450 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 450 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2654 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2659 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 38:
-#line 458 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 458 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2665 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 39:
-#line 467 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 467 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2676 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2681 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 40:
-#line 475 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 475 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2686 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 41:
-#line 482 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 482 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2697 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2702 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 42:
-#line 490 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 490 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2707 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2712 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 43:
-#line 497 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 497 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2718 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2723 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 44:
-#line 505 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 505 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2728 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2733 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 45:
-#line 512 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 512 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2739 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2744 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 46:
-#line 521 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 521 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2749,33 +2754,33 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2753 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2758 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 47:
-#line 533 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 533 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2764 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2769 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 48:
-#line 541 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 541 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2775 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2780 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 49:
-#line 550 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 550 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2785,11 +2790,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2789 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2794 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 50:
-#line 562 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 562 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
std::string str = (yyvsp[-3].str);
@@ -2800,77 +2805,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2804 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2809 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 51:
-#line 575 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 575 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2815 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 52:
-#line 583 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 583 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2826 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2831 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 53:
-#line 591 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 591 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2837 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2842 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 54:
-#line 600 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 600 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2848 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2853 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 55:
-#line 608 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 608 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2859 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2864 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 67:
-#line 623 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 623 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 2870 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2875 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 68:
-#line 633 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 633 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -2878,11 +2883,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2882 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2887 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 69:
-#line 642 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 642 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(2);
@@ -2890,11 +2895,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2894 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2899 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 70:
-#line 651 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 651 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -2902,11 +2907,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2906 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2911 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 71:
-#line 660 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 660 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -2914,226 +2919,226 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2918 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2923 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 72:
-#line 669 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 669 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2928 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2933 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 73:
-#line 676 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 676 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2939 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2944 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 74:
-#line 685 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 685 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2950 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2955 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 75:
-#line 694 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 694 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2961 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2966 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 76:
-#line 703 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 703 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2972 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2977 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 77:
-#line 711 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 711 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2983 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 78:
-#line 720 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 720 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2994 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 2999 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 79:
-#line 728 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 728 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3004 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3009 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 80:
-#line 735 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 735 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3015 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3020 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 81:
-#line 744 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 744 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3026 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 82:
-#line 752 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 752 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3037 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3042 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 83:
-#line 760 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 760 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3048 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3053 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 84:
-#line 768 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 768 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3059 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3064 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 85:
-#line 777 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 777 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3070 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3075 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 86:
-#line 785 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 785 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3081 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3086 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 87:
-#line 794 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 794 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
}
-#line 3089 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3094 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 88:
-#line 800 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 800 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3100 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 89:
-#line 808 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 808 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3111 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3116 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 90:
-#line 817 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 817 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3122 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 91:
-#line 825 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 825 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3133 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3138 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 92:
-#line 834 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 834 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3141,77 +3146,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3145 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 93:
-#line 843 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 843 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3156 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3161 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 94:
-#line 852 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 852 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3167 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 95:
-#line 860 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 860 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3178 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3183 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 96:
-#line 869 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 869 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3189 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3194 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 97:
-#line 877 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 877 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3200 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 98:
-#line 885 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 885 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3211 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3216 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 99:
-#line 894 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 894 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3219,11 +3224,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3223 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3228 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 100:
-#line 903 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 903 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3231,22 +3236,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3235 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3240 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 101:
-#line 912 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 912 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3246 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 102:
-#line 920 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 920 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3254,11 +3259,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3258 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3263 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 103:
-#line 930 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 930 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3267,40 +3272,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3271 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3276 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 104:
-#line 940 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 940 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
}
-#line 3280 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3285 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 105:
-#line 946 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 946 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3291 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3296 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 107:
-#line 957 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 957 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
}
-#line 3300 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3305 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 108:
-#line 963 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 963 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3308,11 +3313,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3312 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3317 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 109:
-#line 973 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 973 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3320,11 +3325,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3324 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3329 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 110:
-#line 983 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 983 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3332,20 +3337,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3336 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3341 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 111:
-#line 993 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 993 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
}
-#line 3345 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3350 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 112:
-#line 999 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 999 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3353,11 +3358,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3357 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3362 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 113:
-#line 1009 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1009 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3365,11 +3370,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3369 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3374 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 114:
-#line 1019 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1019 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3377,11 +3382,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3381 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3386 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 115:
-#line 1029 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1029 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3389,11 +3394,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3393 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3398 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 116:
-#line 1038 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1038 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3401,11 +3406,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3405 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3410 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 117:
-#line 1048 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1048 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3414,11 +3419,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3418 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3423 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 118:
-#line 1059 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1059 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3426,22 +3431,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3430 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 119:
-#line 1068 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1068 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3441 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3446 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 120:
-#line 1076 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1076 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3449,11 +3454,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3453 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3458 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 121:
-#line 1086 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1086 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3461,11 +3466,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3465 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3470 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 122:
-#line 1095 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1095 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3473,22 +3478,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3477 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 123:
-#line 1105 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1105 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3488 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 124:
-#line 1114 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1114 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3496,21 +3501,21 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3500 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 125:
-#line 1123 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1123 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3510 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3515 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 126:
-#line 1130 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1130 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3518,11 +3523,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3522 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3527 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 127:
-#line 1140 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1140 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3530,11 +3535,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3534 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3539 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 128:
-#line 1149 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1149 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3542,11 +3547,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3546 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3551 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 129:
-#line 1159 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1159 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3554,33 +3559,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3558 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 130:
-#line 1168 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1168 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3569 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 131:
-#line 1176 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1176 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3580 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3585 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 132:
-#line 1185 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1185 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3588,11 +3593,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3592 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3597 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 133:
-#line 1194 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1194 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3600,11 +3605,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3604 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3609 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 134:
-#line 1203 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1203 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3612,22 +3617,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3616 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3621 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 135:
-#line 1212 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1212 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3627 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3632 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 136:
-#line 1220 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1220 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3635,22 +3640,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3639 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3644 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 137:
-#line 1229 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1229 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3650 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3655 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 138:
-#line 1238 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1238 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3658,11 +3663,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3662 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3667 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 139:
-#line 1248 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1248 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3670,11 +3675,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3674 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3679 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 140:
-#line 1258 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1258 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3682,11 +3687,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3686 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 141:
-#line 1267 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1267 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3694,11 +3699,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3698 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3703 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 142:
-#line 1277 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1277 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3706,22 +3711,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3710 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3715 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 143:
-#line 1286 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1286 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3721 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3726 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 144:
-#line 1294 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1294 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3729,11 +3734,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3733 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3738 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 145:
-#line 1303 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1303 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3741,11 +3746,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3745 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3750 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 146:
-#line 1313 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1313 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3753,11 +3758,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3757 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3762 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 147:
-#line 1322 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1322 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3765,33 +3770,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3769 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3774 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 148:
-#line 1332 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1332 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3780 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3785 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 149:
-#line 1340 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1340 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3791 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3796 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 150:
-#line 1348 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1348 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3799,11 +3804,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3803 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3808 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 151:
-#line 1358 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1358 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3811,11 +3816,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3815 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 152:
-#line 1367 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1367 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3823,11 +3828,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3827 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3832 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 153:
-#line 1377 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1377 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3835,11 +3840,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3839 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3844 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 154:
-#line 1386 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1386 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3847,11 +3852,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3851 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3856 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 155:
-#line 1395 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1395 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3859,11 +3864,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3863 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3868 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 156:
-#line 1405 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1405 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3871,11 +3876,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3875 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3880 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 157:
-#line 1415 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1415 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(3);
@@ -3883,11 +3888,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3887 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 158:
-#line 1424 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1424 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3895,11 +3900,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3899 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 159:
-#line 1434 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1434 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3907,11 +3912,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3911 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 160:
-#line 1443 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1443 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3919,11 +3924,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3923 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 161:
-#line 1452 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1452 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3931,11 +3936,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3935 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 162:
-#line 1461 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1461 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3943,11 +3948,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3947 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 163:
-#line 1470 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1470 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3955,11 +3960,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3959 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 164:
-#line 1479 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1479 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3967,11 +3972,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3971 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3976 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 165:
-#line 1489 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1489 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3979,11 +3984,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3983 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 3988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 166:
-#line 1498 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1498 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3991,11 +3996,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3995 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4000 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 167:
-#line 1507 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1507 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4003,11 +4008,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4007 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4012 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 168:
-#line 1516 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1516 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4015,11 +4020,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4019 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4024 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 169:
-#line 1525 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1525 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4027,11 +4032,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4031 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4036 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 170:
-#line 1535 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1535 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4039,11 +4044,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4043 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4048 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 171:
-#line 1544 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1544 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4051,11 +4056,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4055 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4060 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 172:
-#line 1553 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1553 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4063,11 +4068,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4067 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4072 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 173:
-#line 1562 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1562 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4075,11 +4080,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4079 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4084 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 174:
-#line 1571 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1571 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4087,11 +4092,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4091 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4096 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 175:
-#line 1580 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1580 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4099,11 +4104,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4103 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4108 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 176:
-#line 1589 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1589 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4111,11 +4116,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4115 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4120 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 177:
-#line 1598 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1598 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4123,11 +4128,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4127 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4132 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 178:
-#line 1607 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1607 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4135,11 +4140,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4139 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4144 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 179:
-#line 1616 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1616 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4147,11 +4152,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4151 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4156 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 180:
-#line 1625 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1625 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4159,11 +4164,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4163 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4168 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 181:
-#line 1634 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1634 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4171,11 +4176,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4175 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4180 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 182:
-#line 1644 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1644 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4183,11 +4188,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4187 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 183:
-#line 1654 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1654 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4196,11 +4201,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4200 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 184:
-#line 1665 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1665 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4208,11 +4213,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4212 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4217 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 185:
-#line 1675 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1675 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4220,11 +4225,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4224 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4229 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 186:
-#line 1685 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1685 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4232,11 +4237,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4236 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4241 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 187:
-#line 1694 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1694 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4244,11 +4249,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4248 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4253 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 188:
-#line 1703 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1703 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4256,11 +4261,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4260 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4265 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 189:
-#line 1712 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1712 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4268,11 +4273,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4272 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 190:
-#line 1721 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1721 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4280,11 +4285,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4284 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 191:
-#line 1730 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1730 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4292,11 +4297,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 192:
-#line 1739 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1739 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4304,11 +4309,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4308 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 193:
-#line 1749 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1749 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4316,11 +4321,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4320 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 194:
-#line 1759 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1759 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4328,11 +4333,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4332 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 195:
-#line 1769 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1769 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4340,40 +4345,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4344 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 196:
-#line 1779 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1779 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
}
-#line 4353 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4358 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 197:
-#line 1786 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1786 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
}
-#line 4362 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 198:
-#line 1792 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1792 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4373 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 199:
-#line 1800 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1800 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4381,22 +4386,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4385 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4390 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 200:
-#line 1809 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1809 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4396 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4401 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 201:
-#line 1817 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1817 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4404,11 +4409,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4408 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4413 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 202:
-#line 1827 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1827 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4416,11 +4421,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4420 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4425 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 203:
-#line 1837 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1837 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4428,11 +4433,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4432 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4437 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 204:
-#line 1846 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1846 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4440,11 +4445,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4444 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4449 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 205:
-#line 1856 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1856 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4452,11 +4457,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4456 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4461 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 206:
-#line 1865 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1865 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4464,58 +4469,58 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4468 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4473 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 207:
-#line 1875 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1875 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
}
-#line 4477 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 208:
-#line 1882 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1882 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
}
-#line 4486 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4491 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 209:
-#line 1889 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1889 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(7);
}
-#line 4495 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4500 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 210:
-#line 1897 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1897 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(9);
}
-#line 4504 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 211:
-#line 1903 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1903 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4515 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 212:
-#line 1911 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1911 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4523,22 +4528,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4527 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4532 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 213:
-#line 1920 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1920 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4538 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4543 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 214:
-#line 1928 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1928 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4546,33 +4551,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4550 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4555 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 215:
-#line 1939 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1939 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(9);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4561 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4566 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 216:
-#line 1947 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1947 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4572 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4577 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 217:
-#line 1955 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1955 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4580,11 +4585,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4584 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4589 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 218:
-#line 1965 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1965 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4592,11 +4597,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4596 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4601 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 219:
-#line 1974 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1974 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4604,11 +4609,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4608 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4613 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 220:
-#line 1984 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1984 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4616,11 +4621,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4620 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4625 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 221:
-#line 1994 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 1994 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4628,11 +4633,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4632 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 222:
-#line 2003 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2003 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4640,11 +4645,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4644 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4649 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 223:
-#line 2013 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2013 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4652,11 +4657,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4656 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4661 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 224:
-#line 2022 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2022 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4664,11 +4669,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4668 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4673 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 225:
-#line 2032 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2032 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4677,31 +4682,31 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4681 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4686 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 226:
-#line 2042 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2042 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4692 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4697 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 227:
-#line 2050 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2050 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
}
-#line 4701 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 228:
-#line 2057 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2057 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4710,11 +4715,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4714 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4719 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 229:
-#line 2068 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2068 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4722,11 +4727,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4726 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4731 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 230:
-#line 2078 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2078 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4734,11 +4739,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4738 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4743 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 231:
-#line 2088 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2088 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4746,11 +4751,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4750 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4755 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 232:
-#line 2098 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2098 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4758,11 +4763,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4762 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4767 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 233:
-#line 2107 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2107 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -4770,22 +4775,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4774 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4779 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 234:
-#line 2116 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2116 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4785 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 235:
-#line 2124 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2124 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4793,11 +4798,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4797 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 236:
-#line 2134 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2134 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4805,11 +4810,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4809 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 237:
-#line 2143 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2143 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4817,20 +4822,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4821 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 238:
-#line 2153 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2153 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
}
-#line 4830 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4835 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 239:
-#line 2160 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2160 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4838,11 +4843,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4842 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4847 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 240:
-#line 2170 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2170 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4850,11 +4855,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4854 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4859 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 241:
-#line 2179 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2179 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4862,11 +4867,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4866 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4871 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 242:
-#line 2189 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2189 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4874,20 +4879,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4878 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4883 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 243:
-#line 2198 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2198 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
}
-#line 4887 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 244:
-#line 2204 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2204 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4895,11 +4900,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4899 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 245:
-#line 2213 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2213 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4907,11 +4912,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4911 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 246:
-#line 2222 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2222 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4919,11 +4924,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4923 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 247:
-#line 2231 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2231 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4931,11 +4936,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4935 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 248:
-#line 2240 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2240 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4943,11 +4948,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4947 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 249:
-#line 2250 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2250 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(6);
jpCheckEmpty(6);
@@ -4955,22 +4960,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4959 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 250:
-#line 2259 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2259 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4970 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4975 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 251:
-#line 2267 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2267 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4978,22 +4983,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4982 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4987 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 252:
-#line 2276 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2276 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4993 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 4998 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 253:
-#line 2284 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2284 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5001,11 +5006,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5005 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5010 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 254:
-#line 2294 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2294 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5013,11 +5018,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5017 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5022 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 255:
-#line 2303 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2303 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5025,11 +5030,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5029 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5034 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 256:
-#line 2313 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2313 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5037,11 +5042,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5041 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5046 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 257:
-#line 2322 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2322 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5049,11 +5054,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5053 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5058 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 258:
-#line 2331 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2331 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5061,11 +5066,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5065 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5070 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 259:
-#line 2340 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2340 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5073,22 +5078,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5077 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5082 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 260:
-#line 2349 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2349 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5088 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5093 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 261:
-#line 2357 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2357 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5096,11 +5101,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5100 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 262:
-#line 2367 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2367 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5108,11 +5113,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5112 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5117 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 263:
-#line 2376 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2376 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5120,11 +5125,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5124 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5129 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 264:
-#line 2386 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2386 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5132,29 +5137,29 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5136 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5141 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 265:
-#line 2396 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2396 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
}
-#line 5145 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 266:
-#line 2402 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2402 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
}
-#line 5154 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5159 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 267:
-#line 2409 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2409 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5163,11 +5168,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5167 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 268:
-#line 2419 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2419 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5176,11 +5181,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5180 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5185 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 269:
-#line 2429 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2429 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5189,11 +5194,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5193 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5198 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 270:
-#line 2439 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2439 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5202,11 +5207,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5206 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5211 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 271:
-#line 2450 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2450 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5215,11 +5220,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5219 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5224 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 272:
-#line 2460 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2460 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5229,11 +5234,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5233 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5238 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 273:
-#line 2471 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2471 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5242,11 +5247,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5246 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 274:
-#line 2481 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2481 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5255,11 +5260,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5259 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5264 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 275:
-#line 2492 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2492 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5268,11 +5273,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5272 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 276:
-#line 2502 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2502 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5280,11 +5285,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5284 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 277:
-#line 2512 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2512 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5292,11 +5297,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 278:
-#line 2521 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2521 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5304,11 +5309,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5308 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 279:
-#line 2530 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2530 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5316,11 +5321,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5320 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 280:
-#line 2539 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2539 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5328,11 +5333,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5332 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 281:
-#line 2548 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2548 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5340,11 +5345,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5344 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 282:
-#line 2558 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2558 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5352,11 +5357,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5356 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5361 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 283:
-#line 2568 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2568 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5364,11 +5369,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5368 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5373 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 284:
-#line 2578 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2578 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5376,11 +5381,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5380 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5385 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 285:
-#line 2587 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2587 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5388,11 +5393,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5392 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5397 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 286:
-#line 2596 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2596 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5400,11 +5405,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5404 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5409 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 287:
-#line 2605 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2605 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5412,11 +5417,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5416 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5421 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 288:
-#line 2614 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2614 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5424,11 +5429,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5428 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5433 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 289:
-#line 2624 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2624 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5436,11 +5441,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5440 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5445 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 290:
-#line 2634 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2634 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5448,11 +5453,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5452 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5457 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 291:
-#line 2644 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2644 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5460,11 +5465,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5464 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5469 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 292:
-#line 2653 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2653 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5472,11 +5477,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5476 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5481 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 293:
-#line 2662 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2662 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5484,11 +5489,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5488 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 294:
-#line 2671 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2671 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5496,11 +5501,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5500 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 295:
-#line 2681 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2681 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5508,11 +5513,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5512 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5517 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 296:
-#line 2690 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2690 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5520,20 +5525,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5524 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5529 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 297:
-#line 2699 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2699 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
}
-#line 5533 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5538 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 298:
-#line 2706 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2706 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5541,11 +5546,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5545 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5550 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 299:
-#line 2715 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2715 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5553,11 +5558,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5557 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5562 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 300:
-#line 2724 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2724 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5565,11 +5570,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5569 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 301:
-#line 2733 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2733 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5577,11 +5582,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5581 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5586 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 302:
-#line 2743 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2743 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5589,11 +5594,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5593 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5598 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 303:
-#line 2752 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2752 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5601,11 +5606,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5605 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5610 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 304:
-#line 2761 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2761 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5613,11 +5618,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5617 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5622 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 305:
-#line 2771 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2771 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5625,11 +5630,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5629 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5634 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 306:
-#line 2780 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2780 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5637,11 +5642,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5641 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5646 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 307:
-#line 2789 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2789 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5649,11 +5654,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5653 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5658 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 308:
-#line 2798 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2798 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5661,11 +5666,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5665 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 309:
-#line 2808 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2808 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5673,11 +5678,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5677 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5682 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 310:
-#line 2817 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2817 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5685,11 +5690,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5689 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5694 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 311:
-#line 2826 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2826 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5697,11 +5702,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5701 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 312:
-#line 2835 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2835 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5709,11 +5714,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5713 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5718 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 313:
-#line 2844 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2844 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5721,11 +5726,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5725 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5730 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 314:
-#line 2853 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2853 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5733,11 +5738,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5737 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5742 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 315:
-#line 2863 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2863 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5745,11 +5750,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5749 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5754 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 316:
-#line 2872 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2872 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5757,11 +5762,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5761 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5766 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 317:
-#line 2881 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2881 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5769,11 +5774,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5773 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5778 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 318:
-#line 2891 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2891 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5781,11 +5786,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5785 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 319:
-#line 2900 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2900 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5793,11 +5798,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5797 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 320:
-#line 2910 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2910 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5805,11 +5810,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5809 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 321:
-#line 2919 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2919 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5817,11 +5822,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5821 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 322:
-#line 2929 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2929 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5829,11 +5834,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5833 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5838 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 323:
-#line 2938 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2938 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5841,11 +5846,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5845 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5850 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 324:
-#line 2948 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2948 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5853,11 +5858,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5857 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5862 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 325:
-#line 2957 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2957 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5865,11 +5870,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5869 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5874 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 326:
-#line 2967 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2967 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5877,11 +5882,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5881 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5886 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 327:
-#line 2976 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2976 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5889,11 +5894,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5893 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5898 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 328:
-#line 2986 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2986 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5901,11 +5906,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5905 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5910 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 329:
-#line 2995 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 2995 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5913,11 +5918,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5917 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5922 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 330:
-#line 3005 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3005 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5925,11 +5930,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5929 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5934 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 331:
-#line 3014 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3014 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5937,11 +5942,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5941 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5946 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 332:
-#line 3024 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3024 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5949,11 +5954,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5953 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5958 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 333:
-#line 3034 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3034 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5962,11 +5967,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5966 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5971 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 334:
-#line 3044 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3044 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5974,11 +5979,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5978 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5983 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 335:
-#line 3053 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3053 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5986,11 +5991,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5990 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 5995 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 336:
-#line 3063 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3063 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5998,11 +6003,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6002 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6007 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 337:
-#line 3072 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3072 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6010,11 +6015,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6014 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6019 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 338:
-#line 3081 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3081 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6022,11 +6027,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6026 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 339:
-#line 3090 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3090 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6034,11 +6039,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6038 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6043 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 340:
-#line 3099 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3099 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6046,11 +6051,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6050 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6055 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 341:
-#line 3108 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3108 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6058,11 +6063,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6062 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6067 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 342:
-#line 3117 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3117 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6070,11 +6075,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6074 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6079 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 343:
-#line 3126 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3126 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6082,11 +6087,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6086 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6091 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 344:
-#line 3135 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3135 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6094,11 +6099,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6098 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6103 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 345:
-#line 3144 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3144 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6106,11 +6111,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6110 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6115 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 346:
-#line 3153 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3153 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6118,11 +6123,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6122 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 347:
-#line 3162 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3162 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6130,11 +6135,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6134 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6139 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 348:
-#line 3172 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3172 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6142,11 +6147,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6146 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6151 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 349:
-#line 3182 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3182 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6154,11 +6159,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6158 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6163 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 350:
-#line 3192 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3192 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6166,11 +6171,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6170 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6175 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
case 351:
-#line 3201 "cmDependsJavaParser.y" /* yacc.c:1646 */
+#line 3201 "cmDependsJavaParser.y" /* yacc.c:1652 */
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -6179,11 +6184,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6183 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6188 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
break;
-#line 6187 "cmDependsJavaParser.cxx" /* yacc.c:1646 */
+#line 6192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -6208,14 +6213,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -6299,12 +6303,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -6367,6 +6369,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -6374,6 +6377,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
+
#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
@@ -6384,6 +6388,10 @@ yyexhaustedlab:
/* Fall through. */
#endif
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -6413,7 +6421,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 3210 "cmDependsJavaParser.y" /* yacc.c:1906 */
+#line 3210 "cmDependsJavaParser.y" /* yacc.c:1918 */
/* End of grammar */
diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h
index 7f18f1dd8..6bbc0848d 100644
--- a/Source/LexerParser/cmDependsJavaParserTokens.h
+++ b/Source/LexerParser/cmDependsJavaParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
#ifndef YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
# define YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
/* Debug traces. */
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index 73ece2b4f..8416e7249 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
#define yynerrs cmExpr_yynerrs
-/* Copy the first part of user declarations. */
-#line 1 "cmExprParser.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 1 "cmExprParser.y" /* yacc.c:337 */
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -112,13 +116,16 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 116 "cmExprParser.cxx" /* yacc.c:339 */
-
+#line 120 "cmExprParser.cxx" /* yacc.c:337 */
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -187,9 +194,7 @@ int cmExpr_yyparse (yyscan_t yyscanner);
#endif /* !YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 193 "cmExprParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -210,13 +215,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
-typedef short int yytype_int16;
+typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -228,7 +233,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
@@ -264,15 +269,6 @@ typedef short int yytype_int16;
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
-# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
@@ -280,7 +276,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -429,29 +425,29 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 17
+#define YYFINAL 19
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 30
+#define YYLAST 34
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 17
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 10
/* YYNRULES -- Number of rules. */
-#define YYNRULES 23
+#define YYNRULES 24
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 39
+#define YYNSTATES 41
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 271
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
+ as returned by yylex. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -490,7 +486,7 @@ static const yytype_uint8 yyrline[] =
{
0, 77, 77, 82, 85, 90, 93, 98, 101, 106,
109, 112, 117, 120, 123, 128, 131, 134, 140, 145,
- 148, 151, 156, 159
+ 148, 151, 154, 159, 162
};
#endif
@@ -517,10 +513,10 @@ static const yytype_uint16 yytoknum[] =
};
# endif
-#define YYPACT_NINF -8
+#define YYPACT_NINF -11
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-8)))
+ (!!((Yystate) == (-11)))
#define YYTABLE_NINF -1
@@ -531,10 +527,11 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int8 yypact[] =
{
- 0, 0, 0, 0, -8, 2, -7, -5, 8, 3,
- 10, 1, -8, -8, -8, -8, 6, -8, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -5,
- 8, 3, 10, 10, 1, 1, -8, -8, -8
+ 1, 1, 1, 1, 1, -11, 6, -10, -4, 9,
+ 4, 11, 2, -11, -11, -11, -11, 7, -11, -11,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ -11, -4, 9, 4, 11, 11, 2, 2, -11, -11,
+ -11
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -542,22 +539,23 @@ static const yytype_int8 yypact[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 0, 0, 0, 22, 0, 2, 3, 5, 7,
- 9, 12, 15, 19, 20, 21, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 23, 4,
- 6, 8, 10, 11, 13, 14, 16, 17, 18
+ 0, 0, 0, 0, 0, 23, 0, 2, 3, 5,
+ 7, 9, 12, 15, 19, 20, 21, 0, 22, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 24, 4, 6, 8, 10, 11, 13, 14, 16, 17,
+ 18
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -8, -8, 12, 5, 11, 9, -2, 4, -1, -8
+ -11, -11, 22, 10, 8, 12, -3, -2, -1, -11
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 5, 6, 7, 8, 9, 10, 11, 12, 13
+ -1, 6, 7, 8, 9, 10, 11, 12, 13, 14
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -565,28 +563,29 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 14, 15, 17, 1, 2, 18, 25, 26, 27, 19,
- 3, 21, 22, 23, 24, 16, 4, 28, 18, 32,
- 33, 20, 0, 29, 36, 37, 38, 34, 35, 31,
- 30
+ 15, 16, 20, 18, 1, 2, 19, 27, 28, 29,
+ 21, 3, 23, 24, 25, 26, 4, 5, 30, 20,
+ 34, 35, 22, 36, 37, 17, 38, 39, 40, 32,
+ 31, 0, 0, 0, 33
};
static const yytype_int8 yycheck[] =
{
- 1, 2, 0, 3, 4, 12, 5, 6, 7, 14,
- 10, 8, 9, 3, 4, 3, 16, 11, 12, 21,
- 22, 13, -1, 18, 25, 26, 27, 23, 24, 20,
- 19
+ 1, 2, 12, 4, 3, 4, 0, 5, 6, 7,
+ 14, 10, 8, 9, 3, 4, 15, 16, 11, 12,
+ 23, 24, 13, 25, 26, 3, 27, 28, 29, 21,
+ 20, -1, -1, -1, 22
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 4, 10, 16, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 25, 25, 19, 0, 12, 14,
- 13, 8, 9, 3, 4, 5, 6, 7, 11, 20,
- 21, 22, 23, 23, 24, 24, 25, 25, 25
+ 0, 3, 4, 10, 15, 16, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 25, 25, 19, 25, 0,
+ 12, 14, 13, 8, 9, 3, 4, 5, 6, 7,
+ 11, 20, 21, 22, 23, 23, 24, 24, 25, 25,
+ 25
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -594,7 +593,7 @@ static const yytype_uint8 yyr1[] =
{
0, 17, 18, 19, 19, 20, 20, 21, 21, 22,
22, 22, 23, 23, 23, 24, 24, 24, 24, 25,
- 25, 25, 26, 26
+ 25, 25, 25, 26, 26
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -602,7 +601,7 @@ static const yytype_uint8 yyr2[] =
{
0, 2, 1, 1, 3, 1, 3, 1, 3, 1,
3, 3, 1, 3, 3, 1, 3, 3, 3, 1,
- 2, 2, 1, 3
+ 2, 2, 2, 1, 3
};
@@ -618,22 +617,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (yyscanner, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
/* Error token number */
#define YYTERROR 1
@@ -673,38 +672,38 @@ do { \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
YYUSE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
YYUSE (yytype);
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- YYFPRINTF (yyoutput, "%s %s (",
+ YYFPRINTF (yyo, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -738,7 +737,7 @@ do { \
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
{
- unsigned long int yylno = yyrline[yyrule];
+ unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -749,7 +748,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
+ &yyvsp[(yyi + 1) - (yynrhs)]
, yyscanner);
YYFPRINTF (stderr, "\n");
}
@@ -853,7 +852,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -871,7 +873,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres)
return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -949,10 +951,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
}
}
@@ -964,6 +966,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -975,9 +978,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
if (*yymsg_alloc < yysize)
@@ -1108,23 +1112,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
@@ -1140,14 +1152,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -1163,22 +1171,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1187,11 +1195,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -1264,7 +1272,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -1285,186 +1293,194 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 77 "cmExprParser.y" /* yacc.c:1646 */
+#line 77 "cmExprParser.y" /* yacc.c:1652 */
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
-#line 1293 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1301 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 3:
-#line 82 "cmExprParser.y" /* yacc.c:1646 */
+#line 82 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1301 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1309 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 4:
-#line 85 "cmExprParser.y" /* yacc.c:1646 */
+#line 85 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
-#line 1309 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1317 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 5:
-#line 90 "cmExprParser.y" /* yacc.c:1646 */
+#line 90 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1317 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1325 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 6:
-#line 93 "cmExprParser.y" /* yacc.c:1646 */
+#line 93 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
-#line 1325 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1333 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 7:
-#line 98 "cmExprParser.y" /* yacc.c:1646 */
+#line 98 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1333 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1341 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 8:
-#line 101 "cmExprParser.y" /* yacc.c:1646 */
+#line 101 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
-#line 1341 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1349 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 9:
-#line 106 "cmExprParser.y" /* yacc.c:1646 */
+#line 106 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1349 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1357 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 10:
-#line 109 "cmExprParser.y" /* yacc.c:1646 */
+#line 109 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
-#line 1357 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1365 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 11:
-#line 112 "cmExprParser.y" /* yacc.c:1646 */
+#line 112 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
-#line 1365 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1373 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 12:
-#line 117 "cmExprParser.y" /* yacc.c:1646 */
+#line 117 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1373 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1381 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 13:
-#line 120 "cmExprParser.y" /* yacc.c:1646 */
+#line 120 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
-#line 1381 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1389 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 14:
-#line 123 "cmExprParser.y" /* yacc.c:1646 */
+#line 123 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
-#line 1389 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1397 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 15:
-#line 128 "cmExprParser.y" /* yacc.c:1646 */
+#line 128 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1397 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1405 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 16:
-#line 131 "cmExprParser.y" /* yacc.c:1646 */
+#line 131 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
-#line 1405 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1413 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 17:
-#line 134 "cmExprParser.y" /* yacc.c:1646 */
+#line 134 "cmExprParser.y" /* yacc.c:1652 */
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
-#line 1416 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1424 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 18:
-#line 140 "cmExprParser.y" /* yacc.c:1646 */
+#line 140 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
-#line 1424 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1432 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 19:
-#line 145 "cmExprParser.y" /* yacc.c:1646 */
+#line 145 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1432 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1440 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 20:
-#line 148 "cmExprParser.y" /* yacc.c:1646 */
+#line 148 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = + (yyvsp[0].Number);
}
-#line 1440 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1448 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 21:
-#line 151 "cmExprParser.y" /* yacc.c:1646 */
+#line 151 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = - (yyvsp[0].Number);
}
-#line 1448 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1456 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 22:
-#line 156 "cmExprParser.y" /* yacc.c:1646 */
+#line 154 "cmExprParser.y" /* yacc.c:1652 */
{
- (yyval.Number) = (yyvsp[0].Number);
+ (yyval.Number) = ~ (yyvsp[0].Number);
}
-#line 1456 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1464 "cmExprParser.cxx" /* yacc.c:1652 */
break;
case 23:
-#line 159 "cmExprParser.y" /* yacc.c:1646 */
+#line 159 "cmExprParser.y" /* yacc.c:1652 */
+ {
+ (yyval.Number) = (yyvsp[0].Number);
+ }
+#line 1472 "cmExprParser.cxx" /* yacc.c:1652 */
+ break;
+
+ case 24:
+#line 162 "cmExprParser.y" /* yacc.c:1652 */
{
(yyval.Number) = (yyvsp[-1].Number);
}
-#line 1464 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1480 "cmExprParser.cxx" /* yacc.c:1652 */
break;
-#line 1468 "cmExprParser.cxx" /* yacc.c:1646 */
+#line 1484 "cmExprParser.cxx" /* yacc.c:1652 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1489,14 +1505,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -1580,12 +1595,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1648,6 +1661,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -1655,6 +1669,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
+
#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
@@ -1665,6 +1680,10 @@ yyexhaustedlab:
/* Fall through. */
#endif
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -1694,7 +1713,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 164 "cmExprParser.y" /* yacc.c:1906 */
+#line 167 "cmExprParser.y" /* yacc.c:1918 */
/* End of grammar */
diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y
index 213747340..7ae21188e 100644
--- a/Source/LexerParser/cmExprParser.y
+++ b/Source/LexerParser/cmExprParser.y
@@ -151,6 +151,9 @@ unary:
| exp_MINUS unary {
$<Number>$ = - $<Number>2;
}
+| exp_NOT unary {
+ $<Number>$ = ~ $<Number>2;
+ }
factor:
exp_NUMBER {
diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h
index 84b2bbdcd..5ffd7c510 100644
--- a/Source/LexerParser/cmExprParserTokens.h
+++ b/Source/LexerParser/cmExprParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
#ifndef YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
# define YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
/* Debug traces. */
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 015cab9f9..2ca79276d 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
#define yynerrs cmFortran_yynerrs
-/* Copy the first part of user declarations. */
-#line 1 "cmFortranParser.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 1 "cmFortranParser.y" /* yacc.c:337 */
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -131,13 +135,16 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 135 "cmFortranParser.cxx" /* yacc.c:339 */
-
+#line 139 "cmFortranParser.cxx" /* yacc.c:337 */
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -251,11 +258,11 @@ extern int cmFortran_yydebug;
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:355 */
+#line 73 "cmFortranParser.y" /* yacc.c:352 */
char* string;
-#line 259 "cmFortranParser.cxx" /* yacc.c:355 */
+#line 266 "cmFortranParser.cxx" /* yacc.c:352 */
};
typedef union YYSTYPE YYSTYPE;
@@ -269,9 +276,7 @@ int cmFortran_yyparse (yyscan_t yyscanner);
#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 275 "cmFortranParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -292,13 +297,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
-typedef short int yytype_int16;
+typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -310,7 +315,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
@@ -346,15 +351,6 @@ typedef short int yytype_int16;
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
-# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
@@ -362,7 +358,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -524,16 +520,16 @@ union yyalloc
/* YYNSTATES -- Number of states. */
#define YYNSTATES 126
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 295
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+ ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
+ as returned by yylex. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -863,22 +859,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (yyscanner, YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
/* Error token number */
#define YYTERROR 1
@@ -918,38 +914,38 @@ do { \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
YYUSE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
YYUSE (yytype);
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- YYFPRINTF (yyoutput, "%s %s (",
+ YYFPRINTF (yyo, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -983,7 +979,7 @@ do { \
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
{
- unsigned long int yylno = yyrline[yyrule];
+ unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -994,7 +990,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
+ &yyvsp[(yyi + 1) - (yynrhs)]
, yyscanner);
YYFPRINTF (stderr, "\n");
}
@@ -1098,7 +1094,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -1116,7 +1115,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres)
return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
+ return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -1194,10 +1193,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
}
}
@@ -1209,6 +1208,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1220,9 +1220,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+ yysize = yysize1;
+ else
return 2;
- yysize = yysize1;
}
if (*yymsg_alloc < yysize)
@@ -1353,23 +1354,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
@@ -1385,14 +1394,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -1408,22 +1413,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1432,11 +1437,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -1509,7 +1514,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -1530,26 +1535,26 @@ yyreduce:
switch (yyn)
{
case 4:
-#line 104 "cmFortranParser.y" /* yacc.c:1646 */
+#line 104 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1539 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1544 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 5:
-#line 108 "cmFortranParser.y" /* yacc.c:1646 */
+#line 108 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1549 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1554 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 6:
-#line 113 "cmFortranParser.y" /* yacc.c:1646 */
+#line 113 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1559,22 +1564,22 @@ yyreduce:
}
free((yyvsp[-2].string));
}
-#line 1563 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1568 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 7:
-#line 122 "cmFortranParser.y" /* yacc.c:1646 */
+#line 122 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1574 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1579 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 8:
-#line 128 "cmFortranParser.y" /* yacc.c:1646 */
+#line 128 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1582,40 +1587,40 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1586 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1591 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 9:
-#line 135 "cmFortranParser.y" /* yacc.c:1646 */
+#line 135 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
-#line 1596 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1601 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 10:
-#line 140 "cmFortranParser.y" /* yacc.c:1646 */
+#line 140 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
-#line 1605 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1610 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 11:
-#line 144 "cmFortranParser.y" /* yacc.c:1646 */
+#line 144 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1615 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1620 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 12:
-#line 149 "cmFortranParser.y" /* yacc.c:1646 */
+#line 149 "cmFortranParser.y" /* yacc.c:1652 */
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1624,139 +1629,139 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1628 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1633 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 13:
-#line 157 "cmFortranParser.y" /* yacc.c:1646 */
+#line 157 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1638 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1643 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 14:
-#line 162 "cmFortranParser.y" /* yacc.c:1646 */
+#line 162 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1648 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1653 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 15:
-#line 167 "cmFortranParser.y" /* yacc.c:1646 */
+#line 167 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1658 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1663 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 16:
-#line 172 "cmFortranParser.y" /* yacc.c:1646 */
+#line 172 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1668 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1673 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 17:
-#line 177 "cmFortranParser.y" /* yacc.c:1646 */
+#line 177 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1678 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1683 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 18:
-#line 182 "cmFortranParser.y" /* yacc.c:1646 */
+#line 182 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1688 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1693 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 19:
-#line 187 "cmFortranParser.y" /* yacc.c:1646 */
+#line 187 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1698 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1703 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 20:
-#line 192 "cmFortranParser.y" /* yacc.c:1646 */
+#line 192 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1708 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1713 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 21:
-#line 197 "cmFortranParser.y" /* yacc.c:1646 */
+#line 197 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1717 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1722 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 22:
-#line 201 "cmFortranParser.y" /* yacc.c:1646 */
+#line 201 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1726 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1731 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 23:
-#line 205 "cmFortranParser.y" /* yacc.c:1646 */
+#line 205 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1735 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1740 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 24:
-#line 209 "cmFortranParser.y" /* yacc.c:1646 */
+#line 209 "cmFortranParser.y" /* yacc.c:1652 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1744 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1749 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 48:
-#line 231 "cmFortranParser.y" /* yacc.c:1646 */
+#line 231 "cmFortranParser.y" /* yacc.c:1652 */
{ free ((yyvsp[0].string)); }
-#line 1750 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1755 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
case 55:
-#line 238 "cmFortranParser.y" /* yacc.c:1646 */
+#line 238 "cmFortranParser.y" /* yacc.c:1652 */
{ free ((yyvsp[0].string)); }
-#line 1756 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1761 "cmFortranParser.cxx" /* yacc.c:1652 */
break;
-#line 1760 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1765 "cmFortranParser.cxx" /* yacc.c:1652 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1781,14 +1786,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -1872,12 +1876,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1940,6 +1942,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -1947,6 +1950,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
+
#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
@@ -1957,6 +1961,10 @@ yyexhaustedlab:
/* Fall through. */
#endif
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result. |
+`-----------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -1986,6 +1994,6 @@ yyreturn:
#endif
return yyresult;
}
-#line 249 "cmFortranParser.y" /* yacc.c:1906 */
+#line 249 "cmFortranParser.y" /* yacc.c:1918 */
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h
index 29c6d60a9..0da4c1c43 100644
--- a/Source/LexerParser/cmFortranParserTokens.h
+++ b/Source/LexerParser/cmFortranParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4. */
+/* A Bison parser, made by GNU Bison 3.3.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_,
+ are private implementation details. Do not rely on them. */
+
#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -130,11 +134,11 @@ extern int cmFortran_yydebug;
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:1909 */
+#line 73 "cmFortranParser.y" /* yacc.c:1921 */
char* string;
-#line 138 "cmFortranParserTokens.h" /* yacc.c:1909 */
+#line 142 "cmFortranParserTokens.h" /* yacc.c:1921 */
};
typedef union YYSTYPE YYSTYPE;
diff --git a/Source/Modules/CheckCXXLinkerFlag.cmake b/Source/Modules/CheckCXXLinkerFlag.cmake
deleted file mode 100644
index 9ad2ad630..000000000
--- a/Source/Modules/CheckCXXLinkerFlag.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-include_guard(GLOBAL)
-include(CheckCXXSourceCompiles)
-include(CMakeCheckCompilerFlagCommonPatterns)
-
-function(check_cxx_linker_flag _flag _var)
- set(CMAKE_REQUIRED_LIBRARIES "${_flag}")
-
- # Normalize locale during test compilation.
- set(_locale_vars LC_ALL LC_MESSAGES LANG)
- foreach(v IN LISTS _locale_vars)
- set(_locale_vars_saved_${v} "$ENV{${v}}")
- set(ENV{${v}} C)
- endforeach()
- check_compiler_flag_common_patterns(_common_patterns)
- check_cxx_source_compiles("int main() { return 0; }" ${_var}
- ${_common_patterns}
- )
- foreach(v IN LISTS _locale_vars)
- set(ENV{${v}} ${_locale_vars_saved_${v}})
- endforeach()
- set(${_var} "${${_var}}" PARENT_SCOPE)
-endfunction()
diff --git a/Source/QtDialog/AddCacheEntry.h b/Source/QtDialog/AddCacheEntry.h
index 65e11c06d..e7a60ddb3 100644
--- a/Source/QtDialog/AddCacheEntry.h
+++ b/Source/QtDialog/AddCacheEntry.h
@@ -4,7 +4,6 @@
#define AddCacheEntry_h
#include "QCMake.h"
-
#include <QCheckBox>
#include <QStringList>
#include <QWidget>
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index c9ebba83a..ee81a7d62 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -1,16 +1,8 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "QCMake.h" // include to disable MS warnings
+#include <iostream>
-#include "CMakeSetupDialog.h"
-#include "cmAlgorithms.h"
-#include "cmDocumentation.h"
-#include "cmDocumentationEntry.h"
-#include "cmVersion.h"
-#include "cmake.h"
-#include "cmsys/CommandLineArguments.hxx"
-#include "cmsys/Encoding.hxx"
-#include "cmsys/SystemTools.hxx"
+#include "QCMake.h" // include to disable MS warnings
#include <QApplication>
#include <QDir>
#include <QLocale>
@@ -18,9 +10,19 @@
#include <QTextCodec>
#include <QTranslator>
#include <QtPlugin>
-#include <iostream>
+#include "cmsys/CommandLineArguments.hxx"
+#include "cmsys/Encoding.hxx"
+#include "cmsys/SystemTools.hxx"
+
+#include "CMakeSetupDialog.h"
+#include "cmAlgorithms.h"
+#include "cmDocumentation.h"
+#include "cmDocumentationEntry.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h" // IWYU pragma: keep
+#include "cmVersion.h"
+#include "cmake.h"
static const char* cmDocumentationName[][2] = { { nullptr,
" cmake-gui - CMake GUI." },
@@ -227,10 +229,12 @@ int main(int argc, char** argv)
}
#if defined(Q_OS_MAC)
-# include "cm_sys_stat.h"
-# include <errno.h>
-# include <string.h>
+# include <cerrno>
+# include <cstring>
+
# include <unistd.h>
+
+# include "cm_sys_stat.h"
static bool cmOSXInstall(std::string const& dir, std::string const& tool)
{
if (tool.empty()) {
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index e98cdcf4a..436a90466 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -26,15 +26,17 @@
# include <QWinTaskbarProgress>
#endif
-#include "AddCacheEntry.h"
-#include "FirstConfigure.h"
#include "QCMake.h"
#include "QCMakeCacheView.h"
-#include "RegexExplorer.h"
-#include "WarningMessagesDialog.h"
+
#include "cmSystemTools.h"
#include "cmVersion.h"
+#include "AddCacheEntry.h"
+#include "FirstConfigure.h"
+#include "RegexExplorer.h"
+#include "WarningMessagesDialog.h"
+
QCMakeThread::QCMakeThread(QObject* p)
: QThread(p)
, CMakeInstance(nullptr)
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 39c1053cb..f23aee6e8 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -4,12 +4,12 @@
#define CMakeSetupDialog_h
#include "QCMake.h"
-
-#include "ui_CMakeSetupDialog.h"
#include <QEventLoop>
#include <QMainWindow>
#include <QThread>
+#include "ui_CMakeSetupDialog.h"
+
class QCMakeThread;
class CMakeCacheModel;
class QProgressBar;
diff --git a/Source/QtDialog/Compilers.h b/Source/QtDialog/Compilers.h
index 96770e3f4..931c93566 100644
--- a/Source/QtDialog/Compilers.h
+++ b/Source/QtDialog/Compilers.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <QWidget>
-
#include <ui_Compilers.h>
+#include <QWidget>
+
class Compilers
: public QWidget
, public Ui::Compilers
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index 364a378b3..ca28b1972 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -1,13 +1,15 @@
#include "FirstConfigure.h"
-#include "Compilers.h"
-
#include <QComboBox>
#include <QRadioButton>
#include <QSettings>
#include <QVBoxLayout>
+#include "cmStringAlgorithms.h"
+
+#include "Compilers.h"
+
StartCompilerSetup::StartCompilerSetup(QWidget* p)
: QWizardPage(p)
{
@@ -106,8 +108,7 @@ void StartCompilerSetup::setGenerators(
->GeneratorDefaultPlatform[QString::fromLocal8Bit(gen.name.c_str())] =
QString::fromLocal8Bit(gen.defaultPlatform.c_str());
- std::vector<std::string>::const_iterator platformIt =
- gen.supportedPlatforms.cbegin();
+ auto platformIt = gen.supportedPlatforms.cbegin();
while (platformIt != gen.supportedPlatforms.cend()) {
this->GeneratorSupportedPlatforms.insert(
@@ -183,10 +184,9 @@ void StartCompilerSetup::onGeneratorChanged(QString const& name)
if (GeneratorsSupportingPlatform.contains(name)) {
// Change the label title to include the default platform
- std::string label = "Optional platform for generator";
- label += "(if empty, generator uses: ";
- label += this->GeneratorDefaultPlatform[name].toStdString();
- label += ")";
+ std::string label =
+ cmStrCat("Optional platform for generator(if empty, generator uses: ",
+ this->GeneratorDefaultPlatform[name].toStdString(), ')');
this->PlatformLabel->setText(tr(label.c_str()));
// Regenerate the list of supported platform
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index f357f9032..b608fcbfc 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -7,6 +7,7 @@
#include "cmExternalMakefileProjectGenerator.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#ifdef Q_OS_WIN
@@ -256,14 +257,14 @@ void QCMake::setProperties(const QCMakePropertyList& newProps)
}
}
- // remove some properites
+ // remove some properties
foreach (QString const& s, toremove) {
this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data());
state->RemoveCacheEntry(s.toLocal8Bit().data());
}
- // add some new properites
+ // add some new properties
foreach (QCMakeProperty const& s, props) {
this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data());
@@ -312,7 +313,7 @@ QCMakePropertyList QCMake::properties() const
prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED");
if (t == cmStateEnums::BOOL) {
prop.Type = QCMakeProperty::BOOL;
- prop.Value = cmSystemTools::IsOn(cachedValue);
+ prop.Value = cmIsOn(cachedValue);
} else if (t == cmStateEnums::PATH) {
prop.Type = QCMakeProperty::PATH;
} else if (t == cmStateEnums::FILEPATH) {
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index f2fd6d923..fa4451bc2 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -50,7 +50,7 @@ struct QCMakeProperty
};
// list of properties
-typedef QList<QCMakeProperty> QCMakePropertyList;
+using QCMakePropertyList = QList<QCMakeProperty>;
// allow QVariant to be a property or list of properties
Q_DECLARE_METATYPE(QCMakeProperty)
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 78a271024..3e6a49e09 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "QCMakeCacheView.h"
+#include "QCMakeWidgets.h"
#include <QApplication>
#include <QEvent>
#include <QHBoxLayout>
@@ -11,8 +12,6 @@
#include <QSortFilterProxyModel>
#include <QStyle>
-#include "QCMakeWidgets.h"
-
// filter for searches
class QCMakeSearchFilter : public QSortFilterProxyModel
{
@@ -210,7 +209,8 @@ void QCMakeCacheModel::clear()
void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
{
- QSet<QCMakeProperty> newProps, newProps2;
+ QSet<QCMakeProperty> newProps;
+ QSet<QCMakeProperty> newProps2;
if (this->ShowNewProperties) {
newProps = props.toSet();
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index c1debf590..bea196586 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -4,7 +4,6 @@
#define QCMakeCacheView_h
#include "QCMake.h"
-
#include <QItemDelegate>
#include <QSet>
#include <QStandardItemModel>
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index eab418fe7..332a770ef 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -2,12 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "QCMakeWidgets.h"
+#include <utility>
+
#include <QDirModel>
#include <QFileDialog>
#include <QFileInfo>
#include <QResizeEvent>
#include <QToolButton>
-#include <utility>
QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var)
: QLineEdit(p)
diff --git a/Source/QtDialog/RegexExplorer.h b/Source/QtDialog/RegexExplorer.h
index c7dbb76cd..1a1d7700f 100644
--- a/Source/QtDialog/RegexExplorer.h
+++ b/Source/QtDialog/RegexExplorer.h
@@ -3,10 +3,12 @@
#ifndef RegexExplorer_h
#define RegexExplorer_h
-#include "cmsys/RegularExpression.hxx"
-#include <QDialog>
#include <string>
+#include <QDialog>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "ui_RegexExplorer.h"
class QString;
diff --git a/Source/QtDialog/WarningMessagesDialog.h b/Source/QtDialog/WarningMessagesDialog.h
index 9b29ad63c..f209dbdb3 100644
--- a/Source/QtDialog/WarningMessagesDialog.h
+++ b/Source/QtDialog/WarningMessagesDialog.h
@@ -3,10 +3,10 @@
#ifndef WarningMessagesDialog_h
#define WarningMessagesDialog_h
+#include "QCMake.h"
#include <QDialog>
#include <QWidget>
-#include "QCMake.h"
#include "ui_WarningMessagesDialog.h"
/**
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index a1072948f..b85cc3359 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -64,11 +64,17 @@
*/
#include "bindexplib.h"
-#include "cmsys/Encoding.hxx"
-#include "cmsys/FStream.hxx"
#include <iostream>
+#include <sstream>
+#include <vector>
+
#include <windows.h>
+#include "cmsys/Encoding.hxx"
+#include "cmsys/FStream.hxx"
+
+#include "cmSystemTools.h"
+
#ifndef IMAGE_FILE_MACHINE_ARM
# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#endif
@@ -301,7 +307,63 @@ private:
bool IsI386;
};
-bool DumpFile(const char* filename, std::set<std::string>& symbols,
+bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
+ std::set<std::string>& symbols,
+ std::set<std::string>& dataSymbols)
+{
+ std::string output;
+ // break up command line into a vector
+ std::vector<std::string> command;
+ command.push_back(nmPath);
+ command.push_back("--no-weak");
+ command.push_back("--defined-only");
+ command.push_back("--format=posix");
+ command.push_back(filename);
+
+ // run the command
+ int exit_code = 0;
+ cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "",
+ cmSystemTools::OUTPUT_NONE);
+
+ if (exit_code != 0) {
+ fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str());
+ return false;
+ }
+
+ std::istringstream ss(output);
+ std::string line;
+ while (std::getline(ss, line)) {
+ if (line.empty()) { // last line
+ continue;
+ }
+ size_t sym_end = line.find(" ");
+ if (sym_end == std::string::npos) {
+ fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n",
+ line.c_str());
+ return false;
+ }
+ if (line.size() < sym_end + 1) {
+ fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n",
+ line.c_str());
+ return false;
+ }
+ const std::string sym = line.substr(0, sym_end);
+ const char sym_type = line[sym_end + 1];
+ switch (sym_type) {
+ case 'D':
+ dataSymbols.insert(sym);
+ break;
+ case 'T':
+ symbols.insert(sym);
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool DumpFile(std::string const& nmPath, const char* filename,
+ std::set<std::string>& symbols,
std::set<std::string>& dataSymbols)
{
HANDLE hFile;
@@ -356,16 +418,26 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols,
(imageHeader->Machine == IMAGE_FILE_MACHINE_I386));
symbolDumper.DumpObjFile();
} else {
- // check for /bigobj format
+ // check for /bigobj and llvm LTO format
cmANON_OBJECT_HEADER_BIGOBJ* h =
(cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase;
if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
+ // bigobj
DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase, symbols,
dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386));
symbolDumper.DumpObjFile();
+ } else if (
+ // BCexCODE - llvm bitcode
+ (h->Sig1 == 0x4342 && h->Sig2 == 0xDEC0) ||
+ // 0x0B17C0DE - llvm bitcode BC wrapper
+ (h->Sig1 == 0x0B17 && h->Sig2 == 0xC0DE)) {
+
+ return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols);
+
} else {
- printf("unrecognized file format in '%s'\n", filename);
+ printf("unrecognized file format in '%s, %u'\n", filename,
+ imageHeader->Machine);
return false;
}
}
@@ -378,7 +450,7 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols,
bool bindexplib::AddObjectFile(const char* filename)
{
- return DumpFile(filename, this->Symbols, this->DataSymbols);
+ return DumpFile(NmPath, filename, this->Symbols, this->DataSymbols);
}
bool bindexplib::AddDefinitionFile(const char* filename)
@@ -419,3 +491,8 @@ void bindexplib::WriteFile(FILE* file)
fprintf(file, "\t%s\n", s.c_str());
}
}
+
+void bindexplib::SetNmPath(std::string const& nm)
+{
+ NmPath = nm;
+}
diff --git a/Source/bindexplib.h b/Source/bindexplib.h
index 3e22ac78e..538177dff 100644
--- a/Source/bindexplib.h
+++ b/Source/bindexplib.h
@@ -6,19 +6,23 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <set>
-#include <stdio.h>
#include <string>
+#include <stdio.h>
+
class bindexplib
{
public:
- bindexplib() {}
+ bindexplib() { NmPath = "nm"; }
bool AddDefinitionFile(const char* filename);
bool AddObjectFile(const char* filename);
void WriteFile(FILE* file);
+ void SetNmPath(std::string const& nm);
+
private:
std::set<std::string> Symbols;
std::set<std::string> DataSymbols;
+ std::string NmPath;
};
#endif
diff --git a/Source/cmAddCompileDefinitionsCommand.cxx b/Source/cmAddCompileDefinitionsCommand.cxx
index 04748192a..b00a4a7f7 100644
--- a/Source/cmAddCompileDefinitionsCommand.cxx
+++ b/Source/cmAddCompileDefinitionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddCompileDefinitionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddCompileDefinitionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddCompileDefinition(i);
+ mf.AddCompileDefinition(i);
}
return true;
}
diff --git a/Source/cmAddCompileDefinitionsCommand.h b/Source/cmAddCompileDefinitionsCommand.h
index e985dca8f..4bd621c4b 100644
--- a/Source/cmAddCompileDefinitionsCommand.h
+++ b/Source/cmAddCompileDefinitionsCommand.h
@@ -8,24 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddCompileDefinitionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddCompileDefinitionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx
index 412fb38a2..8ccb5129a 100644
--- a/Source/cmAddCompileOptionsCommand.cxx
+++ b/Source/cmAddCompileOptionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddCompileOptionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddCompileOptionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddCompileOption(i);
+ mf.AddCompileOption(i);
}
return true;
}
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index 3d53d097b..b172412be 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -8,24 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddCompileOptionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddCompileOptionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 0be3c85e1..6e04ce582 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -4,43 +4,50 @@
#include <sstream>
#include <unordered_set>
-#include <utility>
+#include "cmCheckCustomOutputs.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
+#include "cmCustomCommandTypes.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
-#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmAddCustomCommandCommand
-bool cmAddCustomCommandCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
/* Let's complain at the end of this function about the lack of a particular
arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
are required.
*/
if (args.size() < 4) {
- this->SetError("called with wrong number of arguments.");
+ status.SetError("called with wrong number of arguments.");
return false;
}
- std::string source, target, main_dependency, working, depfile, job_pool;
+ cmMakefile& mf = status.GetMakefile();
+ std::string source;
+ std::string target;
+ std::string main_dependency;
+ std::string working;
+ std::string depfile;
+ std::string job_pool;
std::string comment_buffer;
const char* comment = nullptr;
- std::vector<std::string> depends, outputs, output, byproducts;
+ std::vector<std::string> depends;
+ std::vector<std::string> outputs;
+ std::vector<std::string> output;
+ std::vector<std::string> byproducts;
bool verbatim = false;
bool append = false;
bool uses_terminal = false;
bool command_expand_lists = false;
std::string implicit_depends_lang;
- cmCustomCommand::ImplicitDependsList implicit_depends;
+ cmImplicitDependsList implicit_depends;
// Accumulate one command line at a time.
cmCustomCommandLine currentLine;
@@ -48,7 +55,7 @@ bool cmAddCustomCommandCommand::InitialPass(
// Save all command lines.
cmCustomCommandLines commandLines;
- cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
+ cmCustomCommandType cctype = cmCustomCommandType::POST_BUILD;
enum tdoing
{
@@ -95,30 +102,29 @@ bool cmAddCustomCommandCommand::InitialPass(
MAKE_STATIC_KEYWORD(VERBATIM);
MAKE_STATIC_KEYWORD(WORKING_DIRECTORY);
#undef MAKE_STATIC_KEYWORD
- static std::unordered_set<std::string> keywords;
- if (keywords.empty()) {
- keywords.insert(keyAPPEND);
- keywords.insert(keyARGS);
- keywords.insert(keyBYPRODUCTS);
- keywords.insert(keyCOMMAND);
- keywords.insert(keyCOMMAND_EXPAND_LISTS);
- keywords.insert(keyCOMMENT);
- keywords.insert(keyDEPENDS);
- keywords.insert(keyDEPFILE);
- keywords.insert(keyIMPLICIT_DEPENDS);
- keywords.insert(keyJOB_POOL);
- keywords.insert(keyMAIN_DEPENDENCY);
- keywords.insert(keyOUTPUT);
- keywords.insert(keyOUTPUTS);
- keywords.insert(keyPOST_BUILD);
- keywords.insert(keyPRE_BUILD);
- keywords.insert(keyPRE_LINK);
- keywords.insert(keySOURCE);
- keywords.insert(keyTARGET);
- keywords.insert(keyUSES_TERMINAL);
- keywords.insert(keyVERBATIM);
- keywords.insert(keyWORKING_DIRECTORY);
- }
+ static std::unordered_set<std::string> const keywords{
+ keyAPPEND,
+ keyARGS,
+ keyBYPRODUCTS,
+ keyCOMMAND,
+ keyCOMMAND_EXPAND_LISTS,
+ keyCOMMENT,
+ keyDEPENDS,
+ keyDEPFILE,
+ keyIMPLICIT_DEPENDS,
+ keyJOB_POOL,
+ keyMAIN_DEPENDENCY,
+ keyOUTPUT,
+ keyOUTPUTS,
+ keyPOST_BUILD,
+ keyPRE_BUILD,
+ keyPRE_LINK,
+ keySOURCE,
+ keyTARGET,
+ keyUSES_TERMINAL,
+ keyVERBATIM,
+ keyWORKING_DIRECTORY
+ };
for (std::string const& copy : args) {
if (keywords.count(copy)) {
@@ -133,11 +139,11 @@ bool cmAddCustomCommandCommand::InitialPass(
currentLine.clear();
}
} else if (copy == keyPRE_BUILD) {
- cctype = cmTarget::PRE_BUILD;
+ cctype = cmCustomCommandType::PRE_BUILD;
} else if (copy == keyPRE_LINK) {
- cctype = cmTarget::PRE_LINK;
+ cctype = cmCustomCommandType::PRE_LINK;
} else if (copy == keyPOST_BUILD) {
- cctype = cmTarget::POST_BUILD;
+ cctype = cmCustomCommandType::POST_BUILD;
} else if (copy == keyVERBATIM) {
verbatim = true;
} else if (copy == keyAPPEND) {
@@ -168,9 +174,9 @@ bool cmAddCustomCommandCommand::InitialPass(
doing = doing_comment;
} else if (copy == keyDEPFILE) {
doing = doing_depfile;
- if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") {
- this->SetError("Option DEPFILE not supported by " +
- this->Makefile->GetGlobalGenerator()->GetName());
+ if (mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ status.SetError("Option DEPFILE not supported by " +
+ mf.GetGlobalGenerator()->GetName());
return false;
}
} else if (copy == keyJOB_POOL) {
@@ -193,8 +199,7 @@ bool cmAddCustomCommandCommand::InitialPass(
// and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
// This is fairly obscure so we can wait for someone to
// complain.
- filename = this->Makefile->GetCurrentBinaryDirectory();
- filename += "/";
+ filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/');
}
filename += copy;
cmSystemTools::ConvertToUnixSlashes(filename);
@@ -239,6 +244,8 @@ bool cmAddCustomCommandCommand::InitialPass(
// An implicit dependency starting point is also an
// explicit dependency.
std::string dep = copy;
+ // Upfront path conversion is correct because Genex
+ // are not supported.
cmSystemTools::ConvertToUnixSlashes(dep);
depends.push_back(dep);
@@ -255,9 +262,7 @@ bool cmAddCustomCommandCommand::InitialPass(
target = copy;
break;
case doing_depends: {
- std::string dep = copy;
- cmSystemTools::ConvertToUnixSlashes(dep);
- depends.push_back(std::move(dep));
+ depends.push_back(copy);
} break;
case doing_outputs:
outputs.push_back(filename);
@@ -270,7 +275,7 @@ bool cmAddCustomCommandCommand::InitialPass(
comment = comment_buffer.c_str();
break;
default:
- this->SetError("Wrong syntax. Unknown type of argument.");
+ status.SetError("Wrong syntax. Unknown type of argument.");
return false;
}
}
@@ -285,49 +290,43 @@ bool cmAddCustomCommandCommand::InitialPass(
// At this point we could complain about the lack of arguments. For
// the moment, let's say that COMMAND, TARGET are always required.
if (output.empty() && target.empty()) {
- this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
+ status.SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
return false;
}
if (source.empty() && !target.empty() && !output.empty()) {
- this->SetError(
+ status.SetError(
"Wrong syntax. A TARGET and OUTPUT can not both be specified.");
return false;
}
if (append && output.empty()) {
- this->SetError("given APPEND option with no OUTPUT.");
+ status.SetError("given APPEND option with no OUTPUT.");
return false;
}
// Make sure the output names and locations are safe.
- if (!this->CheckOutputs(output) || !this->CheckOutputs(outputs) ||
- !this->CheckOutputs(byproducts)) {
+ if (!cmCheckCustomOutputs(output, "OUTPUT", status) ||
+ !cmCheckCustomOutputs(outputs, "OUTPUTS", status) ||
+ !cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
return false;
}
// Check for an append request.
if (append) {
- // Lookup an existing command.
- if (cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0])) {
- if (cmCustomCommand* cc = sf->GetCustomCommand()) {
- cc->AppendCommands(commandLines);
- cc->AppendDepends(depends);
- cc->AppendImplicitDepends(implicit_depends);
- return true;
- }
+ if (mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends,
+ commandLines)) {
+ return true;
}
// No command for this output exists.
- std::ostringstream e;
- e << "given APPEND option with output\n\"" << output[0]
- << "\"\nwhich is not already a custom command output.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("given APPEND option with output\n ", output[0],
+ "\nwhich is not already a custom command output."));
return false;
}
if (uses_terminal && !job_pool.empty()) {
- this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+ status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
return false;
}
@@ -336,46 +335,27 @@ bool cmAddCustomCommandCommand::InitialPass(
if (source.empty() && output.empty()) {
// Source is empty, use the target.
std::vector<std::string> no_depends;
- this->Makefile->AddCustomCommandToTarget(
- target, byproducts, no_depends, commandLines, cctype, comment,
- working.c_str(), escapeOldStyle, uses_terminal, depfile, job_pool,
- command_expand_lists);
+ mf.AddCustomCommandToTarget(target, byproducts, no_depends, commandLines,
+ cctype, comment, working.c_str(),
+ escapeOldStyle, uses_terminal, depfile,
+ job_pool, command_expand_lists);
} else if (target.empty()) {
// Target is empty, use the output.
- this->Makefile->AddCustomCommandToOutput(
- output, byproducts, depends, main_dependency, commandLines, comment,
- working.c_str(), false, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
-
- // Add implicit dependency scanning requests if any were given.
- if (!implicit_depends.empty()) {
- bool okay = false;
- if (cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0])) {
- if (cmCustomCommand* cc = sf->GetCustomCommand()) {
- okay = true;
- cc->SetImplicitDepends(implicit_depends);
- }
- }
- if (!okay) {
- std::ostringstream e;
- e << "could not locate source file with a custom command producing \""
- << output[0] << "\" even though this command tried to create it!";
- this->SetError(e.str());
- return false;
- }
- }
+ mf.AddCustomCommandToOutput(
+ output, byproducts, depends, main_dependency, implicit_depends,
+ commandLines, comment, working.c_str(), false, escapeOldStyle,
+ uses_terminal, command_expand_lists, depfile, job_pool);
} else if (!byproducts.empty()) {
- this->SetError("BYPRODUCTS may not be specified with SOURCE signatures");
+ status.SetError("BYPRODUCTS may not be specified with SOURCE signatures");
return false;
} else if (uses_terminal) {
- this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
+ status.SetError("USES_TERMINAL may not be used with SOURCE signatures");
return false;
} else {
bool issueMessage = true;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0050)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0050)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n";
break;
@@ -392,43 +372,16 @@ bool cmAddCustomCommandCommand::InitialPass(
if (issueMessage) {
e << "The SOURCE signatures of add_custom_command are no longer "
"supported.";
- this->Makefile->IssueMessage(messageType, e.str());
+ mf.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
}
// Use the old-style mode for backward compatibility.
- this->Makefile->AddCustomCommandOldStyle(target, outputs, depends, source,
- commandLines, comment);
+ mf.AddCustomCommandOldStyle(target, outputs, depends, source, commandLines,
+ comment);
}
return true;
}
-
-bool cmAddCustomCommandCommand::CheckOutputs(
- const std::vector<std::string>& outputs)
-{
- for (std::string const& o : outputs) {
- // Make sure the file will not be generated into the source
- // directory during an out of source build.
- if (!this->Makefile->CanIWriteThisFile(o)) {
- std::string e = "attempted to have a file \"" + o +
- "\" in a source directory as an output of custom command.";
- this->SetError(e);
- cmSystemTools::SetFatalErrorOccured();
- return false;
- }
-
- // Make sure the output file name has no invalid characters.
- std::string::size_type pos = o.find_first_of("#<>");
- if (pos != std::string::npos) {
- std::ostringstream msg;
- msg << "called with OUTPUT containing a \"" << o[pos]
- << "\". This character is not allowed.";
- this->SetError(msg.str());
- return false;
- }
- }
- return true;
-}
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 6af4f1055..4f8c58fef 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -8,33 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddCustomCommandCommand
- * \brief cmAddCustomCommandCommand defines a new command (rule) that can
- * be executed within the build process
- *
- */
-
-class cmAddCustomCommandCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddCustomCommandCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool CheckOutputs(const std::vector<std::string>& outputs);
-};
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 0ecd5f5a2..e27b126dd 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -2,38 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddCustomTargetCommand.h"
-#include <sstream>
#include <utility>
+#include "cmCheckCustomOutputs.h"
#include "cmCustomCommandLines.h"
+#include "cmCustomCommandTypes.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmAddCustomTargetCommand
-bool cmAddCustomTargetCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string const& targetName = args[0];
// Check the target name.
if (targetName.find_first_of("/\\") != std::string::npos) {
- std::ostringstream e;
- e << "called with invalid target name \"" << targetName
- << "\". Target names may not contain a slash. "
- << "Use ADD_CUSTOM_COMMAND to generate files.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("called with invalid target name \"", targetName,
+ "\". Target names may not contain a slash. "
+ "Use ADD_CUSTOM_COMMAND to generate files."));
return false;
}
@@ -44,7 +43,8 @@ bool cmAddCustomTargetCommand::InitialPass(
cmCustomCommandLines commandLines;
// Accumulate dependencies.
- std::vector<std::string> depends, byproducts;
+ std::vector<std::string> depends;
+ std::vector<std::string> byproducts;
std::string working_directory;
bool verbatim = false;
bool uses_terminal = false;
@@ -122,12 +122,11 @@ bool cmAddCustomTargetCommand::InitialPass(
case doing_byproducts: {
std::string filename;
if (!cmSystemTools::FileIsFullPath(copy)) {
- filename = this->Makefile->GetCurrentBinaryDirectory();
- filename += "/";
+ filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/');
}
filename += copy;
cmSystemTools::ConvertToUnixSlashes(filename);
- byproducts.push_back(filename);
+ byproducts.push_back(cmSystemTools::CollapseFullPath(filename));
} break;
case doing_depends: {
std::string dep = copy;
@@ -145,7 +144,7 @@ bool cmAddCustomTargetCommand::InitialPass(
job_pool = copy;
break;
default:
- this->SetError("Wrong syntax. Unknown type of argument.");
+ status.SetError("Wrong syntax. Unknown type of argument.");
return false;
}
}
@@ -153,10 +152,9 @@ bool cmAddCustomTargetCommand::InitialPass(
std::string::size_type pos = targetName.find_first_of("#<>");
if (pos != std::string::npos) {
- std::ostringstream msg;
- msg << "called with target name containing a \"" << targetName[pos]
- << "\". This character is not allowed.";
- this->SetError(msg.str());
+ status.SetError(cmStrCat("called with target name containing a \"",
+ targetName[pos],
+ "\". This character is not allowed."));
return false;
}
@@ -168,8 +166,7 @@ bool cmAddCustomTargetCommand::InitialPass(
if (nameOk) {
nameOk = targetName.find(':') == std::string::npos;
}
- if (!nameOk &&
- !this->Makefile->CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
+ if (!nameOk && !mf.CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
return false;
}
@@ -182,40 +179,43 @@ bool cmAddCustomTargetCommand::InitialPass(
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(targetName, msg, true)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(targetName, msg, true)) {
+ status.SetError(msg);
return false;
}
}
if (commandLines.empty() && !byproducts.empty()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "BYPRODUCTS may not be specified without any COMMAND");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "BYPRODUCTS may not be specified without any COMMAND");
return true;
}
if (commandLines.empty() && uses_terminal) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "USES_TERMINAL may not be specified without any COMMAND");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "USES_TERMINAL may not be specified without any COMMAND");
return true;
}
if (commandLines.empty() && command_expand_lists) {
- this->Makefile->IssueMessage(
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"COMMAND_EXPAND_LISTS may not be specified without any COMMAND");
return true;
}
if (uses_terminal && !job_pool.empty()) {
- this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+ status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+ return false;
+ }
+
+ // Make sure the byproduct names and locations are safe.
+ if (!cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
return false;
}
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
- cmTarget* target = this->Makefile->AddUtilityCommand(
- targetName, cmMakefile::TargetOrigin::Project, excludeFromAll,
+ cmTarget* target = mf.AddUtilityCommand(
+ targetName, cmCommandOrigin::Project, excludeFromAll,
working_directory.c_str(), byproducts, depends, commandLines,
escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool);
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index 1a55116e3..e23ef9fcc 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddCustomTargetCommand
- * \brief Command that adds a target to the build system.
- *
- * cmAddCustomTargetCommand adds an extra target to the build system.
- * This is useful when you would like to add special
- * targets like "install,", "clean," and so on.
- */
-class cmAddCustomTargetCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddCustomTargetCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
index 62e57a309..0b10aeef6 100644
--- a/Source/cmAddDefinitionsCommand.cxx
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -2,21 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddDefinitionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmAddDefinitionsCommand
-bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- // it is OK to have no arguments
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddDefineFlag(i);
+ mf.AddDefineFlag(i);
}
return true;
}
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index 7b75638cb..a67f09516 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddDefinitionsCommand
- * \brief Specify a list of compiler defines
- *
- * cmAddDefinitionsCommand specifies a list of compiler defines. These defines
- * will be added to the compile command.
- */
-class cmAddDefinitionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddDefinitionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index 4956a471c..b1fc89341 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -2,46 +2,47 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddDependenciesCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmDependenciesCommand
-bool cmAddDependenciesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string const& target_name = args[0];
- if (this->Makefile->IsAlias(target_name)) {
- std::ostringstream e;
- e << "Cannot add target-level dependencies to alias target \""
- << target_name << "\".\n";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ if (mf.IsAlias(target_name)) {
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot add target-level dependencies to alias target \"",
+ target_name, "\".\n"));
}
- if (cmTarget* target = this->Makefile->FindTargetToUse(target_name)) {
+ if (cmTarget* target = mf.FindTargetToUse(target_name)) {
// skip over target_name
for (std::string const& arg : cmMakeRange(args).advance(1)) {
- target->AddUtility(arg, this->Makefile);
+ target->AddUtility(arg, &mf);
}
} else {
- std::ostringstream e;
- e << "Cannot add target-level dependencies to non-existent target \""
- << target_name << "\".\n"
- << "The add_dependencies works for top-level logical targets created "
- << "by the add_executable, add_library, or add_custom_target commands. "
- << "If you want to add file-level dependencies see the DEPENDS option "
- << "of the add_custom_target and add_custom_command commands.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Cannot add target-level dependencies to non-existent "
+ "target \"",
+ target_name,
+ "\".\nThe add_dependencies works for "
+ "top-level logical targets created by the add_executable, "
+ "add_library, or add_custom_target commands. If you want to add "
+ "file-level dependencies see the DEPENDS option of the "
+ "add_custom_target and add_custom_command commands."));
}
return true;
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index e10df7109..0c60e3a2d 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddDependenciesCommand
- * \brief Add a dependency to a target
- *
- * cmAddDependenciesCommand adds a dependency to a target
- */
-class cmAddDependenciesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddDependenciesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 5685fdf4b..e738bc467 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -2,25 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddExecutableCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmExecutableCommand
-bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddExecutableCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string>::const_iterator s = args.begin();
+
+ cmMakefile& mf = status.GetMakefile();
+ auto s = args.begin();
std::string const& exename = *s;
@@ -61,110 +60,100 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
if (nameOk && !importTarget && !isAlias) {
nameOk = exename.find(':') == std::string::npos;
}
- if (!nameOk &&
- !this->Makefile->CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
+ if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
return false;
}
// Special modifiers are not allowed with IMPORTED signature.
if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) {
if (use_win32) {
- this->SetError("may not be given WIN32 for an IMPORTED target.");
+ status.SetError("may not be given WIN32 for an IMPORTED target.");
} else if (use_macbundle) {
- this->SetError("may not be given MACOSX_BUNDLE for an IMPORTED target.");
+ status.SetError(
+ "may not be given MACOSX_BUNDLE for an IMPORTED target.");
} else // if(excludeFromAll)
{
- this->SetError(
+ status.SetError(
"may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
}
return false;
}
if (isAlias) {
if (!cmGeneratorExpression::IsValidTargetName(exename)) {
- this->SetError("Invalid name for ALIAS: " + exename);
+ status.SetError("Invalid name for ALIAS: " + exename);
return false;
}
if (excludeFromAll) {
- this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+ status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
return false;
}
if (importTarget || importGlobal) {
- this->SetError("IMPORTED with ALIAS is not allowed.");
+ status.SetError("IMPORTED with ALIAS is not allowed.");
return false;
}
if (args.size() != 3) {
- std::ostringstream e;
- e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str());
+ status.SetError("ALIAS requires exactly one target argument.");
return false;
}
std::string const& aliasedName = *s;
- if (this->Makefile->IsAlias(aliasedName)) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str());
+ if (mf.IsAlias(aliasedName)) {
+ status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
+ "\" because target \"", aliasedName,
+ "\" is itself an ALIAS."));
return false;
}
- cmTarget* aliasedTarget =
- this->Makefile->FindTargetToUse(aliasedName, true);
+ cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
if (!aliasedTarget) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" does not already exist.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
+ "\" because target \"", aliasedName,
+ "\" does not already exist."));
return false;
}
cmStateEnums::TargetType type = aliasedTarget->GetType();
if (type != cmStateEnums::EXECUTABLE) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" is not an executable.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
+ "\" because target \"", aliasedName,
+ "\" is not an executable."));
return false;
}
if (aliasedTarget->IsImported() &&
!aliasedTarget->IsImportedGloballyVisible()) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << exename << "\" because target \""
- << aliasedName << "\" is imported but not globally visible.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
+ "\" because target \"", aliasedName,
+ "\" is imported but not globally visible."));
return false;
}
- this->Makefile->AddAlias(exename, aliasedName);
+ mf.AddAlias(exename, aliasedName);
return true;
}
// Handle imported target creation.
if (importTarget) {
// Make sure the target does not already exist.
- if (this->Makefile->FindTargetToUse(exename)) {
- std::ostringstream e;
- e << "cannot create imported target \"" << exename
- << "\" because another target with the same name already exists.";
- this->SetError(e.str());
+ if (mf.FindTargetToUse(exename)) {
+ status.SetError(cmStrCat(
+ "cannot create imported target \"", exename,
+ "\" because another target with the same name already exists."));
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(exename, cmStateEnums::EXECUTABLE,
- importGlobal);
+ mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal);
return true;
}
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(exename, msg)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(exename, msg)) {
+ status.SetError(msg);
return false;
}
}
std::vector<std::string> srclists(s, args.end());
- cmTarget* tgt =
- this->Makefile->AddExecutable(exename, srclists, excludeFromAll);
+ cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll);
if (use_win32) {
tgt->SetProperty("WIN32_EXECUTABLE", "ON");
}
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index bdf607d8d..f7bc27336 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmExecutablesCommand
- * \brief Defines a list of executables to build.
- *
- * cmExecutablesCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddExecutableCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddExecutableCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddExecutableCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index ad12e89b9..0439c518c 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,40 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLibraryCommand.h"
-#include <sstream>
-
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmLibraryCommand
-bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddLibraryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+
+ cmMakefile& mf = status.GetMakefile();
// Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
// otherwise it defaults to static library.
cmStateEnums::TargetType type = cmStateEnums::SHARED_LIBRARY;
- if (cmSystemTools::IsOff(
- this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
+ if (cmIsOff(mf.GetDefinition("BUILD_SHARED_LIBS"))) {
type = cmStateEnums::STATIC_LIBRARY;
}
bool excludeFromAll = false;
bool importTarget = false;
bool importGlobal = false;
- std::vector<std::string>::const_iterator s = args.begin();
+ auto s = args.begin();
std::string const& libName = *s;
@@ -50,9 +47,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
std::string libType = *s;
if (libType == "STATIC") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting STATIC type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting STATIC type.");
return false;
}
++s;
@@ -60,9 +56,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "SHARED") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting SHARED type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting SHARED type.");
return false;
}
++s;
@@ -70,9 +65,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "MODULE") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting MODULE type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting MODULE type.");
return false;
}
++s;
@@ -80,9 +74,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "OBJECT") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting OBJECT type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting OBJECT type.");
return false;
}
++s;
@@ -90,9 +83,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "UNKNOWN") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting UNKNOWN type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting UNKNOWN type.");
return false;
}
++s;
@@ -100,30 +92,26 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (libType == "ALIAS") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting ALIAS type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting ALIAS type.");
return false;
}
++s;
isAlias = true;
} else if (libType == "INTERFACE") {
if (haveSpecifiedType) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting/multiple types.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting/multiple types.");
return false;
}
if (isAlias) {
- std::ostringstream e;
- e << "INTERFACE library specified with conflicting ALIAS type.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified with conflicting ALIAS type.");
return false;
}
if (excludeFromAll) {
- std::ostringstream e;
- e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
@@ -131,9 +119,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
haveSpecifiedType = true;
} else if (*s == "EXCLUDE_FROM_ALL") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
@@ -145,9 +132,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
++s;
importGlobal = true;
} else if (type == cmStateEnums::INTERFACE_LIBRARY && *s == "GLOBAL") {
- std::ostringstream e;
- e << "GLOBAL option may only be used with IMPORTED libraries.";
- this->SetError(e.str());
+ status.SetError(
+ "GLOBAL option may only be used with IMPORTED libraries.");
return false;
} else {
break;
@@ -156,15 +142,12 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (s != args.end()) {
- std::ostringstream e;
- e << "INTERFACE library requires no source arguments.";
- this->SetError(e.str());
+ status.SetError("INTERFACE library requires no source arguments.");
return false;
}
if (importGlobal && !importTarget) {
- std::ostringstream e;
- e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
- this->SetError(e.str());
+ status.SetError(
+ "INTERFACE library specified as GLOBAL, but not as IMPORTED.");
return false;
}
}
@@ -175,47 +158,40 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
if (nameOk && !importTarget && !isAlias) {
nameOk = libName.find(':') == std::string::npos;
}
- if (!nameOk && !this->Makefile->CheckCMP0037(libName, type)) {
+ if (!nameOk && !mf.CheckCMP0037(libName, type)) {
return false;
}
if (isAlias) {
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
- this->SetError("Invalid name for ALIAS: " + libName);
+ status.SetError("Invalid name for ALIAS: " + libName);
return false;
}
if (excludeFromAll) {
- this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+ status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
return false;
}
if (importTarget || importGlobal) {
- this->SetError("IMPORTED with ALIAS is not allowed.");
+ status.SetError("IMPORTED with ALIAS is not allowed.");
return false;
}
if (args.size() != 3) {
- std::ostringstream e;
- e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str());
+ status.SetError("ALIAS requires exactly one target argument.");
return false;
}
std::string const& aliasedName = *s;
- if (this->Makefile->IsAlias(aliasedName)) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << libName << "\" because target \""
- << aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str());
+ if (mf.IsAlias(aliasedName)) {
+ status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
+ "\" because target \"", aliasedName,
+ "\" is itself an ALIAS."));
return false;
}
- cmTarget* aliasedTarget =
- this->Makefile->FindTargetToUse(aliasedName, true);
+ cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
if (!aliasedTarget) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << libName << "\" because target \""
- << aliasedName
- << "\" does not already "
- "exist.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
+ "\" because target \"", aliasedName,
+ "\" does not already exist."));
return false;
}
cmStateEnums::TargetType aliasedType = aliasedTarget->GetType();
@@ -226,26 +202,24 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
aliasedType != cmStateEnums::INTERFACE_LIBRARY &&
!(aliasedType == cmStateEnums::UNKNOWN_LIBRARY &&
aliasedTarget->IsImported())) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << libName << "\" because target \""
- << aliasedName << "\" is not a library.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
+ "\" because target \"", aliasedName,
+ "\" is not a library."));
return false;
}
if (aliasedTarget->IsImported() &&
!aliasedTarget->IsImportedGloballyVisible()) {
- std::ostringstream e;
- e << "cannot create ALIAS target \"" << libName << "\" because target \""
- << aliasedName << "\" is imported but not globally visible.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
+ "\" because target \"", aliasedName,
+ "\" is imported but not globally visible."));
return false;
}
- this->Makefile->AddAlias(libName, aliasedName);
+ mf.AddAlias(libName, aliasedName);
return true;
}
if (importTarget && excludeFromAll) {
- this->SetError("excludeFromAll with IMPORTED target makes no sense.");
+ status.SetError("excludeFromAll with IMPORTED target makes no sense.");
return false;
}
@@ -255,14 +229,14 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
yet its linker language. */
if ((type == cmStateEnums::SHARED_LIBRARY ||
type == cmStateEnums::MODULE_LIBRARY) &&
- !this->Makefile->GetState()->GetGlobalPropertyAsBool(
- "TARGET_SUPPORTS_SHARED_LIBS")) {
- std::ostringstream w;
- w << "ADD_LIBRARY called with "
- << (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE")
- << " option but the target platform does not support dynamic linking. "
- "Building a STATIC library instead. This may lead to problems.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ "ADD_LIBRARY called with ",
+ (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"),
+ " option but the target platform does not support dynamic linking. ",
+ "Building a STATIC library instead. This may lead to problems."));
type = cmStateEnums::STATIC_LIBRARY;
}
@@ -270,14 +244,13 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
if (importTarget) {
// The IMPORTED signature requires a type to be specified explicitly.
if (!haveSpecifiedType) {
- this->SetError("called with IMPORTED argument but no library type.");
+ status.SetError("called with IMPORTED argument but no library type.");
return false;
}
if (type == cmStateEnums::OBJECT_LIBRARY) {
std::string reason;
- if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
- &reason)) {
- this->Makefile->IssueMessage(
+ if (!mf.GetGlobalGenerator()->HasKnownObjectFileLocation(&reason)) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The OBJECT library type may not be used for IMPORTED libraries" +
reason + ".");
@@ -286,30 +259,28 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
}
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
- std::ostringstream e;
- e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "Invalid name for IMPORTED INTERFACE library target: ", libName));
return false;
}
}
// Make sure the target does not already exist.
- if (this->Makefile->FindTargetToUse(libName)) {
- std::ostringstream e;
- e << "cannot create imported target \"" << libName
- << "\" because another target with the same name already exists.";
- this->SetError(e.str());
+ if (mf.FindTargetToUse(libName)) {
+ status.SetError(cmStrCat(
+ "cannot create imported target \"", libName,
+ "\" because another target with the same name already exists."));
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(libName, type, importGlobal);
+ mf.AddImportedTarget(libName, type, importGlobal);
return true;
}
// A non-imported target may not have UNKNOWN type.
if (type == cmStateEnums::UNKNOWN_LIBRARY) {
- this->Makefile->IssueMessage(
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The UNKNOWN library type may be used only for IMPORTED libraries.");
return true;
@@ -318,8 +289,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(libName, msg)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(libName, msg)) {
+ status.SetError(msg);
return false;
}
}
@@ -329,19 +300,18 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (!cmGeneratorExpression::IsValidTargetName(libName) ||
libName.find("::") != std::string::npos) {
- std::ostringstream e;
- e << "Invalid name for INTERFACE library target: " << libName;
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("Invalid name for INTERFACE library target: ", libName));
return false;
}
- this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+ mf.AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
cmAppend(srclists, s, args.end());
- this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+ mf.AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index aa212611d..609449c87 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmLibrarysCommand
- * \brief Defines a list of executables to build.
- *
- * cmLibrarysCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddLibraryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddLibraryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddLibraryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddLinkOptionsCommand.cxx b/Source/cmAddLinkOptionsCommand.cxx
index 10ebd1284..7ed31bdbc 100644
--- a/Source/cmAddLinkOptionsCommand.cxx
+++ b/Source/cmAddLinkOptionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLinkOptionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddLinkOptionsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddLinkOption(i);
+ mf.AddLinkOption(i);
}
return true;
}
diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h
index 30fff0058..466fc3215 100644
--- a/Source/cmAddLinkOptionsCommand.h
+++ b/Source/cmAddLinkOptionsCommand.h
@@ -8,24 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddLinkOptionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddLinkOptionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 7947188a5..6a1a514f7 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -2,24 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddSubDirectoryCommand.h"
-#include <sstream>
-#include <string.h>
+#include <cstring>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-// cmAddSubDirectoryCommand
-bool cmAddSubDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
// store the binpath
std::string const& srcArg = args.front();
std::string binArg;
@@ -35,7 +34,7 @@ bool cmAddSubDirectoryCommand::InitialPass(
if (binArg.empty()) {
binArg = arg;
} else {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
}
@@ -46,15 +45,12 @@ bool cmAddSubDirectoryCommand::InitialPass(
if (cmSystemTools::FileIsFullPath(srcArg)) {
srcPath = srcArg;
} else {
- srcPath = this->Makefile->GetCurrentSourceDirectory();
- srcPath += "/";
- srcPath += srcArg;
+ srcPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', srcArg);
}
if (!cmSystemTools::FileIsDirectory(srcPath)) {
- std::string error = "given source \"";
- error += srcArg;
- error += "\" which is not an existing directory.";
- this->SetError(error);
+ std::string error = cmStrCat("given source \"", srcArg,
+ "\" which is not an existing directory.");
+ status.SetError(error);
return false;
}
srcPath = cmSystemTools::CollapseFullPath(srcPath);
@@ -65,22 +61,22 @@ bool cmAddSubDirectoryCommand::InitialPass(
// No binary directory was specified. If the source directory is
// not a subdirectory of the current directory then it is an
// error.
- if (!cmSystemTools::IsSubDirectory(
- srcPath, this->Makefile->GetCurrentSourceDirectory())) {
- std::ostringstream e;
- e << "not given a binary directory but the given source directory "
- << "\"" << srcPath << "\" is not a subdirectory of \""
- << this->Makefile->GetCurrentSourceDirectory() << "\". "
- << "When specifying an out-of-tree source a binary directory "
- << "must be explicitly specified.";
- this->SetError(e.str());
+ if (!cmSystemTools::IsSubDirectory(srcPath,
+ mf.GetCurrentSourceDirectory())) {
+ status.SetError(
+ cmStrCat("not given a binary directory but the given source ",
+ "directory \"", srcPath, "\" is not a subdirectory of \"",
+ mf.GetCurrentSourceDirectory(),
+ "\". When specifying an "
+ "out-of-tree source a binary directory must be explicitly "
+ "specified."));
return false;
}
// Remove the CurrentDirectory from the srcPath and replace it
// with the CurrentOutputDirectory.
- const std::string& src = this->Makefile->GetCurrentSourceDirectory();
- const std::string& bin = this->Makefile->GetCurrentBinaryDirectory();
+ const std::string& src = mf.GetCurrentSourceDirectory();
+ const std::string& bin = mf.GetCurrentBinaryDirectory();
size_t srcLen = src.length();
size_t binLen = bin.length();
if (srcLen > 0 && src.back() == '/') {
@@ -96,15 +92,13 @@ bool cmAddSubDirectoryCommand::InitialPass(
if (cmSystemTools::FileIsFullPath(binArg)) {
binPath = binArg;
} else {
- binPath = this->Makefile->GetCurrentBinaryDirectory();
- binPath += "/";
- binPath += binArg;
+ binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg);
}
}
binPath = cmSystemTools::CollapseFullPath(binPath);
// Add the subdirectory using the computed full paths.
- this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, true);
+ mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true);
return true;
}
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index 0ea442329..87da8402b 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddSubDirectoryCommand
- * \brief Specify a subdirectory to build
- *
- * cmAddSubDirectoryCommand specifies a subdirectory to process
- * by CMake. CMake will descend
- * into the specified source directory and process any CMakeLists.txt found.
- */
-class cmAddSubDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddSubDirectoryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index bf28702ce..89421131a 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -2,62 +2,63 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddTestCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmTest.h"
#include "cmTestGenerator.h"
-class cmExecutionStatus;
+static bool cmAddTestCommandHandleNameMode(
+ std::vector<std::string> const& args, cmExecutionStatus& status);
-// cmExecutableCommand
-bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddTestCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (!args.empty() && args[0] == "NAME") {
- return this->HandleNameMode(args);
+ return cmAddTestCommandHandleNameMode(args, status);
}
// First argument is the name of the test Second argument is the name of
// the executable to run (a target or external program) Remaining arguments
// are the arguments to pass to the executable
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
// Collect the command with arguments.
std::vector<std::string> command(args.begin() + 1, args.end());
// Create the test but add a generator only the first time it is
// seen. This preserves behavior from before test generators.
- cmTest* test = this->Makefile->GetTest(args[0]);
+ cmTest* test = mf.GetTest(args[0]);
if (test) {
// If the test was already added by a new-style signature do not
// allow it to be duplicated.
if (!test->GetOldStyle()) {
- std::ostringstream e;
- e << " given test name \"" << args[0]
- << "\" which already exists in this directory.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(" given test name \"", args[0],
+ "\" which already exists in this directory."));
return false;
}
} else {
- test = this->Makefile->CreateTest(args[0]);
+ test = mf.CreateTest(args[0]);
test->SetOldStyle(true);
- this->Makefile->AddTestGenerator(new cmTestGenerator(test));
+ mf.AddTestGenerator(new cmTestGenerator(test));
}
test->SetCommand(command);
return true;
}
-bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
+bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
std::string name;
std::vector<std::string> configurations;
std::string working_directory;
std::vector<std::string> command;
+ bool command_expand_lists = false;
// Read the arguments.
enum Doing
@@ -72,22 +73,29 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "COMMAND") {
if (!command.empty()) {
- this->SetError(" may be given at most one COMMAND.");
+ status.SetError(" may be given at most one COMMAND.");
return false;
}
doing = DoingCommand;
} else if (args[i] == "CONFIGURATIONS") {
if (!configurations.empty()) {
- this->SetError(" may be given at most one set of CONFIGURATIONS.");
+ status.SetError(" may be given at most one set of CONFIGURATIONS.");
return false;
}
doing = DoingConfigs;
} else if (args[i] == "WORKING_DIRECTORY") {
if (!working_directory.empty()) {
- this->SetError(" may be given at most one WORKING_DIRECTORY.");
+ status.SetError(" may be given at most one WORKING_DIRECTORY.");
return false;
}
doing = DoingWorkingDirectory;
+ } else if (args[i] == "COMMAND_EXPAND_LISTS") {
+ if (command_expand_lists) {
+ status.SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
+ return false;
+ }
+ command_expand_lists = true;
+ doing = DoingNone;
} else if (doing == DoingName) {
name = args[i];
doing = DoingNone;
@@ -99,42 +107,41 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
working_directory = args[i];
doing = DoingNone;
} else {
- std::ostringstream e;
- e << " given unknown argument:\n " << args[i] << "\n";
- this->SetError(e.str());
+ status.SetError(cmStrCat(" given unknown argument:\n ", args[i], "\n"));
return false;
}
}
// Require a test name.
if (name.empty()) {
- this->SetError(" must be given non-empty NAME.");
+ status.SetError(" must be given non-empty NAME.");
return false;
}
// Require a command.
if (command.empty()) {
- this->SetError(" must be given non-empty COMMAND.");
+ status.SetError(" must be given non-empty COMMAND.");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Require a unique test name within the directory.
- if (this->Makefile->GetTest(name)) {
- std::ostringstream e;
- e << " given test NAME \"" << name
- << "\" which already exists in this directory.";
- this->SetError(e.str());
+ if (mf.GetTest(name)) {
+ status.SetError(cmStrCat(" given test NAME \"", name,
+ "\" which already exists in this directory."));
return false;
}
// Add the test.
- cmTest* test = this->Makefile->CreateTest(name);
+ cmTest* test = mf.CreateTest(name);
test->SetOldStyle(false);
test->SetCommand(command);
if (!working_directory.empty()) {
test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
}
- this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations));
+ test->SetCommandExpandLists(command_expand_lists);
+ mf.AddTestGenerator(new cmTestGenerator(test, configurations));
return true;
}
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index bea3f3d5d..5877547e8 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -8,32 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddTestCommand
- * \brief Add a test to the lists of tests to run.
- *
- * cmAddTestCommand adds a test to the list of tests to run .
- */
-class cmAddTestCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAddTestCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandleNameMode(std::vector<std::string> const& args);
-};
+bool cmAddTestCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx
index 09b029866..8f9fe2ad8 100644
--- a/Source/cmAffinity.cxx
+++ b/Source/cmAffinity.cxx
@@ -13,16 +13,17 @@
# include <pthread.h>
# include <sched.h>
// On some platforms CPU_ZERO needs memset but sched.h forgets string.h
-# include <string.h> // IWYU pragma: keep
+# include <cstring> // IWYU pragma: keep
# if defined(__FreeBSD__)
# include <pthread_np.h>
+
# include <sys/cpuset.h>
# include <sys/param.h>
# endif
# if defined(__linux__)
-typedef cpu_set_t cm_cpuset_t;
+using cm_cpuset_t = cpu_set_t;
# else
-typedef cpuset_t cm_cpuset_t;
+using cm_cpuset_t = cpuset_t;
# endif
# endif
#endif
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index d1e32b0d4..e0d27eedf 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -5,78 +5,25 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmRange.h"
-
-#include "cm_kwiml.h"
#include <algorithm>
#include <functional>
#include <iterator>
-#include <memory>
-#include <sstream>
-#include <string.h>
-#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
-inline bool cmHasLiteralPrefixImpl(const std::string& str1, const char* str2,
- size_t N)
-{
- return strncmp(str1.c_str(), str2, N) == 0;
-}
-
-inline bool cmHasLiteralPrefixImpl(const char* str1, const char* str2,
- size_t N)
-{
- return strncmp(str1, str2, N) == 0;
-}
-
-inline bool cmHasLiteralSuffixImpl(const std::string& str1, const char* str2,
- size_t N)
-{
- size_t len = str1.size();
- return len >= N && strcmp(str1.c_str() + len - N, str2) == 0;
-}
-
-inline bool cmHasLiteralSuffixImpl(const char* str1, const char* str2,
- size_t N)
-{
- size_t len = strlen(str1);
- return len >= N && strcmp(str1 + len - N, str2) == 0;
-}
+#include "cm_kwiml.h"
-template <typename T, size_t N>
-bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N])
-{
- return cmHasLiteralPrefixImpl(str1, str2, N - 1);
-}
+#include "cmRange.h"
-template <typename T, size_t N>
-bool cmHasLiteralSuffix(const T& str1, const char (&str2)[N])
+template <std::size_t N>
+struct cmOverloadPriority : cmOverloadPriority<N - 1>
{
- return cmHasLiteralSuffixImpl(str1, str2, N - 1);
-}
+};
-struct cmStrCmp
+template <>
+struct cmOverloadPriority<0>
{
- cmStrCmp(const char* test)
- : m_test(test)
- {
- }
- cmStrCmp(std::string test)
- : m_test(std::move(test))
- {
- }
-
- bool operator()(const std::string& input) const { return m_test == input; }
-
- bool operator()(const char* input) const
- {
- return strcmp(input, m_test.c_str()) == 0;
- }
-
-private:
- const std::string m_test;
};
template <typename FwdIt>
@@ -95,6 +42,34 @@ void cmEraseIf(Container& cont, Predicate pred)
cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
}
+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 T>
@@ -142,7 +117,7 @@ FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
template <typename Range>
struct BinarySearcher
{
- typedef typename Range::value_type argument_type;
+ using argument_type = typename Range::value_type;
BinarySearcher(Range const& r)
: m_range(r)
{
@@ -158,11 +133,9 @@ private:
};
}
-typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
-
class cmListFileBacktrace;
-typedef cmRange<std::vector<cmListFileBacktrace>::const_iterator>
- cmBacktraceRange;
+using cmBacktraceRange =
+ cmRange<std::vector<cmListFileBacktrace>::const_iterator>;
template <typename Range>
void cmDeleteAll(Range const& r)
@@ -184,31 +157,6 @@ void cmAppend(std::vector<T>& v, InputIt first, InputIt last)
}
template <typename Range>
-std::string cmJoin(Range const& r, const char* delimiter)
-{
- if (r.empty()) {
- return std::string();
- }
- std::ostringstream os;
- typedef typename Range::value_type ValueType;
- typedef typename Range::const_iterator InputIt;
- const InputIt first = r.begin();
- InputIt last = r.end();
- --last;
- std::copy(first, last, std::ostream_iterator<ValueType>(os, delimiter));
-
- os << *last;
-
- return os.str();
-}
-
-template <typename Range>
-std::string cmJoin(Range const& r, std::string const& delimiter)
-{
- return cmJoin(r, delimiter.c_str());
-}
-
-template <typename Range>
typename Range::const_iterator cmRemoveN(Range& r, size_t n)
{
return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
@@ -219,14 +167,14 @@ typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem)
{
typename InputRange::const_iterator remIt = rem.begin();
typename InputRange::const_iterator remEnd = rem.end();
- const typename Range::iterator rangeEnd = r.end();
+ const auto rangeEnd = r.end();
if (remIt == remEnd) {
return rangeEnd;
}
- typename Range::iterator writer = r.begin();
+ auto writer = r.begin();
std::advance(writer, *remIt);
- typename Range::iterator pivot = writer;
+ auto pivot = writer;
typename InputRange::value_type prevRem = *remIt;
++remIt;
size_t count = 1;
@@ -268,7 +216,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
ForwardIterator result = first;
while (first != last) {
- if (uniq.find(first) == uniq.end()) {
+ if (!cmContains(uniq, first)) {
if (result != first) {
*result = std::move(*first);
}
@@ -286,141 +234,10 @@ typename Range::const_iterator cmRemoveDuplicates(Range& r)
return cmRemoveDuplicates(r.begin(), r.end());
}
-template <typename Range>
-std::string cmWrap(std::string const& prefix, Range const& r,
- std::string const& suffix, std::string const& sep)
-{
- if (r.empty()) {
- return std::string();
- }
- return prefix + cmJoin(r, suffix + sep + prefix) + suffix;
-}
-
-template <typename Range>
-std::string cmWrap(char prefix, Range const& r, char suffix,
- std::string const& sep)
-{
- return cmWrap(std::string(1, prefix), r, std::string(1, suffix), sep);
-}
-
template <typename Range, typename T>
typename Range::const_iterator cmFindNot(Range const& r, T const& t)
{
return std::find_if(r.begin(), r.end(), [&t](T const& i) { return i != t; });
}
-template <class Iter>
-std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
-{
- return std::reverse_iterator<Iter>(it);
-}
-
-inline bool cmHasPrefix(std::string const& str, std::string const& prefix)
-{
- if (str.size() < prefix.size()) {
- return false;
- }
- return str.compare(0, prefix.size(), prefix) == 0;
-}
-
-inline bool cmHasSuffix(const std::string& str, const std::string& suffix)
-{
- if (str.size() < suffix.size()) {
- return false;
- }
- return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
-inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix)
-{
- if (cmHasSuffix(str, suffix)) {
- str.resize(str.size() - suffix.size());
- }
-}
-
-namespace cm {
-
-#if defined(CMake_HAVE_CXX_MAKE_UNIQUE)
-
-using std::make_unique;
-
-#else
-
-template <typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args)
-{
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-
-#endif
-
-#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
-
-using std::size;
-
-#else
-
-// std::size backport from C++17.
-template <class C>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- auto
- size(C const& c) -> decltype(c.size())
-{
- return c.size();
-}
-
-template <typename T, size_t N>
-# if !defined(_MSC_VER) || _MSC_VER >= 1900
-constexpr
-# endif
- std::size_t
- size(const T (&)[N]) throw()
-{
- return N;
-}
-
-#endif
-
-template <typename T>
-int isize(const T& t)
-{
- return static_cast<int>(cm::size(t));
-}
-
-#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
-
-using std::cbegin;
-using std::cend;
-
-#else
-
-// std::c{begin,end} backport from C++14
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto cbegin(C const& c)
-# else
-constexpr auto cbegin(C const& c) noexcept(noexcept(std::begin(c)))
-# endif
- -> decltype(std::begin(c))
-{
- return std::begin(c);
-}
-
-template <class C>
-# if defined(_MSC_VER) && _MSC_VER < 1900
-auto cend(C const& c)
-# else
-constexpr auto cend(C const& c) noexcept(noexcept(std::end(c)))
-# endif
- -> decltype(std::end(c))
-{
- return std::end(c);
-}
-
-#endif
-
-} // namespace cm
-
#endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 359d57af6..e5eea795d 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -2,17 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmArchiveWrite.h"
-#include "cmLocale.h"
-#include "cmSystemTools.h"
-#include "cm_get_date.h"
-#include "cm_libarchive.h"
+#include <cstring>
+#include <ctime>
+#include <iostream>
+#include <sstream>
+
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
-#include <iostream>
-#include <sstream>
-#include <string.h>
-#include <time.h>
+
+#include "cm_get_date.h"
+#include "cm_libarchive.h"
+
+#include "cmLocale.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
#ifndef __LA_SSIZE_T
# define __LA_SSIZE_T la_ssize_t
@@ -85,22 +89,22 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
switch (c) {
case CompressNone:
if (archive_write_add_filter_none(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_none: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_none: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
case CompressCompress:
if (archive_write_add_filter_compress(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_compress: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_compress: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
case CompressGZip: {
if (archive_write_add_filter_gzip(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_gzip: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_gzip: ",
+ cm_archive_error_string(this->Archive));
return;
}
std::string source_date_epoch;
@@ -110,60 +114,60 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
// The next best thing is to omit the timestamp entirely.
if (archive_write_set_filter_option(this->Archive, "gzip", "timestamp",
nullptr) != ARCHIVE_OK) {
- this->Error = "archive_write_set_filter_option: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_set_filter_option: ",
+ cm_archive_error_string(this->Archive));
return;
}
}
} break;
case CompressBZip2:
if (archive_write_add_filter_bzip2(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_bzip2: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_bzip2: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
case CompressLZMA:
if (archive_write_add_filter_lzma(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_lzma: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_lzma: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
case CompressXZ:
if (archive_write_add_filter_xz(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_xz: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_xz: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
case CompressZstd:
if (archive_write_add_filter_zstd(this->Archive) != ARCHIVE_OK) {
- this->Error = "archive_write_add_filter_zstd: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_add_filter_zstd: ",
+ cm_archive_error_string(this->Archive));
return;
}
break;
}
#if !defined(_WIN32) || defined(__CYGWIN__)
if (archive_read_disk_set_standard_lookup(this->Disk) != ARCHIVE_OK) {
- this->Error = "archive_read_disk_set_standard_lookup: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_read_disk_set_standard_lookup: ",
+ cm_archive_error_string(this->Archive));
return;
}
#endif
if (archive_write_set_format_by_name(this->Archive, format.c_str()) !=
ARCHIVE_OK) {
- this->Error = "archive_write_set_format_by_name: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_set_format_by_name: ",
+ cm_archive_error_string(this->Archive));
return;
}
// do not pad the last block!!
if (archive_write_set_bytes_in_last_block(this->Archive, 1)) {
- this->Error = "archive_write_set_bytes_in_last_block: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_set_bytes_in_last_block: ",
+ cm_archive_error_string(this->Archive));
return;
}
@@ -171,8 +175,8 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
this->Archive, this, nullptr,
reinterpret_cast<archive_write_callback*>(&Callback::Write),
nullptr) != ARCHIVE_OK) {
- this->Error = "archive_write_open: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error =
+ cmStrCat("archive_write_open: ", cm_archive_error_string(this->Archive));
return;
}
}
@@ -205,8 +209,7 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
}
cmsys::Directory d;
if (d.Load(path)) {
- std::string next = path;
- next += "/";
+ std::string next = cmStrCat(path, '/');
std::string::size_type end = next.size();
unsigned long n = d.GetNumberOfFiles();
for (unsigned long i = 0; i < n; ++i) {
@@ -237,8 +240,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
static_cast<void>(localeRAII);
// Meta-data.
- std::string dest = prefix ? prefix : "";
- dest += out;
+ std::string dest = cmStrCat(prefix ? prefix : "", out);
if (this->Verbose) {
std::cout << dest << "\n";
}
@@ -247,10 +249,8 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
cm_archive_entry_copy_pathname(e, dest);
if (archive_read_disk_entry_from_file(this->Disk, e, -1, nullptr) !=
ARCHIVE_OK) {
- this->Error = "Unable to read from file '";
- this->Error += file;
- this->Error += "': ";
- this->Error += cm_archive_error_string(this->Disk);
+ this->Error = cmStrCat("Unable to read from file '", file,
+ "': ", cm_archive_error_string(this->Disk));
return false;
}
if (!this->MTime.empty()) {
@@ -258,9 +258,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
time(&now);
time_t t = cm_get_date(now, this->MTime.c_str());
if (t == -1) {
- this->Error = "unable to parse mtime '";
- this->Error += this->MTime;
- this->Error += "'";
+ this->Error = cmStrCat("unable to parse mtime '", this->MTime, '\'');
return false;
}
archive_entry_set_mtime(e, t, 0);
@@ -310,8 +308,8 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
}
if (archive_write_header(this->Archive, e) != ARCHIVE_OK) {
- this->Error = "archive_write_header: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_header: ",
+ cm_archive_error_string(this->Archive));
return false;
}
@@ -329,17 +327,15 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
{
cmsys::ifstream fin(file, std::ios::in | std::ios::binary);
if (!fin) {
- this->Error = "Error opening \"";
- this->Error += file;
- this->Error += "\": ";
- this->Error += cmSystemTools::GetLastSystemError();
+ this->Error = cmStrCat("Error opening \"", file,
+ "\": ", cmSystemTools::GetLastSystemError());
return false;
}
char buffer[16384];
size_t nleft = size;
while (nleft > 0) {
- typedef std::streamsize ssize_type;
+ using ssize_type = std::streamsize;
size_t const nnext = nleft > sizeof(buffer) ? sizeof(buffer) : nleft;
ssize_type const nnext_s = static_cast<ssize_type>(nnext);
fin.read(buffer, nnext_s);
@@ -350,17 +346,15 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
break;
}
if (archive_write_data(this->Archive, buffer, nnext) != nnext_s) {
- this->Error = "archive_write_data: ";
- this->Error += cm_archive_error_string(this->Archive);
+ this->Error = cmStrCat("archive_write_data: ",
+ cm_archive_error_string(this->Archive));
return false;
}
nleft -= nnext;
}
if (nleft > 0) {
- this->Error = "Error reading \"";
- this->Error += file;
- this->Error += "\": ";
- this->Error += cmSystemTools::GetLastSystemError();
+ this->Error = cmStrCat("Error reading \"", file,
+ "\": ", cmSystemTools::GetLastSystemError());
return false;
}
return true;
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 9ea88d3dc..e791761cb 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <iosfwd>
-#include <stddef.h>
#include <string>
-#if !defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(CMAKE_BOOTSTRAP)
# error "cmArchiveWrite not allowed during bootstrap build!"
#endif
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 751d117f4..4c8717749 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -61,10 +61,14 @@ void Instance::Bind(MultiStringList& val)
void Instance::Consume(cm::string_view arg, void* result,
std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue)
+ std::vector<std::string>* keywordsMissingValue,
+ std::vector<std::string>* parsedKeywords)
{
auto const it = this->Bindings.Find(arg);
if (it != this->Bindings.end()) {
+ if (parsedKeywords != nullptr) {
+ parsedKeywords->emplace_back(arg);
+ }
it->second(*this, result);
if (this->ExpectValue && keywordsMissingValue != nullptr) {
keywordsMissingValue->emplace_back(arg);
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 6cfe94633..94265372a 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -5,15 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_static_string_view.hxx"
-#include "cm_string_view.hxx"
-
#include <cassert>
#include <functional>
#include <string>
#include <utility>
#include <vector>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
namespace ArgumentParser {
using StringList = std::vector<std::string>;
@@ -45,7 +46,8 @@ public:
void Consume(cm::string_view arg, void* result,
std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue);
+ std::vector<std::string>* keywordsMissingValue,
+ std::vector<std::string>* parsedKeywords);
private:
ActionMap const& Bindings;
@@ -79,21 +81,25 @@ public:
template <typename Range>
void Parse(Result& result, Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
ArgumentParser::Instance instance(this->Bindings);
for (cm::string_view arg : args) {
- instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue);
+ instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
}
}
template <typename Range>
Result Parse(Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
Result result;
- this->Parse(result, args, unparsedArguments, keywordsMissingValue);
+ this->Parse(result, args, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
return result;
}
@@ -116,11 +122,13 @@ public:
template <typename Range>
void Parse(Range const& args,
std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr) const
+ std::vector<std::string>* keywordsMissingValue = nullptr,
+ std::vector<std::string>* parsedKeywords = nullptr) const
{
ArgumentParser::Instance instance(this->Bindings);
for (cm::string_view arg : args) {
- instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue);
+ instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue,
+ parsedKeywords);
}
}
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 106e7a79a..289bb7217 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -2,41 +2,39 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAuxSourceDirectoryCommand.h"
-#include "cmsys/Directory.hxx"
#include <algorithm>
-#include <stddef.h>
+#include <cstddef>
#include <utility>
-#include "cmAlgorithms.h"
+#include "cmsys/Directory.hxx"
+
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-// cmAuxSourceDirectoryCommand
-bool cmAuxSourceDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string sourceListValue;
std::string const& templateDirectory = args[0];
std::string tdir;
if (!cmSystemTools::FileIsFullPath(templateDirectory)) {
- tdir = this->Makefile->GetCurrentSourceDirectory();
- tdir += "/";
- tdir += templateDirectory;
+ tdir = cmStrCat(mf.GetCurrentSourceDirectory(), '/', templateDirectory);
} else {
tdir = templateDirectory;
}
// was the list already populated
- const char* def = this->Makefile->GetDefinition(args[1]);
+ const char* def = mf.GetDefinition(args[1]);
if (def) {
sourceListValue = def;
}
@@ -55,14 +53,12 @@ bool cmAuxSourceDirectoryCommand::InitialPass(
std::string ext = file.substr(dotpos + 1);
std::string base = file.substr(0, dotpos);
// Process only source files
- auto cm = this->Makefile->GetCMakeInstance();
+ auto cm = mf.GetCMakeInstance();
if (!base.empty() && cm->IsSourceExtension(ext)) {
- std::string fullname = templateDirectory;
- fullname += "/";
- fullname += file;
+ std::string fullname = cmStrCat(templateDirectory, '/', file);
// add the file as a class file so
// depends can be done
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(fullname);
+ cmSourceFile* sf = mf.GetOrCreateSource(fullname);
sf->SetProperty("ABSTRACT", "0");
files.push_back(std::move(fullname));
}
@@ -74,6 +70,6 @@ bool cmAuxSourceDirectoryCommand::InitialPass(
sourceListValue += ";";
}
sourceListValue += cmJoin(files, ";");
- this->Makefile->AddDefinition(args[1], sourceListValue.c_str());
+ mf.AddDefinition(args[1], sourceListValue);
return true;
}
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index 3742e3e9b..ae2609205 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -8,33 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAuxSourceDirectoryCommand
- * \brief Specify auxiliary source code directories.
- *
- * cmAuxSourceDirectoryCommand specifies source code directories
- * that must be built as part of this build process. This directories
- * are not recursively processed like the SUBDIR command (cmSubdirCommand).
- * A side effect of this command is to create a subdirectory in the build
- * directory structure.
- */
-class cmAuxSourceDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmAuxSourceDirectoryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmBase32.h b/Source/cmBase32.h
index c6758d4f3..d85198dd5 100644
--- a/Source/cmBase32.h
+++ b/Source/cmBase32.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stddef.h>
+#include <cstddef>
#include <string>
/** \class cmBase32Encoder
diff --git a/Source/cmBinUtilsLinker.cxx b/Source/cmBinUtilsLinker.cxx
new file mode 100644
index 000000000..a9f4d91fc
--- /dev/null
+++ b/Source/cmBinUtilsLinker.cxx
@@ -0,0 +1,16 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsLinker.h"
+
+#include "cmRuntimeDependencyArchive.h"
+
+cmBinUtilsLinker::cmBinUtilsLinker(cmRuntimeDependencyArchive* archive)
+ : Archive(archive)
+{
+}
+
+void cmBinUtilsLinker::SetError(const std::string& e)
+{
+ this->Archive->SetError(e);
+}
diff --git a/Source/cmBinUtilsLinker.h b/Source/cmBinUtilsLinker.h
new file mode 100644
index 000000000..78d517b61
--- /dev/null
+++ b/Source/cmBinUtilsLinker.h
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsLinker_h
+#define cmBinUtilsLinker_h
+
+#include <string>
+
+#include "cmStateTypes.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsLinker
+{
+public:
+ cmBinUtilsLinker(cmRuntimeDependencyArchive* archive);
+ virtual ~cmBinUtilsLinker() = default;
+
+ virtual bool Prepare() { return true; }
+
+ virtual bool ScanDependencies(std::string const& file,
+ cmStateEnums::TargetType type) = 0;
+
+protected:
+ cmRuntimeDependencyArchive* Archive;
+
+ void SetError(const std::string& e);
+};
+
+#endif // cmBinUtilsLinker_h
diff --git a/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..abd12092c
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h"
+
+#include "cmRuntimeDependencyArchive.h"
+
+cmBinUtilsLinuxELFGetRuntimeDependenciesTool::
+ cmBinUtilsLinuxELFGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : Archive(archive)
+{
+}
+
+void cmBinUtilsLinuxELFGetRuntimeDependenciesTool::SetError(
+ const std::string& error)
+{
+ this->Archive->SetError(error);
+}
diff --git a/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..d514e7f91
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h
+#define cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsLinuxELFGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsLinuxELFGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+ virtual ~cmBinUtilsLinuxELFGetRuntimeDependenciesTool() = default;
+
+ virtual bool GetFileInfo(std::string const& file,
+ std::vector<std::string>& needed,
+ std::vector<std::string>& rpaths,
+ std::vector<std::string>& runpaths) = 0;
+
+protected:
+ cmRuntimeDependencyArchive* Archive;
+
+ void SetError(const std::string& e);
+};
+
+#endif // cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
new file mode 100644
index 000000000..0dea8256c
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -0,0 +1,179 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsLinuxELFLinker.h"
+
+#include <sstream>
+
+#include <cm/memory>
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
+#include "cmLDConfigLDConfigTool.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+static std::string ReplaceOrigin(const std::string& rpath,
+ const std::string& origin)
+{
+ static const cmsys::RegularExpression originRegex(
+ "(\\$ORIGIN)([^a-zA-Z0-9_]|$)");
+ static const cmsys::RegularExpression originCurlyRegex("\\${ORIGIN}");
+
+ 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;
+ }
+ 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;
+ }
+ return rpath;
+}
+
+cmBinUtilsLinuxELFLinker::cmBinUtilsLinuxELFLinker(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsLinker(archive)
+{
+}
+
+bool cmBinUtilsLinuxELFLinker::Prepare()
+{
+ std::string tool = this->Archive->GetGetRuntimeDependenciesTool();
+ if (tool.empty()) {
+ tool = "objdump";
+ }
+ if (tool == "objdump") {
+ this->Tool =
+ cm::make_unique<cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool>(
+ this->Archive);
+ } else {
+ std::ostringstream e;
+ e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool;
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string ldConfigTool =
+ this->Archive->GetMakefile()->GetSafeDefinition("CMAKE_LDCONFIG_TOOL");
+ if (ldConfigTool.empty()) {
+ ldConfigTool = "ldconfig";
+ }
+ if (ldConfigTool == "ldconfig") {
+ this->LDConfigTool =
+ cm::make_unique<cmLDConfigLDConfigTool>(this->Archive);
+ } else {
+ std::ostringstream e;
+ e << "Invalid value for CMAKE_LDCONFIG_TOOL: " << ldConfigTool;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
+
+bool cmBinUtilsLinuxELFLinker::ScanDependencies(
+ std::string const& file, cmStateEnums::TargetType /* unused */)
+{
+ std::vector<std::string> parentRpaths;
+ return this->ScanDependencies(file, parentRpaths);
+}
+
+bool cmBinUtilsLinuxELFLinker::ScanDependencies(
+ std::string const& file, std::vector<std::string> const& parentRpaths)
+{
+ std::string origin = cmSystemTools::GetFilenamePath(file);
+ std::vector<std::string> needed;
+ std::vector<std::string> rpaths;
+ std::vector<std::string> runpaths;
+ if (!this->Tool->GetFileInfo(file, needed, rpaths, runpaths)) {
+ return false;
+ }
+ for (auto& runpath : runpaths) {
+ runpath = ReplaceOrigin(runpath, origin);
+ }
+ for (auto& rpath : rpaths) {
+ rpath = ReplaceOrigin(rpath, origin);
+ }
+
+ std::vector<std::string> searchPaths;
+ if (!runpaths.empty()) {
+ searchPaths = runpaths;
+ } else {
+ searchPaths = rpaths;
+ searchPaths.insert(searchPaths.end(), parentRpaths.begin(),
+ parentRpaths.end());
+ }
+
+ std::vector<std::string> ldConfigPaths;
+ if (!this->LDConfigTool->GetLDConfigPaths(ldConfigPaths)) {
+ return false;
+ }
+ searchPaths.insert(searchPaths.end(), ldConfigPaths.begin(),
+ ldConfigPaths.end());
+
+ for (auto const& dep : needed) {
+ if (!this->Archive->IsPreExcluded(dep)) {
+ std::string path;
+ bool resolved = false;
+ if (dep.find('/') != std::string::npos) {
+ this->SetError("Paths to dependencies are not supported");
+ return false;
+ }
+ if (!this->ResolveDependency(dep, searchPaths, path, resolved)) {
+ return false;
+ }
+ if (resolved) {
+ if (!this->Archive->IsPostExcluded(path)) {
+ bool unique;
+ this->Archive->AddResolvedPath(dep, path, unique);
+ if (unique && !this->ScanDependencies(path, rpaths)) {
+ return false;
+ }
+ }
+ } else {
+ this->Archive->AddUnresolvedPath(dep);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool cmBinUtilsLinuxELFLinker::ResolveDependency(
+ std::string const& name, std::vector<std::string> const& searchPaths,
+ std::string& path, bool& resolved)
+{
+ for (auto const& searchPath : searchPaths) {
+ path = cmStrCat(searchPath, '/', name);
+ if (cmSystemTools::PathExists(path)) {
+ resolved = true;
+ return true;
+ }
+ }
+
+ for (auto const& searchPath : this->Archive->GetSearchDirectories()) {
+ path = cmStrCat(searchPath, '/', name);
+ if (cmSystemTools::PathExists(path)) {
+ std::ostringstream warning;
+ warning << "Dependency " << name << " found in search directory:\n "
+ << searchPath
+ << "\nSee file(GET_RUNTIME_DEPENDENCIES) documentation for "
+ << "more information.";
+ this->Archive->GetMakefile()->IssueMessage(MessageType::WARNING,
+ warning.str());
+ resolved = true;
+ return true;
+ }
+ }
+
+ resolved = false;
+ return true;
+}
diff --git a/Source/cmBinUtilsLinuxELFLinker.h b/Source/cmBinUtilsLinuxELFLinker.h
new file mode 100644
index 000000000..b17df11ee
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFLinker.h
@@ -0,0 +1,44 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsLinuxELFLinker_h
+#define cmBinUtilsLinuxELFLinker_h
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsLinker.h"
+#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h"
+#include "cmLDConfigTool.h"
+#include "cmStateTypes.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsLinuxELFLinker : public cmBinUtilsLinker
+{
+public:
+ cmBinUtilsLinuxELFLinker(cmRuntimeDependencyArchive* archive);
+
+ bool Prepare() override;
+
+ bool ScanDependencies(std::string const& file,
+ cmStateEnums::TargetType type) override;
+
+private:
+ std::unique_ptr<cmBinUtilsLinuxELFGetRuntimeDependenciesTool> Tool;
+ std::unique_ptr<cmLDConfigTool> LDConfigTool;
+ bool HaveLDConfigPaths = false;
+ std::vector<std::string> LDConfigPaths;
+
+ bool ScanDependencies(std::string const& file,
+ std::vector<std::string> const& parentRpaths);
+
+ bool ResolveDependency(std::string const& name,
+ std::vector<std::string> const& searchPaths,
+ std::string& path, bool& resolved);
+
+ bool GetLDConfigPaths();
+};
+
+#endif // cmBinUtilsLinuxELFLinker_h
diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..566e4a488
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,85 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
+
+#include <sstream>
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmRuntimeDependencyArchive.h"
+#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
+
+cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::
+ cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsLinuxELFGetRuntimeDependenciesTool(archive)
+{
+}
+
+bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
+ std::string const& file, std::vector<std::string>& needed,
+ std::vector<std::string>& rpaths, std::vector<std::string>& runpaths)
+{
+ cmUVProcessChainBuilder builder;
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+ std::vector<std::string> command;
+ if (!this->Archive->GetGetRuntimeDependenciesCommand("objdump", command)) {
+ this->SetError("Could not find objdump");
+ return false;
+ }
+ command.emplace_back("-p");
+ command.push_back(file);
+ builder.AddCommand(command);
+
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::ostringstream e;
+ e << "Failed to start objdump process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string line;
+ static const cmsys::RegularExpression neededRegex("^ *NEEDED *([^\n]*)$");
+ static const cmsys::RegularExpression rpathRegex("^ *RPATH *([^\n]*)$");
+ static const cmsys::RegularExpression runpathRegex("^ *RUNPATH *([^\n]*)$");
+ while (std::getline(*process.OutputStream(), line)) {
+ cmsys::RegularExpressionMatch match;
+ if (neededRegex.find(line.c_str(), match)) {
+ needed.push_back(match.match(1));
+ } else if (rpathRegex.find(line.c_str(), match)) {
+ std::vector<std::string> rpathSplit =
+ cmSystemTools::SplitString(match.match(1), ':');
+ rpaths.reserve(rpaths.size() + rpathSplit.size());
+ for (auto const& rpath : rpathSplit) {
+ rpaths.push_back(rpath);
+ }
+ } else if (runpathRegex.find(line.c_str(), match)) {
+ std::vector<std::string> runpathSplit =
+ cmSystemTools::SplitString(match.match(1), ':');
+ runpaths.reserve(runpaths.size() + runpathSplit.size());
+ for (auto const& runpath : runpathSplit) {
+ runpaths.push_back(runpath);
+ }
+ }
+ }
+
+ if (!process.Wait()) {
+ std::ostringstream e;
+ e << "Failed to wait on objdump process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ std::ostringstream e;
+ e << "Failed to run objdump on:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..969e4d4dc
--- /dev/null
+++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
@@ -0,0 +1,26 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsLinuxELFGetRuntimeCollectDependenciesTool_h
+#define cmBinUtilsLinuxELFGetRuntimeCollectDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool
+ : public cmBinUtilsLinuxELFGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+
+ bool GetFileInfo(std::string const& file, std::vector<std::string>& needed,
+ std::vector<std::string>& rpaths,
+ std::vector<std::string>& runpaths) override;
+};
+
+#endif // cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..a296a474c
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h"
+
+#include "cmRuntimeDependencyArchive.h"
+
+cmBinUtilsMacOSMachOGetRuntimeDependenciesTool::
+ cmBinUtilsMacOSMachOGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : Archive(archive)
+{
+}
+
+void cmBinUtilsMacOSMachOGetRuntimeDependenciesTool::SetError(
+ const std::string& error)
+{
+ this->Archive->SetError(error);
+}
diff --git a/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..dbb288255
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.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 cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h
+#define cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsMacOSMachOGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsMacOSMachOGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+ virtual ~cmBinUtilsMacOSMachOGetRuntimeDependenciesTool() = default;
+
+ virtual bool GetFileInfo(std::string const& file,
+ std::vector<std::string>& libs,
+ std::vector<std::string>& rpaths) = 0;
+
+protected:
+ cmRuntimeDependencyArchive* Archive;
+
+ void SetError(const std::string& error);
+};
+
+#endif // cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
new file mode 100644
index 000000000..98250b1c0
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -0,0 +1,231 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsMacOSMachOLinker.h"
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h"
+#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsLinker(archive)
+{
+}
+
+bool cmBinUtilsMacOSMachOLinker::Prepare()
+{
+ std::string tool = this->Archive->GetGetRuntimeDependenciesTool();
+ if (tool.empty()) {
+ tool = "otool";
+ }
+ if (tool == "otool") {
+ this->Tool =
+ cm::make_unique<cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool>(
+ this->Archive);
+ } else {
+ std::ostringstream e;
+ e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
+
+bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
+ std::string const& file, cmStateEnums::TargetType type)
+{
+ std::string executableFile;
+ if (type == cmStateEnums::EXECUTABLE) {
+ executableFile = file;
+ } else {
+ executableFile = this->Archive->GetBundleExecutable();
+ }
+ std::string executablePath;
+ if (!executableFile.empty()) {
+ executablePath = cmSystemTools::GetFilenamePath(executableFile);
+ }
+ return this->ScanDependencies(file, executablePath);
+}
+
+bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
+ std::string const& file, std::string const& executablePath)
+{
+ std::vector<std::string> libs;
+ std::vector<std::string> rpaths;
+ if (!this->Tool->GetFileInfo(file, libs, rpaths)) {
+ return false;
+ }
+
+ std::string loaderPath = cmSystemTools::GetFilenamePath(file);
+ return this->GetFileDependencies(libs, executablePath, loaderPath, rpaths);
+}
+
+bool cmBinUtilsMacOSMachOLinker::GetFileDependencies(
+ std::vector<std::string> const& names, std::string const& executablePath,
+ std::string const& loaderPath, std::vector<std::string> const& rpaths)
+{
+ for (std::string const& name : names) {
+ if (!this->Archive->IsPreExcluded(name)) {
+ std::string path;
+ bool resolved;
+ if (!this->ResolveDependency(name, executablePath, loaderPath, rpaths,
+ path, resolved)) {
+ return false;
+ }
+ if (resolved) {
+ if (!this->Archive->IsPostExcluded(path)) {
+ auto filename = cmSystemTools::GetFilenameName(path);
+ bool unique;
+ this->Archive->AddResolvedPath(filename, path, unique);
+ if (unique && !this->ScanDependencies(path, executablePath)) {
+ return false;
+ }
+ }
+ } else {
+ this->Archive->AddUnresolvedPath(name);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool cmBinUtilsMacOSMachOLinker::ResolveDependency(
+ std::string const& name, std::string const& executablePath,
+ std::string const& loaderPath, std::vector<std::string> const& rpaths,
+ std::string& path, bool& resolved)
+{
+ resolved = false;
+ if (cmHasLiteralPrefix(name, "@rpath/")) {
+ if (!this->ResolveRPathDependency(name, executablePath, loaderPath, rpaths,
+ path, resolved)) {
+ return false;
+ }
+ } else if (cmHasLiteralPrefix(name, "@loader_path/")) {
+ if (!this->ResolveLoaderPathDependency(name, loaderPath, path, resolved)) {
+ return false;
+ }
+ } else if (cmHasLiteralPrefix(name, "@executable_path/")) {
+ if (!this->ResolveExecutablePathDependency(name, executablePath, path,
+ resolved)) {
+ return false;
+ }
+ } else {
+ resolved = true;
+ path = name;
+ }
+
+ if (resolved && !cmSystemTools::FileIsFullPath(path)) {
+ this->SetError("Resolved path is not absolute");
+ return false;
+ }
+
+ return true;
+}
+
+bool cmBinUtilsMacOSMachOLinker::ResolveExecutablePathDependency(
+ std::string const& name, std::string const& executablePath,
+ std::string& path, bool& resolved)
+{
+ if (executablePath.empty()) {
+ resolved = false;
+ return true;
+ }
+
+ // 16 is == "@executable_path".length()
+ path = name;
+ path.replace(0, 16, executablePath);
+
+ if (!cmSystemTools::PathExists(path)) {
+ resolved = false;
+ return true;
+ }
+
+ resolved = true;
+ return true;
+}
+
+bool cmBinUtilsMacOSMachOLinker::ResolveLoaderPathDependency(
+ std::string const& name, std::string const& loaderPath, std::string& path,
+ bool& resolved)
+{
+ if (loaderPath.empty()) {
+ resolved = false;
+ return true;
+ }
+
+ // 12 is "@loader_path".length();
+ path = name;
+ path.replace(0, 12, loaderPath);
+
+ if (!cmSystemTools::PathExists(path)) {
+ resolved = false;
+ return true;
+ }
+
+ resolved = true;
+ return true;
+}
+
+bool cmBinUtilsMacOSMachOLinker::ResolveRPathDependency(
+ std::string const& name, std::string const& executablePath,
+ std::string const& loaderPath, std::vector<std::string> const& rpaths,
+ std::string& path, bool& resolved)
+{
+ for (std::string const& rpath : rpaths) {
+ std::string searchFile = name;
+ searchFile.replace(0, 6, rpath);
+ if (cmHasLiteralPrefix(searchFile, "@loader_path/")) {
+ if (!this->ResolveLoaderPathDependency(searchFile, loaderPath, path,
+ resolved)) {
+ return false;
+ }
+ if (resolved) {
+ return true;
+ }
+ } else if (cmHasLiteralPrefix(searchFile, "@executable_path/")) {
+ if (!this->ResolveExecutablePathDependency(searchFile, executablePath,
+ path, resolved)) {
+ return false;
+ }
+ if (resolved) {
+ return true;
+ }
+ } else if (cmSystemTools::PathExists(searchFile)) {
+ /*
+ * paraphrasing @ben.boeckel:
+ * if /b/libB.dylib is supposed to be used,
+ * /a/libbB.dylib will be found first if it exists. CMake tries to
+ * sort rpath directories to avoid this, but sometimes there is no
+ * right answer.
+ *
+ * I believe it is possible to resolve this using otools -l
+ * then checking the LC_LOAD_DYLIB command whose name is
+ * equal to the value of search_file, UNLESS the build
+ * specifically sets the RPath to paths that will match
+ * duplicate libs; at this point can we just point to
+ * user error, or is there a reason why the advantages
+ * to this scenario outweigh its disadvantages?
+ *
+ * Also priority seems to be the order as passed in when compiled
+ * so as long as this method's resolution guarantees priority
+ * in that manner further checking should not be necessary?
+ */
+ path = searchFile;
+ resolved = true;
+ return true;
+ }
+ }
+
+ resolved = false;
+ return true;
+}
diff --git a/Source/cmBinUtilsMacOSMachOLinker.h b/Source/cmBinUtilsMacOSMachOLinker.h
new file mode 100644
index 000000000..4a24ea35e
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOLinker.h
@@ -0,0 +1,59 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsMacOSMachOLinker_h
+#define cmBinUtilsMacOSMachOLinker_h
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsLinker.h"
+#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h"
+#include "cmStateTypes.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsMacOSMachOLinker : public cmBinUtilsLinker
+{
+public:
+ cmBinUtilsMacOSMachOLinker(cmRuntimeDependencyArchive* archive);
+
+ bool Prepare() override;
+
+ bool ScanDependencies(std::string const& file,
+ cmStateEnums::TargetType type) override;
+
+private:
+ std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool;
+
+ bool ScanDependencies(std::string const& file,
+ std::string const& executablePath);
+
+ bool GetFileDependencies(std::vector<std::string> const& names,
+ std::string const& executablePath,
+ std::string const& loaderPath,
+ std::vector<std::string> const& rpaths);
+
+ bool ResolveDependency(std::string const& name,
+ std::string const& executablePath,
+ std::string const& loaderPath,
+ std::vector<std::string> const& rpaths,
+ std::string& path, bool& resolved);
+
+ bool ResolveExecutablePathDependency(std::string const& name,
+ std::string const& executablePath,
+ std::string& path, bool& resolved);
+
+ bool ResolveLoaderPathDependency(std::string const& name,
+ std::string const& loaderPath,
+ std::string& path, bool& resolved);
+
+ bool ResolveRPathDependency(std::string const& name,
+ std::string const& executablePath,
+ std::string const& loaderPath,
+ std::vector<std::string> const& rpaths,
+ std::string& path, bool& resolved);
+};
+
+#endif // cmBinUtilsMacOSMachOLinker_h
diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..351d92aa8
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,100 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h"
+
+#include <sstream>
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmRuntimeDependencyArchive.h"
+#include "cmUVProcessChain.h"
+
+cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::
+ cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsMacOSMachOGetRuntimeDependenciesTool(archive)
+{
+}
+
+bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
+ std::string const& file, std::vector<std::string>& libs,
+ std::vector<std::string>& rpaths)
+{
+ std::vector<std::string> command;
+ if (!this->Archive->GetGetRuntimeDependenciesCommand("otool", command)) {
+ this->SetError("Could not find otool");
+ return false;
+ }
+ command.emplace_back("-l");
+ command.emplace_back(file);
+
+ cmUVProcessChainBuilder builder;
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .AddCommand(command);
+
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::ostringstream e;
+ e << "Failed to start otool process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string line;
+ static const cmsys::RegularExpression rpathRegex("^ *cmd LC_RPATH$");
+ static const cmsys::RegularExpression loadDylibRegex(
+ "^ *cmd LC_LOAD_DYLIB$");
+ static const cmsys::RegularExpression pathRegex(
+ "^ *path (.*) \\(offset [0-9]+\\)$");
+ static const cmsys::RegularExpression nameRegex(
+ "^ *name (.*) \\(offset [0-9]+\\)$");
+ while (std::getline(*process.OutputStream(), line)) {
+ cmsys::RegularExpressionMatch cmdMatch;
+ if (rpathRegex.find(line.c_str(), cmdMatch)) {
+ if (!std::getline(*process.OutputStream(), line) ||
+ !std::getline(*process.OutputStream(), line)) {
+ this->SetError("Invalid output from otool");
+ return false;
+ }
+
+ cmsys::RegularExpressionMatch pathMatch;
+ if (pathRegex.find(line.c_str(), pathMatch)) {
+ rpaths.push_back(pathMatch.match(1));
+ } else {
+ this->SetError("Invalid output from otool");
+ return false;
+ }
+ } else if (loadDylibRegex.find(line.c_str(), cmdMatch)) {
+ if (!std::getline(*process.OutputStream(), line) ||
+ !std::getline(*process.OutputStream(), line)) {
+ this->SetError("Invalid output from otool");
+ return false;
+ }
+
+ cmsys::RegularExpressionMatch nameMatch;
+ if (nameRegex.find(line.c_str(), nameMatch)) {
+ libs.push_back(nameMatch.match(1));
+ } else {
+ this->SetError("Invalid output from otool");
+ return false;
+ }
+ }
+ }
+
+ if (!process.Wait()) {
+ std::ostringstream e;
+ e << "Failed to wait on otool process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ std::ostringstream e;
+ e << "Failed to run otool on:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..8ac7e188e
--- /dev/null
+++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
@@ -0,0 +1,25 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h
+#define cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool
+ : public cmBinUtilsMacOSMachOGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+
+ bool GetFileInfo(std::string const& file, std::vector<std::string>& libs,
+ std::vector<std::string>& rpaths) override;
+};
+
+#endif // cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..f342884dc
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,68 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
+
+#include <sstream>
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmRuntimeDependencyArchive.h"
+#include "cmUVProcessChain.h"
+
+cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::
+ cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsWindowsPEGetRuntimeDependenciesTool(archive)
+{
+}
+
+bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
+ const std::string& file, std::vector<std::string>& needed)
+{
+ cmUVProcessChainBuilder builder;
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+ std::vector<std::string> command;
+ if (!this->Archive->GetGetRuntimeDependenciesCommand("dumpbin", command)) {
+ this->SetError("Could not find dumpbin");
+ return false;
+ }
+ command.emplace_back("/dependents");
+ command.push_back(file);
+ builder.AddCommand(command);
+
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::ostringstream e;
+ e << "Failed to start dumpbin process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string line;
+ static const cmsys::RegularExpression regex(
+ "^ ([^\n]*\\.[Dd][Ll][Ll])\r$");
+ while (std::getline(*process.OutputStream(), line)) {
+ cmsys::RegularExpressionMatch match;
+ if (regex.find(line.c_str(), match)) {
+ needed.push_back(match.match(1));
+ }
+ }
+
+ if (!process.Wait()) {
+ std::ostringstream e;
+ e << "Failed to wait on dumpbin process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ std::ostringstream e;
+ e << "Failed to run dumpbin on:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..eae22eae8
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
@@ -0,0 +1,25 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h
+#define cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool
+ : public cmBinUtilsWindowsPEGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+
+ bool GetFileInfo(const std::string& file,
+ std::vector<std::string>& needed) override;
+};
+
+#endif // cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..468a40c7a
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
+
+#include "cmRuntimeDependencyArchive.h"
+
+cmBinUtilsWindowsPEGetRuntimeDependenciesTool::
+ cmBinUtilsWindowsPEGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : Archive(archive)
+{
+}
+
+void cmBinUtilsWindowsPEGetRuntimeDependenciesTool::SetError(
+ const std::string& error)
+{
+ this->Archive->SetError(error);
+}
diff --git a/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..e9e402b0f
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h
@@ -0,0 +1,28 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h
+#define cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsWindowsPEGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsWindowsPEGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+ virtual ~cmBinUtilsWindowsPEGetRuntimeDependenciesTool() = default;
+
+ virtual bool GetFileInfo(const std::string& file,
+ std::vector<std::string>& needed) = 0;
+
+protected:
+ cmRuntimeDependencyArchive* Archive;
+
+ void SetError(const std::string& error);
+};
+
+#endif // cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h
diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx
new file mode 100644
index 000000000..79e39e9c5
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPELinker.cxx
@@ -0,0 +1,123 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsWindowsPELinker.h"
+
+#include <sstream>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
+#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
+#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+cmBinUtilsWindowsPELinker::cmBinUtilsWindowsPELinker(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsLinker(archive)
+{
+}
+
+bool cmBinUtilsWindowsPELinker::Prepare()
+{
+ std::string tool = this->Archive->GetGetRuntimeDependenciesTool();
+ if (tool.empty()) {
+ std::vector<std::string> command;
+ if (this->Archive->GetGetRuntimeDependenciesCommand("dumpbin", command)) {
+ tool = "dumpbin";
+ } else {
+ tool = "objdump";
+ }
+ }
+ if (tool == "dumpbin") {
+ this->Tool =
+ cm::make_unique<cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool>(
+ this->Archive);
+ } else if (tool == "objdump") {
+ this->Tool =
+ cm::make_unique<cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool>(
+ this->Archive);
+ } else {
+ std::ostringstream e;
+ e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
+
+bool cmBinUtilsWindowsPELinker::ScanDependencies(
+ std::string const& file, cmStateEnums::TargetType /* unused */)
+{
+ std::vector<std::string> needed;
+ if (!this->Tool->GetFileInfo(file, needed)) {
+ return false;
+ }
+ for (auto& n : needed) {
+ n = cmSystemTools::LowerCase(n);
+ }
+ std::string origin = cmSystemTools::GetFilenamePath(file);
+
+ for (auto const& lib : needed) {
+ if (!this->Archive->IsPreExcluded(lib)) {
+ std::string path;
+ bool resolved = false;
+ if (!this->ResolveDependency(lib, origin, path, resolved)) {
+ return false;
+ }
+ if (resolved) {
+ if (!this->Archive->IsPostExcluded(path)) {
+ bool unique;
+ this->Archive->AddResolvedPath(lib, path, unique);
+ if (unique &&
+ !this->ScanDependencies(path, cmStateEnums::SHARED_LIBRARY)) {
+ return false;
+ }
+ }
+ } else {
+ this->Archive->AddUnresolvedPath(lib);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool cmBinUtilsWindowsPELinker::ResolveDependency(std::string const& name,
+ std::string const& origin,
+ std::string& path,
+ bool& resolved)
+{
+ auto dirs = this->Archive->GetSearchDirectories();
+
+#ifdef _WIN32
+ char buf[MAX_PATH];
+ unsigned int len;
+ if ((len = GetWindowsDirectoryA(buf, MAX_PATH)) > 0) {
+ dirs.insert(dirs.begin(), std::string(buf, len));
+ }
+ if ((len = GetSystemDirectoryA(buf, MAX_PATH)) > 0) {
+ dirs.insert(dirs.begin(), std::string(buf, len));
+ }
+#endif
+
+ dirs.insert(dirs.begin(), origin);
+
+ for (auto const& searchPath : dirs) {
+ path = cmStrCat(searchPath, '/', name);
+ if (cmSystemTools::PathExists(path)) {
+ resolved = true;
+ return true;
+ }
+ }
+
+ resolved = false;
+ return true;
+}
diff --git a/Source/cmBinUtilsWindowsPELinker.h b/Source/cmBinUtilsWindowsPELinker.h
new file mode 100644
index 000000000..a8bb59629
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPELinker.h
@@ -0,0 +1,33 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsWindowsPELinker_h
+#define cmBinUtilsWindowsPELinker_h
+
+#include <memory>
+#include <string>
+
+#include "cmBinUtilsLinker.h"
+#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
+#include "cmStateTypes.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsWindowsPELinker : public cmBinUtilsLinker
+{
+public:
+ cmBinUtilsWindowsPELinker(cmRuntimeDependencyArchive* archive);
+
+ bool Prepare() override;
+
+ bool ScanDependencies(std::string const& file,
+ cmStateEnums::TargetType type) override;
+
+private:
+ std::unique_ptr<cmBinUtilsWindowsPEGetRuntimeDependenciesTool> Tool;
+
+ bool ResolveDependency(std::string const& name, std::string const& origin,
+ std::string& path, bool& resolved);
+};
+
+#endif // cmBinUtilsWindowsPELinker_h
diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
new file mode 100644
index 000000000..1effda053
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
@@ -0,0 +1,68 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
+
+#include <sstream>
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmRuntimeDependencyArchive.h"
+#include "cmUVProcessChain.h"
+
+cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::
+ cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive)
+ : cmBinUtilsWindowsPEGetRuntimeDependenciesTool(archive)
+{
+}
+
+bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
+ const std::string& file, std::vector<std::string>& needed)
+{
+ cmUVProcessChainBuilder builder;
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+ std::vector<std::string> command;
+ if (!this->Archive->GetGetRuntimeDependenciesCommand("objdump", command)) {
+ this->SetError("Could not find objdump");
+ return false;
+ }
+ command.emplace_back("-p");
+ command.push_back(file);
+ builder.AddCommand(command);
+
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::ostringstream e;
+ e << "Failed to start objdump process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string line;
+ static const cmsys::RegularExpression regex(
+ "^\t*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])\r$");
+ while (std::getline(*process.OutputStream(), line)) {
+ cmsys::RegularExpressionMatch match;
+ if (regex.find(line.c_str(), match)) {
+ needed.push_back(match.match(1));
+ }
+ }
+
+ if (!process.Wait()) {
+ std::ostringstream e;
+ e << "Failed to wait on objdump process for:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ std::ostringstream e;
+ e << "Failed to run objdump on:\n " << file;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
new file mode 100644
index 000000000..a67cb0cf1
--- /dev/null
+++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
@@ -0,0 +1,25 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h
+#define cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h
+
+#include <string>
+#include <vector>
+
+#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool
+ : public cmBinUtilsWindowsPEGetRuntimeDependenciesTool
+{
+public:
+ cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool(
+ cmRuntimeDependencyArchive* archive);
+
+ bool GetFileInfo(const std::string& file,
+ std::vector<std::string>& needed) override;
+};
+
+#endif // cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h
diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx
index d07898fd6..95db689cd 100644
--- a/Source/cmBreakCommand.cxx
+++ b/Source/cmBreakCommand.cxx
@@ -10,14 +10,14 @@
#include "cmPolicies.h"
// cmBreakCommand
-bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+bool cmBreakCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (!this->Makefile->IsLoopBlock()) {
+ if (!status.GetMakefile().IsLoopBlock()) {
bool issueMessage = true;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
break;
@@ -34,7 +34,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
if (issueMessage) {
e << "A BREAK command was found outside of a proper "
"FOREACH or WHILE loop scope.";
- this->Makefile->IssueMessage(messageType, e.str());
+ status.GetMakefile().IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
@@ -47,7 +47,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
bool issueMessage = true;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0055)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
break;
@@ -63,7 +63,7 @@ bool cmBreakCommand::InitialPass(std::vector<std::string> const& args,
if (issueMessage) {
e << "The BREAK command does not accept any arguments.";
- this->Makefile->IssueMessage(messageType, e.str());
+ status.GetMakefile().IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index 3b1856736..e6ce6fe74 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmBreakCommand
+/**
* \brief Break from an enclosing foreach or while loop
*
* cmBreakCommand returns from an enclosing foreach or while loop
*/
-class cmBreakCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmBreakCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmBreakCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 428a0b224..49c943975 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -2,32 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmBuildCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-bool cmBuildCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
-{
- // Support the legacy signature of the command:
- //
- if (2 == args.size()) {
- return this->TwoArgsSignature(args);
- }
-
- return this->MainSignature(args);
-}
+namespace {
-bool cmBuildCommand::MainSignature(std::vector<std::string> const& args)
+bool MainSignature(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("requires at least one argument naming a CMake variable");
+ status.SetError("requires at least one argument naming a CMake variable");
return false;
}
@@ -63,9 +52,7 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args)
doing = DoingNone;
target = args[i];
} else {
- std::ostringstream e;
- e << "unknown argument \"" << args[i] << "\"";
- this->SetError(e.str());
+ status.SetError(cmStrCat("unknown argument \"", args[i], "\""));
return false;
}
}
@@ -82,30 +69,32 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args)
configuration = "Release";
}
+ cmMakefile& mf = status.GetMakefile();
if (!project_name.empty()) {
- this->Makefile->IssueMessage(
- MessageType::AUTHOR_WARNING,
- "Ignoring PROJECT_NAME option because it has no effect.");
+ mf.IssueMessage(MessageType::AUTHOR_WARNING,
+ "Ignoring PROJECT_NAME option because it has no effect.");
}
- std::string makecommand =
- this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand(
- target, configuration, "", this->Makefile->IgnoreErrorsCMP0061());
+ std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
+ target, configuration, "", mf.IgnoreErrorsCMP0061());
- this->Makefile->AddDefinition(variable, makecommand.c_str());
+ mf.AddDefinition(variable, makecommand);
return true;
}
-bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args)
+bool TwoArgsSignature(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with less than two arguments");
+ status.SetError("called with less than two arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
std::string const& define = args[0];
- const char* cacheValue = this->Makefile->GetDefinition(define);
+ const char* cacheValue = mf.GetDefinition(define);
std::string configType;
if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) ||
@@ -113,16 +102,28 @@ bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args)
configType = "Release";
}
- std::string makecommand =
- this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand(
- "", configType, "", this->Makefile->IgnoreErrorsCMP0061());
+ std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
+ "", configType, "", mf.IgnoreErrorsCMP0061());
if (cacheValue) {
return true;
}
- this->Makefile->AddCacheDefinition(define, makecommand.c_str(),
- "Command used to build entire project "
- "from the command line.",
- cmStateEnums::STRING);
+ mf.AddCacheDefinition(define, makecommand.c_str(),
+ "Command used to build entire project "
+ "from the command line.",
+ cmStateEnums::STRING);
return true;
}
+
+} // namespace
+
+bool cmBuildCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ // Support the legacy signature of the command:
+ if (args.size() == 2) {
+ return TwoArgsSignature(args, status);
+ }
+
+ return MainSignature(args, status);
+}
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
index e0529a414..45aa71da2 100644
--- a/Source/cmBuildCommand.h
+++ b/Source/cmBuildCommand.h
@@ -8,42 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmBuildCommand
- * \brief build_command command
- *
- * cmBuildCommand implements the build_command CMake command
- */
-class cmBuildCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmBuildCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * The primary command signature with optional, KEYWORD-based args.
- */
- virtual bool MainSignature(std::vector<std::string> const& args);
-
- /**
- * Legacy "exactly 2 args required" signature.
- */
- virtual bool TwoArgsSignature(std::vector<std::string> const& args);
-
-private:
- bool IgnoreErrors() const;
-};
+bool cmBuildCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index ddff68686..3e517dca4 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -2,24 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmBuildNameCommand.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-// cmBuildNameCommand
-bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmBuildNameCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- const char* cacheValue = this->Makefile->GetDefinition(args[0]);
+ cmMakefile& mf = status.GetMakefile();
+ const char* cacheValue = mf.GetDefinition(args[0]);
if (cacheValue) {
// do we need to correct the value?
cmsys::RegularExpression reg("[()/]");
@@ -28,14 +28,14 @@ bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args,
std::replace(cv.begin(), cv.end(), '/', '_');
std::replace(cv.begin(), cv.end(), '(', '_');
std::replace(cv.begin(), cv.end(), ')', '_');
- this->Makefile->AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
- cmStateEnums::STRING);
+ mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
+ cmStateEnums::STRING);
}
return true;
}
std::string buildname = "WinNT";
- if (this->Makefile->GetDefinition("UNIX")) {
+ if (mf.GetDefinition("UNIX")) {
buildname.clear();
cmSystemTools::RunSingleCommand("uname -a", &buildname, &buildname);
if (!buildname.empty()) {
@@ -47,14 +47,14 @@ bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args,
}
}
std::string compiler = "${CMAKE_CXX_COMPILER}";
- this->Makefile->ExpandVariablesInString(compiler);
+ mf.ExpandVariablesInString(compiler);
buildname += "-";
buildname += cmSystemTools::GetFilenameName(compiler);
std::replace(buildname.begin(), buildname.end(), '/', '_');
std::replace(buildname.begin(), buildname.end(), '(', '_');
std::replace(buildname.begin(), buildname.end(), ')', '_');
- this->Makefile->AddCacheDefinition(args[0], buildname.c_str(),
- "Name of build.", cmStateEnums::STRING);
+ mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.",
+ cmStateEnums::STRING);
return true;
}
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index 4bb72d147..37a72689c 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -8,16 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmBuildNameCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmBuildNameCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmBuildNameCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCLocaleEnvironmentScope.cxx b/Source/cmCLocaleEnvironmentScope.cxx
index 737e3ea86..c6c38f83c 100644
--- a/Source/cmCLocaleEnvironmentScope.cxx
+++ b/Source/cmCLocaleEnvironmentScope.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCLocaleEnvironmentScope.h"
-#include "cmSystemTools.h"
-
#include <sstream>
#include <utility>
+#include "cmSystemTools.h"
+
cmCLocaleEnvironmentScope::cmCLocaleEnvironmentScope()
{
this->SetEnv("LANGUAGE", "");
diff --git a/Source/cmCLocaleEnvironmentScope.h b/Source/cmCLocaleEnvironmentScope.h
index 93032c12e..aa2827e74 100644
--- a/Source/cmCLocaleEnvironmentScope.h
+++ b/Source/cmCLocaleEnvironmentScope.h
@@ -22,7 +22,7 @@ private:
std::string GetEnv(std::string const& key);
void SetEnv(std::string const& key, std::string const& value);
- typedef std::map<std::string, std::string> backup_map_t;
+ using backup_map_t = std::map<std::string, std::string>;
backup_map_t EnvironmentBackup;
};
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 54f08bbcd..26e9af027 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -2,11 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeHostSystemInformationCommand.h"
-#include <sstream>
+#include <cstddef>
-#include "cmMakefile.h"
#include "cmsys/SystemInformation.hxx"
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+
#if defined(_WIN32)
# include "cmAlgorithms.h"
# include "cmGlobalGenerator.h"
@@ -16,16 +18,22 @@
# define HAVE_VS_SETUP_HELPER
#endif
-class cmExecutionStatus;
+namespace {
+bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
+ std::string const& key, std::string& value);
+std::string ValueToString(size_t value);
+std::string ValueToString(const char* value);
+std::string ValueToString(std::string const& value);
+}
// cmCMakeHostSystemInformation
-bool cmCMakeHostSystemInformationCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
size_t current_index = 0;
if (args.size() < (current_index + 2) || args[current_index] != "RESULT") {
- this->SetError("missing RESULT specification.");
+ status.SetError("missing RESULT specification.");
return false;
}
@@ -33,7 +41,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass(
current_index += 2;
if (args.size() < (current_index + 2) || args[current_index] != "QUERY") {
- this->SetError("missing QUERY specification");
+ status.SetError("missing QUERY specification");
return false;
}
@@ -49,89 +57,91 @@ bool cmCMakeHostSystemInformationCommand::InitialPass(
result_list += ";";
}
std::string value;
- if (!this->GetValue(info, key, value)) {
+ if (!GetValue(status, info, key, value)) {
return false;
}
result_list += value;
}
- this->Makefile->AddDefinition(variable, result_list.c_str());
+ status.GetMakefile().AddDefinition(variable, result_list);
return true;
}
-bool cmCMakeHostSystemInformationCommand::GetValue(
- cmsys::SystemInformation& info, std::string const& key, std::string& value)
+namespace {
+
+bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
+ std::string const& key, std::string& value)
{
if (key == "NUMBER_OF_LOGICAL_CORES") {
- value = this->ValueToString(info.GetNumberOfLogicalCPU());
+ value = ValueToString(info.GetNumberOfLogicalCPU());
} else if (key == "NUMBER_OF_PHYSICAL_CORES") {
- value = this->ValueToString(info.GetNumberOfPhysicalCPU());
+ value = ValueToString(info.GetNumberOfPhysicalCPU());
} else if (key == "HOSTNAME") {
- value = this->ValueToString(info.GetHostname());
+ value = ValueToString(info.GetHostname());
} else if (key == "FQDN") {
- value = this->ValueToString(info.GetFullyQualifiedDomainName());
+ value = ValueToString(info.GetFullyQualifiedDomainName());
} else if (key == "TOTAL_VIRTUAL_MEMORY") {
- value = this->ValueToString(info.GetTotalVirtualMemory());
+ value = ValueToString(info.GetTotalVirtualMemory());
} else if (key == "AVAILABLE_VIRTUAL_MEMORY") {
- value = this->ValueToString(info.GetAvailableVirtualMemory());
+ value = ValueToString(info.GetAvailableVirtualMemory());
} else if (key == "TOTAL_PHYSICAL_MEMORY") {
- value = this->ValueToString(info.GetTotalPhysicalMemory());
+ value = ValueToString(info.GetTotalPhysicalMemory());
} else if (key == "AVAILABLE_PHYSICAL_MEMORY") {
- value = this->ValueToString(info.GetAvailablePhysicalMemory());
+ value = ValueToString(info.GetAvailablePhysicalMemory());
} else if (key == "IS_64BIT") {
- value = this->ValueToString(info.Is64Bits());
+ value = ValueToString(info.Is64Bits());
} else if (key == "HAS_FPU") {
- value = this->ValueToString(
+ value = ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU));
} else if (key == "HAS_MMX") {
- value = this->ValueToString(
+ value = ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX));
} else if (key == "HAS_MMX_PLUS") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS));
} else if (key == "HAS_SSE") {
- value = this->ValueToString(
+ value = ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE));
} else if (key == "HAS_SSE2") {
- value = this->ValueToString(
+ value = ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2));
} else if (key == "HAS_SSE_FP") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SSE_FP));
} else if (key == "HAS_SSE_MMX") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SSE_MMX));
} else if (key == "HAS_AMD_3DNOW") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW));
} else if (key == "HAS_AMD_3DNOW_PLUS") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS));
} else if (key == "HAS_IA64") {
- value = this->ValueToString(
+ value = ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64));
} else if (key == "HAS_SERIAL_NUMBER") {
- value = this->ValueToString(info.DoesCPUSupportFeature(
+ value = ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER));
} else if (key == "PROCESSOR_NAME") {
- value = this->ValueToString(info.GetExtendedProcessorName());
+ value = ValueToString(info.GetExtendedProcessorName());
} else if (key == "PROCESSOR_DESCRIPTION") {
value = info.GetCPUDescription();
} else if (key == "PROCESSOR_SERIAL_NUMBER") {
- value = this->ValueToString(info.GetProcessorSerialNumber());
+ value = ValueToString(info.GetProcessorSerialNumber());
} else if (key == "OS_NAME") {
- value = this->ValueToString(info.GetOSName());
+ value = ValueToString(info.GetOSName());
} else if (key == "OS_RELEASE") {
- value = this->ValueToString(info.GetOSRelease());
+ value = ValueToString(info.GetOSRelease());
} else if (key == "OS_VERSION") {
- value = this->ValueToString(info.GetOSVersion());
+ value = ValueToString(info.GetOSVersion());
} else if (key == "OS_PLATFORM") {
- value = this->ValueToString(info.GetOSPlatform());
+ value = ValueToString(info.GetOSPlatform());
#ifdef HAVE_VS_SETUP_HELPER
} else if (key == "VS_15_DIR") {
// If generating for the VS 15 IDE, use the same instance.
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) {
cmGlobalVisualStudioVersionedGenerator* vs15gen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
@@ -147,7 +157,7 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
}
} else if (key == "VS_16_DIR") {
// If generating for the VS 16 IDE, use the same instance.
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) {
cmGlobalVisualStudioVersionedGenerator* vs16gen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
@@ -164,30 +174,26 @@ bool cmCMakeHostSystemInformationCommand::GetValue(
#endif
} else {
std::string e = "does not recognize <key> " + key;
- this->SetError(e);
+ status.SetError(e);
return false;
}
return true;
}
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
- size_t value) const
+std::string ValueToString(size_t value)
{
- std::ostringstream tmp;
- tmp << value;
- return tmp.str();
+ return std::to_string(value);
}
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
- const char* value) const
+std::string ValueToString(const char* value)
{
std::string safe_string = value ? value : "";
return safe_string;
}
-std::string cmCMakeHostSystemInformationCommand::ValueToString(
- std::string const& value) const
+std::string ValueToString(std::string const& value)
{
return value;
}
+}
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index b8716418c..79e3f2702 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -5,48 +5,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stddef.h>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-namespace cmsys {
-class SystemInformation;
-} // namespace cmsys
-/** \class cmCMakeHostSystemInformationCommand
+/**
* \brief Query host system specific information
*
* cmCMakeHostSystemInformationCommand queries system information of
* the system on which CMake runs.
*/
-class cmCMakeHostSystemInformationCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- return new cmCMakeHostSystemInformationCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool GetValue(cmsys::SystemInformation& info, std::string const& key,
- std::string& value);
-
- std::string ValueToString(size_t value) const;
- std::string ValueToString(const char* value) const;
- std::string ValueToString(std::string const& value) const;
-};
+bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
index 4b4bca243..1b03873d0 100644
--- a/Source/cmCMakeMinimumRequired.cxx
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -2,29 +2,35 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeMinimumRequired.h"
+#include <cstdio>
#include <sstream>
-#include <stdio.h>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
-class cmExecutionStatus;
+namespace {
+bool EnforceUnknownArguments(std::string const& version_max,
+ std::vector<std::string> const& unknown_arguments,
+ cmExecutionStatus& status);
+}
// cmCMakeMinimumRequired
-bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmCMakeMinimumRequired(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Process arguments.
std::string version_string;
bool doing_version = false;
+ std::vector<std::string> unknown_arguments;
for (std::string const& arg : args) {
if (arg == "VERSION") {
doing_version = true;
} else if (arg == "FATAL_ERROR") {
if (doing_version) {
- this->SetError("called with no value for VERSION.");
+ status.SetError("called with no value for VERSION.");
return false;
}
doing_version = false;
@@ -32,17 +38,17 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
doing_version = false;
version_string = arg;
} else {
- this->UnknownArguments.push_back(arg);
+ unknown_arguments.push_back(arg);
}
}
if (doing_version) {
- this->SetError("called with no value for VERSION.");
+ status.SetError("called with no value for VERSION.");
return false;
}
// Make sure there was a version to check.
if (version_string.empty()) {
- return this->EnforceUnknownArguments(std::string());
+ return EnforceUnknownArguments(std::string(), unknown_arguments, status);
}
// Separate the <min> version and any trailing ...<max> component.
@@ -56,13 +62,13 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
std::ostringstream e;
e << "VERSION \"" << version_string
<< R"(" does not have a version on both sides of "...".)";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
// Save the required version string.
- this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION",
- version_min.c_str());
+ status.GetMakefile().AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION",
+ version_min);
// Get the current version number.
unsigned int current_major = cmVersion::GetMajorVersion();
@@ -80,7 +86,7 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
&required_minor, &required_patch, &required_tweak) < 2) {
std::ostringstream e;
e << "could not parse VERSION \"" << version_min << "\".";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -96,32 +102,34 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
e << "CMake " << version_min
<< " or higher is required. You are running version "
<< cmVersion::GetCMakeVersion();
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return true;
}
// The version is not from the future, so enforce unknown arguments.
- if (!this->EnforceUnknownArguments(version_max)) {
+ if (!EnforceUnknownArguments(version_max, unknown_arguments, status)) {
return false;
}
if (required_major < 2 || (required_major == 2 && required_minor < 4)) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
"Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.");
- this->Makefile->SetPolicyVersion("2.4", version_max);
+ status.GetMakefile().SetPolicyVersion("2.4", version_max);
} else {
- this->Makefile->SetPolicyVersion(version_min, version_max);
+ status.GetMakefile().SetPolicyVersion(version_min, version_max);
}
return true;
}
-bool cmCMakeMinimumRequired::EnforceUnknownArguments(
- std::string const& version_max)
+namespace {
+bool EnforceUnknownArguments(std::string const& version_max,
+ std::vector<std::string> const& unknown_arguments,
+ cmExecutionStatus& status)
{
- if (this->UnknownArguments.empty()) {
+ if (unknown_arguments.empty()) {
return true;
}
@@ -150,7 +158,8 @@ bool cmCMakeMinimumRequired::EnforceUnknownArguments(
}
std::ostringstream e;
- e << "called with unknown argument \"" << this->UnknownArguments[0] << "\".";
- this->SetError(e.str());
+ e << "called with unknown argument \"" << unknown_arguments[0] << "\".";
+ status.SetError(e.str());
return false;
}
+}
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index f9b61e142..53f78f690 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -8,33 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmCMakeMinimumRequired
+/**
* \brief cmake_minimum_required command
*
* cmCMakeMinimumRequired implements the cmake_minimum_required CMake command
*/
-class cmCMakeMinimumRequired : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmCMakeMinimumRequired; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::vector<std::string> UnknownArguments;
- bool EnforceUnknownArguments(std::string const& version_max);
-};
+bool cmCMakeMinimumRequired(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 8da5ef760..b7f08d2dd 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -2,90 +2,99 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakePolicyCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
-
-class cmExecutionStatus;
+#include "cmStringAlgorithms.h"
+
+namespace {
+bool HandleSetMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+bool HandleGetMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+bool HandleVersionMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+bool HandleGetWarningMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+}
// cmCMakePolicyCommand
-bool cmCMakePolicyCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("requires at least one argument.");
+ status.SetError("requires at least one argument.");
return false;
}
if (args[0] == "SET") {
- return this->HandleSetMode(args);
+ return HandleSetMode(args, status);
}
if (args[0] == "GET") {
- return this->HandleGetMode(args);
+ return HandleGetMode(args, status);
}
if (args[0] == "PUSH") {
if (args.size() > 1) {
- this->SetError("PUSH may not be given additional arguments.");
+ status.SetError("PUSH may not be given additional arguments.");
return false;
}
- this->Makefile->PushPolicy();
+ status.GetMakefile().PushPolicy();
return true;
}
if (args[0] == "POP") {
if (args.size() > 1) {
- this->SetError("POP may not be given additional arguments.");
+ status.SetError("POP may not be given additional arguments.");
return false;
}
- this->Makefile->PopPolicy();
+ status.GetMakefile().PopPolicy();
return true;
}
if (args[0] == "VERSION") {
- return this->HandleVersionMode(args);
+ return HandleVersionMode(args, status);
}
if (args[0] == "GET_WARNING") {
- return this->HandleGetWarningMode(args);
+ return HandleGetWarningMode(args, status);
}
- std::ostringstream e;
- e << "given unknown first argument \"" << args[0] << "\"";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given unknown first argument \"", args[0], "\""));
return false;
}
-bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
+namespace {
+
+bool HandleSetMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("SET must be given exactly 2 additional arguments.");
+ status.SetError("SET must be given exactly 2 additional arguments.");
return false;
}
- cmPolicies::PolicyStatus status;
+ cmPolicies::PolicyStatus policyStatus;
if (args[2] == "OLD") {
- status = cmPolicies::OLD;
+ policyStatus = cmPolicies::OLD;
} else if (args[2] == "NEW") {
- status = cmPolicies::NEW;
+ policyStatus = cmPolicies::NEW;
} else {
- std::ostringstream e;
- e << "SET given unrecognized policy status \"" << args[2] << "\"";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("SET given unrecognized policy status \"", args[2], "\""));
return false;
}
- if (!this->Makefile->SetPolicy(args[1].c_str(), status)) {
- this->SetError("SET failed to set policy.");
+ if (!status.GetMakefile().SetPolicy(args[1].c_str(), policyStatus)) {
+ status.SetError("SET failed to set policy.");
return false;
}
if (args[1] == "CMP0001" &&
- (status == cmPolicies::WARN || status == cmPolicies::OLD)) {
- if (!(this->Makefile->GetState()->GetInitializedCacheValue(
+ (policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD)) {
+ if (!(status.GetMakefile().GetState()->GetInitializedCacheValue(
"CMAKE_BACKWARDS_COMPATIBILITY"))) {
// Set it to 2.4 because that is the last version where the
// variable had meaning.
- this->Makefile->AddCacheDefinition(
+ status.GetMakefile().AddCacheDefinition(
"CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
"For backwards compatibility, what version of CMake "
"commands and "
@@ -96,14 +105,15 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
return true;
}
-bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
+bool HandleGetMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
bool parent_scope = false;
if (args.size() == 4 && args[3] == "PARENT_SCOPE") {
// Undocumented PARENT_SCOPE option for use within CMake.
parent_scope = true;
} else if (args.size() != 3) {
- this->SetError("GET must be given exactly 2 additional arguments.");
+ status.SetError("GET must be given exactly 2 additional arguments.");
return false;
}
@@ -114,54 +124,55 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
// Lookup the policy number.
cmPolicies::PolicyID pid;
if (!cmPolicies::GetPolicyID(id.c_str(), pid)) {
- std::ostringstream e;
- e << "GET given policy \"" << id << "\" which is not known to this "
- << "version of CMake.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("GET given policy \"", id,
+ "\" which is not known to this version of CMake."));
return false;
}
// Lookup the policy setting.
- cmPolicies::PolicyStatus status =
- this->Makefile->GetPolicyStatus(pid, parent_scope);
- switch (status) {
+ cmPolicies::PolicyStatus policyStatus =
+ status.GetMakefile().GetPolicyStatus(pid, parent_scope);
+ switch (policyStatus) {
case cmPolicies::OLD:
// Report that the policy is set to OLD.
- this->Makefile->AddDefinition(var, "OLD");
+ status.GetMakefile().AddDefinition(var, "OLD");
break;
case cmPolicies::WARN:
// Report that the policy is not set.
- this->Makefile->AddDefinition(var, "");
+ status.GetMakefile().AddDefinition(var, "");
break;
case cmPolicies::NEW:
// Report that the policy is set to NEW.
- this->Makefile->AddDefinition(var, "NEW");
+ status.GetMakefile().AddDefinition(var, "NEW");
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// The policy is required to be set before anything needs it.
{
- std::ostringstream e;
- e << cmPolicies::GetRequiredPolicyError(pid) << "\n"
- << "The call to cmake_policy(GET " << id << " ...) at which this "
- << "error appears requests the policy, and this version of CMake "
- << "requires that the policy be set to NEW before it is checked.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ cmPolicies::GetRequiredPolicyError(pid), "\n",
+ "The call to cmake_policy(GET ", id,
+ " ...) at which this "
+ "error appears requests the policy, and this version of CMake ",
+ "requires that the policy be set to NEW before it is checked."));
}
}
return true;
}
-bool cmCMakePolicyCommand::HandleVersionMode(
- std::vector<std::string> const& args)
+bool HandleVersionMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() <= 1) {
- this->SetError("VERSION not given an argument");
+ status.SetError("VERSION not given an argument");
return false;
}
if (args.size() >= 3) {
- this->SetError("VERSION given too many arguments");
+ status.SetError("VERSION given too many arguments");
return false;
}
std::string const& version_string = args[1];
@@ -174,22 +185,21 @@ bool cmCMakePolicyCommand::HandleVersionMode(
: std::string();
if (dd != std::string::npos &&
(version_min.empty() || version_max.empty())) {
- std::ostringstream e;
- e << "VERSION \"" << version_string
- << R"(" does not have a version on both sides of "...".)";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("VERSION \"", version_string,
+ R"(" does not have a version on both sides of "...".)"));
return false;
}
- this->Makefile->SetPolicyVersion(version_min, version_max);
+ status.GetMakefile().SetPolicyVersion(version_min, version_max);
return true;
}
-bool cmCMakePolicyCommand::HandleGetWarningMode(
- std::vector<std::string> const& args)
+bool HandleGetWarningMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError(
+ status.SetError(
"GET_WARNING must be given exactly 2 additional arguments.");
return false;
}
@@ -201,16 +211,15 @@ bool cmCMakePolicyCommand::HandleGetWarningMode(
// Lookup the policy number.
cmPolicies::PolicyID pid;
if (!cmPolicies::GetPolicyID(id.c_str(), pid)) {
- std::ostringstream e;
- e << "GET_WARNING given policy \"" << id
- << "\" which is not known to this version of CMake.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("GET_WARNING given policy \"", id,
+ "\" which is not known to this version of CMake."));
return false;
}
// Lookup the policy warning.
- this->Makefile->AddDefinition(var,
- cmPolicies::GetPolicyWarning(pid).c_str());
+ status.GetMakefile().AddDefinition(var, cmPolicies::GetPolicyWarning(pid));
return true;
}
+}
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index cca140617..ba9397d76 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -8,36 +8,15 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmCMakePolicyCommand
+/**
* \brief Set how CMake should handle policies
*
* cmCMakePolicyCommand sets how CMake should deal with backwards
* compatibility policies.
*/
-class cmCMakePolicyCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmCMakePolicyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandleSetMode(std::vector<std::string> const& args);
- bool HandleGetMode(std::vector<std::string> const& args);
- bool HandleVersionMode(std::vector<std::string> const& args);
- bool HandleGetWarningMode(std::vector<std::string> const& args);
-};
+bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
index a33b824f3..cc9ad0103 100644
--- a/Source/cmCPackPropertiesGenerator.cxx
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -1,12 +1,12 @@
#include "cmCPackPropertiesGenerator.h"
+#include <map>
+#include <ostream>
+
#include "cmGeneratorExpression.h"
#include "cmInstalledFile.h"
#include "cmOutputConverter.h"
-#include <map>
-#include <ostream>
-
cmCPackPropertiesGenerator::cmCPackPropertiesGenerator(
cmLocalGenerator* lg, cmInstalledFile const& installedFile,
std::vector<std::string> const& configurations)
diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h
index ad943c588..83392383a 100644
--- a/Source/cmCPackPropertiesGenerator.h
+++ b/Source/cmCPackPropertiesGenerator.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmScriptGenerator.h"
+
class cmInstalledFile;
class cmLocalGenerator;
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 255a8e62a..177bca889 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -7,6 +7,8 @@
#include "cmCPluginAPI.h"
+#include <cstdlib>
+
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -14,8 +16,6 @@
#include "cmState.h"
#include "cmVersion.h"
-#include <stdlib.h>
-
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
@@ -65,8 +65,10 @@ unsigned int CCONV cmGetMinorVersion(void*)
void CCONV cmAddDefinition(void* arg, const char* name, const char* value)
{
- cmMakefile* mf = static_cast<cmMakefile*>(arg);
- mf->AddDefinition(name, value);
+ if (value) {
+ cmMakefile* mf = static_cast<cmMakefile*>(arg);
+ mf->AddDefinition(name, value);
+ }
}
/* Add a definition to this makefile and the global cmake cache. */
@@ -218,8 +220,10 @@ void CCONV cmAddUtilityCommand(void* arg, const char* utilityName,
}
// Pass the call to the makefile instance.
- mf->AddUtilityCommand(utilityName, cmMakefile::TargetOrigin::Project,
- (all ? false : true), nullptr, depends2, commandLines);
+ std::vector<std::string> no_byproducts;
+ mf->AddUtilityCommand(utilityName, cmCommandOrigin::Project,
+ (all ? false : true), nullptr, no_byproducts, depends2,
+ commandLines);
}
void CCONV cmAddCustomCommand(void* arg, const char* source,
const char* command, int numArgs,
@@ -317,16 +321,16 @@ void CCONV cmAddCustomCommandToTarget(void* arg, const char* target,
commandLines.push_back(commandLine);
// Select the command type.
- cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
+ cmCustomCommandType cctype = cmCustomCommandType::POST_BUILD;
switch (commandType) {
case CM_PRE_BUILD:
- cctype = cmTarget::PRE_BUILD;
+ cctype = cmCustomCommandType::PRE_BUILD;
break;
case CM_PRE_LINK:
- cctype = cmTarget::PRE_LINK;
+ cctype = cmCustomCommandType::PRE_LINK;
break;
case CM_POST_BUILD:
- cctype = cmTarget::POST_BUILD;
+ cctype = cmCustomCommandType::POST_BUILD;
break;
}
@@ -421,7 +425,7 @@ int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs,
// Assume all arguments are quoted.
lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0);
}
- cmExecutionStatus status;
+ cmExecutionStatus status(*mf);
return mf->ExecuteCommand(lff, status);
}
@@ -488,9 +492,9 @@ class cmCPluginAPISourceFileMap
: public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
{
public:
- typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived;
- typedef derived::iterator iterator;
- typedef derived::value_type value_type;
+ using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>;
+ using iterator = derived::iterator;
+ using value_type = derived::value_type;
cmCPluginAPISourceFileMap() = default;
~cmCPluginAPISourceFileMap()
{
@@ -529,12 +533,12 @@ void CCONV* cmGetSource(void* arg, const char* name)
cmMakefile* mf = static_cast<cmMakefile*>(arg);
if (cmSourceFile* rsf = mf->GetSource(name)) {
// Lookup the proxy source file object for this source.
- cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf);
+ auto i = cmCPluginAPISourceFiles.find(rsf);
if (i == cmCPluginAPISourceFiles.end()) {
// Create a proxy source file object for this source.
cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
sf->RealSourceFile = rsf;
- sf->FullPath = rsf->GetFullPath();
+ sf->FullPath = rsf->ResolveFullPath();
sf->SourceName =
cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath);
sf->SourceExtension =
@@ -559,7 +563,7 @@ void* CCONV cmAddSource(void* arg, void* arg2)
// Create the real cmSourceFile instance and copy over saved information.
cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath);
- rsf->GetProperties() = osf->Properties;
+ rsf->SetProperties(osf->Properties);
for (std::string const& d : osf->Depends) {
rsf->AddDepend(d);
}
@@ -606,7 +610,7 @@ int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
if (cmSourceFile* rsf = sf->RealSourceFile) {
return rsf->GetPropertyAsBool(prop) ? 1 : 0;
}
- return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0;
+ return cmIsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0;
}
void CCONV cmSourceFileSetProperty(void* arg, const char* prop,
@@ -688,9 +692,7 @@ void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir,
// Next, try the various source extensions
for (std::string const& ext : sourceExts) {
- hname = pathname;
- hname += ".";
- hname += ext;
+ hname = cmStrCat(pathname, '.', ext);
if (cmSystemTools::FileExists(hname)) {
sf->SourceExtension = ext;
sf->FullPath = hname;
@@ -700,9 +702,7 @@ void CCONV cmSourceFileSetName(void* arg, const char* name, const char* dir,
// Finally, try the various header extensions
for (std::string const& ext : headerExts) {
- hname = pathname;
- hname += ".";
- hname += ext;
+ hname = cmStrCat(pathname, '.', ext);
if (cmSystemTools::FileExists(hname)) {
sf->SourceExtension = ext;
sf->FullPath = hname;
diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h
index adc57a202..6a9514869 100644
--- a/Source/cmCPluginAPI.h
+++ b/Source/cmCPluginAPI.h
@@ -28,6 +28,7 @@ this is the structure of function entry points that a plugin may call. This
structure must be kept in sync with the static decaled at the bottom of
cmCPLuginAPI.cxx
=========================================================================*/
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef struct
{
/*=========================================================================
@@ -194,12 +195,21 @@ define the different types of custom commands for a target
/*=========================================================================
Finally we define the key data structures and function prototypes
=========================================================================*/
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef const char*(CCONV* CM_DOC_FUNCTION)();
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef int(CCONV* CM_INITIAL_PASS_FUNCTION)(void* info, void* mf, int argc,
char* []);
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef void(CCONV* CM_FINAL_PASS_FUNCTION)(void* info, void* mf);
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef void(CCONV* CM_DESTRUCTOR_FUNCTION)(void* info);
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef struct
{
unsigned long reserved1; /* Reserved for future use. DO NOT USE. */
@@ -216,6 +226,7 @@ typedef struct
void* ClientData;
} cmLoadedCommandInfo;
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef void(CCONV* CM_INIT_FUNCTION)(cmLoadedCommandInfo*);
#ifdef __cplusplus
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index d1226c3c8..6eae26e4c 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2,34 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTest.h"
-#include "cm_curl.h"
-#include "cm_zlib.h"
-#include "cmsys/Base64.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/Process.h"
-#include "cmsys/SystemInformation.hxx"
#include <algorithm>
+#include <cctype>
#include <chrono>
-#include <ctype.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#include <iostream>
#include <map>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <string>
-#include <time.h>
#include <utility>
#include <vector>
+
+#include "cmsys/Base64.h"
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/Process.h"
+#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 "cmAlgorithms.h"
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
@@ -51,6 +54,7 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmVersionConfig.h"
@@ -153,7 +157,7 @@ struct cmCTest::Private
bool TomorrowTag = false;
int TestModel = cmCTest::EXPERIMENTAL;
- std::string SpecificTrack;
+ std::string SpecificGroup;
cmDuration TimeOut = cmDuration::zero();
@@ -321,12 +325,11 @@ cmCTest::cmCTest()
{
std::string envValue;
if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) {
- this->Impl->OutputTestOutputOnTestFailure =
- !cmSystemTools::IsOff(envValue);
+ this->Impl->OutputTestOutputOnTestFailure = !cmIsOff(envValue);
}
envValue.clear();
if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) {
- this->Impl->TestProgressOutput = !cmSystemTools::IsOff(envValue);
+ this->Impl->TestProgressOutput = !cmIsOff(envValue);
}
this->Impl->Parts[PartStart].SetName("Start");
@@ -507,10 +510,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
day != lctime->tm_mday) {
tag.clear();
}
- std::string track;
- if (cmSystemTools::GetLineFromStream(tfin, track) &&
+ std::string group;
+ if (cmSystemTools::GetLineFromStream(tfin, group) &&
!this->Impl->Parts[PartStart] && !command) {
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
std::string model;
if (cmSystemTools::GetLineFromStream(tfin, model) &&
@@ -563,13 +566,13 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
}
} else {
- std::string track;
+ std::string group;
std::string modelStr;
int model = cmCTest::UNKNOWN;
if (tfin) {
cmSystemTools::GetLineFromStream(tfin, tag);
- cmSystemTools::GetLineFromStream(tfin, track);
+ cmSystemTools::GetLineFromStream(tfin, group);
if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
model = GetTestModelFromString(modelStr.c_str());
}
@@ -604,15 +607,15 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
quiet);
}
- if (!this->Impl->SpecificTrack.empty() &&
- track != this->Impl->SpecificTrack) {
+ if (!this->Impl->SpecificGroup.empty() &&
+ group != this->Impl->SpecificGroup) {
cmCTestOptionalLog(this, WARNING,
- "Track given in TAG does not match "
- "track given in ctest_start()"
+ "Group given in TAG does not match "
+ "group given in ctest_start()"
<< std::endl,
quiet);
} else {
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
cmCTestOptionalLog(this, OUTPUT,
@@ -640,12 +643,10 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
cmMakefile* mf = command->GetMakefile();
std::string fname;
- std::string src_dir_fname = src_dir;
- src_dir_fname += "/CTestConfig.cmake";
+ std::string src_dir_fname = cmStrCat(src_dir, "/CTestConfig.cmake");
cmSystemTools::ConvertToUnixSlashes(src_dir_fname);
- std::string bld_dir_fname = bld_dir;
- bld_dir_fname += "/CTestConfig.cmake";
+ std::string bld_dir_fname = cmStrCat(bld_dir, "/CTestConfig.cmake");
cmSystemTools::ConvertToUnixSlashes(bld_dir_fname);
if (cmSystemTools::FileExists(bld_dir_fname)) {
@@ -661,8 +662,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
command->ShouldBeQuiet());
bool readit = mf->ReadDependentFile(fname);
if (!readit) {
- std::string m = "Could not find include file: ";
- m += fname;
+ std::string m = cmStrCat("Could not find include file: ", fname);
command->SetError(m);
return false;
}
@@ -752,7 +752,7 @@ bool cmCTest::UpdateCTestConfiguration()
std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
if (!testLoad.empty()) {
unsigned long load;
- if (cmSystemTools::StringToULong(testLoad.c_str(), &load)) {
+ if (cmStrToULong(testLoad, &load)) {
this->SetTestLoad(load);
} else {
cmCTestLog(this, WARNING,
@@ -761,7 +761,7 @@ bool cmCTest::UpdateCTestConfiguration()
}
if (this->Impl->ProduceXML) {
this->Impl->CompressXMLFiles =
- cmSystemTools::IsOn(this->GetCTestConfiguration("CompressSubmission"));
+ cmIsOn(this->GetCTestConfiguration("CompressSubmission"));
}
return true;
}
@@ -855,8 +855,7 @@ bool cmCTest::AddIfExists(Part part, const char* file)
if (this->CTestFileExists(file)) {
this->AddSubmitFile(part, file);
} else {
- std::string name = file;
- name += ".gz";
+ std::string name = cmStrCat(file, ".gz");
if (this->CTestFileExists(name)) {
this->AddSubmitFile(part, file);
} else {
@@ -1020,8 +1019,8 @@ int cmCTest::ProcessSteps()
std::string cmCTest::GetTestModelString()
{
- if (!this->Impl->SpecificTrack.empty()) {
- return this->Impl->SpecificTrack;
+ if (!this->Impl->SpecificGroup.empty()) {
+ return this->Impl->SpecificGroup;
}
switch (this->Impl->TestModel) {
case cmCTest::NIGHTLY:
@@ -1098,9 +1097,10 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output,
cmProcessOutput processOutput(encoding);
std::string strdata;
cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
- " Each . represents " << tick_len << " bytes of output"
- << std::endl
- << " " << std::flush);
+ " Each . represents " << tick_len
+ << " bytes of output\n"
+ " "
+ << std::flush);
while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
processOutput.DecodeText(data, length, strdata);
for (char& cc : strdata) {
@@ -1115,8 +1115,7 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output,
if (tick % tick_line_len == 0 && tick > 0) {
cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Size: " << int((double(output.size()) / 1024.0) + 1)
- << "K" << std::endl
- << " " << std::flush);
+ << "K\n " << std::flush);
}
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
@@ -1221,9 +1220,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
timeout != cmCTest::MaxDuration() &&
timeout > cmDuration::zero()) {
args.emplace_back("--test-timeout");
- std::ostringstream msg;
- msg << cmDurationTo<unsigned int>(timeout);
- args.push_back(msg.str());
+ args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout)));
}
args.emplace_back(i);
}
@@ -1319,23 +1316,19 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
OutputTestErrors(tempOutput);
}
*retVal = cmsysProcess_GetExitException(cp);
- std::string outerr = "\n*** Exception executing: ";
- outerr += cmsysProcess_GetExceptionString(cp);
+ std::string outerr = cmStrCat("\n*** Exception executing: ",
+ cmsysProcess_GetExceptionString(cp));
if (output) {
*output += outerr;
}
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- outerr << std::endl
- << std::flush);
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
} else if (result == cmsysProcess_State_Error) {
- std::string outerr = "\n*** ERROR executing: ";
- outerr += cmsysProcess_GetErrorString(cp);
+ std::string outerr =
+ cmStrCat("\n*** ERROR executing: ", cmsysProcess_GetErrorString(cp));
if (output) {
*output += outerr;
}
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- outerr << std::endl
- << std::flush);
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
}
cmsysProcess_Delete(cp);
@@ -1455,8 +1448,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
if (labels) {
xml.StartElement("Labels");
std::string l = labels;
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(l, args);
+ std::vector<std::string> args = cmExpandedList(l);
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1488,14 +1480,12 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
{
std::string labelsForSubprojects =
this->GetCTestConfiguration("LabelsForSubprojects");
- std::vector<std::string> subprojects;
- cmSystemTools::ExpandListArgument(labelsForSubprojects, subprojects);
+ std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects);
// sort the array
std::sort(subprojects.begin(), subprojects.end());
// remove duplicates
- std::vector<std::string>::iterator new_end =
- std::unique(subprojects.begin(), subprojects.end());
+ auto new_end = std::unique(subprojects.begin(), subprojects.end());
subprojects.erase(new_end, subprojects.end());
return subprojects;
@@ -1856,7 +1846,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
i++;
long repeat = 1;
- if (!cmSystemTools::StringToLong(args[i].c_str(), &repeat)) {
+ if (!cmStrToLong(args[i], &repeat)) {
errormsg =
"'--repeat-until-fail' given non-integer value '" + args[i] + "'";
return false;
@@ -1870,7 +1860,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
i++;
unsigned long load;
- if (cmSystemTools::StringToULong(args[i].c_str(), &load)) {
+ if (cmStrToULong(args[i], &load)) {
this->SetTestLoad(load);
} else {
cmCTestLog(this, WARNING,
@@ -1911,9 +1901,15 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->Impl->Debug = true;
this->Impl->ShowLineNumbers = true;
}
+ if (this->CheckArgument(arg, "--group") && i < args.size() - 1) {
+ i++;
+ this->Impl->SpecificGroup = args[i];
+ }
+ // This is an undocumented / deprecated option.
+ // "Track" has been renamed to "Group".
if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
i++;
- this->Impl->SpecificTrack = args[i];
+ this->Impl->SpecificGroup = args[i];
}
if (this->CheckArgument(arg, "--show-line-numbers")) {
this->Impl->ShowLineNumbers = true;
@@ -1944,7 +1940,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i < args.size() - 1) {
i++;
long outputSize;
- if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
+ if (cmStrToLong(args[i], &outputSize)) {
this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize));
} else {
cmCTestLog(this, WARNING,
@@ -1956,7 +1952,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
i < args.size() - 1) {
i++;
long outputSize;
- if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) {
+ if (cmStrToLong(args[i], &outputSize)) {
this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize));
} else {
cmCTestLog(this, WARNING,
@@ -1967,7 +1963,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "-N", "--show-only")) {
this->Impl->ShowOnly = true;
}
- if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) {
+ if (cmHasLiteralPrefix(arg, "--show-only=")) {
this->Impl->ShowOnly = true;
// Check if a specific format is requested. Defaults to human readable
@@ -2003,7 +1999,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "--interactive-debug-mode") &&
i < args.size() - 1) {
i++;
- this->Impl->InteractiveDebugMode = cmSystemTools::IsOn(args[i]);
+ this->Impl->InteractiveDebugMode = cmIsOn(args[i]);
}
if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) {
i++;
@@ -2094,6 +2090,15 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
}
+ if (this->CheckArgument(arg, "--resource-spec-file") &&
+ i < args.size() - 1) {
+ i++;
+ this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
+ args[i].c_str());
+ this->GetMemCheckHandler()->SetPersistentOption("ResourceSpecFile",
+ args[i].c_str());
+ }
+
if (this->CheckArgument(arg, "--rerun-failed")) {
this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
@@ -2132,6 +2137,11 @@ bool cmCTest::ColoredOutputSupportedByConsole()
return false;
#else
// On UNIX we need a non-dumb tty.
+ std::string clicolor_force;
+ if (cmSystemTools::GetEnv("CLICOLOR_FORCE", clicolor_force) &&
+ !clicolor_force.empty() && clicolor_force != "0") {
+ return true;
+ }
return ConsoleIsNotDumb();
#endif
}
@@ -2229,7 +2239,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// attempts are simply ignored since previous ctest versions ignore
// this too. (As well as many other unknown command line args.)
//
- if (arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D")) {
+ if (arg != "-D" && cmHasLiteralPrefix(arg, "-D")) {
std::string input = arg.substr(2);
this->AddVariableDefinition(input);
}
@@ -2425,7 +2435,7 @@ int cmCTest::RunCMakeAndTest(std::string* output)
cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler();
int retv = handler->ProcessHandler();
*output = handler->GetOutput();
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDynamicLoader::FlushCache();
#endif
if (retv != 0) {
@@ -2502,8 +2512,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
"* Read custom CTest configuration directory: " << dir
<< std::endl);
- std::string fname = dir;
- fname += "/CTestCustom.cmake";
+ std::string fname = cmStrCat(dir, "/CTestCustom.cmake");
cmCTestLog(this, DEBUG, "* Check for file: " << fname << std::endl);
if (cmSystemTools::FileExists(fname)) {
cmCTestLog(this, DEBUG,
@@ -2523,8 +2532,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
}
}
- std::string rexpr = dir;
- rexpr += "/CTestCustom.ctest";
+ std::string rexpr = cmStrCat(dir, "/CTestCustom.ctest");
cmCTestLog(this, DEBUG, "* Check for file: " << rexpr << std::endl);
if (!found && cmSystemTools::FileExists(rexpr)) {
cmsys::Glob gl;
@@ -2567,7 +2575,7 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def,
cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl);
vec.clear();
- cmSystemTools::ExpandListArgument(dval, vec);
+ cmExpandList(dval, vec);
for (std::string const& it : vec) {
cmCTestLog(this, DEBUG, " -- " << it << std::endl);
@@ -2676,8 +2684,7 @@ std::string cmCTest::GetSubmitURL()
std::string site = this->GetCTestConfiguration("DropSite");
std::string location = this->GetCTestConfiguration("DropLocation");
- url = method.empty() ? "http" : method;
- url += "://";
+ url = cmStrCat(method.empty() ? "http" : method, "://");
if (!user.empty()) {
url += user;
if (!password.empty()) {
@@ -2772,21 +2779,21 @@ std::vector<std::string>& cmCTest::GetInitialCommandLineArguments()
return this->Impl->InitialCommandLineArguments;
}
-const char* cmCTest::GetSpecificTrack()
+const char* cmCTest::GetSpecificGroup()
{
- if (this->Impl->SpecificTrack.empty()) {
+ if (this->Impl->SpecificGroup.empty()) {
return nullptr;
}
- return this->Impl->SpecificTrack.c_str();
+ return this->Impl->SpecificGroup.c_str();
}
-void cmCTest::SetSpecificTrack(const char* track)
+void cmCTest::SetSpecificGroup(const char* group)
{
- if (!track) {
- this->Impl->SpecificTrack.clear();
+ if (!group) {
+ this->Impl->SpecificGroup.clear();
return;
}
- this->Impl->SpecificTrack = track;
+ this->Impl->SpecificGroup = group;
}
void cmCTest::SetFailover(bool failover)
@@ -3077,11 +3084,11 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
} else {
*this->Impl->OutputLogFile << cmCTestStringLogType[logType];
}
- *this->Impl->OutputLogFile << "] " << std::endl << std::flush;
+ *this->Impl->OutputLogFile << "] " << std::endl;
}
*this->Impl->OutputLogFile << msg << std::flush;
if (logType != this->Impl->OutputLogFileLastTag) {
- *this->Impl->OutputLogFile << std::endl << std::flush;
+ *this->Impl->OutputLogFile << std::endl;
this->Impl->OutputLogFileLastTag = logType;
}
}
@@ -3194,7 +3201,7 @@ void cmCTest::OutputTestErrors(std::vector<char> const& process_output)
if (!process_output.empty()) {
test_outputs.append(process_output.data(), process_output.size());
}
- cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl << std::flush);
+ cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl);
}
bool cmCTest::CompressString(std::string& str)
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index d300c33fa..82a6f4cbd 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -5,17 +5,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDuration.h"
-#include "cmProcessOutput.h"
-
#include <chrono>
+#include <ctime>
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
#include <string>
-#include <time.h>
#include <vector>
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
+
class cmCTestBuildHandler;
class cmCTestBuildAndTestHandler;
class cmCTestCoverageHandler;
@@ -41,7 +41,7 @@ class cmXMLWriter;
class cmCTest
{
public:
- typedef cmProcessOutput::Encoding Encoding;
+ using Encoding = cmProcessOutput::Encoding;
/** Enumerate parts of the testing and submission process. */
enum Part
{
@@ -404,9 +404,9 @@ public:
std::vector<std::string>& GetInitialCommandLineArguments();
- /** Set the track to submit to */
- void SetSpecificTrack(const char* track);
- const char* GetSpecificTrack();
+ /** Set the group to submit to */
+ void SetSpecificGroup(const char* group);
+ const char* GetSpecificGroup();
void SetFailover(bool failover);
bool GetFailover() const;
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 358f095bb..d627465c7 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCacheManager.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
#include <algorithm>
+#include <cstdio>
+#include <cstring>
#include <sstream>
-#include <stdio.h>
-#include <string.h>
#include <string>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
@@ -25,9 +27,7 @@ cmCacheManager::cmCacheManager()
void cmCacheManager::CleanCMakeFiles(const std::string& path)
{
- std::string glob = path;
- glob += "/CMakeFiles";
- glob += "/*.cmake";
+ std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake");
cmsys::Glob globIt;
globIt.FindFiles(glob);
std::vector<std::string> files = globIt.GetFiles();
@@ -38,8 +38,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
std::set<std::string>& excludes,
std::set<std::string>& includes)
{
- std::string cacheFile = path;
- cacheFile += "/CMakeCache.txt";
+ std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
// clear the old cache, if we are reading in internal values
if (internal) {
this->Cache.clear();
@@ -104,12 +103,10 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
// not visible in the gui
if (!internal) {
e.Type = cmStateEnums::INTERNAL;
- helpString = "DO NOT EDIT, ";
- helpString += entryKey;
- helpString += " loaded from external file. "
- "To change this value edit this file: ";
- helpString += path;
- helpString += "/CMakeCache.txt";
+ helpString = cmStrCat("DO NOT EDIT, ", entryKey,
+ " loaded from external file. "
+ "To change this value edit this file: ",
+ path, "/CMakeCache.txt");
e.SetProperty("HELPSTRING", helpString.c_str());
}
if (!this->ReadPropertyEntry(entryKey, e)) {
@@ -214,14 +211,11 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
{
for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
if (const char* value = i.GetProperty(*p)) {
- std::string helpstring = *p;
- helpstring += " property for variable: ";
- helpstring += i.GetName();
+ std::string helpstring =
+ cmStrCat(*p, " property for variable: ", i.GetName());
cmCacheManager::OutputHelpString(os, helpstring);
- std::string key = i.GetName();
- key += "-";
- key += *p;
+ std::string key = cmStrCat(i.GetName(), '-', *p);
cmCacheManager::OutputKey(os, key);
os << ":INTERNAL=";
cmCacheManager::OutputValue(os, value);
@@ -234,8 +228,7 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
{
- std::string cacheFile = path;
- cacheFile += "/CMakeCache.txt";
+ std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
cmGeneratedFileStream fout(cacheFile);
fout.SetCopyIfDifferent(true);
if (!fout) {
@@ -356,8 +349,7 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
}
fout << "\n";
fout.Close();
- std::string checkCacheFile = path;
- checkCacheFile += "/CMakeFiles";
+ std::string checkCacheFile = cmStrCat(path, "/CMakeFiles");
cmSystemTools::MakeDirectory(checkCacheFile);
checkCacheFile += "/cmake.check_cache";
cmsys::ofstream checkCache(checkCacheFile.c_str());
@@ -473,15 +465,14 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
{
if (value.find('\n') != std::string::npos) {
if (messenger) {
- std::string message = "Value of ";
- message += key;
- message += " contained a newline; truncating";
+ std::string message =
+ cmStrCat("Value of ", key, " contained a newline; truncating");
messenger->IssueMessage(MessageType::WARNING, message);
}
- std::string comment = "WARNING: Value of ";
- comment += key;
- comment += " contained a newline and was truncated. Original value:";
+ std::string comment =
+ cmStrCat("WARNING: Value of ", key,
+ " contained a newline and was truncated. Original value:");
OutputWarningComment(fout, comment, true);
OutputWarningComment(fout, value, false);
@@ -490,7 +481,7 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
void cmCacheManager::RemoveCacheEntry(const std::string& key)
{
- CacheEntryMap::iterator i = this->Cache.find(key);
+ auto i = this->Cache.find(key);
if (i != this->Cache.end()) {
this->Cache.erase(i);
}
@@ -499,7 +490,7 @@ void cmCacheManager::RemoveCacheEntry(const std::string& key)
cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
const std::string& key)
{
- CacheEntryMap::iterator i = this->Cache.find(key);
+ auto i = this->Cache.find(key);
if (i != this->Cache.end()) {
return &i->second;
}
@@ -508,13 +499,13 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key)
{
- return CacheIterator(*this, key);
+ return { *this, key };
}
const std::string* cmCacheManager::GetInitializedCacheValue(
const std::string& key) const
{
- CacheEntryMap::const_iterator i = this->Cache.find(key);
+ auto i = this->Cache.find(key);
if (i != this->Cache.end() && i->second.Initialized) {
return &i->second.Value;
}
@@ -551,8 +542,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
if (e.Value.find(';') != std::string::npos) {
- std::vector<std::string> paths;
- cmSystemTools::ExpandListArgument(e.Value, paths);
+ std::vector<std::string> paths = cmExpandedList(e.Value);
const char* sep = "";
e.Value = "";
for (std::string& i : paths) {
@@ -615,12 +605,12 @@ void cmCacheManager::CacheIterator::SetValue(const char* value)
bool cmCacheManager::CacheIterator::GetValueAsBool() const
{
- return cmSystemTools::IsOn(this->GetEntry().Value);
+ return cmIsOn(this->GetEntry().Value);
}
std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
{
- return this->Properties.GetPropertyList();
+ return this->Properties.GetKeys();
}
const char* cmCacheManager::CacheEntry::GetProperty(
@@ -695,7 +685,7 @@ bool cmCacheManager::CacheIterator::GetPropertyAsBool(
const std::string& prop) const
{
if (const char* value = this->GetProperty(prop)) {
- return cmSystemTools::IsOn(value);
+ return cmIsOn(value);
}
return false;
}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index 65f22f72b..faa60c528 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -94,7 +94,7 @@ public:
};
//! return an iterator to iterate through the cache map
- cmCacheManager::CacheIterator NewIterator() { return CacheIterator(*this); }
+ cmCacheManager::CacheIterator NewIterator() { return { *this }; }
//! Load a cache for given makefile. Loads from path/CMakeCache.txt.
bool LoadCache(const std::string& path, bool internal,
@@ -212,7 +212,7 @@ protected:
unsigned int CacheMinorVersion;
private:
- typedef std::map<std::string, CacheEntry> CacheEntryMap;
+ using CacheEntryMap = std::map<std::string, CacheEntry>;
static void OutputHelpString(std::ostream& fout,
const std::string& helpString);
static void OutputWarningComment(std::ostream& fout,
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index f7a224492..9e152ff80 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -4,6 +4,7 @@
#include <sstream>
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(_MSC_VER)
@@ -328,8 +329,7 @@ HRESULT FindVisualStudioInstances(const std::string& slnFile,
if (SUCCEEDED(hr)) {
std::map<std::string, IUnknownPtr>::iterator it;
for (it = mrot.begin(); it != mrot.end(); ++it) {
- if (cmSystemTools::StringStartsWith(it->first.c_str(),
- "!VisualStudio.DTE.")) {
+ if (cmHasLiteralPrefix(it->first, "!VisualStudio.DTE.")) {
IDispatchPtr disp(it->second);
if (disp != (IDispatch*)0) {
std::string slnName;
diff --git a/Source/cmCheckCustomOutputs.cxx b/Source/cmCheckCustomOutputs.cxx
new file mode 100644
index 000000000..7645c8808
--- /dev/null
+++ b/Source/cmCheckCustomOutputs.cxx
@@ -0,0 +1,36 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCheckCustomOutputs.h"
+
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
+ cm::string_view keyword, cmExecutionStatus& status)
+{
+ cmMakefile& mf = status.GetMakefile();
+
+ for (std::string const& o : outputs) {
+ // Make sure the file will not be generated into the source
+ // directory during an out of source build.
+ if (!mf.CanIWriteThisFile(o)) {
+ status.SetError(
+ cmStrCat("attempted to have a file\n ", o,
+ "\nin a source directory as an output of custom command."));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ // Make sure the output file name has no invalid characters.
+ std::string::size_type pos = o.find_first_of("#<>");
+ if (pos != std::string::npos) {
+ status.SetError(cmStrCat("called with ", keyword, " containing a \"",
+ o[pos], "\". This character is not allowed."));
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/Source/cmCheckCustomOutputs.h b/Source/cmCheckCustomOutputs.h
new file mode 100644
index 000000000..9f33d1665
--- /dev/null
+++ b/Source/cmCheckCustomOutputs.h
@@ -0,0 +1,18 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCheckCustomOutputs_h
+#define cmCheckCustomOutputs_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+#include <cm/string_view>
+
+class cmExecutionStatus;
+
+bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
+ cm::string_view keyword, cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx
index d349c9167..0c2734e0f 100644
--- a/Source/cmCommand.cxx
+++ b/Source/cmCommand.cxx
@@ -2,11 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCommand.h"
+#include <utility>
+
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
struct cmListFileArgument;
+void cmCommand::SetExecutionStatus(cmExecutionStatus* status)
+{
+ this->Status = status;
+ this->Makefile = &status->GetMakefile();
+}
+
bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
cmExecutionStatus& status)
{
@@ -19,15 +27,33 @@ bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
return this->InitialPass(expandedArguments, status);
}
-const char* cmCommand::GetError()
+void cmCommand::SetError(const std::string& e)
{
- if (this->Error.empty()) {
- return "unknown error.";
- }
- return this->Error.c_str();
+ this->Status->SetError(e);
}
-void cmCommand::SetError(const std::string& e)
+cmLegacyCommandWrapper::cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd)
+ : Command(std::move(cmd))
+{
+}
+
+cmLegacyCommandWrapper::cmLegacyCommandWrapper(
+ cmLegacyCommandWrapper const& other)
+ : Command(other.Command->Clone())
+{
+}
+
+cmLegacyCommandWrapper& cmLegacyCommandWrapper::operator=(
+ cmLegacyCommandWrapper const& other)
+{
+ this->Command = other.Command->Clone();
+ return *this;
+}
+
+bool cmLegacyCommandWrapper::operator()(
+ std::vector<cmListFileArgument> const& args, cmExecutionStatus& status) const
{
- this->Error = e;
+ auto cmd = this->Command->Clone();
+ cmd->SetExecutionStatus(&status);
+ return cmd->InvokeInitialPass(args, status);
}
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 9ccd773f6..bcb178d38 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -41,16 +42,18 @@ public:
/**
* Specify the makefile.
*/
- void SetMakefile(cmMakefile* m) { this->Makefile = m; }
cmMakefile* GetMakefile() { return this->Makefile; }
+ void SetExecutionStatus(cmExecutionStatus* s);
+ cmExecutionStatus* GetExecutionStatus() { return this->Status; };
+
/**
* This is called by the cmMakefile when the command is first
* encountered in the CMakeLists.txt file. It expands the command's
* arguments and then invokes the InitialPass.
*/
- virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus& status);
+ bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus& status);
/**
* This is called when the command is first encountered in
@@ -60,27 +63,9 @@ public:
cmExecutionStatus&) = 0;
/**
- * This is called at the end after all the information
- * specified by the command is accumulated. Most commands do
- * not implement this method. At this point, reading and
- * writing to the cache can be done.
- */
- virtual void FinalPass() {}
-
- /**
- * Does this command have a final pass? Query after InitialPass.
- */
- virtual bool HasFinalPass() const { return false; }
-
- /**
* This is a virtual constructor for the command.
*/
- virtual cmCommand* Clone() = 0;
-
- /**
- * Return the last error string.
- */
- const char* GetError();
+ virtual std::unique_ptr<cmCommand> Clone() = 0;
/**
* Set the error message
@@ -91,7 +76,25 @@ protected:
cmMakefile* Makefile = nullptr;
private:
- std::string Error;
+ cmExecutionStatus* Status = nullptr;
+};
+
+class cmLegacyCommandWrapper
+{
+public:
+ explicit cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd);
+
+ cmLegacyCommandWrapper(cmLegacyCommandWrapper const& other);
+ cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper const& other);
+
+ cmLegacyCommandWrapper(cmLegacyCommandWrapper&&) = default;
+ cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper&&) = default;
+
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status) const;
+
+private:
+ std::unique_ptr<cmCommand> Command;
};
#endif
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index ca2996741..613ae06d1 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -2,15 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCommandArgumentParserHelper.h"
+#include <cstring>
+#include <iostream>
+#include <sstream>
+
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <iostream>
-#include <sstream>
-#include <string.h>
-
int cmCommandArgument_yyparse(yyscan_t yyscanner);
//
cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
@@ -58,7 +59,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
std::string str;
if (cmSystemTools::GetEnv(var, str)) {
if (this->EscapeQuotes) {
- return this->AddString(cmSystemTools::EscapeQuotes(str));
+ return this->AddString(cmEscapeQuotes(str));
}
return this->AddString(str);
}
@@ -68,7 +69,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
if (const std::string* c =
this->Makefile->GetState()->GetInitializedCacheValue(var)) {
if (this->EscapeQuotes) {
- return this->AddString(cmSystemTools::EscapeQuotes(*c));
+ return this->AddString(cmEscapeQuotes(*c));
}
return this->AddString(*c);
}
@@ -87,9 +88,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
return nullptr;
}
if (this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0) {
- std::ostringstream ostr;
- ostr << this->FileLine;
- return this->AddString(ostr.str());
+ return this->AddString(std::to_string(this->FileLine));
}
const char* value = this->Makefile->GetDefinition(var);
if (!value) {
@@ -99,7 +98,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
}
}
if (this->EscapeQuotes && value) {
- return this->AddString(cmSystemTools::EscapeQuotes(value));
+ return this->AddString(cmEscapeQuotes(value));
}
return this->AddString(value ? value : "");
}
@@ -123,9 +122,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
// - this->ReplaceAtSyntax is false
// - this->ReplaceAtSyntax is true, but this->RemoveEmpty is false,
// and the variable was not defined
- std::string ref = "@";
- ref += var;
- ref += "@";
+ std::string ref = cmStrCat('@', var, '@');
return this->AddString(ref);
}
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 63c539734..ff73b279d 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -1,8 +1,9 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
#include "cmCommands.h"
-#include "cmPolicies.h"
-#include "cmState.h"
+
+#include <cm/memory>
#include "cmAddCompileDefinitionsCommand.h"
#include "cmAddCustomCommandCommand.h"
@@ -17,6 +18,7 @@
#include "cmBuildCommand.h"
#include "cmCMakeMinimumRequired.h"
#include "cmCMakePolicyCommand.h"
+#include "cmCommand.h"
#include "cmConfigureFileCommand.h"
#include "cmContinueCommand.h"
#include "cmCreateTestSourceList.h"
@@ -57,6 +59,7 @@
#include "cmMessageCommand.h"
#include "cmOptionCommand.h"
#include "cmParseArgumentsCommand.h"
+#include "cmPolicies.h"
#include "cmProjectCommand.h"
#include "cmReturnCommand.h"
#include "cmSeparateArgumentsCommand.h"
@@ -67,6 +70,7 @@
#include "cmSetTargetPropertiesCommand.h"
#include "cmSetTestsPropertiesCommand.h"
#include "cmSiteNameCommand.h"
+#include "cmState.h"
#include "cmStringCommand.h"
#include "cmSubdirCommand.h"
#include "cmTargetCompileDefinitionsCommand.h"
@@ -74,13 +78,14 @@
#include "cmTargetCompileOptionsCommand.h"
#include "cmTargetIncludeDirectoriesCommand.h"
#include "cmTargetLinkLibrariesCommand.h"
+#include "cmTargetPrecompileHeadersCommand.h"
#include "cmTargetSourcesCommand.h"
#include "cmTryCompileCommand.h"
#include "cmTryRunCommand.h"
#include "cmUnsetCommand.h"
#include "cmWhileCommand.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmAddCompileOptionsCommand.h"
# include "cmAddLinkOptionsCommand.h"
# include "cmAuxSourceDirectoryCommand.h"
@@ -112,52 +117,48 @@
void GetScriptingCommands(cmState* state)
{
- state->AddBuiltinCommand("break", new cmBreakCommand);
- state->AddBuiltinCommand("cmake_minimum_required",
- new cmCMakeMinimumRequired);
- state->AddBuiltinCommand("cmake_policy", new cmCMakePolicyCommand);
- state->AddBuiltinCommand("configure_file", new cmConfigureFileCommand);
- state->AddBuiltinCommand("continue", new cmContinueCommand);
- state->AddBuiltinCommand("exec_program", new cmExecProgramCommand);
- state->AddBuiltinCommand("execute_process", new cmExecuteProcessCommand);
- state->AddBuiltinCommand("file", new cmFileCommand);
- state->AddBuiltinCommand("find_file", new cmFindFileCommand);
- state->AddBuiltinCommand("find_library", new cmFindLibraryCommand);
- state->AddBuiltinCommand("find_package", new cmFindPackageCommand);
- state->AddBuiltinCommand("find_path", new cmFindPathCommand);
- state->AddBuiltinCommand("find_program", new cmFindProgramCommand);
- state->AddBuiltinCommand("foreach", new cmForEachCommand);
- state->AddBuiltinCommand("function", new cmFunctionCommand);
- state->AddBuiltinCommand("get_cmake_property",
- new cmGetCMakePropertyCommand);
+ state->AddBuiltinCommand("break", cmBreakCommand);
+ state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
+ state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
+ state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
+ state->AddBuiltinCommand("continue", cmContinueCommand);
+ state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
+ state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
+ state->AddBuiltinCommand("file", cmFileCommand);
+ state->AddBuiltinCommand("find_file", cmFindFile);
+ state->AddBuiltinCommand("find_library", cmFindLibrary);
+ state->AddBuiltinCommand("find_package", cmFindPackage);
+ state->AddBuiltinCommand("find_path", cmFindPath);
+ state->AddBuiltinCommand("find_program", cmFindProgram);
+ state->AddBuiltinCommand("foreach", cmForEachCommand);
+ state->AddBuiltinCommand("function", cmFunctionCommand);
+ state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
state->AddBuiltinCommand("get_directory_property",
- new cmGetDirectoryPropertyCommand);
+ cmGetDirectoryPropertyCommand);
state->AddBuiltinCommand("get_filename_component",
- new cmGetFilenameComponentCommand);
- state->AddBuiltinCommand("get_property", new cmGetPropertyCommand);
- state->AddBuiltinCommand("if", new cmIfCommand);
- state->AddBuiltinCommand("include", new cmIncludeCommand);
- state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand);
- state->AddBuiltinCommand("list", new cmListCommand);
- state->AddBuiltinCommand("macro", new cmMacroCommand);
- state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand);
- state->AddBuiltinCommand("mark_as_advanced", new cmMarkAsAdvancedCommand);
- state->AddBuiltinCommand("math", new cmMathCommand);
- state->AddBuiltinCommand("message", new cmMessageCommand);
- state->AddBuiltinCommand("option", new cmOptionCommand);
- state->AddBuiltinCommand("cmake_parse_arguments",
- new cmParseArgumentsCommand);
- state->AddBuiltinCommand("return", new cmReturnCommand);
- state->AddBuiltinCommand("separate_arguments",
- new cmSeparateArgumentsCommand);
- state->AddBuiltinCommand("set", new cmSetCommand);
+ cmGetFilenameComponentCommand);
+ state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
+ state->AddBuiltinCommand("if", cmIfCommand);
+ state->AddBuiltinCommand("include", cmIncludeCommand);
+ state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
+ state->AddBuiltinCommand("list", cmListCommand);
+ state->AddBuiltinCommand("macro", cmMacroCommand);
+ state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
+ state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
+ state->AddBuiltinCommand("math", cmMathCommand);
+ state->AddBuiltinCommand("message", cmMessageCommand);
+ state->AddBuiltinCommand("option", cmOptionCommand);
+ state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
+ state->AddBuiltinCommand("return", cmReturnCommand);
+ state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
+ state->AddBuiltinCommand("set", cmSetCommand);
state->AddBuiltinCommand("set_directory_properties",
- new cmSetDirectoryPropertiesCommand);
- state->AddBuiltinCommand("set_property", new cmSetPropertyCommand);
- state->AddBuiltinCommand("site_name", new cmSiteNameCommand);
- state->AddBuiltinCommand("string", new cmStringCommand);
- state->AddBuiltinCommand("unset", new cmUnsetCommand);
- state->AddBuiltinCommand("while", new cmWhileCommand);
+ cmSetDirectoryPropertiesCommand);
+ state->AddBuiltinCommand("set_property", cmSetPropertyCommand);
+ state->AddBuiltinCommand("site_name", cmSiteNameCommand);
+ state->AddBuiltinCommand("string", cmStringCommand);
+ state->AddBuiltinCommand("unset", cmUnsetCommand);
+ state->AddBuiltinCommand("while", cmWhileCommand);
state->AddUnexpectedCommand(
"else",
@@ -194,18 +195,18 @@ void GetScriptingCommands(cmState* state)
"WHILE ENDWHILE structure. Or its arguments did not "
"match the opening WHILE command.");
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("cmake_host_system_information",
- new cmCMakeHostSystemInformationCommand);
- state->AddBuiltinCommand("remove", new cmRemoveCommand);
- state->AddBuiltinCommand("variable_watch", new cmVariableWatchCommand);
- state->AddBuiltinCommand("write_file", new cmWriteFileCommand);
+ cmCMakeHostSystemInformationCommand);
+ state->AddBuiltinCommand("remove", cmRemoveCommand);
+ state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
+ state->AddBuiltinCommand("write_file", cmWriteFileCommand);
state->AddDisallowedCommand(
- "build_name", new cmBuildNameCommand, cmPolicies::CMP0036,
+ "build_name", cmBuildNameCommand, cmPolicies::CMP0036,
"The build_name command should not be called; see CMP0036.");
state->AddDisallowedCommand(
- "use_mangled_mesa", new cmUseMangledMesaCommand, cmPolicies::CMP0030,
+ "use_mangled_mesa", cmUseMangledMesaCommand, cmPolicies::CMP0030,
"The use_mangled_mesa command should not be called; see CMP0030.");
#endif
@@ -213,101 +214,96 @@ void GetScriptingCommands(cmState* state)
void GetProjectCommands(cmState* state)
{
- state->AddBuiltinCommand("add_custom_command",
- new cmAddCustomCommandCommand);
- state->AddBuiltinCommand("add_custom_target", new cmAddCustomTargetCommand);
- state->AddBuiltinCommand("add_definitions", new cmAddDefinitionsCommand);
- state->AddBuiltinCommand("add_dependencies", new cmAddDependenciesCommand);
- state->AddBuiltinCommand("add_executable", new cmAddExecutableCommand);
- state->AddBuiltinCommand("add_library", new cmAddLibraryCommand);
- state->AddBuiltinCommand("add_subdirectory", new cmAddSubDirectoryCommand);
- state->AddBuiltinCommand("add_test", new cmAddTestCommand);
- state->AddBuiltinCommand("build_command", new cmBuildCommand);
- state->AddBuiltinCommand("create_test_sourcelist",
- new cmCreateTestSourceList);
- state->AddBuiltinCommand("define_property", new cmDefinePropertyCommand);
- state->AddBuiltinCommand("enable_language", new cmEnableLanguageCommand);
- state->AddBuiltinCommand("enable_testing", new cmEnableTestingCommand);
+ state->AddBuiltinCommand("add_custom_command", cmAddCustomCommandCommand);
+ state->AddBuiltinCommand("add_custom_target", cmAddCustomTargetCommand);
+ state->AddBuiltinCommand("add_definitions", cmAddDefinitionsCommand);
+ state->AddBuiltinCommand("add_dependencies", cmAddDependenciesCommand);
+ state->AddBuiltinCommand("add_executable", cmAddExecutableCommand);
+ state->AddBuiltinCommand("add_library", cmAddLibraryCommand);
+ state->AddBuiltinCommand("add_subdirectory", cmAddSubDirectoryCommand);
+ state->AddBuiltinCommand("add_test", cmAddTestCommand);
+ state->AddBuiltinCommand("build_command", cmBuildCommand);
+ state->AddBuiltinCommand("create_test_sourcelist", cmCreateTestSourceList);
+ state->AddBuiltinCommand("define_property", cmDefinePropertyCommand);
+ state->AddBuiltinCommand("enable_language", cmEnableLanguageCommand);
+ state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand);
state->AddBuiltinCommand("get_source_file_property",
- new cmGetSourceFilePropertyCommand);
- state->AddBuiltinCommand("get_target_property",
- new cmGetTargetPropertyCommand);
- state->AddBuiltinCommand("get_test_property", new cmGetTestPropertyCommand);
- state->AddBuiltinCommand("include_directories",
- new cmIncludeDirectoryCommand);
+ cmGetSourceFilePropertyCommand);
+ state->AddBuiltinCommand("get_target_property", cmGetTargetPropertyCommand);
+ state->AddBuiltinCommand("get_test_property", cmGetTestPropertyCommand);
+ state->AddBuiltinCommand("include_directories", cmIncludeDirectoryCommand);
state->AddBuiltinCommand("include_regular_expression",
- new cmIncludeRegularExpressionCommand);
- state->AddBuiltinCommand("install", new cmInstallCommand);
- state->AddBuiltinCommand("install_files", new cmInstallFilesCommand);
- state->AddBuiltinCommand("install_targets", new cmInstallTargetsCommand);
- state->AddBuiltinCommand("link_directories", new cmLinkDirectoriesCommand);
- state->AddBuiltinCommand("project", new cmProjectCommand);
+ cmIncludeRegularExpressionCommand);
+ state->AddBuiltinCommand("install", cmInstallCommand);
+ state->AddBuiltinCommand("install_files", cmInstallFilesCommand);
+ state->AddBuiltinCommand("install_targets", cmInstallTargetsCommand);
+ state->AddBuiltinCommand("link_directories", cmLinkDirectoriesCommand);
+ state->AddBuiltinCommand("project", cmProjectCommand);
state->AddBuiltinCommand("set_source_files_properties",
- new cmSetSourceFilesPropertiesCommand);
+ cmSetSourceFilesPropertiesCommand);
state->AddBuiltinCommand("set_target_properties",
- new cmSetTargetPropertiesCommand);
+ cmSetTargetPropertiesCommand);
state->AddBuiltinCommand("set_tests_properties",
- new cmSetTestsPropertiesCommand);
- state->AddBuiltinCommand("subdirs", new cmSubdirCommand);
+ cmSetTestsPropertiesCommand);
+ state->AddBuiltinCommand("subdirs", cmSubdirCommand);
state->AddBuiltinCommand("target_compile_definitions",
- new cmTargetCompileDefinitionsCommand);
+ cmTargetCompileDefinitionsCommand);
state->AddBuiltinCommand("target_compile_features",
- new cmTargetCompileFeaturesCommand);
+ cmTargetCompileFeaturesCommand);
state->AddBuiltinCommand("target_compile_options",
- new cmTargetCompileOptionsCommand);
+ cmTargetCompileOptionsCommand);
state->AddBuiltinCommand("target_include_directories",
- new cmTargetIncludeDirectoriesCommand);
+ cmTargetIncludeDirectoriesCommand);
state->AddBuiltinCommand("target_link_libraries",
- new cmTargetLinkLibrariesCommand);
- state->AddBuiltinCommand("target_sources", new cmTargetSourcesCommand);
- state->AddBuiltinCommand("try_compile", new cmTryCompileCommand);
- state->AddBuiltinCommand("try_run", new cmTryRunCommand);
+ cmTargetLinkLibrariesCommand);
+ state->AddBuiltinCommand("target_sources", cmTargetSourcesCommand);
+ state->AddBuiltinCommand("try_compile",
+ cm::make_unique<cmTryCompileCommand>());
+ state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
+ state->AddBuiltinCommand("target_precompile_headers",
+ cmTargetPrecompileHeadersCommand);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("add_compile_definitions",
- new cmAddCompileDefinitionsCommand);
- state->AddBuiltinCommand("add_compile_options",
- new cmAddCompileOptionsCommand);
+ cmAddCompileDefinitionsCommand);
+ state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand);
state->AddBuiltinCommand("aux_source_directory",
- new cmAuxSourceDirectoryCommand);
- state->AddBuiltinCommand("export", new cmExportCommand);
- state->AddBuiltinCommand("fltk_wrap_ui", new cmFLTKWrapUICommand);
+ cmAuxSourceDirectoryCommand);
+ state->AddBuiltinCommand("export", cmExportCommand);
+ state->AddBuiltinCommand("fltk_wrap_ui", cmFLTKWrapUICommand);
state->AddBuiltinCommand("include_external_msproject",
- new cmIncludeExternalMSProjectCommand);
- state->AddBuiltinCommand("install_programs", new cmInstallProgramsCommand);
- state->AddBuiltinCommand("add_link_options", new cmAddLinkOptionsCommand);
- state->AddBuiltinCommand("link_libraries", new cmLinkLibrariesCommand);
- state->AddBuiltinCommand("target_link_options",
- new cmTargetLinkOptionsCommand);
+ cmIncludeExternalMSProjectCommand);
+ state->AddBuiltinCommand("install_programs", cmInstallProgramsCommand);
+ state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand);
+ state->AddBuiltinCommand("link_libraries", cmLinkLibrariesCommand);
+ state->AddBuiltinCommand("target_link_options", cmTargetLinkOptionsCommand);
state->AddBuiltinCommand("target_link_directories",
- new cmTargetLinkDirectoriesCommand);
- state->AddBuiltinCommand("load_cache", new cmLoadCacheCommand);
- state->AddBuiltinCommand("qt_wrap_cpp", new cmQTWrapCPPCommand);
- state->AddBuiltinCommand("qt_wrap_ui", new cmQTWrapUICommand);
- state->AddBuiltinCommand("remove_definitions",
- new cmRemoveDefinitionsCommand);
- state->AddBuiltinCommand("source_group", new cmSourceGroupCommand);
+ cmTargetLinkDirectoriesCommand);
+ state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
+ state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand);
+ state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand);
+ state->AddBuiltinCommand("remove_definitions", cmRemoveDefinitionsCommand);
+ state->AddBuiltinCommand("source_group", cmSourceGroupCommand);
state->AddDisallowedCommand(
- "export_library_dependencies", new cmExportLibraryDependenciesCommand,
+ "export_library_dependencies", cmExportLibraryDependenciesCommand,
cmPolicies::CMP0033,
"The export_library_dependencies command should not be called; "
"see CMP0033.");
state->AddDisallowedCommand(
- "load_command", new cmLoadCommandCommand, cmPolicies::CMP0031,
+ "load_command", cmLoadCommandCommand, cmPolicies::CMP0031,
"The load_command command should not be called; see CMP0031.");
state->AddDisallowedCommand(
- "output_required_files", new cmOutputRequiredFilesCommand,
- cmPolicies::CMP0032,
+ "output_required_files", cmOutputRequiredFilesCommand, cmPolicies::CMP0032,
"The output_required_files command should not be called; see CMP0032.");
state->AddDisallowedCommand(
- "subdir_depends", new cmSubdirDependsCommand, cmPolicies::CMP0029,
+ "subdir_depends", cmSubdirDependsCommand, cmPolicies::CMP0029,
"The subdir_depends command should not be called; see CMP0029.");
state->AddDisallowedCommand(
- "utility_source", new cmUtilitySourceCommand, cmPolicies::CMP0034,
+ "utility_source", cmUtilitySourceCommand, cmPolicies::CMP0034,
"The utility_source command should not be called; see CMP0034.");
state->AddDisallowedCommand(
- "variable_requires", new cmVariableRequiresCommand, cmPolicies::CMP0035,
+ "variable_requires", cmVariableRequiresCommand, cmPolicies::CMP0035,
"The variable_requires command should not be called; see CMP0035.");
#endif
}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 66250f329..19a096bdf 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -6,7 +6,6 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
@@ -17,6 +16,7 @@
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
: GeneratorTarget(gt)
@@ -59,10 +59,11 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(
// Append the flag and value. Use ConvertToLinkReference to help
// vs6's "cl -link" pass it to the linker.
- std::string flag = defFileFlag;
- flag += this->LocalCommonGenerator->ConvertToOutputFormat(
- linkLineComputer->ConvertToLinkReference(mdi->DefFile),
- cmOutputConverter::SHELL);
+ std::string flag =
+ cmStrCat(defFileFlag,
+ this->LocalCommonGenerator->ConvertToOutputFormat(
+ linkLineComputer->ConvertToLinkReference(mdi->DefFile),
+ cmOutputConverter::SHELL));
this->LocalCommonGenerator->AppendFlags(flags, flag);
}
@@ -89,13 +90,13 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
if (var) {
this->LocalCommonGenerator->AppendFlags(
- flags, this->Makefile->GetDefinition(var));
+ flags, this->Makefile->GetSafeDefinition(var));
}
}
std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
{
- ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
+ auto i = this->FlagsByLanguage.find(l);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
@@ -110,7 +111,7 @@ std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
{
- ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
+ auto i = this->DefinesByLanguage.find(l);
if (i == this->DefinesByLanguage.end()) {
std::set<std::string> defines;
this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget,
@@ -127,7 +128,7 @@ std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
{
- ByLanguageMap::iterator i = this->IncludesByLanguage.find(l);
+ auto i = this->IncludesByLanguage.find(l);
if (i == this->IncludesByLanguage.end()) {
std::string includes;
this->AddIncludeFlags(includes, l);
@@ -155,9 +156,8 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
&& linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
emitted.insert(linkee).second) {
cmLocalGenerator* lg = linkee->GetLocalGenerator();
- std::string di = lg->GetCurrentBinaryDirectory();
- di += "/";
- di += lg->GetTargetDirectory(linkee);
+ std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
+ lg->GetTargetDirectory(linkee));
dirs.push_back(std::move(di));
}
}
@@ -171,6 +171,7 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
return compilePdbPath;
}
+
compilePdbPath =
this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
if (compilePdbPath.empty()) {
@@ -210,11 +211,7 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
const char* name, bool so)
{
// Lookup the flag to specify the version.
- std::string fvar = "CMAKE_";
- fvar += lang;
- fvar += "_OSX_";
- fvar += name;
- fvar += "_VERSION_FLAG";
+ std::string fvar = cmStrCat("CMAKE_", lang, "_OSX_", name, "_VERSION_FLAG");
const char* flag = this->Makefile->GetDefinition(fvar);
// Skip if no such flag.
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 6b0f74efd..17792d6ac 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -50,7 +50,7 @@ protected:
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
- typedef std::map<std::string, std::string> ByLanguageMap;
+ using ByLanguageMap = std::map<std::string, std::string>;
std::string GetFlags(const std::string& l);
ByLanguageMap FlagsByLanguage;
std::string GetDefines(const std::string& l);
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index 113463f63..af257ee03 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -3,8 +3,7 @@
#include "cmComputeComponentGraph.h"
#include <algorithm>
-
-#include <assert.h>
+#include <cassert>
cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input)
: InputGraph(input)
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index 8cd4fe73a..202888cf9 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGraphAdjacencyList.h"
-
#include <stack>
#include <vector>
+#include "cmGraphAdjacencyList.h"
+
/** \class cmComputeComponentGraph
* \brief Analyze a graph to determine strongly connected components.
*
@@ -24,9 +24,9 @@ class cmComputeComponentGraph
{
public:
// Represent the graph with an adjacency list.
- typedef cmGraphNodeList NodeList;
- typedef cmGraphEdgeList EdgeList;
- typedef cmGraphAdjacencyList Graph;
+ using NodeList = cmGraphNodeList;
+ using EdgeList = cmGraphEdgeList;
+ using Graph = cmGraphAdjacencyList;
cmComputeComponentGraph(Graph const& input);
~cmComputeComponentGraph();
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 186deb60c..7a9e2b7f6 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -2,7 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmComputeLinkDepends.h"
-#include "cmAlgorithms.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <iterator>
+#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+
#include "cmComputeComponentGraph.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -11,18 +20,10 @@
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmake.h"
-#include <algorithm>
-#include <assert.h>
-#include <iterator>
-#include <sstream>
-#include <stdio.h>
-#include <string.h>
-#include <utility>
-
/*
This file computes an ordered list of link items to use when linking a
@@ -199,11 +200,7 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
this->CCG = nullptr;
}
-cmComputeLinkDepends::~cmComputeLinkDepends()
-{
- cmDeleteAll(this->InferredDependSets);
- delete this->CCG;
-}
+cmComputeLinkDepends::~cmComputeLinkDepends() = default;
void cmComputeLinkDepends::SetOldLinkDirMode(bool b)
{
@@ -282,10 +279,9 @@ std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
{
std::map<cmLinkItem, int>::value_type index_entry(
item, static_cast<int>(this->EntryList.size()));
- std::map<cmLinkItem, int>::iterator lei =
- this->LinkEntryIndex.insert(index_entry).first;
+ auto lei = this->LinkEntryIndex.insert(index_entry).first;
this->EntryList.emplace_back();
- this->InferredDependSets.push_back(nullptr);
+ this->InferredDependSets.emplace_back();
this->EntryConstraintGraph.emplace_back();
return lei;
}
@@ -293,7 +289,7 @@ std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
{
// Check if the item entry has already been added.
- std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.find(item);
+ auto lei = this->LinkEntryIndex.find(item);
if (lei != this->LinkEntryIndex.end()) {
// Yes. We do not need to follow the item's dependencies again.
return lei->second;
@@ -318,15 +314,14 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
this->BFSQueue.push(qe);
} else {
// Look for an old-style <item>_LIB_DEPENDS variable.
- std::string var = entry.Item;
- var += "_LIB_DEPENDS";
+ std::string var = cmStrCat(entry.Item, "_LIB_DEPENDS");
if (const char* val = this->Makefile->GetDefinition(var)) {
// The item dependencies are known. Follow them.
BFSEntry qe = { index, val };
this->BFSQueue.push(qe);
} else if (!entry.IsFlag) {
// The item dependencies are not known. We need to infer them.
- this->InferredDependSets[index] = new DependSetList;
+ this->InferredDependSets[index].Initialized = true;
}
}
@@ -394,8 +389,7 @@ void cmComputeLinkDepends::QueueSharedDependencies(
void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
{
// Check if the target already has an entry.
- std::map<cmLinkItem, int>::iterator lei =
- this->LinkEntryIndex.find(dep.Item);
+ auto lei = this->LinkEntryIndex.find(dep.Item);
if (lei == this->LinkEntryIndex.end()) {
// Allocate a spot for the item entry.
lei = this->AllocateLinkEntry(dep.Item);
@@ -436,8 +430,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// This is called to add the dependencies named by
// <item>_LIB_DEPENDS. The variable contains a semicolon-separated
// list. The list contains link-type;item pairs and just items.
- std::vector<std::string> deplist;
- cmSystemTools::ExpandListArgument(value, deplist);
+ std::vector<std::string> deplist = cmExpandedList(value);
// Look for entries meant for this configuration.
std::vector<cmLinkItem> actual_libs;
@@ -460,8 +453,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// the export_library_dependencies command from CMake 2.4 and
// lower.
if (!haveLLT) {
- std::string var = d;
- var += "_LINK_TYPE";
+ std::string var = cmStrCat(d, "_LINK_TYPE");
if (const char* val = this->Makefile->GetDefinition(var)) {
if (strcmp(val, "debug") == 0) {
llt = DEBUG_LibraryType;
@@ -542,7 +534,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
}
// If this item needs to have dependencies inferred, do so.
- if (this->InferredDependSets[dependee_index]) {
+ if (this->InferredDependSets[dependee_index].Initialized) {
// Make sure an entry exists to hold the set for the item.
dependSets[dependee_index];
}
@@ -550,7 +542,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
// Store the inferred dependency sets discovered for this list.
for (auto const& dependSet : dependSets) {
- this->InferredDependSets[dependSet.first]->push_back(dependSet.second);
+ this->InferredDependSets[dependSet.first].push_back(dependSet.second);
}
}
@@ -577,14 +569,14 @@ void cmComputeLinkDepends::InferDependencies()
depender_index < this->InferredDependSets.size(); ++depender_index) {
// Skip items for which dependencies do not need to be inferred or
// for which the inferred dependency sets are empty.
- DependSetList* sets = this->InferredDependSets[depender_index];
- if (!sets || sets->empty()) {
+ DependSetList& sets = this->InferredDependSets[depender_index];
+ if (!sets.Initialized || sets.empty()) {
continue;
}
// Intersect the sets for this item.
- DependSet common = sets->front();
- for (DependSet const& i : cmMakeRange(*sets).advance(1)) {
+ DependSet common = sets.front();
+ for (DependSet const& i : cmMakeRange(sets).advance(1)) {
DependSet intersection;
std::set_intersection(common.begin(), common.end(), i.begin(), i.end(),
std::inserter(intersection, intersection.begin()));
@@ -632,7 +624,8 @@ void cmComputeLinkDepends::OrderLinkEntires()
// the same order in which the items were originally discovered in
// the BFS. This should preserve the original order when no
// constraints disallow it.
- this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph);
+ this->CCG =
+ cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
// The component graph is guaranteed to be acyclic. Start a DFS
// from every entry to compute a topological order for the
@@ -720,8 +713,7 @@ void cmComputeLinkDepends::VisitEntry(int index)
// This entry has now been seen. Update its component.
bool completed = false;
int component = this->CCG->GetComponentMap()[index];
- std::map<int, PendingComponent>::iterator mi =
- this->PendingComponents.find(this->ComponentOrder[component]);
+ auto mi = this->PendingComponents.find(this->ComponentOrder[component]);
if (mi != this->PendingComponents.end()) {
// The entry is in an already pending component.
PendingComponent& pc = mi->second;
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index dfaaf8b96..645189ad5 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -5,16 +5,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGraphAdjacencyList.h"
-#include "cmLinkItem.h"
-#include "cmTargetLinkLibraryType.h"
-
#include <map>
-#include <queue>
+#include <memory>
#include <set>
#include <string>
#include <vector>
+#include <queue>
+
+#include "cmGraphAdjacencyList.h"
+#include "cmLinkItem.h"
+#include "cmTargetLinkLibraryType.h"
+
class cmComputeComponentGraph;
class cmGeneratorTarget;
class cmGlobalGenerator;
@@ -43,7 +45,7 @@ public:
bool IsFlag = false;
};
- typedef std::vector<LinkEntry> EntryVector;
+ using EntryVector = std::vector<LinkEntry>;
EntryVector const& Compute();
void SetOldLinkDirMode(bool b);
@@ -105,14 +107,15 @@ private:
};
struct DependSetList : public std::vector<DependSet>
{
+ bool Initialized = false;
};
- std::vector<DependSetList*> InferredDependSets;
+ std::vector<DependSetList> InferredDependSets;
void InferDependencies();
// Ordering constraint graph adjacency list.
- typedef cmGraphNodeList NodeList;
- typedef cmGraphEdgeList EdgeList;
- typedef cmGraphAdjacencyList Graph;
+ using NodeList = cmGraphNodeList;
+ using EdgeList = cmGraphEdgeList;
+ using Graph = cmGraphAdjacencyList;
Graph EntryConstraintGraph;
void CleanConstraintGraph();
void DisplayConstraintGraph();
@@ -137,7 +140,7 @@ private:
std::set<int> Entries;
};
std::map<int, PendingComponent> PendingComponents;
- cmComputeComponentGraph* CCG;
+ std::unique_ptr<cmComputeComponentGraph> CCG;
std::vector<int> FinalLinkOrder;
void DisplayComponents();
void VisitComponent(unsigned int c);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 44d8615e0..8773d1036 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -2,10 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmComputeLinkInformation.h"
+#include <algorithm>
+#include <cctype>
+#include <cstring>
+#include <sstream>
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -14,16 +21,11 @@
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
-#include <algorithm>
-#include <ctype.h>
-#include <sstream>
-#include <string.h>
-#include <utility>
-
//#define CM_COMPUTE_LINK_INFO_DEBUG
/*
@@ -268,10 +270,6 @@ cmComputeLinkInformation::cmComputeLinkInformation(
return;
}
- // Check whether we should use an import library for linking a target.
- this->UseImportLibrary =
- this->Makefile->IsDefinitionSet("CMAKE_IMPORT_LIBRARY_SUFFIX");
-
// Check whether we should skip dependencies on shared library files.
this->LinkDependsNoShared =
this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
@@ -280,21 +278,35 @@ cmComputeLinkInformation::cmComputeLinkInformation(
// to use when creating a plugin (module) that obtains symbols from
// the program that will load it.
this->LoaderFlag = nullptr;
- if (!this->UseImportLibrary &&
+ if (!this->Target->IsDLLPlatform() &&
this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
- std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
- loader_flag_var += this->LinkLanguage;
- loader_flag_var += "_FLAG";
+ std::string loader_flag_var =
+ cmStrCat("CMAKE_SHARED_MODULE_LOADER_", this->LinkLanguage, "_FLAG");
this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var);
}
// Get options needed to link libraries.
- this->LibLinkFlag =
- this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
- this->LibLinkFileFlag =
- this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
- this->LibLinkSuffix =
- this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+ if (const char* flag = this->Makefile->GetDefinition(
+ "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FLAG")) {
+ this->LibLinkFlag = flag;
+ } else {
+ this->LibLinkFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
+ }
+ if (const char* flag = this->Makefile->GetDefinition(
+ "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FILE_FLAG")) {
+ this->LibLinkFileFlag = flag;
+ } else {
+ this->LibLinkFileFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
+ }
+ if (const char* suffix = this->Makefile->GetDefinition(
+ "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_SUFFIX")) {
+ this->LibLinkSuffix = suffix;
+ } else {
+ this->LibLinkSuffix =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+ }
// Get options needed to specify RPATHs.
this->RuntimeUseChrpath = false;
@@ -302,11 +314,8 @@ cmComputeLinkInformation::cmComputeLinkInformation(
const char* tType = ((this->Target->GetType() == cmStateEnums::EXECUTABLE)
? "EXECUTABLE"
: "SHARED_LIBRARY");
- std::string rtVar = "CMAKE_";
- rtVar += tType;
- rtVar += "_RUNTIME_";
- rtVar += this->LinkLanguage;
- rtVar += "_FLAG";
+ std::string rtVar =
+ cmStrCat("CMAKE_", tType, "_RUNTIME_", this->LinkLanguage, "_FLAG");
std::string rtSepVar = rtVar + "_SEP";
this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar);
this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar);
@@ -316,19 +325,15 @@ cmComputeLinkInformation::cmComputeLinkInformation(
this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
// Get options needed to help find dependent libraries.
- std::string rlVar = "CMAKE_";
- rlVar += tType;
- rlVar += "_RPATH_LINK_";
- rlVar += this->LinkLanguage;
- rlVar += "_FLAG";
+ std::string rlVar =
+ cmStrCat("CMAKE_", tType, "_RPATH_LINK_", this->LinkLanguage, "_FLAG");
this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar);
}
// Check if we need to include the runtime search path at link time.
{
- std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
- var += this->LinkLanguage;
- var += "_WITH_RUNTIME_PATH";
+ std::string var = cmStrCat("CMAKE_SHARED_LIBRARY_LINK_",
+ this->LinkLanguage, "_WITH_RUNTIME_PATH");
this->LinkWithRuntimePath = this->Makefile->IsOn(var);
}
@@ -402,6 +407,18 @@ cmComputeLinkInformation::~cmComputeLinkInformation()
delete this->OrderDependentRPath;
}
+void cmComputeLinkInformation::AppendValues(
+ std::string& result, std::vector<BT<std::string>>& values)
+{
+ for (BT<std::string>& p : values) {
+ if (result.empty()) {
+ result.append(" ");
+ }
+
+ result.append(p.Value);
+ }
+}
+
cmComputeLinkInformation::ItemVector const&
cmComputeLinkInformation::GetItems() const
{
@@ -414,6 +431,28 @@ std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
return this->OrderLinkerSearchPath->GetOrderedDirectories();
}
+std::vector<BT<std::string>>
+cmComputeLinkInformation::GetDirectoriesWithBacktraces()
+{
+ std::vector<BT<std::string>> directoriesWithBacktraces;
+
+ std::vector<BT<std::string>> targetLinkDirectores =
+ this->Target->GetLinkDirectories(this->Config, this->LinkLanguage);
+
+ const std::vector<std::string>& orderedDirectories = this->GetDirectories();
+ for (const std::string& dir : orderedDirectories) {
+ auto result =
+ std::find(targetLinkDirectores.begin(), targetLinkDirectores.end(), dir);
+ if (result != targetLinkDirectores.end()) {
+ directoriesWithBacktraces.emplace_back(std::move(*result));
+ } else {
+ directoriesWithBacktraces.emplace_back(dir);
+ }
+ }
+
+ return directoriesWithBacktraces;
+}
+
std::string cmComputeLinkInformation::GetRPathLinkString() const
{
// If there is no separate linker runtime search flag (-rpath-link)
@@ -479,7 +518,7 @@ 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 (cmSystemTools::IsOn(lss)) {
+ if (cmIsOn(lss)) {
this->SetCurrentLinkType(LinkStatic);
} else {
this->SetCurrentLinkType(this->StartLinkType);
@@ -493,9 +532,7 @@ bool cmComputeLinkInformation::Compute()
std::set<cmGeneratorTarget const*> const& wrongItems =
cld.GetOldWrongConfigItems();
for (cmGeneratorTarget const* tgt : wrongItems) {
- bool implib = (this->UseImportLibrary &&
- (tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
- cmStateEnums::ArtifactType artifact = implib
+ cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
this->OldLinkDirItems.push_back(
@@ -547,14 +584,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
// Add libraries for this language that are not implied by the
// linker language.
- std::string libVar = "CMAKE_";
- libVar += lang;
- libVar += "_IMPLICIT_LINK_LIBRARIES";
+ std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES");
if (const char* libs = this->Makefile->GetDefinition(libVar)) {
- std::vector<std::string> libsVec;
- cmSystemTools::ExpandListArgument(libs, libsVec);
+ std::vector<std::string> libsVec = cmExpandedList(libs);
for (std::string const& i : libsVec) {
- if (this->ImplicitLinkLibs.find(i) == this->ImplicitLinkLibs.end()) {
+ if (!cmContains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -562,12 +596,9 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// Add linker search paths for this language that are not
// implied by the linker language.
- std::string dirVar = "CMAKE_";
- dirVar += lang;
- dirVar += "_IMPLICIT_LINK_DIRECTORIES";
+ std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES");
if (const char* dirs = this->Makefile->GetDefinition(dirVar)) {
- std::vector<std::string> dirsVec;
- cmSystemTools::ExpandListArgument(dirs, dirsVec);
+ std::vector<std::string> dirsVec = cmExpandedList(dirs);
this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
}
}
@@ -578,7 +609,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// Compute the proper name to use to link this library.
const std::string& config = this->Config;
bool impexe = (tgt && tgt->IsExecutableWithExports());
- if (impexe && !this->UseImportLibrary && !this->LoaderFlag) {
+ if (impexe && !tgt->HasImportLibrary(config) && !this->LoaderFlag) {
// Skip linking to executables on platforms with no import
// libraries or loader flags.
return;
@@ -592,7 +623,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// platform. Add it now.
std::string linkItem;
linkItem = this->LoaderFlag;
- cmStateEnums::ArtifactType artifact = this->UseImportLibrary
+ cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
@@ -616,15 +647,21 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// Its object-files should already have been extracted for linking.
} else {
// Decide whether to use an import library.
- bool implib =
- (this->UseImportLibrary &&
- (impexe || tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
- cmStateEnums::ArtifactType artifact = implib
+ cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
// Pass the full path to the target file.
std::string lib = tgt->GetFullPath(config, artifact, true);
+ if (tgt->Target->IsAIX() && cmHasLiteralSuffix(lib, "-NOTFOUND") &&
+ artifact == cmStateEnums::ImportLibraryArtifact) {
+ // This is an imported executable on AIX that has ENABLE_EXPORTS
+ // but not IMPORTED_IMPLIB. CMake used to produce and accept such
+ // imported executables on AIX before we taught it to use linker
+ // import files. For compatibility, simply skip linking to this
+ // executable as we did before. It works with runtime linking.
+ return;
+ }
if (!this->LinkDependsNoShared ||
tgt->GetType() != cmStateEnums::SHARED_LIBRARY) {
this->Depends.push_back(lib);
@@ -694,7 +731,7 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
// linked will be able to find it.
std::string lib;
if (tgt) {
- cmStateEnums::ArtifactType artifact = this->UseImportLibrary
+ cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
lib = tgt->GetFullPath(this->Config, artifact);
@@ -754,19 +791,15 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
break;
}
if (target_type_str) {
- std::string static_link_type_flag_var = "CMAKE_";
- static_link_type_flag_var += target_type_str;
- static_link_type_flag_var += "_LINK_STATIC_";
- static_link_type_flag_var += this->LinkLanguage;
- static_link_type_flag_var += "_FLAGS";
+ std::string static_link_type_flag_var =
+ cmStrCat("CMAKE_", target_type_str, "_LINK_STATIC_", this->LinkLanguage,
+ "_FLAGS");
static_link_type_flag =
this->Makefile->GetDefinition(static_link_type_flag_var);
- std::string shared_link_type_flag_var = "CMAKE_";
- shared_link_type_flag_var += target_type_str;
- shared_link_type_flag_var += "_LINK_DYNAMIC_";
- shared_link_type_flag_var += this->LinkLanguage;
- shared_link_type_flag_var += "_FLAGS";
+ std::string shared_link_type_flag_var =
+ cmStrCat("CMAKE_", target_type_str, "_LINK_DYNAMIC_", this->LinkLanguage,
+ "_FLAGS");
shared_link_type_flag =
this->Makefile->GetDefinition(shared_link_type_flag_var);
}
@@ -782,7 +815,7 @@ 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 = cmSystemTools::IsOn(lss) ? LinkStatic : LinkShared;
+ this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
this->CurrentLinkType = this->StartLinkType;
}
@@ -805,16 +838,14 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
LinkUnknown);
if (const char* linkSuffixes =
mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
- std::vector<std::string> linkSuffixVec;
- cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
+ std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes);
for (std::string const& i : linkSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkUnknown);
}
}
if (const char* sharedSuffixes =
mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
- std::vector<std::string> sharedSuffixVec;
- cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
+ std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes);
for (std::string const& i : sharedSuffixVec) {
this->AddLinkExtension(i.c_str(), LinkShared);
}
@@ -842,8 +873,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
reg += "([^/:]*)";
// Create a regex to match any library name.
- std::string reg_any = reg;
- reg_any += libext;
+ std::string reg_any = cmStrCat(reg, libext);
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
#endif
@@ -851,9 +881,8 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
// Create a regex to match static library names.
if (!this->StaticLinkExtensions.empty()) {
- std::string reg_static = reg;
- reg_static +=
- this->CreateExtensionRegex(this->StaticLinkExtensions, LinkStatic);
+ std::string reg_static = cmStrCat(
+ reg, this->CreateExtensionRegex(this->StaticLinkExtensions, LinkStatic));
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
#endif
@@ -990,16 +1019,11 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
return;
}
- // If this platform wants a flag before the full path, add it.
- if (!this->LibLinkFileFlag.empty()) {
- this->Items.emplace_back(this->LibLinkFileFlag, false);
- }
-
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
- this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
- this->OldLinkDirMask.end()) {
+ !cmContains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item))) {
this->OldLinkDirItems.push_back(item);
}
@@ -1052,16 +1076,11 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode &&
- this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
- this->OldLinkDirMask.end()) {
+ !cmContains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item))) {
this->OldLinkDirItems.push_back(item);
}
- // If this platform wants a flag before the full path, add it.
- if (!this->LibLinkFileFlag.empty()) {
- this->Items.emplace_back(this->LibLinkFileFlag, false);
- }
-
// Now add the full path to the library.
this->Items.emplace_back(item, true);
}
@@ -1077,7 +1096,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 (this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end()) {
+ if (!cmContains(this->ImplicitLinkDirs, dir)) {
// Only libraries in implicit link directories are converted to
// pathless items.
return false;
@@ -1219,9 +1238,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item,
}
// Create an option to ask the linker to search for the library.
- std::string out = this->LibLinkFlag;
- out += lib;
- out += this->LibLinkSuffix;
+ std::string out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix);
this->Items.emplace_back(out, false);
// Here we could try to find the library the linker will find and
@@ -1243,12 +1260,7 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
std::string fw_path = this->SplitFramework.match(1);
std::string fw = this->SplitFramework.match(2);
- std::string full_fw = fw_path;
- full_fw += "/";
- full_fw += fw;
- full_fw += ".framework";
- full_fw += "/";
- full_fw += fw;
+ std::string full_fw = cmStrCat(fw_path, '/', fw, ".framework/", fw);
// Add the directory portion to the framework search path.
this->AddFrameworkPath(fw_path);
@@ -1293,16 +1305,15 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
// Get platform-wide implicit directories.
if (const char* implicitLinks = this->Makefile->GetDefinition(
"CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) {
- cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
+ cmExpandList(implicitLinks, implicitDirVec);
}
// Get language-specific implicit directories.
- std::string implicitDirVar = "CMAKE_";
- implicitDirVar += this->LinkLanguage;
- implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
+ std::string implicitDirVar = cmStrCat(
+ "CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
if (const char* implicitDirs =
this->Makefile->GetDefinition(implicitDirVar)) {
- cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
+ cmExpandList(implicitDirs, implicitDirVec);
}
this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(),
@@ -1356,8 +1367,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
std::string const& file)
{
// Do not depend on things that do not exist.
- std::vector<std::string>::iterator i =
- std::find(this->Depends.begin(), this->Depends.end(), item);
+ auto i = std::find(this->Depends.begin(), this->Depends.end(), item);
if (i != this->Depends.end()) {
this->Depends.erase(i);
}
@@ -1372,8 +1382,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
switch (this->Target->GetPolicyStatusCMP0008()) {
case cmPolicies::WARN: {
// Print the warning at most once for this item.
- std::string wid = "CMP0008-WARNING-GIVEN-";
- wid += item;
+ std::string wid = cmStrCat("CMP0008-WARNING-GIVEN-", item);
if (!this->CMakeInstance->GetState()->GetGlobalPropertyAsBool(wid)) {
this->CMakeInstance->GetState()->SetGlobalProperty(wid, "1");
std::ostringstream w;
@@ -1521,7 +1530,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get platform-wide implicit directories.
if (const char* implicitLinks = (this->Makefile->GetDefinition(
"CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"))) {
- cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
+ cmExpandList(implicitLinks, implicitDirVec);
}
// Append library architecture to all implicit platform directories
@@ -1534,12 +1543,11 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
}
// Get language-specific implicit directories.
- std::string implicitDirVar = "CMAKE_";
- implicitDirVar += this->LinkLanguage;
- implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
+ std::string implicitDirVar =
+ cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
if (const char* implicitDirs =
this->Makefile->GetDefinition(implicitDirVar)) {
- cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
+ cmExpandList(implicitDirs, implicitDirVec);
}
// Store implicit link directories.
@@ -1547,12 +1555,11 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get language-specific implicit libraries.
std::vector<std::string> implicitLibVec;
- std::string implicitLibVar = "CMAKE_";
- implicitLibVar += this->LinkLanguage;
- implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
+ std::string implicitLibVar =
+ cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
if (const char* implicitLibs =
this->Makefile->GetDefinition(implicitLibVar)) {
- cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
+ cmExpandList(implicitLibs, implicitLibVec);
}
// Store implicit link libraries.
@@ -1567,7 +1574,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get platform specific rpath link directories
if (const char* rpathDirs =
(this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"))) {
- cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
+ cmExpandList(rpathDirs, this->RuntimeLinkDirs);
}
}
@@ -1673,8 +1680,7 @@ static void cmCLI_ExpandListUnique(const char* str,
std::vector<std::string>& out,
std::set<std::string>& emitted)
{
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(str, tmp);
+ std::vector<std::string> tmp = cmExpandedList(str);
for (std::string const& i : tmp) {
if (emitted.insert(i).second) {
out.push_back(i);
@@ -1695,7 +1701,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
(for_install ||
this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
bool use_install_rpath =
- (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+ (outputRuntime && this->Target->HaveInstallTreeRPATH(this->Config) &&
linking_for_install);
bool use_build_rpath =
(outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
@@ -1715,15 +1721,17 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// Construct the RPATH.
std::set<std::string> emitted;
if (use_install_rpath) {
- const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
- cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
+ std::string install_rpath;
+ this->Target->GetInstallRPATH(this->Config, install_rpath);
+ cmCLI_ExpandListUnique(install_rpath.c_str(), runtimeDirs, emitted);
}
if (use_build_rpath) {
// Add directories explicitly specified by user
- if (const char* build_rpath = this->Target->GetProperty("BUILD_RPATH")) {
+ std::string build_rpath;
+ if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
// This will not resolve entries to use $ORIGIN, the user is expected to
// do that if necessary.
- cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
+ cmCLI_ExpandListUnique(build_rpath.c_str(), runtimeDirs, emitted);
}
}
if (use_build_rpath || use_link_rpath) {
@@ -1751,9 +1759,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
d = d.substr(rootPath.size());
} else if (stagePath && *stagePath && d.find(stagePath) == 0) {
std::string suffix = d.substr(strlen(stagePath));
- d = installPrefix;
- d += "/";
- d += suffix;
+ d = cmStrCat(installPrefix, '/', suffix);
cmSystemTools::ConvertToUnixSlashes(d);
} else if (use_relative_build_rpath) {
// If expansion of the $ORIGIN token is supported and permitted per
@@ -1762,7 +1768,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
cmSystemTools::IsSubDirectory(d, topBinaryDir)) {
d = cmSystemTools::RelativePath(targetOutputDir, d);
if (!d.empty()) {
- d = originToken + "/" + d;
+ d = cmStrCat(originToken, "/", d);
} else {
d = originToken;
}
@@ -1784,9 +1790,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
d = d.substr(rootPath.size());
} else if (stagePath && *stagePath && d.find(stagePath) == 0) {
std::string suffix = d.substr(strlen(stagePath));
- d = installPrefix;
- d += "/";
- d += suffix;
+ d = cmStrCat(installPrefix, '/', suffix);
cmSystemTools::ConvertToUnixSlashes(d);
}
if (emitted.insert(d).second) {
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 863639c6a..92ab83b3b 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -5,18 +5,21 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
#include <iosfwd>
#include <set>
#include <string>
#include <utility>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
class cmOrderDirectories;
class cmake;
+template <typename T>
+class BT;
/** \class cmComputeLinkInformation
* \brief Compute link information for a target in one configuration.
@@ -42,9 +45,11 @@ public:
bool IsPath = true;
cmGeneratorTarget const* Target = nullptr;
};
- typedef std::vector<Item> ItemVector;
+ using ItemVector = std::vector<Item>;
+ void AppendValues(std::string& result, std::vector<BT<std::string>>& values);
ItemVector const& GetItems() const;
std::vector<std::string> const& GetDirectories() const;
+ std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
std::vector<std::string> const& GetDepends() const;
std::vector<std::string> const& GetFrameworkPaths() const;
std::string GetLinkLanguage() const { return this->LinkLanguage; }
@@ -56,11 +61,18 @@ public:
std::string GetChrpathString() const;
std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
+ std::string const& GetLibLinkFileFlag() const
+ {
+ return this->LibLinkFileFlag;
+ }
+
std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
std::string GetRPathLinkString() const;
std::string GetConfig() const { return this->Config; }
+ const cmGeneratorTarget* GetTarget() { return this->Target; }
+
private:
void AddItem(std::string const& item, const cmGeneratorTarget* tgt);
void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt);
@@ -179,7 +191,6 @@ private:
bool OldLinkDirMode;
bool OpenBSD;
bool LinkDependsNoShared;
- bool UseImportLibrary;
bool RuntimeUseChrpath;
bool NoSONameUsesPath;
bool LinkWithRuntimePath;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 01d4c07e0..162bab298 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmComputeTargetDepends.h"
+#include <cassert>
+#include <cstdio>
+#include <sstream>
+#include <utility>
+
#include "cmComputeComponentGraph.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -20,11 +25,6 @@
#include "cmTargetDepend.h"
#include "cmake.h"
-#include <assert.h>
-#include <sstream>
-#include <stdio.h>
-#include <utility>
-
/*
This class is meant to analyze inter-target dependencies globally
@@ -140,8 +140,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
{
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmGeneratorTarget const*, int>::const_iterator tii =
- this->TargetIndex.find(t);
+ auto tii = this->TargetIndex.find(t);
assert(tii != this->TargetIndex.end());
int i = tii->second;
@@ -149,7 +148,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
EdgeList const& nl = this->FinalGraph[i];
for (cmGraphEdge const& ni : nl) {
cmGeneratorTarget const* dep = this->Targets[ni];
- cmTargetDependSet::iterator di = deps.insert(dep).first;
+ auto di = deps.insert(dep).first;
di->SetType(ni.IsStrong());
di->SetBacktrace(ni.GetBacktrace());
}
@@ -197,11 +196,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
{
std::set<cmLinkItem> emitted;
- std::vector<std::string> configs;
- depender->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ std::vector<std::string> const& configs =
+ depender->Makefile->GetGeneratorConfigs();
for (std::string const& it : configs) {
std::vector<cmSourceFile const*> objectFiles;
depender->GetExternalObjects(objectFiles, it);
@@ -371,8 +367,7 @@ void cmComputeTargetDepends::AddTargetDepend(
} else {
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmGeneratorTarget const*, int>::const_iterator tii =
- this->TargetIndex.find(dependee);
+ auto tii = this->TargetIndex.find(dependee);
assert(tii != this->TargetIndex.end());
int dependee_index = tii->second;
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 3840bd752..d8060aede 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGraphAdjacencyList.h"
-#include "cmListFileCache.h"
-
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmGraphAdjacencyList.h"
+#include "cmListFileCache.h"
+
class cmComputeComponentGraph;
class cmGeneratorTarget;
class cmGlobalGenerator;
@@ -70,9 +70,9 @@ private:
// Represent the target dependency graph. The entry at each
// top-level index corresponds to a depender whose dependencies are
// listed.
- typedef cmGraphNodeList NodeList;
- typedef cmGraphEdgeList EdgeList;
- typedef cmGraphAdjacencyList Graph;
+ using NodeList = cmGraphNodeList;
+ using EdgeList = cmGraphEdgeList;
+ using Graph = cmGraphAdjacencyList;
Graph InitialGraph;
Graph FinalGraph;
void DisplayGraph(Graph const& graph, const std::string& name);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index e7e91c1a8..003e60d57 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -2,22 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConditionEvaluator.h"
-#include "cmsys/RegularExpression.hxx"
-#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <functional>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <utility>
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-class cmCommand;
class cmTest;
static std::string const keyAND = "AND";
@@ -219,10 +220,10 @@ bool cmConditionEvaluator::GetBooleanValue(
}
// Check named constants.
- if (cmSystemTools::IsOn(arg.c_str())) {
+ if (cmIsOn(arg.GetValue())) {
return true;
}
- if (cmSystemTools::IsOff(arg.c_str())) {
+ if (cmIsOff(arg.GetValue())) {
return false;
}
@@ -238,7 +239,7 @@ bool cmConditionEvaluator::GetBooleanValue(
// Check definition.
const char* def = this->GetDefinitionIfUnquoted(arg);
- return !cmSystemTools::IsOff(def);
+ return !cmIsOff(def);
}
//=========================================================================
@@ -255,14 +256,14 @@ bool cmConditionEvaluator::GetBooleanValueOld(
return true;
}
const char* def = this->GetDefinitionIfUnquoted(arg);
- return !cmSystemTools::IsOff(def);
+ return !cmIsOff(def);
}
// Old GetVariableOrNumber behavior.
const char* def = this->GetDefinitionIfUnquoted(arg);
if (!def && atoi(arg.c_str())) {
def = arg.c_str();
}
- return !cmSystemTools::IsOff(def);
+ return !cmIsOff(def);
}
//=========================================================================
@@ -367,7 +368,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
int reducible;
do {
reducible = 0;
- cmArgumentList::iterator arg = newArgs.begin();
+ auto arg = newArgs.begin();
while (arg != newArgs.end()) {
if (IsKeyword(keyParenL, *arg)) {
// search for the closing paren for this opening one
@@ -393,7 +394,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
std::vector<cmExpandedCommandArgument> newArgs2;
// copy to the list structure
- cmArgumentList::iterator argP1 = arg;
+ auto argP1 = arg;
argP1++;
cmAppend(newArgs2, argP1, argClose);
newArgs2.pop_back();
@@ -424,7 +425,7 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
int reducible;
do {
reducible = 0;
- cmArgumentList::iterator arg = newArgs.begin();
+ auto arg = newArgs.begin();
cmArgumentList::iterator argP1;
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
@@ -452,7 +453,7 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
}
// does a command exist
if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) {
- cmCommand* command =
+ cmState::Command command =
this->Makefile.GetState()->GetCommand(argP1->c_str());
this->HandlePredicate(command != nullptr, reducible, arg, newArgs,
argP1, argP2);
@@ -524,7 +525,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
const char* def2;
do {
reducible = 0;
- cmArgumentList::iterator arg = newArgs.begin();
+ auto arg = newArgs.begin();
cmArgumentList::iterator argP1;
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
@@ -668,10 +669,9 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
def2 = this->Makefile.GetDefinition(argP2->GetValue());
if (def2) {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(def2, list, true);
+ std::vector<std::string> list = cmExpandedList(def2, true);
- result = std::find(list.begin(), list.end(), def) != list.end();
+ result = cmContains(list, def);
}
this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
@@ -701,7 +701,7 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs,
int reducible;
do {
reducible = 0;
- cmArgumentList::iterator arg = newArgs.begin();
+ auto arg = newArgs.begin();
cmArgumentList::iterator argP1;
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
@@ -729,7 +729,7 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs,
bool rhs;
do {
reducible = 0;
- cmArgumentList::iterator arg = newArgs.begin();
+ auto arg = newArgs.begin();
cmArgumentList::iterator argP1;
cmArgumentList::iterator argP2;
while (arg != newArgs.end()) {
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
index 59e1396f6..082534ce8 100644
--- a/Source/cmConditionEvaluator.h
+++ b/Source/cmConditionEvaluator.h
@@ -19,7 +19,7 @@ class cmMakefile;
class cmConditionEvaluator
{
public:
- typedef std::list<cmExpandedCommandArgument> cmArgumentList;
+ using cmArgumentList = std::list<cmExpandedCommandArgument>;
cmConditionEvaluator(cmMakefile& makefile, cmListFileContext context,
cmListFileBacktrace bt);
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index 19b1cd4e3..4de1c5d6f 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -26,4 +26,8 @@
#define CM_FALLTHROUGH cmsys_FALLTHROUGH
+#if defined(_WIN32) && !defined(NOMINMAX)
+# define NOMINMAX
+#endif
+
#endif
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 0917d1102..8767386cf 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -2,78 +2,74 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConfigureFileCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmNewLineStyle.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmConfigureFileCommand
-bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmConfigureFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments, expected 2");
+ status.SetError("called with incorrect number of arguments, expected 2");
return false;
}
std::string const& inFile = args[0];
- this->InputFile = cmSystemTools::CollapseFullPath(
- inFile, this->Makefile->GetCurrentSourceDirectory());
+ const std::string inputFile = cmSystemTools::CollapseFullPath(
+ inFile, status.GetMakefile().GetCurrentSourceDirectory());
// If the input location is a directory, error out.
- if (cmSystemTools::FileIsDirectory(this->InputFile)) {
- std::ostringstream e;
- /* clang-format off */
- e << "input location\n"
- << " " << this->InputFile << "\n"
- << "is a directory but a file was expected.";
- /* clang-format on */
- this->SetError(e.str());
+ if (cmSystemTools::FileIsDirectory(inputFile)) {
+ status.SetError(cmStrCat("input location\n ", inputFile,
+ "\n"
+ "is a directory but a file was expected."));
return false;
}
std::string const& outFile = args[1];
- this->OutputFile = cmSystemTools::CollapseFullPath(
- outFile, this->Makefile->GetCurrentBinaryDirectory());
+ std::string outputFile = cmSystemTools::CollapseFullPath(
+ outFile, status.GetMakefile().GetCurrentBinaryDirectory());
// If the output location is already a directory put the file in it.
- if (cmSystemTools::FileIsDirectory(this->OutputFile)) {
- this->OutputFile += "/";
- this->OutputFile += cmSystemTools::GetFilenameName(inFile);
+ if (cmSystemTools::FileIsDirectory(outputFile)) {
+ outputFile += "/";
+ outputFile += cmSystemTools::GetFilenameName(inFile);
}
- if (!this->Makefile->CanIWriteThisFile(this->OutputFile)) {
- std::string e = "attempted to configure a file: " + this->OutputFile +
+ if (!status.GetMakefile().CanIWriteThisFile(outputFile)) {
+ std::string e = "attempted to configure a file: " + outputFile +
" into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
std::string errorMessage;
- if (!this->NewLineStyle.ReadFromArguments(args, errorMessage)) {
- this->SetError(errorMessage);
+ cmNewLineStyle newLineStyle;
+ if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
+ status.SetError(errorMessage);
return false;
}
- this->CopyOnly = false;
- this->EscapeQuotes = false;
+ bool copyOnly = false;
+ bool escapeQuotes = false;
std::string unknown_args;
- this->AtOnly = false;
+ bool atOnly = false;
for (unsigned int i = 2; i < args.size(); ++i) {
if (args[i] == "COPYONLY") {
- this->CopyOnly = true;
- if (this->NewLineStyle.IsValid()) {
- this->SetError("COPYONLY could not be used in combination "
- "with NEWLINE_STYLE");
+ copyOnly = true;
+ if (newLineStyle.IsValid()) {
+ status.SetError("COPYONLY could not be used in combination "
+ "with NEWLINE_STYLE");
return false;
}
} else if (args[i] == "ESCAPE_QUOTES") {
- this->EscapeQuotes = true;
+ escapeQuotes = true;
} else if (args[i] == "@ONLY") {
- this->AtOnly = true;
+ atOnly = true;
} else if (args[i] == "IMMEDIATE") {
/* Ignore legacy option. */
} else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
@@ -87,22 +83,16 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args,
}
}
if (!unknown_args.empty()) {
- std::string msg = "configure_file called with unknown argument(s):\n";
- msg += unknown_args;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+ std::string msg = cmStrCat(
+ "configure_file called with unknown argument(s):\n", unknown_args);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, msg);
}
- if (!this->ConfigureFile()) {
- this->SetError("Problem configuring file");
+ if (!status.GetMakefile().ConfigureFile(
+ inputFile, outputFile, copyOnly, atOnly, escapeQuotes, newLineStyle)) {
+ status.SetError("Problem configuring file");
return false;
}
return true;
}
-
-int cmConfigureFileCommand::ConfigureFile()
-{
- return this->Makefile->ConfigureFile(this->InputFile, this->OutputFile,
- this->CopyOnly, this->AtOnly,
- this->EscapeQuotes, this->NewLineStyle);
-}
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index 5603c505c..c7f95b852 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -8,33 +8,8 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmNewLineStyle.h"
-
class cmExecutionStatus;
-class cmConfigureFileCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmConfigureFileCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- int ConfigureFile();
-
- cmNewLineStyle NewLineStyle;
-
- std::string InputFile;
- std::string OutputFile;
- bool CopyOnly = false;
- bool EscapeQuotes = false;
- bool AtOnly = false;
-};
-
+bool cmConfigureFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
index 166426bfc..884e31432 100644
--- a/Source/cmConnection.cxx
+++ b/Source/cmConnection.cxx
@@ -2,12 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConnection.h"
-#include "cmServer.h"
-#include "cm_uv.h"
-
#include <cassert>
#include <cstring>
+#include "cm_uv.h"
+
+#include "cmServer.h"
+
struct write_req_t
{
uv_write_t req;
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
index 092b91302..7bb249404 100644
--- a/Source/cmConnection.h
+++ b/Source/cmConnection.h
@@ -5,13 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmUVHandlePtr.h"
-#include "cm_uv.h"
-
#include <cstddef>
#include <memory>
#include <string>
+#include "cm_uv.h"
+
+#include "cmUVHandlePtr.h"
+
class cmServerBase;
/***
diff --git a/Source/cmContinueCommand.cxx b/Source/cmContinueCommand.cxx
index 48f1f411b..bb63dffd6 100644
--- a/Source/cmContinueCommand.cxx
+++ b/Source/cmContinueCommand.cxx
@@ -8,13 +8,14 @@
#include "cmSystemTools.h"
// cmContinueCommand
-bool cmContinueCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+bool cmContinueCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (!this->Makefile->IsLoopBlock()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "A CONTINUE command was found outside of a "
- "proper FOREACH or WHILE loop scope.");
+ if (!status.GetMakefile().IsLoopBlock()) {
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ "A CONTINUE command was found outside of a "
+ "proper FOREACH or WHILE loop scope.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -22,9 +23,10 @@ bool cmContinueCommand::InitialPass(std::vector<std::string> const& args,
status.SetContinueInvoked();
if (!args.empty()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "The CONTINUE command does not accept any "
- "arguments.");
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ "The CONTINUE command does not accept any "
+ "arguments.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
index d383d1d03..ff903aaf6 100644
--- a/Source/cmContinueCommand.h
+++ b/Source/cmContinueCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmContinueCommand
+/**
* \brief Continue from an enclosing foreach or while loop
*
* cmContinueCommand returns from an enclosing foreach or while loop
*/
-class cmContinueCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmContinueCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmContinueCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index f12ef0b4a..5711cae49 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -2,14 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCoreTryCompile.h"
-#include "cmsys/Directory.hxx"
+#include <cstdio>
+#include <cstring>
#include <set>
#include <sstream>
-#include <stdio.h>
-#include <string.h>
#include <utility>
-#include "cmAlgorithms.h"
+#include "cmsys/Directory.hxx"
+
+#include "cm_static_string_view.hxx"
+
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -17,10 +19,10 @@
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmVersion.h"
-#include "cm_static_string_view.hxx"
#include "cmake.h"
static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
@@ -54,6 +56,8 @@ static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
+static std::string const kCMAKE_Swift_COMPILER_TARGET =
+ "CMAKE_Swift_COMPILER_TARGET";
static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
@@ -132,13 +136,19 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string copyFile;
std::string copyFileError;
std::string cStandard;
+ std::string objcStandard;
std::string cxxStandard;
+ std::string objcxxStandard;
std::string cudaStandard;
std::string cStandardRequired;
std::string cxxStandardRequired;
+ std::string objcStandardRequired;
+ std::string objcxxStandardRequired;
std::string cudaStandardRequired;
std::string cExtensions;
std::string cxxExtensions;
+ std::string objcExtensions;
+ std::string objcxxExtensions;
std::string cudaExtensions;
std::vector<std::string> targets;
std::vector<std::string> linkOptions;
@@ -150,12 +160,18 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool didCopyFileError = false;
bool didCStandard = false;
bool didCxxStandard = false;
+ bool didObjCStandard = false;
+ bool didObjCxxStandard = false;
bool didCudaStandard = false;
bool didCStandardRequired = false;
bool didCxxStandardRequired = false;
+ bool didObjCStandardRequired = false;
+ bool didObjCxxStandardRequired = false;
bool didCudaStandardRequired = false;
bool didCExtensions = false;
bool didCxxExtensions = false;
+ bool didObjCExtensions = false;
+ bool didObjCxxExtensions = false;
bool didCudaExtensions = false;
bool useSources = argv[2] == "SOURCES";
std::vector<std::string> sources;
@@ -172,12 +188,18 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
DoingCopyFileError,
DoingCStandard,
DoingCxxStandard,
+ DoingObjCStandard,
+ DoingObjCxxStandard,
DoingCudaStandard,
DoingCStandardRequired,
DoingCxxStandardRequired,
+ DoingObjCStandardRequired,
+ DoingObjCxxStandardRequired,
DoingCudaStandardRequired,
DoingCExtensions,
DoingCxxExtensions,
+ DoingObjCExtensions,
+ DoingObjCxxExtensions,
DoingCudaExtensions,
DoingSources,
DoingCMakeInternal
@@ -208,6 +230,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "CXX_STANDARD") {
doing = DoingCxxStandard;
didCxxStandard = true;
+ } else if (argv[i] == "OBJC_STANDARD") {
+ doing = DoingObjCStandard;
+ didObjCStandard = true;
+ } else if (argv[i] == "OBJCXX_STANDARD") {
+ doing = DoingObjCxxStandard;
+ didObjCxxStandard = true;
} else if (argv[i] == "CUDA_STANDARD") {
doing = DoingCudaStandard;
didCudaStandard = true;
@@ -217,6 +245,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "CXX_STANDARD_REQUIRED") {
doing = DoingCxxStandardRequired;
didCxxStandardRequired = true;
+ } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
+ doing = DoingObjCStandardRequired;
+ didObjCStandardRequired = true;
+ } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
+ doing = DoingObjCxxStandardRequired;
+ didObjCxxStandardRequired = true;
} else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
doing = DoingCudaStandardRequired;
didCudaStandardRequired = true;
@@ -226,6 +260,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "CXX_EXTENSIONS") {
doing = DoingCxxExtensions;
didCxxExtensions = true;
+ } else if (argv[i] == "OBJC_EXTENSIONS") {
+ doing = DoingObjCExtensions;
+ didObjCExtensions = true;
+ } else if (argv[i] == "OBJCXX_EXTENSIONS") {
+ doing = DoingObjCxxExtensions;
+ didObjCxxExtensions = true;
} else if (argv[i] == "CUDA_EXTENSIONS") {
doing = DoingCudaExtensions;
didCudaExtensions = true;
@@ -234,11 +274,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCMakeFlags) {
cmakeFlags.push_back(argv[i]);
} else if (doing == DoingCompileDefinitions) {
- cmSystemTools::ExpandListArgument(argv[i], compileDefs);
+ cmExpandList(argv[i], compileDefs);
} else if (doing == DoingLinkOptions) {
linkOptions.push_back(argv[i]);
} else if (doing == DoingLinkLibraries) {
- libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
+ libsToLink += "\"" + cmTrimWhitespace(argv[i]) + "\" ";
if (cmTarget* tgt = this->Makefile->FindTargetToUse(argv[i])) {
switch (tgt->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
@@ -281,6 +321,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCxxStandard) {
cxxStandard = argv[i];
doing = DoingNone;
+ } else if (doing == DoingObjCStandard) {
+ objcStandard = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingObjCxxStandard) {
+ objcxxStandard = argv[i];
+ doing = DoingNone;
} else if (doing == DoingCudaStandard) {
cudaStandard = argv[i];
doing = DoingNone;
@@ -290,6 +336,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCxxStandardRequired) {
cxxStandardRequired = argv[i];
doing = DoingNone;
+ } else if (doing == DoingObjCStandardRequired) {
+ objcStandardRequired = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingObjCxxStandardRequired) {
+ objcxxStandardRequired = argv[i];
+ doing = DoingNone;
} else if (doing == DoingCudaStandardRequired) {
cudaStandardRequired = argv[i];
doing = DoingNone;
@@ -299,6 +351,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (doing == DoingCxxExtensions) {
cxxExtensions = argv[i];
doing = DoingNone;
+ } else if (doing == DoingObjCExtensions) {
+ objcExtensions = argv[i];
+ doing = DoingNone;
+ } else if (doing == DoingObjCxxExtensions) {
+ objcxxExtensions = argv[i];
+ doing = DoingNone;
} else if (doing == DoingCudaExtensions) {
cudaExtensions = argv[i];
doing = DoingNone;
@@ -411,8 +469,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
// compute the binary dir when TRY_COMPILE is called with a src file
// signature
if (this->SrcFileSignature) {
- this->BinaryDirectory += "/CMakeFiles";
- this->BinaryDirectory += "/CMakeTmp";
+ this->BinaryDirectory += "/CMakeFiles/CMakeTmp";
} else {
// only valid for srcfile signatures
if (!compileDefs.empty()) {
@@ -514,7 +571,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
for (std::string const& li : testLangs) {
projectLangs += " " + li;
std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE";
- std::string rulesOverrideLang = rulesOverrideBase + "_" + li;
+ std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, "_", li);
if (const char* rulesOverridePath =
this->Makefile->GetDefinition(rulesOverrideLang)) {
fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(),
@@ -574,7 +631,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string const cfg =
!tcConfig.empty() ? cmSystemTools::UpperCase(tcConfig) : cfgDefault;
for (std::string const& li : testLangs) {
- std::string const langFlagsCfg = "CMAKE_" + li + "_FLAGS_" + cfg;
+ std::string const langFlagsCfg =
+ cmStrCat("CMAKE_", li, "_FLAGS_", cfg);
const char* flagsCfg = this->Makefile->GetDefinition(langFlagsCfg);
fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(),
cmOutputConverter::EscapeForCMake(flagsCfg ? flagsCfg : "")
@@ -669,13 +727,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_SYSROOT);
vars.insert(kCMAKE_SYSROOT_COMPILE);
vars.insert(kCMAKE_SYSROOT_LINK);
+ vars.insert(kCMAKE_Swift_COMPILER_TARGET);
vars.insert(kCMAKE_WARN_DEPRECATED);
vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
if (const char* varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
- std::vector<std::string> varList;
- cmSystemTools::ExpandListArgument(varListStr, varList);
+ std::vector<std::string> varList = cmExpandedList(varListStr);
vars.insert(varList.begin(), varList.end());
}
@@ -750,16 +808,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fprintf(fout, ")\n");
bool const testC = testLangs.find("C") != testLangs.end();
+ bool const testObjC = testLangs.find("OBJC") != testLangs.end();
bool const testCxx = testLangs.find("CXX") != testLangs.end();
+ bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
bool const testCuda = testLangs.find("CUDA") != testLangs.end();
bool warnCMP0067 = false;
bool honorStandard = true;
- if (!didCStandard && !didCxxStandard && !didCudaStandard &&
- !didCStandardRequired && !didCxxStandardRequired &&
- !didCudaStandardRequired && !didCExtensions && !didCxxExtensions &&
- !didCudaExtensions) {
+ if (!didCStandard && !didCxxStandard && !didObjCStandard &&
+ !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
+ !didCxxStandardRequired && !didObjCStandardRequired &&
+ !didObjCxxStandardRequired && !didCudaStandardRequired &&
+ !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
+ !didObjCxxExtensions && !didCudaExtensions) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
case cmPolicies::WARN:
warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -782,45 +844,42 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
if (honorStandard || warnCMP0067) {
- if (testC) {
- if (!didCStandard) {
- cStandard = this->LookupStdVar("CMAKE_C_STANDARD", warnCMP0067);
- }
- if (!didCStandardRequired) {
- cStandardRequired =
- this->LookupStdVar("CMAKE_C_STANDARD_REQUIRED", warnCMP0067);
- }
- if (!didCExtensions) {
- cExtensions = this->LookupStdVar("CMAKE_C_EXTENSIONS", warnCMP0067);
- }
- }
- if (testCxx) {
- if (!didCxxStandard) {
- cxxStandard = this->LookupStdVar("CMAKE_CXX_STANDARD", warnCMP0067);
- }
- if (!didCxxStandardRequired) {
- cxxStandardRequired =
- this->LookupStdVar("CMAKE_CXX_STANDARD_REQUIRED", warnCMP0067);
- }
- if (!didCxxExtensions) {
- cxxExtensions =
- this->LookupStdVar("CMAKE_CXX_EXTENSIONS", warnCMP0067);
- }
- }
- if (testCuda) {
- if (!didCudaStandard) {
- cudaStandard =
- this->LookupStdVar("CMAKE_CUDA_STANDARD", warnCMP0067);
- }
- if (!didCudaStandardRequired) {
- cudaStandardRequired =
- this->LookupStdVar("CMAKE_CUDA_STANDARD_REQUIRED", warnCMP0067);
- }
- if (!didCudaExtensions) {
- cudaExtensions =
- this->LookupStdVar("CMAKE_CUDA_EXTENSIONS", warnCMP0067);
- }
- }
+
+ auto testLanguage =
+ [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
+ bool didLangExtensions, std::string& langStandard,
+ std::string& langStandardRequired, std::string& langExtensions,
+ const std::string& lang) {
+ if (testLang) {
+ if (!didLangStandard) {
+ langStandard = this->LookupStdVar(
+ cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
+ }
+ if (!didLangStandardRequired) {
+ langStandardRequired = this->LookupStdVar(
+ cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
+ }
+ if (!didLangExtensions) {
+ langExtensions = this->LookupStdVar(
+ cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
+ }
+ }
+ };
+
+ testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
+ cStandard, cStandardRequired, cExtensions, "C");
+ testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
+ didObjCExtensions, objcStandard, objcStandardRequired,
+ objcExtensions, "OBJC");
+ testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
+ didCxxExtensions, cxxStandard, cxxStandardRequired,
+ cxxExtensions, "CXX");
+ testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
+ didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
+ objcxxExtensions, "OBJCXX");
+ testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
+ didCudaExtensions, cudaStandard, cudaStandardRequired,
+ cudaExtensions, "CUDA");
}
if (!this->WarnCMP0067.empty()) {
@@ -837,44 +896,37 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
- if (testC) {
- if (!cStandard.empty()) {
- writeProperty(fout, targetName, "C_STANDARD", cStandard);
- }
- if (!cStandardRequired.empty()) {
- writeProperty(fout, targetName, "C_STANDARD_REQUIRED",
- cStandardRequired);
- }
- if (!cExtensions.empty()) {
- writeProperty(fout, targetName, "C_EXTENSIONS", cExtensions);
- }
- }
-
- if (testCxx) {
- if (!cxxStandard.empty()) {
- writeProperty(fout, targetName, "CXX_STANDARD", cxxStandard);
- }
- if (!cxxStandardRequired.empty()) {
- writeProperty(fout, targetName, "CXX_STANDARD_REQUIRED",
- cxxStandardRequired);
- }
- if (!cxxExtensions.empty()) {
- writeProperty(fout, targetName, "CXX_EXTENSIONS", cxxExtensions);
- }
- }
-
- if (testCuda) {
- if (!cudaStandard.empty()) {
- writeProperty(fout, targetName, "CUDA_STANDARD", cudaStandard);
- }
- if (!cudaStandardRequired.empty()) {
- writeProperty(fout, targetName, "CUDA_STANDARD_REQUIRED",
- cudaStandardRequired);
- }
- if (!cudaExtensions.empty()) {
- writeProperty(fout, targetName, "CUDA_EXTENSIONS", cudaExtensions);
+ auto writeLanguageProperties = [&](bool testLang,
+ const std::string& langStandard,
+ const std::string& langStandardRequired,
+ const std::string& langExtensions,
+ const std::string& lang) {
+ if (testLang) {
+ if (!langStandard.empty()) {
+ writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
+ langStandard);
+ }
+ if (!langStandardRequired.empty()) {
+ writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
+ langStandardRequired);
+ }
+ if (!langExtensions.empty()) {
+ writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
+ langExtensions);
+ }
}
- }
+ };
+
+ writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
+ "C");
+ writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
+ objcExtensions, "OBJC");
+ writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
+ cxxExtensions, "CXX");
+ writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
+ objcxxExtensions, "OBJCXX");
+ writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
+ cudaExtensions, "CUDA");
if (!linkOptions.empty()) {
std::vector<std::string> options;
@@ -932,7 +984,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
cmStateEnums::INTERNAL);
if (!outputVariable.empty()) {
- this->Makefile->AddDefinition(outputVariable, output.c_str());
+ this->Makefile->AddDefinition(outputVariable, output);
}
if (this->SrcFileSignature) {
@@ -961,8 +1013,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
if (!copyFileError.empty()) {
- this->Makefile->AddDefinition(copyFileError,
- copyFileErrorMessage.c_str());
+ this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
}
}
return res;
@@ -1046,16 +1097,14 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
// if a config was specified try that first
if (config && config[0]) {
- std::string tmp = "/";
- tmp += config;
+ std::string tmp = cmStrCat('/', config);
searchDirs.push_back(std::move(tmp));
}
searchDirs.emplace_back("/Debug");
#if defined(__APPLE__)
std::string app = "/" + targetName + ".app";
if (config && config[0]) {
- std::string tmp = "/";
- tmp += config + app;
+ std::string tmp = cmStrCat('/', config, app);
searchDirs.push_back(std::move(tmp));
}
std::string tmp = "/Debug" + app;
@@ -1065,9 +1114,7 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
searchDirs.emplace_back("/Development");
for (std::string const& sdir : searchDirs) {
- std::string command = this->BinaryDirectory;
- command += sdir;
- command += tmpOutputFile;
+ std::string command = cmStrCat(this->BinaryDirectory, sdir, tmpOutputFile);
if (cmSystemTools::FileExists(command)) {
this->OutputFile = cmSystemTools::CollapseFullPath(command);
return;
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index b78493f99..9d492ba84 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -4,22 +4,21 @@
#include <algorithm>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-// cmCreateTestSourceList
-bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmCreateTestSourceList(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with wrong number of arguments.");
+ status.SetError("called with wrong number of arguments.");
return false;
}
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
std::string extraInclude;
std::string function;
std::vector<std::string> tests;
@@ -28,20 +27,17 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args,
if (*i == "EXTRA_INCLUDE") {
++i;
if (i == args.end()) {
- this->SetError("incorrect arguments to EXTRA_INCLUDE");
+ status.SetError("incorrect arguments to EXTRA_INCLUDE");
return false;
}
- extraInclude = "#include \"";
- extraInclude += *i;
- extraInclude += "\"\n";
+ extraInclude = cmStrCat("#include \"", *i, "\"\n");
} else if (*i == "FUNCTION") {
++i;
if (i == args.end()) {
- this->SetError("incorrect arguments to FUNCTION");
+ status.SetError("incorrect arguments to FUNCTION");
return false;
}
- function = *i;
- function += "(&ac, &av);\n";
+ function = cmStrCat(*i, "(&ac, &av);\n");
} else {
tests.push_back(*i);
}
@@ -56,13 +52,12 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args,
// Name of the test driver
// make sure they specified an extension
if (cmSystemTools::GetFilenameExtension(*i).size() < 2) {
- this->SetError(
+ status.SetError(
"You must specify a file extension for the test driver file.");
return false;
}
- std::string driver = this->Makefile->GetCurrentBinaryDirectory();
- driver += "/";
- driver += *i;
+ cmMakefile& mf = status.GetMakefile();
+ std::string driver = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', *i);
++i;
std::string configFile = cmSystemTools::GetCMakeRoot();
@@ -70,7 +65,7 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args,
configFile += "/Templates/TestDriver.cxx.in";
// Create the test driver file
- std::vector<std::string>::const_iterator testsBegin = i;
+ auto testsBegin = i;
std::vector<std::string> tests_func_name;
// The rest of the arguments consist of a list of test source files.
@@ -124,36 +119,32 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args,
numTests++;
}
if (!extraInclude.empty()) {
- this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES",
- extraInclude.c_str());
+ mf.AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", extraInclude);
}
if (!function.empty()) {
- this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION",
- function.c_str());
+ mf.AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function);
}
- this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS",
- forwardDeclareCode.c_str());
- this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES",
- functionMapCode.c_str());
+ mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
+ mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
bool res = true;
- if (!this->Makefile->ConfigureFile(configFile, driver, false, true, false)) {
+ if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
res = false;
}
// Construct the source list.
std::string sourceListValue;
{
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver);
+ cmSourceFile* sf = mf.GetOrCreateSource(driver);
sf->SetProperty("ABSTRACT", "0");
sourceListValue = args[1];
}
for (i = testsBegin; i != tests.end(); ++i) {
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+ cmSourceFile* sf = mf.GetOrCreateSource(*i);
sf->SetProperty("ABSTRACT", "0");
sourceListValue += ";";
sourceListValue += *i;
}
- this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
+ mf.AddDefinition(sourceList, sourceListValue);
return res;
}
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
index 005b32c30..19503f43d 100644
--- a/Source/cmCreateTestSourceList.h
+++ b/Source/cmCreateTestSourceList.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmCreateTestSourceList
- * \brief Test driver generation command
- *
- */
-
-class cmCreateTestSourceList : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmCreateTestSourceList; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmCreateTestSourceList(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index d914eb142..dc7d939c9 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -2,13 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCryptoHash.h"
-#include "cmAlgorithms.h"
-#include "cm_kwiml.h"
-#include "cm_rhash.h"
+#include <cm/memory>
+
#include "cmsys/FStream.hxx"
-#include <string.h>
-#include <memory> // IWYU pragma: keep
+#include "cm_kwiml.h"
+#include "cm_rhash.h"
static unsigned int const cmCryptoHashAlgoToId[] = {
/* clang-format needs this comment to break after the opening brace */
@@ -46,36 +45,36 @@ cmCryptoHash::~cmCryptoHash()
rhash_free(this->CTX);
}
-std::unique_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo)
+std::unique_ptr<cmCryptoHash> cmCryptoHash::New(cm::string_view algo)
{
- if (strcmp(algo, "MD5") == 0) {
+ if (algo == "MD5") {
return cm::make_unique<cmCryptoHash>(AlgoMD5);
}
- if (strcmp(algo, "SHA1") == 0) {
+ if (algo == "SHA1") {
return cm::make_unique<cmCryptoHash>(AlgoSHA1);
}
- if (strcmp(algo, "SHA224") == 0) {
+ if (algo == "SHA224") {
return cm::make_unique<cmCryptoHash>(AlgoSHA224);
}
- if (strcmp(algo, "SHA256") == 0) {
+ if (algo == "SHA256") {
return cm::make_unique<cmCryptoHash>(AlgoSHA256);
}
- if (strcmp(algo, "SHA384") == 0) {
+ if (algo == "SHA384") {
return cm::make_unique<cmCryptoHash>(AlgoSHA384);
}
- if (strcmp(algo, "SHA512") == 0) {
+ if (algo == "SHA512") {
return cm::make_unique<cmCryptoHash>(AlgoSHA512);
}
- if (strcmp(algo, "SHA3_224") == 0) {
+ if (algo == "SHA3_224") {
return cm::make_unique<cmCryptoHash>(AlgoSHA3_224);
}
- if (strcmp(algo, "SHA3_256") == 0) {
+ if (algo == "SHA3_256") {
return cm::make_unique<cmCryptoHash>(AlgoSHA3_256);
}
- if (strcmp(algo, "SHA3_384") == 0) {
+ if (algo == "SHA3_384") {
return cm::make_unique<cmCryptoHash>(AlgoSHA3_384);
}
- if (strcmp(algo, "SHA3_512") == 0) {
+ if (algo == "SHA3_512") {
return cm::make_unique<cmCryptoHash>(AlgoSHA3_512);
}
return std::unique_ptr<cmCryptoHash>(nullptr);
@@ -106,6 +105,7 @@ std::string cmCryptoHash::ByteHashToString(
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
std::string res;
+ res.reserve(hash.size() * 2);
for (unsigned char v : hash) {
res.push_back(hex[v >> 4]);
res.push_back(hex[v & 0xF]);
@@ -113,12 +113,10 @@ std::string cmCryptoHash::ByteHashToString(
return res;
}
-std::vector<unsigned char> cmCryptoHash::ByteHashString(
- const std::string& input)
+std::vector<unsigned char> cmCryptoHash::ByteHashString(cm::string_view input)
{
this->Initialize();
- this->Append(reinterpret_cast<unsigned char const*>(input.c_str()),
- static_cast<int>(input.size()));
+ this->Append(input);
return this->Finalize();
}
@@ -156,7 +154,7 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(const std::string& file)
return std::vector<unsigned char>();
}
-std::string cmCryptoHash::HashString(const std::string& input)
+std::string cmCryptoHash::HashString(cm::string_view input)
{
return ByteHashToString(this->ByteHashString(input));
}
@@ -176,9 +174,9 @@ void cmCryptoHash::Append(void const* buf, size_t sz)
rhash_update(this->CTX, buf, sz);
}
-void cmCryptoHash::Append(std::string const& str)
+void cmCryptoHash::Append(cm::string_view input)
{
- this->Append(str.c_str(), str.size());
+ rhash_update(this->CTX, input.data(), input.size());
}
std::vector<unsigned char> cmCryptoHash::Finalize()
diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h
index b712f09da..f27bb5db4 100644
--- a/Source/cmCryptoHash.h
+++ b/Source/cmCryptoHash.h
@@ -5,11 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <memory> // IWYU pragma: keep
-#include <stddef.h>
+#include <cstddef>
+#include <memory>
#include <string>
#include <vector>
+#include <cm/string_view>
+
/**
* @brief Abstract base class for cryptographic hash generators
*/
@@ -42,7 +44,7 @@ public:
/// SHA3_224, SHA3_256, SHA3_384, SHA3_512
/// @return A valid auto pointer if algo is supported or
/// an invalid/NULL pointer otherwise
- static std::unique_ptr<cmCryptoHash> New(const char* algo);
+ static std::unique_ptr<cmCryptoHash> New(cm::string_view algo);
/// @brief Converts a hex character to its binary value (4 bits)
/// @arg input Hex character [0-9a-fA-F].
@@ -55,7 +57,7 @@ public:
/// @brief Calculates a binary hash from string input data
/// @return Binary hash vector
- std::vector<unsigned char> ByteHashString(const std::string& input);
+ std::vector<unsigned char> ByteHashString(cm::string_view input);
/// @brief Calculates a binary hash from file content
/// @see ByteHashString()
@@ -65,7 +67,7 @@ public:
/// @brief Calculates a hash string from string input data
/// @return Sequence of hex characters pairs for each byte of the binary hash
- std::string HashString(const std::string& input);
+ std::string HashString(cm::string_view input);
/// @brief Calculates a hash string from file content
/// @see HashString()
@@ -75,7 +77,7 @@ public:
void Initialize();
void Append(void const*, size_t);
- void Append(std::string const& str);
+ void Append(cm::string_view input);
std::vector<unsigned char> Finalize();
std::string FinalizeHex();
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
index 0004f666b..233790e54 100644
--- a/Source/cmCurl.cxx
+++ b/Source/cmCurl.cxx
@@ -7,6 +7,7 @@
# define CMAKE_FIND_CAFILE
# include "cmSystemTools.h"
#endif
+#include "cmStringAlgorithms.h"
// curl versions before 7.21.5 did not provide this error code
#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x071505
@@ -72,8 +73,8 @@ std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
} else if (netrc_level == "IGNORED") {
curl_netrc_level = CURL_NETRC_IGNORED;
} else {
- e = "NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: ";
- e += netrc_level;
+ e = cmStrCat("NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: ",
+ netrc_level);
return e;
}
}
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index fe7eb809f..cb73ce631 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -5,9 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_curl.h"
#include <string>
+#include "cm_curl.h"
+
std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
const std::string& netrc_file);
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 7402eeb37..09d269b20 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCustomCommand.h"
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmMakefile.h"
-#include <utility>
-
cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
std::vector<std::string> outputs,
std::vector<std::string> byproducts,
@@ -88,18 +88,17 @@ cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const
return this->Backtrace;
}
-cmCustomCommand::ImplicitDependsList const&
-cmCustomCommand::GetImplicitDepends() const
+cmImplicitDependsList const& cmCustomCommand::GetImplicitDepends() const
{
return this->ImplicitDepends;
}
-void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l)
+void cmCustomCommand::SetImplicitDepends(cmImplicitDependsList const& l)
{
this->ImplicitDepends = l;
}
-void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
+void cmCustomCommand::AppendImplicitDepends(cmImplicitDependsList const& l)
{
cmAppend(this->ImplicitDepends, l);
}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 9a6f2390c..4689aceea 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -5,15 +5,20 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCustomCommandLines.h"
-#include "cmListFileCache.h"
-
#include <string>
#include <utility>
#include <vector>
+#include "cmCustomCommandLines.h"
+#include "cmListFileCache.h"
+
class cmMakefile;
+class cmImplicitDependsList
+ : public std::vector<std::pair<std::string, std::string>>
+{
+};
+
/** \class cmCustomCommand
* \brief A class to encapsulate a custom command
*
@@ -68,13 +73,9 @@ public:
/** Backtrace of the command that created this custom command. */
cmListFileBacktrace const& GetBacktrace() const;
- typedef std::pair<std::string, std::string> ImplicitDependsPair;
- class ImplicitDependsList : public std::vector<ImplicitDependsPair>
- {
- };
- void SetImplicitDepends(ImplicitDependsList const&);
- void AppendImplicitDepends(ImplicitDependsList const&);
- ImplicitDependsList const& GetImplicitDepends() const;
+ void SetImplicitDepends(cmImplicitDependsList const&);
+ void AppendImplicitDepends(cmImplicitDependsList const&);
+ cmImplicitDependsList const& GetImplicitDepends() const;
/** Set/Get whether this custom command should be given access to the
real console (if possible). */
@@ -99,7 +100,7 @@ private:
std::vector<std::string> Depends;
cmCustomCommandLines CommandLines;
cmListFileBacktrace Backtrace;
- ImplicitDependsList ImplicitDepends;
+ cmImplicitDependsList ImplicitDepends;
std::string Comment;
std::string WorkingDirectory;
std::string Depfile;
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index fe228ff2d..c1f412df8 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCustomCommandGenerator.h"
+#include <cstddef>
+#include <memory>
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -10,11 +14,28 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <memory> // IWYU pragma: keep
-#include <stddef.h>
-#include <utility>
+namespace {
+void AppendPaths(const std::vector<std::string>& inputs,
+ cmGeneratorExpression const& ge, cmLocalGenerator* lg,
+ std::string const& config, std::vector<std::string>& output)
+{
+ for (std::string const& in : inputs) {
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(in);
+ std::vector<std::string> result =
+ cmExpandedList(cge->Evaluate(lg, config));
+ for (std::string& it : result) {
+ cmSystemTools::ConvertToUnixSlashes(it);
+ if (cmSystemTools::FileIsFullPath(it)) {
+ it = cmSystemTools::CollapseFullPath(it);
+ }
+ }
+ cmAppend(output, result);
+ }
+}
+}
cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
std::string config,
@@ -24,18 +45,18 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
, LG(lg)
, OldStyle(cc.GetEscapeOldStyle())
, MakeVars(cc.GetEscapeAllowMakeVars())
- , GE(new cmGeneratorExpression(cc.GetBacktrace()))
, EmulatorsWithArguments(cc.GetCommandLines().size())
{
+ cmGeneratorExpression ge(cc.GetBacktrace());
+
const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
for (cmCustomCommandLine const& cmdline : cmdlines) {
cmCustomCommandLine argv;
for (std::string const& clarg : cmdline) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- this->GE->Parse(clarg);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg);
std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
if (this->CC.GetCommandExpandLists()) {
- cmAppend(argv, cmSystemTools::ExpandedListArgument(parsed_arg));
+ cmAppend(argv, cmExpandedList(parsed_arg));
} else {
argv.push_back(std::move(parsed_arg));
}
@@ -45,29 +66,20 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
// lists on an empty command may have left this empty.
// FIXME: Should we define behavior for removing empty commands?
if (argv.empty()) {
- argv.push_back(std::string());
+ argv.emplace_back();
}
this->CommandLines.push_back(std::move(argv));
}
- std::vector<std::string> depends = this->CC.GetDepends();
- for (std::string const& d : depends) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(d);
- std::vector<std::string> result = cmSystemTools::ExpandedListArgument(
- cge->Evaluate(this->LG, this->Config));
- for (std::string& it : result) {
- if (cmSystemTools::FileIsFullPath(it)) {
- it = cmSystemTools::CollapseFullPath(it);
- }
- }
- cmAppend(this->Depends, result);
- }
+ AppendPaths(cc.GetByproducts(), ge, this->LG, this->Config,
+ this->Byproducts);
+ AppendPaths(cc.GetDepends(), ge, this->LG, this->Config, this->Depends);
const std::string& workingdirectory = this->CC.GetWorkingDirectory();
if (!workingdirectory.empty()) {
std::unique_ptr<cmCompiledGeneratorExpression> cge =
- this->GE->Parse(workingdirectory);
+ ge.Parse(workingdirectory);
this->WorkingDirectory = cge->Evaluate(this->LG, this->Config);
// Convert working directory to a full path.
if (!this->WorkingDirectory.empty()) {
@@ -80,11 +92,6 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
this->FillEmulatorsWithArguments();
}
-cmCustomCommandGenerator::~cmCustomCommandGenerator()
-{
- delete this->GE;
-}
-
unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
{
return static_cast<unsigned int>(this->CC.GetCommandLines().size());
@@ -108,8 +115,7 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
continue;
}
- cmSystemTools::ExpandListArgument(emulator_property,
- this->EmulatorsWithArguments[c]);
+ cmExpandList(emulator_property, this->EmulatorsWithArguments[c]);
}
}
}
@@ -169,9 +175,7 @@ std::string escapeForShellOldStyle(const std::string& str)
std::string temp = str;
if (temp.find(" ") != std::string::npos &&
temp.find("\"") == std::string::npos) {
- result = "\"";
- result += str;
- result += "\"";
+ result = cmStrCat('"', str, '"');
return result;
}
return str;
@@ -240,7 +244,7 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
{
- return this->CC.GetByproducts();
+ return this->Byproducts;
}
std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 766f4b81d..67ee9e0e1 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -4,13 +4,13 @@
#define cmCustomCommandGenerator_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCustomCommandLines.h"
#include <string>
#include <vector>
+#include "cmCustomCommandLines.h"
+
class cmCustomCommand;
-class cmGeneratorExpression;
class cmLocalGenerator;
class cmCustomCommandGenerator
@@ -20,9 +20,9 @@ class cmCustomCommandGenerator
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
- cmGeneratorExpression* GE;
cmCustomCommandLines CommandLines;
std::vector<std::vector<std::string>> EmulatorsWithArguments;
+ std::vector<std::string> Byproducts;
std::vector<std::string> Depends;
std::string WorkingDirectory;
@@ -33,7 +33,6 @@ class cmCustomCommandGenerator
public:
cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config,
cmLocalGenerator* lg);
- ~cmCustomCommandGenerator();
cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete;
cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) =
delete;
diff --git a/Source/cmCustomCommandLines.cxx b/Source/cmCustomCommandLines.cxx
new file mode 100644
index 000000000..37ad75b7c
--- /dev/null
+++ b/Source/cmCustomCommandLines.cxx
@@ -0,0 +1,22 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCustomCommandLines.h"
+
+cmCustomCommandLine cmMakeCommandLine(
+ std::initializer_list<cm::string_view> ilist)
+{
+ cmCustomCommandLine commandLine;
+ commandLine.reserve(ilist.size());
+ for (cm::string_view cmd : ilist) {
+ commandLine.emplace_back(cmd);
+ }
+ return commandLine;
+}
+
+cmCustomCommandLines cmMakeSingleCommandLine(
+ std::initializer_list<cm::string_view> ilist)
+{
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(cmMakeCommandLine(ilist));
+ return commandLines;
+}
diff --git a/Source/cmCustomCommandLines.h b/Source/cmCustomCommandLines.h
index 36838f23f..ead579280 100644
--- a/Source/cmCustomCommandLines.h
+++ b/Source/cmCustomCommandLines.h
@@ -5,25 +5,28 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <initializer_list>
#include <string>
#include <vector>
+#include <cm/string_view> // IWYU pragma: keep
+
/** Data structure to represent a single command line. */
class cmCustomCommandLine : public std::vector<std::string>
{
-public:
- typedef std::vector<std::string> Superclass;
- typedef Superclass::iterator iterator;
- typedef Superclass::const_iterator const_iterator;
};
/** Data structure to represent a list of command lines. */
class cmCustomCommandLines : public std::vector<cmCustomCommandLine>
{
-public:
- typedef std::vector<cmCustomCommandLine> Superclass;
- typedef Superclass::iterator iterator;
- typedef Superclass::const_iterator const_iterator;
};
+/** Return a command line from a list of command line parts. */
+cmCustomCommandLine cmMakeCommandLine(
+ std::initializer_list<cm::string_view> ilist);
+
+/** Return a command line vector with a single command line. */
+cmCustomCommandLines cmMakeSingleCommandLine(
+ std::initializer_list<cm::string_view> ilist);
+
#endif
diff --git a/Source/cmCustomCommandTypes.h b/Source/cmCustomCommandTypes.h
new file mode 100644
index 000000000..d4bf1f9c3
--- /dev/null
+++ b/Source/cmCustomCommandTypes.h
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCustomCommandTypes_h
+#define cmCustomCommandTypes_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+/** Target custom command type */
+enum class cmCustomCommandType
+{
+ PRE_BUILD,
+ PRE_LINK,
+ POST_BUILD
+};
+
+/** Where the command originated from. */
+enum class cmCommandOrigin
+{
+ Project,
+ Generator
+};
+
+/** How to handle custom commands for object libraries */
+enum class cmObjectLibraryCommands
+{
+ Reject,
+ Accept
+};
+
+/** Utility target output source file name. */
+struct cmUtilityOutput
+{
+ std::string Name;
+ std::string NameCMP0049;
+};
+
+#endif
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index 86a83dabe..f4e4fda4d 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -2,19 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDefinePropertyCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
-class cmExecutionStatus;
-
-bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmDefinePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -37,17 +35,17 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args,
} else if (scope_arg == "CACHED_VARIABLE") {
scope = cmProperty::CACHED_VARIABLE;
} else {
- std::ostringstream e;
- e << "given invalid scope " << scope_arg << ". "
- << "Valid scopes are "
- << "GLOBAL, DIRECTORY, TARGET, SOURCE, "
- << "TEST, VARIABLE, CACHED_VARIABLE.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given invalid scope ", scope_arg,
+ ". Valid scopes are GLOBAL, DIRECTORY, TARGET, "
+ "SOURCE, TEST, VARIABLE, CACHED_VARIABLE."));
return false;
}
// Parse remaining arguments.
bool inherited = false;
+ std::string PropertyName;
+ std::string BriefDocs;
+ std::string FullDocs;
enum Doing
{
DoingNone,
@@ -68,39 +66,36 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args,
inherited = true;
} else if (doing == DoingProperty) {
doing = DoingNone;
- this->PropertyName = args[i];
+ PropertyName = args[i];
} else if (doing == DoingBrief) {
- this->BriefDocs += args[i];
+ BriefDocs += args[i];
} else if (doing == DoingFull) {
- this->FullDocs += args[i];
+ FullDocs += args[i];
} else {
- std::ostringstream e;
- e << "given invalid argument \"" << args[i] << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given invalid argument \"", args[i], "\"."));
return false;
}
}
// Make sure a property name was found.
- if (this->PropertyName.empty()) {
- this->SetError("not given a PROPERTY <name> argument.");
+ if (PropertyName.empty()) {
+ status.SetError("not given a PROPERTY <name> argument.");
return false;
}
// Make sure documentation was given.
- if (this->BriefDocs.empty()) {
- this->SetError("not given a BRIEF_DOCS <brief-doc> argument.");
+ if (BriefDocs.empty()) {
+ status.SetError("not given a BRIEF_DOCS <brief-doc> argument.");
return false;
}
- if (this->FullDocs.empty()) {
- this->SetError("not given a FULL_DOCS <full-doc> argument.");
+ if (FullDocs.empty()) {
+ status.SetError("not given a FULL_DOCS <full-doc> argument.");
return false;
}
// Actually define the property.
- this->Makefile->GetState()->DefineProperty(
- this->PropertyName, scope, this->BriefDocs.c_str(), this->FullDocs.c_str(),
- inherited);
+ status.GetMakefile().GetState()->DefineProperty(
+ PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited);
return true;
}
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
index a9c185618..60dd76a0d 100644
--- a/Source/cmDefinePropertyCommand.h
+++ b/Source/cmDefinePropertyCommand.h
@@ -8,26 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmDefinePropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmDefinePropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::string PropertyName;
- std::string BriefDocs;
- std::string FullDocs;
-};
+bool cmDefinePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 5fafaf943..69a64276b 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -2,10 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDefinitions.h"
-#include <assert.h>
-#include <set>
+#include <cassert>
+#include <functional>
+#include <unordered_set>
#include <utility>
+#include <cm/string_view>
+
cmDefinitions::Def cmDefinitions::NoDef;
cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key,
@@ -13,10 +16,12 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key,
StackIter end, bool raise)
{
assert(begin != end);
- MapType::iterator i = begin->Map.find(key);
- if (i != begin->Map.end()) {
- i->second.Used = true;
- return i->second;
+ {
+ auto it = begin->Map.find(cm::String::borrow(key));
+ if (it != begin->Map.end()) {
+ it->second.Used = true;
+ return it->second;
+ }
}
StackIter it = begin;
++it;
@@ -27,14 +32,14 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key,
if (!raise) {
return def;
}
- return begin->Map.insert(MapType::value_type(key, def)).first->second;
+ return begin->Map.emplace(key, def).first->second;
}
const std::string* cmDefinitions::Get(const std::string& key, StackIter begin,
StackIter end)
{
Def const& def = cmDefinitions::GetInternal(key, begin, end, false);
- return def.Exists ? &def : nullptr;
+ return def.Value ? def.Value.str_if_stable() : nullptr;
}
void cmDefinitions::Raise(const std::string& key, StackIter begin,
@@ -47,47 +52,27 @@ bool cmDefinitions::HasKey(const std::string& key, StackIter begin,
StackIter end)
{
for (StackIter it = begin; it != end; ++it) {
- MapType::const_iterator i = it->Map.find(key);
- if (i != it->Map.end()) {
+ if (it->Map.find(cm::String::borrow(key)) != it->Map.end()) {
return true;
}
}
return false;
}
-void cmDefinitions::Set(const std::string& key, const char* value)
-{
- Def def(value);
- this->Map[key] = def;
-}
-
-std::vector<std::string> cmDefinitions::UnusedKeys() const
-{
- std::vector<std::string> keys;
- keys.reserve(this->Map.size());
- // Consider local definitions.
- for (auto const& mi : this->Map) {
- if (!mi.second.Used) {
- keys.push_back(mi.first);
- }
- }
- return keys;
-}
-
cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end)
{
cmDefinitions closure;
- std::set<std::string> undefined;
+ std::unordered_set<cm::string_view> undefined;
for (StackIter it = begin; it != end; ++it) {
// Consider local definitions.
for (auto const& mi : it->Map) {
// Use this key if it is not already set or unset.
if (closure.Map.find(mi.first) == closure.Map.end() &&
- undefined.find(mi.first) == undefined.end()) {
- if (mi.second.Exists) {
+ undefined.find(mi.first.view()) == undefined.end()) {
+ if (mi.second.Value) {
closure.Map.insert(mi);
} else {
- undefined.insert(mi.first);
+ undefined.emplace(mi.first.view());
}
}
}
@@ -98,18 +83,41 @@ cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end)
std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin,
StackIter end)
{
- std::set<std::string> bound;
std::vector<std::string> defined;
+ std::unordered_set<cm::string_view> bound;
for (StackIter it = begin; it != end; ++it) {
defined.reserve(defined.size() + it->Map.size());
for (auto const& mi : it->Map) {
// Use this key if it is not already set or unset.
- if (bound.insert(mi.first).second && mi.second.Exists) {
- defined.push_back(mi.first);
+ if (bound.emplace(mi.first.view()).second && mi.second.Value) {
+ defined.push_back(*mi.first.str_if_stable());
}
}
}
return defined;
}
+
+void cmDefinitions::Set(const std::string& key, cm::string_view value)
+{
+ this->Map[key] = Def(value);
+}
+
+void cmDefinitions::Unset(const std::string& key)
+{
+ this->Map[key] = Def();
+}
+
+std::vector<std::string> cmDefinitions::UnusedKeys() const
+{
+ std::vector<std::string> keys;
+ keys.reserve(this->Map.size());
+ // Consider local definitions.
+ for (auto const& mi : this->Map) {
+ if (!mi.second.Used) {
+ keys.push_back(*mi.first.str_if_stable());
+ }
+ }
+ return keys;
+}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 6c252bee5..0e38fb1af 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -5,11 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
+#include <cm/string_view>
+
#include "cmLinkedTree.h"
+#include "cmString.hxx"
/** \class cmDefinitions
* \brief Store a scope of variable definitions for CMake language.
@@ -20,9 +24,11 @@
*/
class cmDefinitions
{
- typedef cmLinkedTree<cmDefinitions>::iterator StackIter;
+ using StackIter = cmLinkedTree<cmDefinitions>::iterator;
public:
+ // -- Static member functions
+
static const std::string* Get(const std::string& key, StackIter begin,
StackIter end);
@@ -30,41 +36,37 @@ public:
static bool HasKey(const std::string& key, StackIter begin, StackIter end);
- /** Set (or unset if null) a value associated with a key. */
- void Set(const std::string& key, const char* value);
-
- std::vector<std::string> UnusedKeys() const;
-
static std::vector<std::string> ClosureKeys(StackIter begin, StackIter end);
static cmDefinitions MakeClosure(StackIter begin, StackIter end);
+ // -- Member functions
+
+ /** Set a value associated with a key. */
+ void Set(const std::string& key, cm::string_view value);
+
+ /** Unset a definition. */
+ void Unset(const std::string& key);
+
+ /** List of unused keys. */
+ std::vector<std::string> UnusedKeys() const;
+
private:
- // String with existence boolean.
- struct Def : public std::string
+ /** String with existence boolean. */
+ struct Def
{
- private:
- typedef std::string std_string;
-
public:
Def() = default;
- Def(const char* v)
- : std_string(v ? v : "")
- , Exists(v ? true : false)
- {
- }
- Def(const std_string& v)
- : std_string(v)
- , Exists(true)
+ Def(cm::string_view value)
+ : Value(value)
{
}
- bool Exists = false;
+ cm::String Value;
bool Used = false;
};
static Def NoDef;
- typedef std::unordered_map<std::string, Def> MapType;
- MapType Map;
+ std::unordered_map<cm::String, Def> Map;
static Def const& GetInternal(const std::string& key, StackIter begin,
StackIter end, bool raise);
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index ed76dbf47..129a5f72f 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,17 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDepends.h"
+#include <sstream>
+#include <utility>
+
+#include "cmsys/FStream.hxx"
+
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmsys/FStream.hxx"
-#include <sstream>
-#include <utility>
-
cmDepends::cmDepends(cmLocalGenerator* lg, std::string targetDir)
: LocalGenerator(lg)
, TargetDirectory(std::move(targetDir))
@@ -30,10 +32,9 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends)
{
std::string const srcLang = "CMAKE_DEPENDS_CHECK_" + this->Language;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- cmSystemTools::ExpandListArgument(mf->GetSafeDefinition(srcLang), pairs);
+ cmExpandList(mf->GetSafeDefinition(srcLang), pairs);
}
- for (std::vector<std::string>::iterator si = pairs.begin();
- si != pairs.end();) {
+ for (auto si = pairs.begin(); si != pairs.end();) {
// Get the source and object file.
std::string const& src = *si++;
if (si == pairs.end()) {
@@ -235,21 +236,18 @@ void cmDepends::SetIncludePathFromLanguage(const std::string& lang)
{
// Look for the new per "TARGET_" variant first:
const char* includePath = nullptr;
- std::string includePathVar = "CMAKE_";
- includePathVar += lang;
- includePathVar += "_TARGET_INCLUDE_PATH";
+ std::string includePathVar =
+ cmStrCat("CMAKE_", lang, "_TARGET_INCLUDE_PATH");
cmMakefile* mf = this->LocalGenerator->GetMakefile();
includePath = mf->GetDefinition(includePathVar);
if (includePath) {
- cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
+ cmExpandList(includePath, this->IncludePath);
} else {
// Fallback to the old directory level variable if no per-target var:
- includePathVar = "CMAKE_";
- includePathVar += lang;
- includePathVar += "_INCLUDE_PATH";
+ includePathVar = cmStrCat("CMAKE_", lang, "_INCLUDE_PATH");
includePath = mf->GetDefinition(includePathVar);
if (includePath) {
- cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
+ cmExpandList(includePath, this->IncludePath);
}
}
}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index b7475f0ae..d9387758c 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -24,7 +24,7 @@ class cmLocalGenerator;
class cmDepends
{
public:
- typedef std::map<std::string, std::vector<std::string>> DependencyMap;
+ using DependencyMap = std::map<std::string, std::vector<std::string>>;
public:
/** Instances need to know the build directory name and the relative
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index dc49c18f8..e30d9597d 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -2,13 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDependsC.h"
-#include "cmsys/FStream.hxx"
#include <utility>
-#include "cmAlgorithms.h"
+#include "cmsys/FStream.hxx"
+
#include "cmFileTime.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#define INCLUDE_REGEX_LINE \
@@ -35,15 +36,12 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
std::string scanRegex = "^.*$";
std::string complainRegex = "^$";
{
- std::string scanRegexVar = "CMAKE_";
- scanRegexVar += lang;
- scanRegexVar += "_INCLUDE_REGEX_SCAN";
+ std::string scanRegexVar = cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_SCAN");
if (const char* sr = mf->GetDefinition(scanRegexVar)) {
scanRegex = sr;
}
- std::string complainRegexVar = "CMAKE_";
- complainRegexVar += lang;
- complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
+ std::string complainRegexVar =
+ cmStrCat("CMAKE_", lang, "_INCLUDE_REGEX_COMPLAIN");
if (const char* cr = mf->GetDefinition(complainRegexVar)) {
complainRegex = cr;
}
@@ -53,17 +51,15 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
this->IncludeRegexScan.compile(scanRegex);
this->IncludeRegexComplain.compile(complainRegex);
this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE;
- this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER;
- this->IncludeRegexScanString += scanRegex;
- this->IncludeRegexComplainString = INCLUDE_REGEX_COMPLAIN_MARKER;
- this->IncludeRegexComplainString += complainRegex;
+ this->IncludeRegexScanString =
+ cmStrCat(INCLUDE_REGEX_SCAN_MARKER, scanRegex);
+ this->IncludeRegexComplainString =
+ cmStrCat(INCLUDE_REGEX_COMPLAIN_MARKER, complainRegex);
this->SetupTransforms();
- this->CacheFileName = this->TargetDirectory;
- this->CacheFileName += "/";
- this->CacheFileName += lang;
- this->CacheFileName += ".includecache";
+ this->CacheFileName =
+ cmStrCat(this->TargetDirectory, '/', lang, ".includecache");
this->ReadCacheFile();
}
@@ -71,7 +67,6 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
cmDependsC::~cmDependsC()
{
this->WriteCacheFile();
- cmDeleteAll(this->FileCache);
}
bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
@@ -176,9 +171,9 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Check whether this file is already in the cache
auto fileIt = this->FileCache.find(fullName);
if (fileIt != this->FileCache.end()) {
- fileIt->second->Used = true;
+ fileIt->second.Used = true;
dependencies.insert(fullName);
- for (UnscannedEntry const& inc : fileIt->second->UnscannedEntries) {
+ for (UnscannedEntry const& inc : fileIt->second.UnscannedEntries) {
if (this->Encountered.find(inc.FileName) ==
this->Encountered.end()) {
this->Encountered.insert(inc.FileName);
@@ -264,8 +259,7 @@ void cmDependsC::ReadCacheFile()
if (res && newer) // cache is newer than the parsed file
{
- cacheEntry = new cmIncludeLines;
- this->FileCache[line] = cacheEntry;
+ cacheEntry = &this->FileCache[line];
}
// file doesn't exist, check that the regular expressions
// haven't changed
@@ -317,10 +311,10 @@ void cmDependsC::WriteCacheFile() const
cacheOut << this->IncludeRegexTransformString << "\n\n";
for (auto const& fileIt : this->FileCache) {
- if (fileIt.second->Used) {
+ if (fileIt.second.Used) {
cacheOut << fileIt.first << std::endl;
- for (UnscannedEntry const& inc : fileIt.second->UnscannedEntries) {
+ for (UnscannedEntry const& inc : fileIt.second.UnscannedEntries) {
cacheOut << inc.FileName << std::endl;
if (inc.QuotedLocation.empty()) {
cacheOut << "-" << std::endl;
@@ -336,9 +330,8 @@ void cmDependsC::WriteCacheFile() const
void cmDependsC::Scan(std::istream& is, const std::string& directory,
const std::string& fullName)
{
- cmIncludeLines* newCacheEntry = new cmIncludeLines;
- newCacheEntry->Used = true;
- this->FileCache[fullName] = newCacheEntry;
+ cmIncludeLines& newCacheEntry = this->FileCache[fullName];
+ newCacheEntry.Used = true;
// Read one line at a time.
std::string line;
@@ -374,7 +367,7 @@ void cmDependsC::Scan(std::istream& is, const std::string& directory,
// This kind of problem will be fixed when a more
// preprocessor-like implementation of this scanner is created.
if (this->IncludeRegexScan.find(entry.FileName)) {
- newCacheEntry->UnscannedEntries.push_back(entry);
+ newCacheEntry.UnscannedEntries.push_back(entry);
if (this->Encountered.find(entry.FileName) ==
this->Encountered.end()) {
this->Encountered.insert(entry.FileName);
@@ -391,7 +384,7 @@ void cmDependsC::SetupTransforms()
std::vector<std::string> transformRules;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
if (const char* xform = mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS")) {
- cmSystemTools::ExpandListArgument(xform, transformRules, true);
+ cmExpandList(xform, transformRules, true);
}
for (std::string const& tr : transformRules) {
this->ParseTransform(tr);
@@ -442,8 +435,7 @@ void cmDependsC::TransformLine(std::string& line)
if (!this->IncludeRegexTransform.find(line)) {
return;
}
- TransformRulesType::const_iterator tri =
- this->TransformRules.find(this->IncludeRegexTransform.match(3));
+ auto tri = this->TransformRules.find(this->IncludeRegexTransform.match(3));
if (tri == this->TransformRules.end()) {
return;
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 3fc839e43..3bb6e36a3 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -5,16 +5,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDepends.h"
-
-#include "cmsys/RegularExpression.hxx"
#include <iosfwd>
#include <map>
-#include <queue>
#include <set>
#include <string>
#include <vector>
+#include <queue>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmDepends.h"
+
class cmLocalGenerator;
/** \class cmDependsC
@@ -59,7 +61,7 @@ protected:
// Regex to transform #include lines.
std::string IncludeRegexTransformString;
cmsys::RegularExpression IncludeRegexTransform;
- typedef std::map<std::string, std::string> TransformRulesType;
+ using TransformRulesType = std::map<std::string, std::string>;
TransformRulesType TransformRules;
void SetupTransforms();
void ParseTransform(std::string const& xform);
@@ -84,7 +86,7 @@ protected:
std::set<std::string> Encountered;
std::queue<UnscannedEntry> Unscanned;
- std::map<std::string, cmIncludeLines*> FileCache;
+ std::map<std::string, cmIncludeLines> FileCache;
std::map<std::string, std::string> HeaderLocationCache;
std::string CacheFileName;
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 178e18b5f..ee4358762 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -2,14 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDependsFortran.h"
-#include "cmsys/FStream.hxx"
-#include <assert.h>
+#include <cassert>
+#include <cstdlib>
#include <iostream>
#include <map>
-#include <stdlib.h>
#include <utility>
-#include "cmAlgorithms.h"
+#include "cmsys/FStream.hxx"
+
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
#include "cmLocalGenerator.h"
@@ -17,6 +17,7 @@
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// TODO: Test compiler for the case of the mod file. Some always
@@ -46,18 +47,17 @@ public:
std::set<std::string> TargetProvides;
// Map modules required by this target to locations.
- typedef std::map<std::string, std::string> TargetRequiresMap;
+ using TargetRequiresMap = std::map<std::string, std::string>;
TargetRequiresMap TargetRequires;
// Information about each object file.
- typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
+ using ObjectInfoMap = std::map<std::string, cmFortranSourceInfo>;
ObjectInfoMap ObjectInfo;
cmFortranSourceInfo& CreateObjectInfo(const std::string& obj,
const std::string& src)
{
- std::map<std::string, cmFortranSourceInfo>::iterator i =
- this->ObjectInfo.find(obj);
+ auto i = this->ObjectInfo.find(obj);
if (i == this->ObjectInfo.end()) {
std::map<std::string, cmFortranSourceInfo>::value_type entry(
obj, cmFortranSourceInfo());
@@ -82,7 +82,7 @@ cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
cmMakefile* mf = this->LocalGenerator->GetMakefile();
if (const char* c_defines =
mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran")) {
- cmSystemTools::ExpandListArgument(c_defines, definitions);
+ cmExpandList(c_defines, definitions);
}
// translate i.e. FOO=BAR to FOO and add it to the list of defined
@@ -170,7 +170,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
}
// Actually write dependencies to the streams.
- typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
+ using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap;
ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
for (auto const& i : objInfo) {
if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir,
@@ -180,8 +180,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
}
// Store the list of modules provided by this target.
- std::string fiName = this->TargetDirectory;
- fiName += "/fortran.internal";
+ std::string fiName = cmStrCat(this->TargetDirectory, "/fortran.internal");
cmGeneratedFileStream fiStream(fiName);
fiStream << "# The fortran modules provided by this target.\n";
fiStream << "provides\n";
@@ -192,23 +191,18 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
// Create a script to clean the modules.
if (!provides.empty()) {
- std::string fcName = this->TargetDirectory;
- fcName += "/cmake_clean_Fortran.cmake";
+ std::string fcName =
+ cmStrCat(this->TargetDirectory, "/cmake_clean_Fortran.cmake");
cmGeneratedFileStream fcStream(fcName);
fcStream << "# Remove fortran modules provided by this target.\n";
fcStream << "FILE(REMOVE";
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (std::string const& i : provides) {
- std::string mod_upper = mod_dir;
- mod_upper += "/";
- std::string mod_lower = mod_dir;
- mod_lower += "/";
+ std::string mod_upper = cmStrCat(mod_dir, '/');
+ std::string mod_lower = cmStrCat(mod_dir, '/');
cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower);
- std::string stamp = stamp_dir;
- stamp += "/";
- stamp += i;
- stamp += ".stamp";
+ std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp");
fcStream << "\n";
fcStream << " \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
@@ -228,7 +222,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
void cmDependsFortran::LocateModules()
{
// Collect the set of modules provided and required by all sources.
- typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
+ using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap;
ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
for (auto const& infoI : objInfo) {
cmFortranSourceInfo const& info = infoI.second;
@@ -254,7 +248,7 @@ void cmDependsFortran::LocateModules()
std::vector<std::string> infoFiles;
if (const char* infoFilesValue =
mf->GetDefinition("CMAKE_TARGET_LINKED_INFO_FILES")) {
- cmSystemTools::ExpandListArgument(infoFilesValue, infoFiles);
+ cmExpandList(infoFilesValue, infoFiles);
}
for (std::string const& i : infoFiles) {
std::string targetDir = cmSystemTools::GetFilenamePath(i);
@@ -309,16 +303,11 @@ void cmDependsFortran::ConsiderModule(const std::string& name,
const std::string& stampDir)
{
// Locate each required module.
- typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
- TargetRequiresMap::iterator required =
- this->Internal->TargetRequires.find(name);
+ auto required = this->Internal->TargetRequires.find(name);
if (required != this->Internal->TargetRequires.end() &&
required->second.empty()) {
// The module is provided by a CMake target. It will have a stamp file.
- std::string stampFile = stampDir;
- stampFile += "/";
- stampFile += name;
- stampFile += ".stamp";
+ std::string stampFile = cmStrCat(stampDir, '/', name, ".stamp");
required->second = stampFile;
}
}
@@ -330,8 +319,6 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::ostream& makeDepends,
std::ostream& internalDepends)
{
- typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
-
// Get the source file for this object.
std::string const& src = info.Source;
@@ -359,8 +346,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// The object file should depend on timestamped files for the
// modules it uses.
- TargetRequiresMap::const_iterator required =
- this->Internal->TargetRequires.find(i);
+ auto required = this->Internal->TargetRequires.find(i);
if (required == this->Internal->TargetRequires.end()) {
abort();
}
@@ -392,16 +378,11 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// Always use lower case for the mod stamp file name. The
// cmake_copy_f90_mod will call back to this class, which will
// try various cases for the real mod file name.
- std::string modFile = mod_dir;
- modFile += "/";
- modFile += i;
+ std::string modFile = cmStrCat(mod_dir, '/', i);
modFile = this->LocalGenerator->ConvertToOutputFormat(
this->MaybeConvertToRelativePath(binDir, modFile),
cmOutputConverter::SHELL);
- std::string stampFile = stamp_dir;
- stampFile += "/";
- stampFile += i;
- stampFile += ".stamp";
+ std::string stampFile = cmStrCat(stamp_dir, '/', i, ".stamp");
stampFile = this->MaybeConvertToRelativePath(binDir, stampFile);
std::string const stampFileForShell =
this->LocalGenerator->ConvertToOutputFormat(stampFile,
@@ -435,8 +416,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// Make sure the module timestamp rule is evaluated by the time
// the target finishes building.
- std::string driver = this->TargetDirectory;
- driver += "/build";
+ std::string driver = cmStrCat(this->TargetDirectory, "/build");
driver = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, driver));
makeDepends << driver << ": " << obj_m << ".provides.build\n";
@@ -456,18 +436,14 @@ bool cmDependsFortran::FindModule(std::string const& name, std::string& module)
std::string fullName;
for (std::string const& ip : this->IncludePath) {
// Try the lower-case name.
- fullName = ip;
- fullName += "/";
- fullName += mod_lower;
+ fullName = cmStrCat(ip, '/', mod_lower);
if (cmSystemTools::FileExists(fullName, true)) {
module = fullName;
return true;
}
// Try the upper-case name.
- fullName = ip;
- fullName += "/";
- fullName += mod_upper;
+ fullName = cmStrCat(ip, '/', mod_upper);
if (cmSystemTools::FileExists(fullName, true)) {
module = fullName;
return true;
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index dd671a1b6..2a9025101 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDepends.h"
-
#include <iosfwd>
#include <set>
#include <string>
+#include "cmDepends.h"
+
/** \class cmDependsJava
* \brief Dependency scanner for Java class files.
*/
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 12d875d6f..516bbbfe0 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -2,17 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDependsJavaParserHelper.h"
-#include "cmDependsJavaLexer.h"
-#include "cmSystemTools.h"
-
-#include "cm_string_view.hxx"
-#include "cmsys/FStream.hxx"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <iostream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <utility>
+#include <cm/string_view>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmDependsJavaLexer.h"
+#include "cmSystemTools.h"
+
int cmDependsJava_yyparse(yyscan_t yyscanner);
cmDependsJavaParserHelper::cmDependsJavaParserHelper()
diff --git a/Source/cmDisallowedCommand.cxx b/Source/cmDisallowedCommand.cxx
deleted file mode 100644
index 418d98c9f..000000000
--- a/Source/cmDisallowedCommand.cxx
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmDisallowedCommand.h"
-
-#include "cmMakefile.h"
-#include "cmMessageType.h"
-
-class cmExecutionStatus;
-
-bool cmDisallowedCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
-{
- switch (this->Makefile->GetPolicyStatus(this->Policy)) {
- case cmPolicies::WARN:
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- cmPolicies::GetPolicyWarning(this->Policy));
- break;
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, this->Message);
- return true;
- }
-
- this->Command->SetMakefile(this->GetMakefile());
- bool const ret = this->Command->InitialPass(args, status);
- this->SetError(this->Command->GetError());
- return ret;
-}
diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h
deleted file mode 100644
index d85c00f8c..000000000
--- a/Source/cmDisallowedCommand.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmDisallowedCommand_h
-#define cmDisallowedCommand_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <vector>
-
-#include "cmCommand.h"
-#include "cmPolicies.h"
-
-class cmExecutionStatus;
-
-class cmDisallowedCommand : public cmCommand
-{
-public:
- cmDisallowedCommand(cmCommand* command, cmPolicies::PolicyID policy,
- const char* message)
- : Command(command)
- , Policy(policy)
- , Message(message)
- {
- }
-
- ~cmDisallowedCommand() override { delete this->Command; }
-
- cmCommand* Clone() override
- {
- return new cmDisallowedCommand(this->Command->Clone(), this->Policy,
- this->Message);
- }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- void FinalPass() override { this->Command->FinalPass(); }
-
- bool HasFinalPass() const override { return this->Command->HasFinalPass(); }
-
-private:
- cmCommand* Command;
- cmPolicies::PolicyID Policy;
- const char* Message;
-};
-
-#endif
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index d4628fa7e..1bc453d37 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -2,19 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDocumentation.h"
+#include <algorithm>
+#include <cctype>
+#include <cstring>
+#include <utility>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+
#include "cmDocumentationEntry.h"
#include "cmDocumentationSection.h"
#include "cmRST.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include <algorithm>
-#include <ctype.h>
-#include <string.h>
-#include <utility>
-
static const char* cmDocumentationStandardOptions[][2] = {
{ "--help,-help,-usage,-h,-H,/?", "Print usage information and exit." },
{ "--version,-version,/V [<f>]", "Print version number and exit." },
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index cf74b800d..3768e1abe 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDocumentationFormatter.h"
-#include "cmDocumentationSection.h"
-
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
+#include "cmDocumentationFormatter.h"
+#include "cmDocumentationSection.h"
+
struct cmDocumentationEntry;
/** Class to generate documentation. */
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index 3e7f9897e..732637e36 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -2,15 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDocumentationFormatter.h"
-#include "cmDocumentationEntry.h"
-#include "cmDocumentationSection.h"
-
+#include <cstring>
#include <iomanip>
#include <ostream>
-#include <string.h>
#include <string>
#include <vector>
+#include "cmDocumentationEntry.h"
+#include "cmDocumentationSection.h"
+
cmDocumentationFormatter::cmDocumentationFormatter() = default;
cmDocumentationFormatter::~cmDocumentationFormatter() = default;
diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h
index 19c7407b7..15cada6de 100644
--- a/Source/cmDocumentationSection.h
+++ b/Source/cmDocumentationSection.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmAlgorithms.h"
-#include "cmDocumentationEntry.h"
-
#include <string>
#include <vector>
+#include "cmAlgorithms.h"
+#include "cmDocumentationEntry.h"
+
// Low-level interface for custom documents:
/** Internal class representing a section of the documentation.
* Cares e.g. for the different section titles in the different
diff --git a/Source/cmDuration.h b/Source/cmDuration.h
index 6df1455b4..ccd1cc1cc 100644
--- a/Source/cmDuration.h
+++ b/Source/cmDuration.h
@@ -5,7 +5,7 @@
#include <chrono>
#include <ratio>
-typedef std::chrono::duration<double, std::ratio<1>> cmDuration;
+using cmDuration = std::chrono::duration<double, std::ratio<1>>;
/*
* This function will return number of seconds in the requested type T.
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 0549cf916..0b72a94b2 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -39,8 +39,7 @@ void cmDynamicLoaderCache::CacheFile(const char* path,
bool cmDynamicLoaderCache::GetCacheFile(const char* path,
cmsys::DynamicLoader::LibraryHandle& p)
{
- std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it =
- this->CacheMap.find(path);
+ auto it = this->CacheMap.find(path);
if (it != this->CacheMap.end()) {
p = it->second;
return true;
@@ -50,8 +49,7 @@ bool cmDynamicLoaderCache::GetCacheFile(const char* path,
bool cmDynamicLoaderCache::FlushCache(const char* path)
{
- std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it =
- this->CacheMap.find(path);
+ auto it = this->CacheMap.find(path);
bool ret = false;
if (it != this->CacheMap.end()) {
cmsys::DynamicLoader::CloseLibrary(it->second);
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 222646365..5976b2f78 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -2,16 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmELF.h"
-#include "cmAlgorithms.h"
-#include "cm_kwiml.h"
-#include "cmsys/FStream.hxx"
+#include <cstddef>
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
-#include <stddef.h>
#include <utility>
#include <vector>
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+
+#include "cm_kwiml.h"
+
+#include "cmAlgorithms.h"
+
// Include the ELF format information system header.
#if defined(__OpenBSD__)
# include <elf_abi.h>
@@ -19,11 +24,11 @@
#elif defined(__HAIKU__)
# include <elf32.h>
# include <elf64.h>
-typedef struct Elf32_Ehdr Elf32_Ehdr;
-typedef struct Elf32_Shdr Elf32_Shdr;
-typedef struct Elf32_Sym Elf32_Sym;
-typedef struct Elf32_Rel Elf32_Rel;
-typedef struct Elf32_Rela Elf32_Rela;
+using Elf32_Ehdr = struct Elf32_Ehdr;
+using Elf32_Shdr = struct Elf32_Shdr;
+using Elf32_Sym = struct Elf32_Sym;
+using Elf32_Rel = struct Elf32_Rel;
+using Elf32_Rela = struct Elf32_Rela;
# define ELFMAG0 0x7F
# define ELFMAG1 'E'
# define ELFMAG2 'L'
@@ -101,7 +106,7 @@ void cmELFByteSwap(T& x)
class cmELFInternal
{
public:
- typedef cmELF::StringEntry StringEntry;
+ using StringEntry = cmELF::StringEntry;
enum ByteOrderType
{
ByteOrderMSB,
@@ -109,10 +114,10 @@ public:
};
// Construct and take ownership of the file stream object.
- cmELFInternal(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin,
+ cmELFInternal(cmELF* external, std::unique_ptr<std::istream> fin,
ByteOrderType order)
: External(external)
- , Stream(*fin.release())
+ , Stream(std::move(fin))
, ByteOrder(order)
, ELFType(cmELF::FileTypeInvalid)
{
@@ -132,7 +137,7 @@ public:
}
// Destruct and delete the file stream object.
- virtual ~cmELFInternal() { delete &this->Stream; }
+ virtual ~cmELFInternal() = default;
// Forward to the per-class implementation.
virtual unsigned int GetNumberOfSections() const = 0;
@@ -171,7 +176,7 @@ protected:
cmELF* External;
// The stream from which to read.
- std::istream& Stream;
+ std::unique_ptr<std::istream> Stream;
// The byte order of the ELF file.
ByteOrderType ByteOrder;
@@ -199,11 +204,11 @@ protected:
// Configure the implementation template for 32-bit ELF files.
struct cmELFTypes32
{
- typedef Elf32_Ehdr ELF_Ehdr;
- typedef Elf32_Shdr ELF_Shdr;
- typedef Elf32_Dyn ELF_Dyn;
- typedef Elf32_Half ELF_Half;
- typedef KWIML_INT_uint32_t tagtype;
+ using ELF_Ehdr = Elf32_Ehdr;
+ using ELF_Shdr = Elf32_Shdr;
+ using ELF_Dyn = Elf32_Dyn;
+ using ELF_Half = Elf32_Half;
+ using tagtype = ::uint32_t;
static const char* GetName() { return "32-bit"; }
};
@@ -211,11 +216,11 @@ struct cmELFTypes32
#ifndef _SCO_DS
struct cmELFTypes64
{
- typedef Elf64_Ehdr ELF_Ehdr;
- typedef Elf64_Shdr ELF_Shdr;
- typedef Elf64_Dyn ELF_Dyn;
- typedef Elf64_Half ELF_Half;
- typedef KWIML_INT_uint64_t tagtype;
+ using ELF_Ehdr = Elf64_Ehdr;
+ using ELF_Shdr = Elf64_Shdr;
+ using ELF_Dyn = Elf64_Dyn;
+ using ELF_Half = Elf64_Half;
+ using tagtype = ::uint64_t;
static const char* GetName() { return "64-bit"; }
};
#endif
@@ -226,14 +231,14 @@ class cmELFInternalImpl : public cmELFInternal
{
public:
// Copy the ELF file format types from our configuration parameter.
- typedef typename Types::ELF_Ehdr ELF_Ehdr;
- typedef typename Types::ELF_Shdr ELF_Shdr;
- typedef typename Types::ELF_Dyn ELF_Dyn;
- typedef typename Types::ELF_Half ELF_Half;
- typedef typename Types::tagtype tagtype;
+ using ELF_Ehdr = typename Types::ELF_Ehdr;
+ using ELF_Shdr = typename Types::ELF_Shdr;
+ using ELF_Dyn = typename Types::ELF_Dyn;
+ using ELF_Half = typename Types::ELF_Half;
+ using tagtype = typename Types::tagtype;
// Construct with a stream and byte swap indicator.
- cmELFInternalImpl(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin,
+ cmELFInternalImpl(cmELF* external, std::unique_ptr<std::istream> fin,
ByteOrderType order);
// Return the number of sections as specified by the ELF header.
@@ -288,9 +293,8 @@ public:
}
private:
- // ByteSwap(ELF_Dyn) assumes d_val and d_ptr are the same size
- typedef char dyn_size_assert
- [sizeof(ELF_Dyn().d_un.d_val) == sizeof(ELF_Dyn().d_un.d_ptr) ? 1 : -1];
+ static_assert(sizeof(ELF_Dyn().d_un.d_val) == sizeof(ELF_Dyn().d_un.d_ptr),
+ "ByteSwap(ELF_Dyn) assumes d_val and d_ptr are the same size");
void ByteSwap(ELF_Ehdr& elf_header)
{
@@ -352,7 +356,7 @@ private:
bool Read(ELF_Ehdr& x)
{
// Read the header from the file.
- if (!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) {
+ if (!this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))) {
return false;
}
@@ -382,26 +386,26 @@ private:
}
bool Read(ELF_Shdr& x)
{
- if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+ if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
this->NeedSwap) {
ByteSwap(x);
}
- return !this->Stream.fail();
+ return !this->Stream->fail();
}
bool Read(ELF_Dyn& x)
{
- if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+ if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
this->NeedSwap) {
ByteSwap(x);
}
- return !this->Stream.fail();
+ return !this->Stream->fail();
}
bool LoadSectionHeader(ELF_Half i)
{
// Read the section header from the file.
- this->Stream.seekg(this->ELFHeader.e_shoff +
- this->ELFHeader.e_shentsize * i);
+ this->Stream->seekg(this->ELFHeader.e_shoff +
+ this->ELFHeader.e_shentsize * i);
if (!this->Read(this->SectionHeaders[i])) {
return false;
}
@@ -426,9 +430,10 @@ private:
};
template <class Types>
-cmELFInternalImpl<Types>::cmELFInternalImpl(
- cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, ByteOrderType order)
- : cmELFInternal(external, fin, order)
+cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external,
+ std::unique_ptr<std::istream> fin,
+ ByteOrderType order)
+ : cmELFInternal(external, std::move(fin), order)
{
// Read the main header.
if (!this->Read(this->ELFHeader)) {
@@ -510,7 +515,7 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
// Read each entry.
for (int j = 0; j < n; ++j) {
// Seek to the beginning of the section entry.
- this->Stream.seekg(sec.sh_offset + sec.sh_entsize * j);
+ this->Stream->seekg(sec.sh_offset + sec.sh_entsize * j);
ELF_Dyn& dyn = this->DynamicSectionEntries[j];
// Try reading the entry.
@@ -584,8 +589,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
unsigned int tag)
{
// Short-circuit if already checked.
- std::map<unsigned int, StringEntry>::iterator dssi =
- this->DynamicSectionStrings.find(tag);
+ auto dssi = this->DynamicSectionStrings.find(tag);
if (dssi != this->DynamicSectionStrings.end()) {
if (dssi->second.Position > 0) {
return &dssi->second;
@@ -613,8 +617,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link];
// Look for the requested entry.
- for (typename std::vector<ELF_Dyn>::iterator di =
- this->DynamicSectionEntries.begin();
+ for (auto di = this->DynamicSectionEntries.begin();
di != this->DynamicSectionEntries.end(); ++di) {
ELF_Dyn& dyn = *di;
if (static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag)) {
@@ -630,7 +633,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val);
unsigned long last = first;
unsigned long end = static_cast<unsigned long>(strtab.sh_size);
- this->Stream.seekg(strtab.sh_offset + first);
+ this->Stream->seekg(strtab.sh_offset + first);
// Read the string. It may be followed by more than one NULL
// terminator. Count the total size of the region allocated to
@@ -639,7 +642,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
// assumption.
bool terminated = false;
char c;
- while (last != end && this->Stream.get(c) && !(terminated && c)) {
+ while (last != end && this->Stream->get(c) && !(terminated && c)) {
++last;
if (c) {
se.Value += c;
@@ -649,7 +652,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
}
// Make sure the whole value was read.
- if (!this->Stream) {
+ if (!(*this->Stream)) {
this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
se.Value = "";
return nullptr;
@@ -679,10 +682,9 @@ const long cmELF::TagMipsRldMapRel = 0;
#endif
cmELF::cmELF(const char* fname)
- : Internal(nullptr)
{
// Try to open the file.
- std::unique_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname));
+ auto fin = cm::make_unique<cmsys::ifstream>(fname);
// Quit now if the file could not be opened.
if (!fin || !*fin) {
@@ -725,12 +727,14 @@ cmELF::cmELF(const char* fname)
// parser implementation.
if (ident[EI_CLASS] == ELFCLASS32) {
// 32-bit ELF
- this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order);
+ this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>(
+ this, std::move(fin), order);
}
#ifndef _SCO_DS
else if (ident[EI_CLASS] == ELFCLASS64) {
// 64-bit ELF
- this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order);
+ this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>(
+ this, std::move(fin), order);
}
#endif
else {
@@ -739,10 +743,7 @@ cmELF::cmELF(const char* fname)
}
}
-cmELF::~cmELF()
-{
- delete this->Internal;
-}
+cmELF::~cmELF() = default;
bool cmELF::Valid() const
{
diff --git a/Source/cmELF.h b/Source/cmELF.h
index 987f0c3a4..123bf9b1f 100644
--- a/Source/cmELF.h
+++ b/Source/cmELF.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -67,7 +68,7 @@ public:
};
/** Represent entire dynamic section header */
- typedef std::vector<std::pair<long, unsigned long>> DynamicEntryList;
+ using DynamicEntryList = std::vector<std::pair<long, unsigned long>>;
/** Get the type of the file opened. */
FileType GetFileType() const;
@@ -108,7 +109,7 @@ public:
private:
friend class cmELFInternal;
bool Valid() const;
- cmELFInternal* Internal;
+ std::unique_ptr<cmELFInternal> Internal;
std::string ErrorMessage;
};
diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx
index ddd26de9e..59522c040 100644
--- a/Source/cmEnableLanguageCommand.cxx
+++ b/Source/cmEnableLanguageCommand.cxx
@@ -2,20 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmEnableLanguageCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmEnableLanguageCommand
-bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmEnableLanguageCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- bool optional = false;
- std::vector<std::string> languages;
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+
+ bool optional = false;
+ std::vector<std::string> languages;
for (std::string const& it : args) {
if (it == "OPTIONAL") {
optional = true;
@@ -24,6 +23,6 @@ bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args,
}
}
- this->Makefile->EnableLanguage(languages, optional);
+ status.GetMakefile().EnableLanguage(languages, optional);
return true;
}
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
index 97645a98c..1f8c4ce7e 100644
--- a/Source/cmEnableLanguageCommand.h
+++ b/Source/cmEnableLanguageCommand.h
@@ -8,32 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmEnableLanguageCommand
- * \brief Specify the name for this build project.
- *
- * cmEnableLanguageCommand is used to specify a name for this build project.
- * It is defined once per set of CMakeList.txt files (including
- * all subdirectories). Currently it just sets the name of the workspace
- * file for Microsoft Visual C++
- */
-class cmEnableLanguageCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmEnableLanguageCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmEnableLanguageCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
index 6a64450f5..89212c801 100644
--- a/Source/cmEnableTestingCommand.cxx
+++ b/Source/cmEnableTestingCommand.cxx
@@ -2,15 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmEnableTestingCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// we do this in the final pass so that we now the subdirs have all
-// been defined
-bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+ cmExecutionStatus& status)
{
- this->Makefile->AddDefinition("CMAKE_TESTING_ENABLED", "1");
+ status.GetMakefile().AddDefinition("CMAKE_TESTING_ENABLED", "1");
return true;
}
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index 88a17b9bf..e4593f2fe 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -8,11 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmEnableTestingCommand
+/**
* \brief Enable testing for this directory and below.
*
* Produce the output testfile. This produces a file in the build directory
@@ -25,20 +23,7 @@ class cmExecutionStatus;
* Note that CTest expects to find this file in the build directory root;
* therefore, this command should be in the source directory root too.
*/
-class cmEnableTestingCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmEnableTestingCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override;
-};
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+ cmExecutionStatus&);
#endif
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 4b559e71a..51fb2191a 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -2,21 +2,30 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExecProgramCommand.h"
+#include <cstdio>
+
#include "cmsys/Process.h"
-#include <stdio.h>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+using Encoding = cmProcessOutput::Encoding;
+
+namespace {
+bool RunCommand(std::string command, std::string& output, int& retVal,
+ const char* directory = nullptr, bool verbose = true,
+ Encoding encoding = cmProcessOutput::Auto);
+}
// cmExecProgramCommand
-bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmExecProgramCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string arguments;
@@ -34,7 +43,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
haveoutput_variable = true;
} else if (haveoutput_variable) {
if (!output_variable.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
output_variable = arg;
@@ -47,7 +56,7 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
havereturn_variable = true;
} else if (havereturn_variable) {
if (!return_variable.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
return_variable = arg;
@@ -67,9 +76,8 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
std::string command;
if (!arguments.empty()) {
- command = cmSystemTools::ConvertToRunCommandPath(args[0]);
- command += " ";
- command += arguments;
+ command = cmStrCat(cmSystemTools::ConvertToRunCommandPath(args[0]), ' ',
+ arguments);
} else {
command = args[0];
}
@@ -82,11 +90,9 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
bool result = true;
if (args.size() - count == 2) {
cmSystemTools::MakeDirectory(args[1]);
- result = cmExecProgramCommand::RunCommand(command, output, retVal,
- args[1].c_str(), verbose);
+ result = RunCommand(command, output, retVal, args[1].c_str(), verbose);
} else {
- result = cmExecProgramCommand::RunCommand(command, output, retVal, nullptr,
- verbose);
+ result = RunCommand(command, output, retVal, nullptr, verbose);
}
if (!result) {
retVal = -1;
@@ -103,21 +109,21 @@ bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
}
std::string coutput = std::string(output, first, last - first + 1);
- this->Makefile->AddDefinition(output_variable, coutput.c_str());
+ status.GetMakefile().AddDefinition(output_variable, coutput);
}
if (!return_variable.empty()) {
char buffer[100];
sprintf(buffer, "%d", retVal);
- this->Makefile->AddDefinition(return_variable, buffer);
+ status.GetMakefile().AddDefinition(return_variable, buffer);
}
return true;
}
-bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
- int& retVal, const char* dir,
- bool verbose, Encoding encoding)
+namespace {
+bool RunCommand(std::string command, std::string& output, int& retVal,
+ const char* dir, bool verbose, Encoding encoding)
{
if (cmSystemTools::GetRunCommandOutput()) {
verbose = false;
@@ -187,10 +193,7 @@ bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
#else
std::string commandInDir;
if (dir) {
- commandInDir = "cd \"";
- commandInDir += dir;
- commandInDir += "\" && ";
- commandInDir += command;
+ commandInDir = cmStrCat("cd \"", dir, "\" && ", command);
} else {
commandInDir = command;
}
@@ -284,3 +287,4 @@ bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
return true;
}
+}
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index ae0fa9b84..7c751e154 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -8,38 +8,16 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmProcessOutput.h"
-
class cmExecutionStatus;
-/** \class cmExecProgramCommand
+/**
* \brief Command that adds a target to the build system.
*
* cmExecProgramCommand adds an extra target to the build system.
* This is useful when you would like to add special
* targets like "install,", "clean," and so on.
*/
-class cmExecProgramCommand : public cmCommand
-{
-public:
- typedef cmProcessOutput::Encoding Encoding;
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmExecProgramCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- static bool RunCommand(std::string command, std::string& output, int& retVal,
- const char* directory = nullptr, bool verbose = true,
- Encoding encoding = cmProcessOutput::Auto);
-};
+bool cmExecProgramCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 494afbb55..80e4bcd63 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -2,23 +2,28 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExecuteProcessCommand.h"
-#include "cm_static_string_view.hxx"
-#include "cmsys/Process.h"
#include <algorithm>
-#include <ctype.h> /* isspace */
+#include <cctype> /* isspace */
+#include <cstdio>
#include <iostream>
-#include <stdio.h>
+#include <memory>
+#include <vector>
+
+#include "cmsys/Process.h"
+
+#include "cm_static_string_view.hxx"
#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-static bool cmExecuteProcessCommandIsWhitespace(char c)
+namespace {
+bool cmExecuteProcessCommandIsWhitespace(char c)
{
return (isspace(static_cast<int>(c)) || c == '\n' || c == '\r');
}
@@ -27,13 +32,14 @@ void cmExecuteProcessCommandFixText(std::vector<char>& output,
bool strip_trailing_whitespace);
void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
int length);
+}
// cmExecuteProcessCommand
-bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmExecuteProcessCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -84,31 +90,31 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
if (!keywordsMissingValue.empty()) {
- this->SetError(" called with no value for " +
- keywordsMissingValue.front() + ".");
+ status.SetError(" called with no value for " +
+ keywordsMissingValue.front() + ".");
return false;
}
if (!unparsedArguments.empty()) {
- this->SetError(" given unknown argument \"" + unparsedArguments.front() +
- "\".");
+ status.SetError(" given unknown argument \"" + unparsedArguments.front() +
+ "\".");
return false;
}
- if (!this->Makefile->CanIWriteThisFile(arguments.OutputFile)) {
- this->SetError("attempted to output into a file: " + arguments.OutputFile +
- " into a source directory.");
+ if (!status.GetMakefile().CanIWriteThisFile(arguments.OutputFile)) {
+ status.SetError("attempted to output into a file: " +
+ arguments.OutputFile + " into a source directory.");
cmSystemTools::SetFatalErrorOccured();
return false;
}
// Check for commands given.
if (arguments.Commands.empty()) {
- this->SetError(" called with no COMMAND argument.");
+ status.SetError(" called with no COMMAND argument.");
return false;
}
for (std::vector<std::string> const& cmd : arguments.Commands) {
if (cmd.empty()) {
- this->SetError(" given COMMAND argument with no value.");
+ status.SetError(" given COMMAND argument with no value.");
return false;
}
}
@@ -117,7 +123,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
double timeout = -1;
if (!arguments.Timeout.empty()) {
if (sscanf(arguments.Timeout.c_str(), "%lg", &timeout) != 1) {
- this->SetError(" called with TIMEOUT value that could not be parsed.");
+ status.SetError(" called with TIMEOUT value that could not be parsed.");
return false;
}
}
@@ -177,8 +183,8 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
bool echo_stdout = false;
bool echo_stderr = false;
bool echo_output_from_variable = true;
- std::string echo_output =
- this->Makefile->GetSafeDefinition("CMAKE_EXECUTE_PROCESS_COMMAND_ECHO");
+ std::string echo_output = status.GetMakefile().GetSafeDefinition(
+ "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO");
if (!arguments.CommandEcho.empty()) {
echo_output_from_variable = false;
echo_output = arguments.CommandEcho;
@@ -201,7 +207,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
if (!echo_output_from_variable) {
error += " for COMMAND_ECHO.";
}
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, error);
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, error);
return true;
}
}
@@ -275,11 +281,13 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
// Store the output obtained.
if (!arguments.OutputVariable.empty() && !tempOutput.empty()) {
- this->Makefile->AddDefinition(arguments.OutputVariable, tempOutput.data());
+ status.GetMakefile().AddDefinition(arguments.OutputVariable,
+ tempOutput.data());
}
if (!merge_output && !arguments.ErrorVariable.empty() &&
!tempError.empty()) {
- this->Makefile->AddDefinition(arguments.ErrorVariable, tempError.data());
+ status.GetMakefile().AddDefinition(arguments.ErrorVariable,
+ tempError.data());
}
// Store the result of running the process.
@@ -289,19 +297,19 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
int v = cmsysProcess_GetExitValue(cp);
char buf[16];
sprintf(buf, "%d", v);
- this->Makefile->AddDefinition(arguments.ResultVariable, buf);
+ status.GetMakefile().AddDefinition(arguments.ResultVariable, buf);
} break;
case cmsysProcess_State_Exception:
- this->Makefile->AddDefinition(arguments.ResultVariable,
- cmsysProcess_GetExceptionString(cp));
+ status.GetMakefile().AddDefinition(
+ arguments.ResultVariable, cmsysProcess_GetExceptionString(cp));
break;
case cmsysProcess_State_Error:
- this->Makefile->AddDefinition(arguments.ResultVariable,
- cmsysProcess_GetErrorString(cp));
+ status.GetMakefile().AddDefinition(arguments.ResultVariable,
+ cmsysProcess_GetErrorString(cp));
break;
case cmsysProcess_State_Expired:
- this->Makefile->AddDefinition(arguments.ResultVariable,
- "Process terminated due to timeout");
+ status.GetMakefile().AddDefinition(
+ arguments.ResultVariable, "Process terminated due to timeout");
break;
}
}
@@ -329,20 +337,20 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
break;
}
}
- this->Makefile->AddDefinition(arguments.ResultsVariable,
- cmJoin(res, ";").c_str());
+ status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+ cmJoin(res, ";"));
} break;
case cmsysProcess_State_Exception:
- this->Makefile->AddDefinition(arguments.ResultsVariable,
- cmsysProcess_GetExceptionString(cp));
+ status.GetMakefile().AddDefinition(
+ arguments.ResultsVariable, cmsysProcess_GetExceptionString(cp));
break;
case cmsysProcess_State_Error:
- this->Makefile->AddDefinition(arguments.ResultsVariable,
- cmsysProcess_GetErrorString(cp));
+ status.GetMakefile().AddDefinition(arguments.ResultsVariable,
+ cmsysProcess_GetErrorString(cp));
break;
case cmsysProcess_State_Expired:
- this->Makefile->AddDefinition(arguments.ResultsVariable,
- "Process terminated due to timeout");
+ status.GetMakefile().AddDefinition(
+ arguments.ResultsVariable, "Process terminated due to timeout");
break;
}
}
@@ -350,6 +358,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
+namespace {
void cmExecuteProcessCommandFixText(std::vector<char>& output,
bool strip_trailing_whitespace)
{
@@ -395,3 +404,4 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
#endif
cmAppend(output, data, data + length);
}
+}
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index b415deb58..9c4b6007f 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -8,30 +8,15 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmExecuteProcessCommand
+/**
* \brief Command that adds a target to the build system.
*
* cmExecuteProcessCommand is a CMake language interface to the KWSys
* Process Execution implementation.
*/
-class cmExecuteProcessCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmExecuteProcessCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmExecuteProcessCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 56199dd93..d2cc9b87a 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -3,6 +3,12 @@
#ifndef cmExecutionStatus_h
#define cmExecutionStatus_h
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <string>
+
+class cmMakefile;
+
/** \class cmExecutionStatus
* \brief Superclass for all command status classes
*
@@ -11,14 +17,17 @@
class cmExecutionStatus
{
public:
- void Clear()
+ cmExecutionStatus(cmMakefile& makefile)
+ : Makefile(makefile)
+ , Error("unknown error.")
{
- this->ReturnInvoked = false;
- this->BreakInvoked = false;
- this->ContinueInvoked = false;
- this->NestedError = false;
}
+ cmMakefile& GetMakefile() { return this->Makefile; }
+
+ void SetError(std::string const& e) { this->Error = e; }
+ std::string const& GetError() const { return this->Error; }
+
void SetReturnInvoked() { this->ReturnInvoked = true; }
bool GetReturnInvoked() const { return this->ReturnInvoked; }
@@ -32,6 +41,8 @@ public:
bool GetNestedError() const { return this->NestedError; }
private:
+ cmMakefile& Makefile;
+ std::string Error;
bool ReturnInvoked = false;
bool BreakInvoked = false;
bool ContinueInvoked = false;
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index ced27c91c..561e83066 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -2,8 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildAndroidMKGenerator.h"
-#include <algorithm>
-#include <memory> // IWYU pragma: keep
#include <sstream>
#include <utility>
@@ -14,6 +12,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -42,8 +41,7 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
std::ostream& os, cmGeneratorTarget const* target,
cmStateEnums::TargetType /*targetType*/)
{
- std::string targetName = this->Namespace;
- targetName += target->GetExportName();
+ std::string targetName = cmStrCat(this->Namespace, target->GetExportName());
os << "include $(CLEAR_VARS)\n";
os << "LOCAL_MODULE := ";
os << targetName << "\n";
@@ -145,8 +143,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
}
} else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
std::string includes = property.second;
- std::vector<std::string> includeList;
- cmSystemTools::ExpandListArgument(includes, includeList);
+ std::vector<std::string> includeList = cmExpandedList(includes);
os << "LOCAL_EXPORT_C_INCLUDES := ";
std::string end;
for (std::string const& i : includeList) {
@@ -156,8 +153,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
os << "\n";
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
os << "LOCAL_EXPORT_LDFLAGS := ";
- std::vector<std::string> linkFlagsList;
- cmSystemTools::ExpandListArgument(property.second, linkFlagsList);
+ std::vector<std::string> linkFlagsList =
+ cmExpandedList(property.second);
os << cmJoin(linkFlagsList, " ") << "\n";
} else {
os << "# " << property.first << " " << (property.second) << "\n";
@@ -168,8 +165,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 (std::find(li->Languages.begin(), li->Languages.end(), "CXX") !=
- li->Languages.end()) {
+ if (cmContains(li->Languages, "CXX")) {
os << "LOCAL_HAS_CPP := true\n";
}
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 012355b41..7e9a98738 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -2,7 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildFileGenerator.h"
-#include "cmAlgorithms.h"
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <utility>
+
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -12,17 +17,11 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmake.h"
-#include <algorithm>
-#include <map>
-#include <set>
-#include <sstream>
-#include <utility>
-
class cmSourceFile;
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
@@ -45,6 +44,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
std::string expectedTargets;
std::string sep;
std::vector<std::string> targets;
+ bool generatedInterfaceRequired = false;
this->GetTargets(targets);
for (std::string const& tei : targets) {
cmGeneratorTarget* te = this->LG->FindGeneratorTargetToUse(tei);
@@ -60,11 +60,13 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->LG->GetMakefile()->GetBacktrace());
return false;
}
- if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) {
- this->GenerateRequiredCMakeVersion(os, "3.0.0");
- }
+ generatedInterfaceRequired |=
+ this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY;
}
+ if (generatedInterfaceRequired) {
+ this->GenerateRequiredCMakeVersion(os, "3.0.0");
+ }
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
@@ -90,6 +92,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
@@ -201,8 +206,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
cmMakefile* mf = target->Makefile;
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- std::string prop = "IMPORTED_OBJECTS";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix);
// Compute all the object files inside this target and setup
// IMPORTED_OBJECTS as a list of object files
@@ -220,8 +224,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
} else {
// Add the main target file.
{
- std::string prop = "IMPORTED_LOCATION";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
std::string value;
if (target->IsAppBundleOnApple()) {
value =
@@ -234,14 +237,14 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
}
// Add the import library for windows DLLs.
- if (target->HasImportLibrary(config) &&
- mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
- std::string prop = "IMPORTED_IMPLIB";
- prop += suffix;
+ if (target->HasImportLibrary(config)) {
+ std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
std::string value =
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
- target->GetImplibGNUtoMS(config, value, value,
- "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ target->GetImplibGNUtoMS(config, value, value,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ }
properties[prop] = value;
}
}
@@ -256,11 +259,11 @@ void cmExportBuildFileGenerator::HandleMissingTarget(
const std::string name = dependee->GetName();
cmGlobalGenerator* gg =
dependee->GetLocalGenerator()->GetGlobalGenerator();
- std::vector<std::string> namespaces = this->FindNamespaces(gg, name);
+ auto exportInfo = this->FindBuildExportInfo(gg, name);
+ std::vector<std::string> const& exportFiles = exportInfo.first;
- int targetOccurrences = static_cast<int>(namespaces.size());
- if (targetOccurrences == 1) {
- std::string missingTarget = namespaces[0];
+ if (exportFiles.size() == 1) {
+ std::string missingTarget = exportInfo.second;
missingTarget += dependee->GetExportName();
link_libs += missingTarget;
@@ -269,7 +272,7 @@ void cmExportBuildFileGenerator::HandleMissingTarget(
}
// We are not appending, so all exported targets should be
// known here. This is probably user-error.
- this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
+ this->ComplainAboutMissingTarget(depender, dependee, exportFiles);
}
// Assume the target will be exported by another command.
// Append it with the export namespace.
@@ -281,7 +284,8 @@ void cmExportBuildFileGenerator::GetTargets(
std::vector<std::string>& targets) const
{
if (this->ExportSet) {
- for (cmTargetExport* te : *this->ExportSet->GetTargetExports()) {
+ for (std::unique_ptr<cmTargetExport> const& te :
+ this->ExportSet->GetTargetExports()) {
targets.push_back(te->TargetName);
}
return;
@@ -289,10 +293,12 @@ void cmExportBuildFileGenerator::GetTargets(
targets = this->Targets;
}
-std::vector<std::string> cmExportBuildFileGenerator::FindNamespaces(
- cmGlobalGenerator* gg, const std::string& name)
+std::pair<std::vector<std::string>, std::string>
+cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
+ const std::string& name)
{
- std::vector<std::string> namespaces;
+ std::vector<std::string> exportFiles;
+ std::string ns;
std::map<std::string, cmExportBuildFileGenerator*>& exportSets =
gg->GetBuildExportSets();
@@ -301,32 +307,32 @@ std::vector<std::string> cmExportBuildFileGenerator::FindNamespaces(
const cmExportBuildFileGenerator* exportSet = exp.second;
std::vector<std::string> targets;
exportSet->GetTargets(targets);
- if (std::find(targets.begin(), targets.end(), name) != targets.end()) {
- namespaces.push_back(exportSet->GetNamespace());
+ if (cmContains(targets, name)) {
+ exportFiles.push_back(exp.first);
+ ns = exportSet->GetNamespace();
}
}
- return namespaces;
+ return { exportFiles, ns };
}
void cmExportBuildFileGenerator::ComplainAboutMissingTarget(
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee, int occurrences)
+ cmGeneratorTarget* depender, cmGeneratorTarget* dependee,
+ std::vector<std::string> const& exportFiles)
{
- if (cmSystemTools::GetErrorOccuredFlag()) {
- return;
- }
-
std::ostringstream e;
e << "export called with target \"" << depender->GetName()
<< "\" which requires target \"" << dependee->GetName() << "\" ";
- if (occurrences == 0) {
- e << "that is not in the export set.\n";
+ if (exportFiles.empty()) {
+ e << "that is not in any export set.";
} else {
- e << "that is not in this export set, but " << occurrences
- << " times in others.\n";
+ e << "that is not in this export set, but in multiple other export sets: "
+ << cmJoin(exportFiles, ", ") << ".\n";
+ e << "An exported target cannot depend upon another target which is "
+ "exported multiple times. Consider consolidating the exports of the "
+ "\""
+ << dependee->GetName() << "\" target to a single export.";
}
- e << "If the required target is not easy to reference in this call, "
- << "consider using the APPEND option with multiple separate calls.";
this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR, e.str(),
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 0a1e75582..11fbd02d6 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -5,14 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmAlgorithms.h"
-#include "cmExportFileGenerator.h"
-#include "cmStateTypes.h"
-
#include <iosfwd>
#include <string>
+#include <utility>
#include <vector>
+#include "cmAlgorithms.h"
+#include "cmExportFileGenerator.h"
+#include "cmStateTypes.h"
+
class cmExportSet;
class cmGeneratorTarget;
class cmGlobalGenerator;
@@ -64,7 +65,7 @@ protected:
void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
cmGeneratorTarget* dependee,
- int occurrences);
+ std::vector<std::string> const& namespaces);
/** Fill in properties indicating built file locations. */
void SetImportLocationProperty(const std::string& config,
@@ -75,8 +76,8 @@ protected:
std::string InstallNameDir(cmGeneratorTarget* target,
const std::string& config) override;
- std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
- const std::string& name);
+ std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
+ cmGlobalGenerator* gg, const std::string& name);
std::vector<std::string> Targets;
cmExportSet* ExportSet;
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index a849aa246..2a6bf5df7 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportCommand.h"
-#include "cm_static_string_view.hxx"
-#include "cmsys/RegularExpression.hxx"
-
-#include <algorithm>
#include <map>
#include <sstream>
#include <utility>
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_static_string_view.hxx"
+
+#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportBuildFileGenerator.h"
-#include "cmExportSetMap.h"
+#include "cmExportSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -23,24 +25,31 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExportSet;
-class cmExecutionStatus;
-
#if defined(__HAIKU__)
# include <FindDirectory.h>
# include <StorageDefs.h>
#endif
-bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+#endif
+
+static bool HandlePackage(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
+static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
+ const char* content, const char* hash);
+
+bool cmExportCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with too few arguments");
+ status.SetError("called with too few arguments");
return false;
}
if (args[0] == "PACKAGE") {
- return this->HandlePackage(args);
+ return HandlePackage(args, status);
}
struct Arguments
@@ -73,7 +82,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
parser.Parse(args, &unknownArgs, &keywordsMissingValue);
if (!unknownArgs.empty()) {
- this->SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
+ status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
return false;
}
@@ -85,7 +94,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
}
if (arguments.Filename.empty() && fname.empty()) {
if (args[0] != "EXPORT") {
- this->SetError("FILE <filename> option missing.");
+ status.SetError("FILE <filename> option missing.");
return false;
}
fname = arguments.ExportSetName + ".cmake";
@@ -96,66 +105,66 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
std::ostringstream e;
e << "FILE option given filename \"" << arguments.Filename
<< "\" which does not have an extension of \".cmake\".\n";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
fname = arguments.Filename;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Get the file to write.
if (cmSystemTools::FileIsFullPath(fname)) {
- if (!this->Makefile->CanIWriteThisFile(fname)) {
+ if (!mf.CanIWriteThisFile(fname)) {
std::ostringstream e;
e << "FILE option given filename \"" << fname
<< "\" which is in the source tree.\n";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
} else {
// Interpret relative paths with respect to the current build dir.
- std::string dir = this->Makefile->GetCurrentBinaryDirectory();
+ std::string const& dir = mf.GetCurrentBinaryDirectory();
fname = dir + "/" + fname;
}
std::vector<std::string> targets;
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator* gg = mf.GetGlobalGenerator();
- cmExportSet* ExportSet = nullptr;
+ cmExportSet* exportSet = nullptr;
if (args[0] == "EXPORT") {
cmExportSetMap& setMap = gg->GetExportSets();
auto const it = setMap.find(arguments.ExportSetName);
if (it == setMap.end()) {
std::ostringstream e;
e << "Export set \"" << arguments.ExportSetName << "\" not found.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- ExportSet = it->second;
+ exportSet = &it->second;
} else if (!arguments.Targets.empty() ||
- std::find(keywordsMissingValue.begin(),
- keywordsMissingValue.end(),
- "TARGETS") != keywordsMissingValue.end()) {
+ cmContains(keywordsMissingValue, "TARGETS")) {
for (std::string const& currentTarget : arguments.Targets) {
- if (this->Makefile->IsAlias(currentTarget)) {
+ if (mf.IsAlias(currentTarget)) {
std::ostringstream e;
e << "given ALIAS target \"" << currentTarget
<< "\" which may not be exported.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (cmTarget* target = gg->FindTarget(currentTarget)) {
if (target->GetType() == cmStateEnums::UTILITY) {
- this->SetError("given custom target \"" + currentTarget +
- "\" which may not be exported.");
+ status.SetError("given custom target \"" + currentTarget +
+ "\" which may not be exported.");
return false;
}
} else {
std::ostringstream e;
e << "given target \"" << currentTarget
<< "\" which is not built by this project.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
targets.push_back(currentTarget);
@@ -168,7 +177,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
}
}
} else {
- this->SetError("EXPORT or TARGETS specifier missing.");
+ status.SetError("EXPORT or TARGETS specifier missing.");
return false;
}
@@ -182,24 +191,24 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(arguments.Namespace);
ebfg->SetAppendMode(arguments.Append);
- if (ExportSet != nullptr) {
- ebfg->SetExportSet(ExportSet);
+ if (exportSet != nullptr) {
+ ebfg->SetExportSet(exportSet);
} else {
ebfg->SetTargets(targets);
}
- this->Makefile->AddExportBuildFileGenerator(ebfg);
+ mf.AddExportBuildFileGenerator(ebfg);
ebfg->SetExportOld(arguments.ExportOld);
// Compute the set of configurations exported.
std::vector<std::string> configurationTypes;
- this->Makefile->GetConfigurations(configurationTypes);
+ mf.GetConfigurations(configurationTypes);
if (configurationTypes.empty()) {
configurationTypes.emplace_back();
}
for (std::string const& ct : configurationTypes) {
ebfg->AddConfiguration(ct);
}
- if (ExportSet != nullptr) {
+ if (exportSet != nullptr) {
gg->AddBuildExportExportSet(ebfg);
} else {
gg->AddBuildExportSet(ebfg);
@@ -208,7 +217,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
-bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
+static bool HandlePackage(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Parse PACKAGE mode arguments.
enum Doing
@@ -225,14 +235,14 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
} else {
std::ostringstream e;
e << "PACKAGE given unknown argument: " << args[i];
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
// Verify the package name.
if (package.empty()) {
- this->SetError("PACKAGE must be given a package name.");
+ status.SetError("PACKAGE must be given a package name.");
return false;
}
const char* packageExpr = "^[A-Za-z0-9_.-]+$";
@@ -241,16 +251,18 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
std::ostringstream e;
e << "PACKAGE given invalid package name \"" << package << "\". "
<< "Package names must match \"" << packageExpr << "\".";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// CMP0090 decides both the default and what variable changes it.
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0090)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) {
case cmPolicies::WARN:
case cmPolicies::OLD:
// Default is to export, but can be disabled.
- if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
+ if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
return true;
}
break;
@@ -258,7 +270,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Default is to not export, but can be enabled.
- if (!this->Makefile->IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
+ if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
return true;
}
break;
@@ -267,22 +279,17 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
// We store the current build directory in the registry as a value
// named by a hash of its own content. This is deterministic and is
// unique with high probability.
- const std::string& outDir = this->Makefile->GetCurrentBinaryDirectory();
+ const std::string& outDir = mf.GetCurrentBinaryDirectory();
std::string hash = cmSystemTools::ComputeStringMD5(outDir);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- this->StorePackageRegistryWin(package, outDir.c_str(), hash.c_str());
-#else
- this->StorePackageRegistryDir(package, outDir.c_str(), hash.c_str());
-#endif
+ StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str());
return true;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-void cmExportCommand::ReportRegistryError(std::string const& msg,
- std::string const& key, long err)
+static void ReportRegistryError(cmMakefile& mf, std::string const& msg,
+ std::string const& key, long err)
{
std::ostringstream e;
e << msg << "\n"
@@ -294,21 +301,19 @@ void cmExportCommand::ReportRegistryError(std::string const& msg,
e << "Windows reported:\n"
<< " " << cmsys::Encoding::ToNarrow(winmsg);
}
- this->Makefile->IssueMessage(MessageType::WARNING, e.str());
+ mf.IssueMessage(MessageType::WARNING, e.str());
}
-void cmExportCommand::StorePackageRegistryWin(std::string const& package,
- const char* content,
- const char* hash)
+static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
+ const char* content, const char* hash)
{
- std::string key = "Software\\Kitware\\CMake\\Packages\\";
- key += package;
+ std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package);
HKEY hKey;
LONG err =
RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0,
0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0);
if (err != ERROR_SUCCESS) {
- this->ReportRegistryError("Cannot create/open registry key", key, err);
+ ReportRegistryError(mf, "Cannot create/open registry key", key, err);
return;
}
@@ -321,14 +326,13 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
if (err != ERROR_SUCCESS) {
std::ostringstream msg;
msg << "Cannot set registry value \"" << hash << "\" under key";
- this->ReportRegistryError(msg.str(), key, err);
+ ReportRegistryError(mf, msg.str(), key, err);
return;
}
}
#else
-void cmExportCommand::StorePackageRegistryDir(std::string const& package,
- const char* content,
- const char* hash)
+static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
+ const char* content, const char* hash)
{
# if defined(__HAIKU__)
char dir[B_PATH_NAME_LENGTH];
@@ -336,9 +340,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
B_OK) {
return;
}
- std::string fname = dir;
- fname += "/cmake/packages/";
- fname += package;
+ std::string fname = cmStrCat(dir, "/cmake/packages/", package);
# else
std::string fname;
if (!cmSystemTools::GetEnv("HOME", fname)) {
@@ -362,7 +364,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
<< " " << fname << "\n"
<< cmSystemTools::GetLastSystemError() << "\n";
/* clang-format on */
- this->Makefile->IssueMessage(MessageType::WARNING, e.str());
+ mf.IssueMessage(MessageType::WARNING, e.str());
}
}
}
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 99f9932b9..965562820 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -8,33 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmExportCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmExportCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandlePackage(std::vector<std::string> const& args);
- void StorePackageRegistryWin(std::string const& package, const char* content,
- const char* hash);
- void StorePackageRegistryDir(std::string const& package, const char* content,
- const char* hash);
- void ReportRegistryError(std::string const& msg, std::string const& key,
- long err);
-};
+bool cmExportCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index a12e0c48d..aeef602bf 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -2,7 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportFileGenerator.h"
-#include "cmAlgorithms.h"
+#include <cassert>
+#include <cstring>
+#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -12,20 +20,13 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
-#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
-#include "cmsys/FStream.hxx"
-#include <assert.h>
-#include <memory> // IWYU pragma: keep
-#include <sstream>
-#include <string.h>
-#include <utility>
-
static std::string cmExportFileGeneratorEscape(std::string const& str)
{
// Escape a property value for writing into a .cmake file.
@@ -215,6 +216,9 @@ static bool checkInterfaceDirs(const std::string& prepro,
if (genexPos == 0) {
continue;
}
+ if (cmHasLiteralPrefix(li, "${_IMPORT_PREFIX}")) {
+ continue;
+ }
MessageType messageType = MessageType::FATAL_ERROR;
std::ostringstream e;
if (genexPos != std::string::npos) {
@@ -236,9 +240,6 @@ static bool checkInterfaceDirs(const std::string& prepro,
hadFatalError = true;
}
}
- if (cmHasLiteralPrefix(li, "${_IMPORT_PREFIX}")) {
- continue;
- }
if (!cmSystemTools::FileIsFullPath(li)) {
/* clang-format off */
e << "Target \"" << target->GetName() << "\" " << prop <<
@@ -380,7 +381,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
this->ReplaceInstallPrefix(dirs);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);
std::string exportDirs =
- cge->Evaluate(target->GetLocalGenerator(), "", false, target);
+ cge->Evaluate(target->GetLocalGenerator(), "", target);
if (cge->GetHadContextSensitiveCondition()) {
cmLocalGenerator* lg = target->GetLocalGenerator();
@@ -499,8 +500,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
if (!p) {
return;
}
- std::vector<std::string> content;
- cmSystemTools::ExpandListArgument(p, content);
+ std::vector<std::string> content = cmExpandedList(p);
ifaceProperties.insert(content.begin(), content.end());
}
@@ -584,8 +584,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties(
const ImportPropertyMap& properties)
{
if (!properties.empty()) {
- std::string targetName = this->Namespace;
- targetName += target->GetExportName();
+ std::string targetName =
+ cmStrCat(this->Namespace, target->GetExportName());
os << "set_target_properties(" << targetName << " PROPERTIES\n";
for (auto const& property : properties) {
os << " " << property.first << " "
@@ -752,9 +752,9 @@ void cmExportFileGenerator::SetImportLinkInterface(
if (iface->ImplementationIsInterface) {
// Policy CMP0022 must not be NEW.
- this->SetImportLinkProperty(suffix, target,
- "IMPORTED_LINK_INTERFACE_LIBRARIES",
- iface->Libraries, properties, missingTargets);
+ this->SetImportLinkProperty(
+ suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries,
+ properties, missingTargets, ImportLinkPropertyTargetNames::Yes);
return;
}
@@ -832,28 +832,25 @@ void cmExportFileGenerator::SetImportDetailProperties(
// Add the transitive link dependencies for this configuration.
if (cmLinkInterface const* iface =
target->GetLinkInterface(config, target)) {
- this->SetImportLinkProperty(suffix, target,
- "IMPORTED_LINK_INTERFACE_LANGUAGES",
- iface->Languages, properties, missingTargets);
+ this->SetImportLinkProperty(
+ suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", iface->Languages,
+ properties, missingTargets, ImportLinkPropertyTargetNames::No);
std::vector<std::string> dummy;
- this->SetImportLinkProperty(suffix, target,
- "IMPORTED_LINK_DEPENDENT_LIBRARIES",
- iface->SharedDeps, properties, dummy);
+ this->SetImportLinkProperty(
+ suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", iface->SharedDeps,
+ properties, dummy, ImportLinkPropertyTargetNames::Yes);
if (iface->Multiplicity > 0) {
- std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
- prop += suffix;
- std::ostringstream m;
- m << iface->Multiplicity;
- properties[prop] = m.str();
+ std::string prop =
+ cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
+ properties[prop] = std::to_string(iface->Multiplicity);
}
}
// Add information if this target is a managed target
if (target->GetManagedType(config) !=
cmGeneratorTarget::ManagedType::Native) {
- std::string prop = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix);
std::string propval;
if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
propval = p;
@@ -883,7 +880,8 @@ template <typename T>
void cmExportFileGenerator::SetImportLinkProperty(
std::string const& suffix, cmGeneratorTarget* target,
const std::string& propName, std::vector<T> const& entries,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
+ ImportLinkPropertyTargetNames targetNames)
{
// Skip the property if there are no entries.
if (entries.empty()) {
@@ -898,14 +896,17 @@ void cmExportFileGenerator::SetImportLinkProperty(
link_entries += sep;
sep = ";";
- std::string temp = asString(l);
- this->AddTargetNamespace(temp, target, missingTargets);
- link_entries += temp;
+ if (targetNames == ImportLinkPropertyTargetNames::Yes) {
+ std::string temp = asString(l);
+ this->AddTargetNamespace(temp, target, missingTargets);
+ link_entries += temp;
+ } else {
+ link_entries += asString(l);
+ }
}
// Store the property.
- std::string prop = propName;
- prop += suffix;
+ std::string prop = cmStrCat(propName, suffix);
properties[prop] = link_entries;
}
@@ -1182,8 +1183,7 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
const std::set<std::string>& importedLocations)
{
// Construct the imported target name.
- std::string targetName = this->Namespace;
- targetName += target->GetExportName();
+ std::string targetName = cmStrCat(this->Namespace, target->GetExportName());
os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName
<< " )\n"
@@ -1191,7 +1191,7 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
<< targetName << " ";
for (std::string const& li : importedLocations) {
- ImportPropertyMap::const_iterator pi = properties.find(li);
+ auto pi = properties.find(li);
if (pi != properties.end()) {
os << cmExportFileGeneratorEscape(pi->second) << " ";
}
@@ -1205,15 +1205,12 @@ bool cmExportFileGenerator::PopulateExportProperties(
std::string& errorMessage)
{
auto& targetProperties = gte->Target->GetProperties();
- const auto& exportProperties = targetProperties.find("EXPORT_PROPERTIES");
- if (exportProperties != targetProperties.end()) {
- std::vector<std::string> propsToExport;
- cmSystemTools::ExpandListArgument(exportProperties->second.GetValue(),
- propsToExport);
- for (auto& prop : propsToExport) {
+ if (const char* exportProperties =
+ targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
+ for (auto& prop : cmExpandedList(exportProperties)) {
/* Black list reserved properties */
- if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") ||
- cmSystemTools::StringStartsWith(prop, "INTERFACE_")) {
+ if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
+ cmHasLiteralPrefix(prop, "INTERFACE_")) {
std::ostringstream e;
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
<< prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* "
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 747503e6d..0d69779f9 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -5,17 +5,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGeneratorExpression.h"
-#include "cmStateTypes.h"
-#include "cmVersion.h"
-#include "cmVersionConfig.h"
-
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmGeneratorExpression.h"
+#include "cmStateTypes.h"
+#include "cmVersion.h"
+#include "cmVersionConfig.h"
+
class cmGeneratorTarget;
#define STRINGIFY_HELPER(X) #X
@@ -62,7 +62,7 @@ public:
bool GenerateImportFile();
protected:
- typedef std::map<std::string, std::string> ImportPropertyMap;
+ using ImportPropertyMap = std::map<std::string, std::string>;
// Generate per-configuration target information to the given output
// stream.
@@ -102,13 +102,19 @@ protected:
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
+ enum class ImportLinkPropertyTargetNames
+ {
+ Yes,
+ No,
+ };
template <typename T>
void SetImportLinkProperty(std::string const& suffix,
cmGeneratorTarget* target,
const std::string& propName,
std::vector<T> const& entries,
ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets);
+ std::vector<std::string>& missingTargets,
+ ImportLinkPropertyTargetNames targetNames);
/** Each subclass knows how to generate its kind of export file. */
virtual bool GenerateMainFile(std::ostream& os) = 0;
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 9bc8089dc..2d732c1db 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -2,8 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportInstallAndroidMKGenerator.h"
+#include <cstddef>
+#include <memory>
#include <ostream>
-#include <stddef.h>
#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportSet.h"
@@ -11,6 +12,7 @@
#include "cmInstallExportGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
@@ -34,7 +36,8 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
}
os << "_IMPORT_PREFIX := "
<< "$(LOCAL_PATH)" << path << "\n\n";
- for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) {
+ for (std::unique_ptr<cmTargetExport> const& te :
+ this->IEGen->GetExportSet()->GetTargetExports()) {
// Collect import properties for this target.
if (te->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
@@ -58,8 +61,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode(
std::ostream& os, cmGeneratorTarget const* target,
cmStateEnums::TargetType /*targetType*/)
{
- std::string targetName = this->Namespace;
- targetName += target->GetExportName();
+ std::string targetName = cmStrCat(this->Namespace, target->GetExportName());
os << "include $(CLEAR_VARS)\n";
os << "LOCAL_MODULE := ";
os << targetName << "\n";
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index f8bc0ab0b..6d29c9994 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -2,9 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportInstallFileGenerator.h"
-#include "cmAlgorithms.h"
+#include <memory>
+#include <sstream>
+#include <utility>
+
#include "cmExportSet.h"
-#include "cmExportSetMap.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -15,13 +17,11 @@
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
-#include <sstream>
-#include <utility>
-
cmExportInstallFileGenerator::cmExportInstallFileGenerator(
cmInstallExportGenerator* iegen)
: IEGen(iegen)
@@ -30,9 +30,7 @@ cmExportInstallFileGenerator::cmExportInstallFileGenerator(
std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
{
- std::string glob = this->FileBase;
- glob += "-*";
- glob += this->FileExt;
+ std::string glob = cmStrCat(this->FileBase, "-*", this->FileExt);
return glob;
}
@@ -42,12 +40,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
{
std::string expectedTargets;
std::string sep;
- for (cmTargetExport* te :
- *this->IEGen->GetExportSet()->GetTargetExports()) {
+ for (std::unique_ptr<cmTargetExport> const& te :
+ this->IEGen->GetExportSet()->GetTargetExports()) {
expectedTargets += sep + this->Namespace + te->Target->GetExportName();
sep = " ";
if (this->ExportedTargets.insert(te->Target).second) {
- allTargets.push_back(te);
+ allTargets.push_back(te.get());
} else {
std::ostringstream e;
e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName()
@@ -96,6 +94,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gt,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
@@ -277,10 +278,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig(
}
// Construct the name of the file to generate.
- std::string fileName = this->FileDir;
- fileName += "/";
- fileName += this->FileBase;
- fileName += "-";
+ std::string fileName = cmStrCat(this->FileDir, '/', this->FileBase, '-');
if (!config.empty()) {
fileName += cmSystemTools::LowerCase(config);
} else {
@@ -319,9 +317,11 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
std::vector<std::string>& missingTargets)
{
// Add each target in the set to the export.
- for (cmTargetExport* te : *this->IEGen->GetExportSet()->GetTargetExports()) {
+ for (std::unique_ptr<cmTargetExport> const& te :
+ this->IEGen->GetExportSet()->GetTargetExports()) {
// Collect import properties for this target.
- if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) {
+ if (this->GetExportTargetType(te.get()) ==
+ cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -392,8 +392,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
if (itgen->IsImportLibrary()) {
// Construct the property name.
- std::string prop = "IMPORTED_IMPLIB";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
// Append the installed file name.
value += cmInstallTargetGenerator::GetInstallFilename(
@@ -404,15 +403,14 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
importedLocations.insert(prop);
} else if (itgen->GetTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
// Construct the property name.
- std::string prop = "IMPORTED_OBJECTS";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_OBJECTS", suffix);
// Compute all the object files inside this target and setup
// IMPORTED_OBJECTS as a list of object files
std::vector<std::string> objects;
itgen->GetInstallObjectNames(config, objects);
for (std::string& obj : objects) {
- obj = value + obj;
+ obj = cmStrCat(value, obj);
}
// Store the property.
@@ -420,8 +418,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
importedLocations.insert(prop);
} else {
// Construct the property name.
- std::string prop = "IMPORTED_LOCATION";
- prop += suffix;
+ std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
// Append the installed file name.
if (target->IsAppBundleOnApple()) {
@@ -458,10 +455,10 @@ void cmExportInstallFileGenerator::HandleMissingTarget(
{
const std::string name = dependee->GetName();
cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator();
- std::vector<std::string> namespaces = this->FindNamespaces(gg, name);
- int targetOccurrences = static_cast<int>(namespaces.size());
- if (targetOccurrences == 1) {
- std::string missingTarget = namespaces[0];
+ auto exportInfo = this->FindNamespaces(gg, name);
+ std::vector<std::string> const& exportFiles = exportInfo.first;
+ if (exportFiles.size() == 1) {
+ std::string missingTarget = exportInfo.second;
missingTarget += dependee->GetExportName();
link_libs += missingTarget;
@@ -469,23 +466,23 @@ void cmExportInstallFileGenerator::HandleMissingTarget(
} else {
// All exported targets should be known here and should be unique.
// This is probably user-error.
- this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
+ this->ComplainAboutMissingTarget(depender, dependee, exportFiles);
}
}
-std::vector<std::string> cmExportInstallFileGenerator::FindNamespaces(
- cmGlobalGenerator* gg, const std::string& name)
+std::pair<std::vector<std::string>, std::string>
+cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg,
+ const std::string& name)
{
- std::vector<std::string> namespaces;
+ std::vector<std::string> exportFiles;
+ std::string ns;
const cmExportSetMap& exportSets = gg->GetExportSets();
for (auto const& expIt : exportSets) {
- const cmExportSet* exportSet = expIt.second;
- std::vector<cmTargetExport*> const* targets =
- exportSet->GetTargetExports();
+ const cmExportSet& exportSet = expIt.second;
bool containsTarget = false;
- for (cmTargetExport* target : *targets) {
+ for (auto const& target : exportSet.GetTargetExports()) {
if (name == target->TargetName) {
containsTarget = true;
break;
@@ -494,29 +491,35 @@ std::vector<std::string> cmExportInstallFileGenerator::FindNamespaces(
if (containsTarget) {
std::vector<cmInstallExportGenerator const*> const* installs =
- exportSet->GetInstallations();
+ exportSet.GetInstallations();
for (cmInstallExportGenerator const* install : *installs) {
- namespaces.push_back(install->GetNamespace());
+ exportFiles.push_back(install->GetDestinationFile());
+ ns = install->GetNamespace();
}
}
}
- return namespaces;
+ return { exportFiles, ns };
}
void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee, int occurrences)
+ cmGeneratorTarget* depender, cmGeneratorTarget* dependee,
+ std::vector<std::string> const& exportFiles)
{
std::ostringstream e;
e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName()
<< "\" ...) "
<< "includes target \"" << depender->GetName()
<< "\" which requires target \"" << dependee->GetName() << "\" ";
- if (occurrences == 0) {
- e << "that is not in the export set.";
+ if (exportFiles.empty()) {
+ e << "that is not in any export set.";
} else {
- e << "that is not in this export set, but " << occurrences
- << " times in others.";
+ e << "that is not in this export set, but in multiple other export sets: "
+ << cmJoin(exportFiles, ", ") << ".\n";
+ e << "An exported target cannot depend upon another target which is "
+ "exported multiple times. Consider consolidating the exports of the "
+ "\""
+ << dependee->GetName() << "\" target to a single export.";
}
cmSystemTools::Error(e.str());
}
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index cbd650767..5fa812c58 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -5,15 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExportFileGenerator.h"
-#include "cmStateTypes.h"
-
#include <iosfwd>
#include <map>
#include <set>
#include <string>
+#include <utility>
#include <vector>
+#include "cmExportFileGenerator.h"
+#include "cmStateTypes.h"
+
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmInstallExportGenerator;
@@ -70,10 +71,10 @@ protected:
void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
cmGeneratorTarget* dependee,
- int occurrences);
+ std::vector<std::string> const& exportFiles);
- std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
- const std::string& name);
+ std::pair<std::vector<std::string>, std::string> FindNamespaces(
+ cmGlobalGenerator* gg, const std::string& name);
/** Generate the relative import prefix. */
virtual void GenerateImportPrefix(std::ostream&);
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index b60a0533c..89093e95f 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -2,74 +2,49 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportLibraryDependenciesCommand.h"
-#include "cmsys/FStream.hxx"
#include <map>
-#include <memory> // IWYU pragma: keep
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-bool cmExportLibraryDependenciesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
-{
- if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
-
- // store the arguments for the final pass
- this->Filename = args[0];
- this->Append = false;
- if (args.size() > 1) {
- if (args[1] == "APPEND") {
- this->Append = true;
- }
- }
- return true;
-}
-
-void cmExportLibraryDependenciesCommand::FinalPass()
-{
- // export_library_dependencies() shouldn't modify anything
- // ensure this by calling a const method
- this->ConstFinalPass();
-}
-
-void cmExportLibraryDependenciesCommand::ConstFinalPass() const
+static void FinalAction(cmMakefile& makefile, std::string const& filename,
+ bool append)
{
// Use copy-if-different if not appending.
std::unique_ptr<cmsys::ofstream> foutPtr;
- if (this->Append) {
+ if (append) {
const auto openmodeApp = std::ios::app;
- foutPtr =
- cm::make_unique<cmsys::ofstream>(this->Filename.c_str(), openmodeApp);
+ foutPtr = cm::make_unique<cmsys::ofstream>(filename.c_str(), openmodeApp);
} else {
std::unique_ptr<cmGeneratedFileStream> ap(
- new cmGeneratedFileStream(this->Filename, true));
+ new cmGeneratedFileStream(filename, true));
ap->SetCopyIfDifferent(true);
foutPtr = std::move(ap);
}
std::ostream& fout = *foutPtr;
if (!fout) {
- cmSystemTools::Error("Error Writing " + this->Filename);
+ cmSystemTools::Error("Error Writing " + filename);
cmSystemTools::ReportLastSystemError("");
return;
}
// Collect dependency information about all library targets built in
// the project.
- cmake* cm = this->Makefile->GetCMakeInstance();
+ cmake* cm = makefile.GetCMakeInstance();
cmGlobalGenerator* global = cm->GetGlobalGenerator();
const std::vector<cmMakefile*>& locals = global->GetMakefiles();
std::map<std::string, std::string> libDepsOld;
@@ -87,8 +62,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
}
// Construct the dependency variable name.
- std::string targetEntry = target.GetName();
- targetEntry += "_LIB_DEPENDS";
+ std::string targetEntry = cmStrCat(target.GetName(), "_LIB_DEPENDS");
// Construct the dependency variable value with the direct link
// dependencies.
@@ -97,8 +71,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
cmTarget::LinkLibraryVectorType const& libs =
target.GetOriginalLinkLibraries();
for (cmTarget::LibraryID const& li : libs) {
- std::string ltVar = li.first;
- ltVar += "_LINK_TYPE";
+ std::string ltVar = cmStrCat(li.first, "_LINK_TYPE");
std::string ltValue;
switch (li.second) {
case GENERAL_LibraryType:
@@ -166,3 +139,21 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
}
fout << "endif()\n";
}
+
+bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.empty()) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string const& filename = args[0];
+ bool const append = args.size() > 1 && args[1] == "APPEND";
+ status.GetMakefile().AddFinalAction(
+ [filename, append](cmMakefile& makefile) {
+ FinalAction(makefile, filename, append);
+ });
+
+ return true;
+}
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 8414866a0..230c90616 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -8,27 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmExportLibraryDependenciesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override
- {
- return new cmExportLibraryDependenciesCommand;
- }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- void FinalPass() override;
- bool HasFinalPass() const override { return true; }
-
-private:
- std::string Filename;
- bool Append = false;
- void ConstFinalPass() const;
-};
+bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx
index a6fa186c7..a20aa9a8a 100644
--- a/Source/cmExportSet.cxx
+++ b/Source/cmExportSet.cxx
@@ -2,28 +2,43 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportSet.h"
-#include "cmAlgorithms.h"
+#include <tuple>
+#include <utility>
+
#include "cmLocalGenerator.h"
#include "cmTargetExport.h"
-cmExportSet::~cmExportSet()
+cmExportSet::cmExportSet(std::string name)
+ : Name(std::move(name))
{
- cmDeleteAll(this->TargetExports);
}
+cmExportSet::~cmExportSet() = default;
+
void cmExportSet::Compute(cmLocalGenerator* lg)
{
- for (cmTargetExport* tgtExport : this->TargetExports) {
+ for (std::unique_ptr<cmTargetExport>& tgtExport : this->TargetExports) {
tgtExport->Target = lg->FindGeneratorTargetToUse(tgtExport->TargetName);
}
}
-void cmExportSet::AddTargetExport(cmTargetExport* te)
+void cmExportSet::AddTargetExport(std::unique_ptr<cmTargetExport> te)
{
- this->TargetExports.push_back(te);
+ this->TargetExports.emplace_back(std::move(te));
}
void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation)
{
this->Installations.push_back(installation);
}
+
+cmExportSet& cmExportSetMap::operator[](const std::string& name)
+{
+ auto it = this->find(name);
+ if (it == this->end()) // Export set not found
+ {
+ auto tup_name = std::make_tuple(name);
+ it = this->emplace(std::piecewise_construct, tup_name, tup_name).first;
+ }
+ return it->second;
+}
diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h
index d654c1285..f0d921f5e 100644
--- a/Source/cmExportSet.h
+++ b/Source/cmExportSet.h
@@ -5,8 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
+#include <memory>
#include <string>
-#include <utility>
#include <vector>
class cmInstallExportGenerator;
@@ -18,10 +19,7 @@ class cmExportSet
{
public:
/// Construct an empty export set named \a name
- cmExportSet(std::string name)
- : Name(std::move(name))
- {
- }
+ cmExportSet(std::string name);
/// Destructor
~cmExportSet();
@@ -30,15 +28,15 @@ public:
void Compute(cmLocalGenerator* lg);
- void AddTargetExport(cmTargetExport* tgt);
+ void AddTargetExport(std::unique_ptr<cmTargetExport> tgt);
void AddInstallation(cmInstallExportGenerator const* installation);
std::string const& GetName() const { return this->Name; }
- std::vector<cmTargetExport*> const* GetTargetExports() const
+ std::vector<std::unique_ptr<cmTargetExport>> const& GetTargetExports() const
{
- return &this->TargetExports;
+ return this->TargetExports;
}
std::vector<cmInstallExportGenerator const*> const* GetInstallations() const
@@ -47,9 +45,21 @@ public:
}
private:
- std::vector<cmTargetExport*> TargetExports;
+ std::vector<std::unique_ptr<cmTargetExport>> TargetExports;
std::string Name;
std::vector<cmInstallExportGenerator const*> Installations;
};
+/// A name -> cmExportSet map with overloaded operator[].
+class cmExportSetMap : public std::map<std::string, cmExportSet>
+{
+public:
+ /** \brief Overloaded operator[].
+ *
+ * The operator is overloaded because cmExportSet has no default constructor:
+ * we do not want unnamed export sets.
+ */
+ cmExportSet& operator[](const std::string& name);
+};
+
#endif
diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx
deleted file mode 100644
index 293e80cf9..000000000
--- a/Source/cmExportSetMap.cxx
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmExportSetMap.h"
-
-#include "cmAlgorithms.h"
-#include "cmExportSet.h"
-
-#include <utility>
-
-cmExportSet* cmExportSetMap::operator[](const std::string& name)
-{
- std::map<std::string, cmExportSet*>::iterator it = this->find(name);
- if (it == this->end()) // Export set not found
- {
- it = this->insert(std::make_pair(name, new cmExportSet(name))).first;
- }
- return it->second;
-}
-
-void cmExportSetMap::clear()
-{
- cmDeleteAll(*this);
- this->derived::clear();
-}
-
-cmExportSetMap::cmExportSetMap() = default;
-
-cmExportSetMap::~cmExportSetMap()
-{
- this->clear();
-}
diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h
deleted file mode 100644
index 385373240..000000000
--- a/Source/cmExportSetMap.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmExportSetMap_h
-#define cmExportSetMap_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <map>
-#include <string>
-
-class cmExportSet;
-
-/// A name -> cmExportSet map with overloaded operator[].
-class cmExportSetMap : public std::map<std::string, cmExportSet*>
-{
- typedef std::map<std::string, cmExportSet*> derived;
-
-public:
- /** \brief Overloaded operator[].
- *
- * The operator is overloaded because cmExportSet has no default constructor:
- * we do not want unnamed export sets.
- */
- cmExportSet* operator[](const std::string& name);
-
- void clear();
-
- cmExportSetMap();
-
- /// Overloaded destructor deletes all member export sets.
- ~cmExportSetMap();
-
- cmExportSetMap(const cmExportSetMap&) = delete;
- cmExportSetMap& operator=(const cmExportSetMap&) = delete;
-};
-
-#endif
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index c169032dd..fafa51b7b 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportTryCompileFileGenerator.h"
+#include <map>
+#include <memory>
+#include <utility>
+
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
@@ -9,13 +13,9 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <utility>
-
cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
cmGlobalGenerator* gg, const std::vector<std::string>& targets,
cmMakefile* mf, std::set<std::string> const& langs)
@@ -74,9 +74,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
- std::string result =
- cge->Evaluate(tgt->GetLocalGenerator(), this->Config, false, &gDummyHead,
- tgt, &dagChecker, language);
+ std::string result = cge->Evaluate(tgt->GetLocalGenerator(), this->Config,
+ &gDummyHead, &dagChecker, tgt, language);
const std::set<cmGeneratorTarget const*>& allTargets =
cge->GetAllTargetsSeen();
@@ -103,8 +102,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
- std::vector<std::string> depends;
- cmSystemTools::ExpandListArgument(evalResult, depends);
+ std::vector<std::string> depends = cmExpandedList(evalResult);
for (std::string const& li : depends) {
cmGeneratorTarget* tgt =
target->GetLocalGenerator()->FindGeneratorTargetToUse(li);
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 2a2ba7e50..7573427f6 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExportFileGenerator.h"
-
#include <iosfwd>
#include <set>
#include <string>
#include <vector>
+#include "cmExportFileGenerator.h"
+
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx
index 80c78a38c..56dfc6c1d 100644
--- a/Source/cmExprParserHelper.cxx
+++ b/Source/cmExprParserHelper.cxx
@@ -2,13 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExprParserHelper.h"
-#include "cmExprLexer.h"
-
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <utility>
+#include "cmExprLexer.h"
+#include "cmStringAlgorithms.h"
+
int cmExpr_yyparse(yyscan_t yyscanner);
//
cmExprParserHelper::cmExprParserHelper()
@@ -41,16 +42,13 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
try {
int res = cmExpr_yyparse(yyscanner);
if (res != 0) {
- std::string e = "cannot parse the expression: \"" + InputBuffer + "\": ";
- e += ErrorString;
- e += ".";
+ std::string e = cmStrCat("cannot parse the expression: \"", InputBuffer,
+ "\": ", ErrorString, '.');
this->SetError(std::move(e));
}
} catch (std::runtime_error const& fail) {
- std::string e =
- "cannot evaluate the expression: \"" + InputBuffer + "\": ";
- e += fail.what();
- e += ".";
+ std::string e = cmStrCat("cannot evaluate the expression: \"", InputBuffer,
+ "\": ", fail.what(), '.');
this->SetError(std::move(e));
} catch (std::out_of_range const&) {
std::string e = "cannot evaluate the expression: \"" + InputBuffer +
diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h
index 42c460acc..eaf5dc78a 100644
--- a/Source/cmExprParserHelper.h
+++ b/Source/cmExprParserHelper.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_kwiml.h"
-
#include <string>
#include <vector>
+#include "cm_kwiml.h"
+
class cmExprParserHelper
{
public:
diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx
index ac548112a..5895d666e 100644
--- a/Source/cmExternalMakefileProjectGenerator.cxx
+++ b/Source/cmExternalMakefileProjectGenerator.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include "cmStringAlgorithms.h"
+
class cmMakefile;
void cmExternalMakefileProjectGenerator::EnableLanguage(
@@ -18,8 +20,7 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
std::string fullName;
if (!globalGenerator.empty()) {
if (!extraGenerator.empty()) {
- fullName = extraGenerator;
- fullName += " - ";
+ fullName = cmStrCat(extraGenerator, " - ");
}
fullName += globalGenerator;
}
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index f47744b60..5a5d95910 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -73,10 +74,9 @@ void cmExtraCodeBlocksGenerator::CreateProjectFile(
std::string outputDir = lgs[0]->GetCurrentBinaryDirectory();
std::string projectName = lgs[0]->GetProjectName();
- std::string filename = outputDir + "/";
- filename += projectName + ".cbp";
- std::string sessionFilename = outputDir + "/";
- sessionFilename += projectName + ".layout";
+ std::string filename = cmStrCat(outputDir, '/', projectName, ".cbp");
+ std::string sessionFilename =
+ cmStrCat(outputDir, '/', projectName, ".layout");
this->CreateNewProjectFile(lgs, filename);
}
@@ -178,18 +178,18 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml,
{
for (std::string const& f : files) {
xml.StartElement("Unit");
- xml.Attribute("filename", fsPath + path + "/" + f);
+ xml.Attribute("filename", cmStrCat(fsPath, path, "/", f));
xml.StartElement("Option");
xml.Attribute("virtualFolder",
- "CMake Files\\" + virtualFolderPath + path + "\\");
+ cmStrCat("CMake Files\\", virtualFolderPath, path, "\\"));
xml.EndElement();
xml.EndElement();
}
for (Tree const& folder : folders) {
- folder.BuildUnitImpl(xml, virtualFolderPath + path + "\\",
- fsPath + path + "/");
+ folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, path, "\\"),
+ cmStrCat(fsPath, path, "/"));
}
}
@@ -234,7 +234,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Also we can disable external (outside the project) files by setting ON
// CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable.
const bool excludeExternal =
- cmSystemTools::IsOn(it.second[0]->GetMakefile()->GetSafeDefinition(
+ cmIsOn(it.second[0]->GetMakefile()->GetSafeDefinition(
"CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
if (!splitted.empty() &&
(!excludeExternal || (relative.find("..") == std::string::npos)) &&
@@ -318,8 +318,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
cmGeneratorTarget* gt = target;
this->AppendTarget(xml, targetName, gt, make, lg, compiler,
makeArgs);
- std::string fastTarget = targetName;
- fastTarget += "/fast";
+ std::string fastTarget = cmStrCat(targetName, "/fast");
this->AppendTarget(xml, fastTarget, gt, make, lg, compiler,
makeArgs);
} break;
@@ -334,7 +333,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Collect all used source files in the project.
// Keep a list of C/C++ source files which might have an accompanying header
// that should be looked for.
- typedef std::map<std::string, CbpUnit> all_files_map_t;
+ using all_files_map_t = std::map<std::string, CbpUnit>;
all_files_map_t allFiles;
std::vector<std::string> cFiles;
@@ -366,13 +365,13 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// check whether it is a C/C++/CUDA implementation file
bool isCFile = false;
- std::string lang = s->GetLanguage();
+ std::string lang = s->GetOrDetermineLanguage();
if (lang == "C" || lang == "CXX" || lang == "CUDA") {
std::string const& srcext = s->GetExtension();
isCFile = cm->IsSourceExtension(srcext);
}
- std::string const& fullPath = s->GetFullPath();
+ std::string const& fullPath = s->ResolveFullPath();
// Check file position relative to project root dir.
const std::string relative =
@@ -380,7 +379,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Do not add this file if it has ".." in relative path and
// if CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable is on.
const bool excludeExternal =
- cmSystemTools::IsOn(lg->GetMakefile()->GetSafeDefinition(
+ cmIsOn(lg->GetMakefile()->GetSafeDefinition(
"CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
if (excludeExternal &&
(relative.find("..") != std::string::npos)) {
@@ -412,15 +411,13 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// A very similar version of that code exists also in the CodeLite
// project generator.
for (std::string const& fileName : cFiles) {
- std::string headerBasename = cmSystemTools::GetFilenamePath(fileName);
- headerBasename += "/";
- headerBasename += cmSystemTools::GetFilenameWithoutExtension(fileName);
+ std::string headerBasename =
+ cmStrCat(cmSystemTools::GetFilenamePath(fileName), '/',
+ cmSystemTools::GetFilenameWithoutExtension(fileName));
// check if there's a matching header around
for (std::string const& ext : headerExts) {
- std::string hname = headerBasename;
- hname += ".";
- hname += ext;
+ std::string hname = cmStrCat(headerBasename, '.', ext);
// if it's already in the set, don't check if it exists on disk
if (allFiles.find(hname) != allFiles.end()) {
break;
@@ -465,12 +462,9 @@ std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
// this file doesn't seem to be used by C::B in custom makefile mode,
// but we generate a unique file for each OBJECT library so in case
// C::B uses it in some way, the targets don't interfere with each other.
- std::string filename = lg->GetCurrentBinaryDirectory();
- filename += "/";
- filename += lg->GetTargetDirectory(target);
- filename += "/";
- filename += target->GetName();
- filename += ".objlib";
+ std::string filename = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
+ lg->GetTargetDirectory(target), '/',
+ target->GetName(), ".objlib");
cmGeneratedFileStream fout(filename);
if (fout) {
/* clang-format off */
@@ -490,8 +484,8 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
const std::string& compiler, const std::string& makeFlags)
{
cmMakefile const* makefile = lg->GetMakefile();
- std::string makefileName = lg->GetCurrentBinaryDirectory();
- makefileName += "/Makefile";
+ std::string makefileName =
+ cmStrCat(lg->GetCurrentBinaryDirectory(), "/Makefile");
xml.StartElement("Target");
xml.Attribute("title", targetName);
@@ -570,19 +564,16 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs,
- cmSystemTools::ExpandedListArgument(systemIncludeDirs));
+ cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs,
- cmSystemTools::ExpandedListArgument(systemIncludeDirs));
+ cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
- std::vector<std::string>::const_iterator end =
- cmRemoveDuplicates(allIncludeDirs);
+ auto end = cmRemoveDuplicates(allIncludeDirs);
for (std::string const& str : cmMakeRange(allIncludeDirs.cbegin(), end)) {
xml.StartElement("Add");
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index 173e28400..d9f92bde5 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExternalMakefileProjectGenerator.h"
-
#include <string>
#include <vector>
+#include "cmExternalMakefileProjectGenerator.h"
+
class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 6fe8c147f..c7b74570f 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -2,6 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExtraCodeLiteGenerator.h"
+#include <cstring>
+#include <map>
+#include <set>
+#include <sstream>
+#include <utility>
+
+#include "cmsys/SystemInformation.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -9,17 +17,11 @@
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
-#include "cmsys/SystemInformation.hxx"
-#include <map>
-#include <set>
-#include <sstream>
-#include <string.h>
-#include <utility>
-
cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
: ConfigName("NoConfig")
{
@@ -67,8 +69,8 @@ void cmExtraCodeLiteGenerator::Generate()
workspaceOutputDir = lg->GetCurrentBinaryDirectory();
workspaceProjectName = lg->GetProjectName();
workspaceSourcePath = lg->GetSourceDirectory();
- workspaceFileName = workspaceOutputDir + "/";
- workspaceFileName += workspaceProjectName + ".workspace";
+ workspaceFileName =
+ cmStrCat(workspaceOutputDir, '/', workspaceProjectName, ".workspace");
this->WorkspacePath = lg->GetCurrentBinaryDirectory();
break;
}
@@ -121,7 +123,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
cmStateEnums::TargetType type = lt->GetType();
std::string const& outputDir = lg->GetCurrentBinaryDirectory();
std::string targetName = lt->GetName();
- std::string filename = outputDir + "/" + targetName + ".project";
+ std::string filename = cmStrCat(outputDir, "/", targetName, ".project");
retval.push_back(targetName);
// Make the project file relative to the workspace
std::string relafilename =
@@ -131,7 +133,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
- visualname = "lib" + visualname;
+ visualname = cmStrCat("lib", visualname);
CM_FALLTHROUGH;
case cmStateEnums::EXECUTABLE:
xml->StartElement("Project");
@@ -161,7 +163,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps(
std::string const& outputDir = it.second[0]->GetCurrentBinaryDirectory();
std::string projectName = it.second[0]->GetProjectName();
retval.push_back(projectName);
- std::string filename = outputDir + "/" + projectName + ".project";
+ std::string filename = cmStrCat(outputDir, "/", projectName, ".project");
// Make the project file relative to the workspace
filename = cmSystemTools::RelativePath(this->WorkspacePath, filename);
@@ -217,22 +219,21 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
+ cmake const* cm = makefile->GetCMakeInstance();
std::vector<cmSourceFile*> sources;
gt->GetSourceFiles(sources,
makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* s : sources) {
+ std::string const& fullPath = s->ResolveFullPath();
+ std::string const& extLower =
+ cmSystemTools::LowerCase(s->GetExtension());
// check whether it is a source or a include file
// then put it accordingly into one of the two containers
- switch (cmSystemTools::GetFileFormat(s->GetExtension())) {
- case cmSystemTools::C_FILE_FORMAT:
- case cmSystemTools::CXX_FILE_FORMAT:
- case cmSystemTools::CUDA_FILE_FORMAT:
- case cmSystemTools::FORTRAN_FILE_FORMAT: {
- cFiles[s->GetFullPath()] = s;
- } break;
- default: {
- otherFiles.insert(s->GetFullPath());
- }
+ if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) ||
+ cm->IsFortranExtension(extLower)) {
+ cFiles[fullPath] = s;
+ } else {
+ otherFiles.insert(fullPath);
}
}
}
@@ -299,17 +300,15 @@ void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles(
// A very similar version of that code exists also in the CodeBlocks
// project generator.
for (auto const& sit : cFiles) {
- std::string headerBasename = cmSystemTools::GetFilenamePath(sit.first);
- headerBasename += "/";
- headerBasename += cmSystemTools::GetFilenameWithoutExtension(sit.first);
+ std::string headerBasename =
+ cmStrCat(cmSystemTools::GetFilenamePath(sit.first), '/',
+ cmSystemTools::GetFilenameWithoutExtension(sit.first));
// check if there's a matching header around
for (std::string const& ext : headerExts) {
- std::string hname = headerBasename;
- hname += ".";
- hname += ext;
+ std::string hname = cmStrCat(headerBasename, '.', ext);
// if it's already in the set, don't check if it exists on disk
- std::set<std::string>::const_iterator headerIt = otherFiles.find(hname);
+ auto headerIt = otherFiles.find(hname);
if (headerIt != otherFiles.end()) {
break;
}
diff --git a/Source/cmExtraCodeLiteGenerator.h b/Source/cmExtraCodeLiteGenerator.h
index dea7ebc11..0ce90b093 100644
--- a/Source/cmExtraCodeLiteGenerator.h
+++ b/Source/cmExtraCodeLiteGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExternalMakefileProjectGenerator.h"
-
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmExternalMakefileProjectGenerator.h"
+
class cmLocalGenerator;
class cmMakefile;
class cmGeneratorTarget;
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index aece3bc57..b286acf0c 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -2,14 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExtraEclipseCDT4Generator.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
#include <map>
#include <sstream>
-#include <stdio.h>
#include <utility>
+#include "cmsys/RegularExpression.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -21,6 +22,7 @@
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -44,6 +46,8 @@ void AppendDictionary(cmXMLWriter& xml, const char* key, T const& value)
cmExtraEclipseCDT4Generator::cmExtraEclipseCDT4Generator()
{
+ this->IsOutOfSourceBuild = false;
+ this->GenerateSourceProject = false;
this->SupportsVirtualFolders = true;
this->GenerateLinkedResources = true;
this->SupportsGmakeErrorParser = true;
@@ -164,6 +168,29 @@ void cmExtraEclipseCDT4Generator::Generate()
// create a .cproject file
this->CreateCProjectFile();
+
+ // create resource settings
+ this->CreateSettingsResourcePrefsFile();
+}
+
+void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
+{
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ cmMakefile* mf = lg->GetMakefile();
+
+ const std::string filename =
+ this->HomeOutputDirectory + "/.settings/org.eclipse.core.resources.prefs";
+
+ cmGeneratedFileStream fout(filename);
+ if (!fout) {
+ return;
+ }
+
+ fout << "eclipse.preferences.version=1" << std::endl;
+ const char* encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING");
+ if (encoding) {
+ fout << "encoding/<project>=" << encoding << std::endl;
+ }
}
void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
@@ -214,8 +241,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
std::string envVarValue;
const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue);
- std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_";
- cacheEntryName += envVar;
+ std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
const std::string* cacheValue =
lg->GetState()->GetInitializedCacheValue(cacheEntryName);
@@ -390,8 +416,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
if (const char* extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures;
- cmSystemTools::ExpandListArgument(extraNaturesProp, extraNatures);
+ std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp);
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -438,9 +463,7 @@ void cmExtraEclipseCDT4Generator::WriteGroups(
cmXMLWriter& xml)
{
for (cmSourceGroup const& sg : sourceGroups) {
- std::string linkName3 = linkName;
- linkName3 += "/";
- linkName3 += sg.GetFullName();
+ std::string linkName3 = cmStrCat(linkName, '/', sg.GetFullName());
std::replace(linkName3.begin(), linkName3.end(), '\\', '/');
@@ -455,9 +478,8 @@ void cmExtraEclipseCDT4Generator::WriteGroups(
std::string const& fullPath = file->GetFullPath();
if (!cmSystemTools::FileIsDirectory(fullPath)) {
- std::string linkName4 = linkName3;
- linkName4 += "/";
- linkName4 += cmSystemTools::GetFilenameName(fullPath);
+ std::string linkName4 =
+ cmStrCat(linkName3, '/', cmSystemTools::GetFilenameName(fullPath));
cmExtraEclipseCDT4Generator::AppendLinkedResource(
xml, linkName4,
cmExtraEclipseCDT4Generator::GetEclipsePath(fullPath), LinkToFile);
@@ -477,8 +499,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
for (cmGeneratorTarget* target : targets) {
- std::string linkName2 = linkName;
- linkName2 += "/";
+ std::string linkName2 = cmStrCat(linkName, '/');
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
@@ -504,7 +525,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* sf : files) {
// Add the file to the list of sources.
- std::string const& source = sf->GetFullPath();
+ std::string const& source = sf->ResolveFullPath();
cmSourceGroup* sourceGroup =
makefile->FindSourceGroup(source, sourceGroups);
sourceGroup->AssignSource(sf);
@@ -540,8 +561,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
// .project itself
if ((baseDir != linkSourceDirectory) &&
!cmSystemTools::IsSubDirectory(baseDir, linkSourceDirectory)) {
- std::string linkName = "[Subprojects]/";
- linkName += it.first;
+ std::string linkName = cmStrCat("[Subprojects]/", it.first);
cmExtraEclipseCDT4Generator::AppendLinkedResource(
xml, linkName,
cmExtraEclipseCDT4Generator::GetEclipsePath(linkSourceDirectory),
@@ -777,12 +797,11 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
if (this->CEnabled && cDefs) {
// Expand the list.
- std::vector<std::string> defs;
- cmSystemTools::ExpandListArgument(cDefs, defs, true);
+ std::vector<std::string> defs = cmExpandedList(cDefs, true);
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
- std::vector<std::string>::const_iterator di = defs.begin();
+ auto di = defs.begin();
while (di != defs.end()) {
std::string def = *di;
++di;
@@ -810,12 +829,11 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
if (this->CXXEnabled && cxxDefs) {
// Expand the list.
- std::vector<std::string> defs;
- cmSystemTools::ExpandListArgument(cxxDefs, defs, true);
+ std::vector<std::string> defs = cmExpandedList(cxxDefs, true);
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
- std::vector<std::string>::const_iterator di = defs.begin();
+ auto di = defs.begin();
while (di != defs.end()) {
std::string def = *di;
++di;
@@ -861,16 +879,14 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
if (this->CEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
+ std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
this->AppendIncludeDirectories(xml, dirs, emmited);
}
compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
if (this->CXXEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
+ std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
this->AppendIncludeDirectories(xml, dirs, emmited);
}
@@ -944,28 +960,21 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
: "[lib] ");
cmExtraEclipseCDT4Generator::AppendTarget(xml, targetName, make,
makeArgs, subdir, prefix);
- std::string fastTarget = targetName;
- fastTarget += "/fast";
+ std::string fastTarget = cmStrCat(targetName, "/fast");
cmExtraEclipseCDT4Generator::AppendTarget(xml, fastTarget, make,
makeArgs, subdir, prefix);
// Add Build and Clean targets in the virtual folder of targets:
if (this->SupportsVirtualFolders) {
- std::string virtDir = "[Targets]/";
- virtDir += prefix;
- virtDir += targetName;
- std::string buildArgs = "-C \"";
- buildArgs += lgen->GetBinaryDirectory();
- buildArgs += "\" ";
- buildArgs += makeArgs;
+ std::string virtDir = cmStrCat("[Targets]/", prefix, targetName);
+ std::string buildArgs =
+ cmStrCat("-C \"", lgen->GetBinaryDirectory(), "\" ", makeArgs);
cmExtraEclipseCDT4Generator::AppendTarget(
xml, "Build", make, buildArgs, virtDir, "", targetName.c_str());
- std::string cleanArgs = "-E chdir \"";
- cleanArgs += lgen->GetCurrentBinaryDirectory();
- cleanArgs += "\" \"";
- cleanArgs += cmSystemTools::GetCMakeCommand();
- cleanArgs += "\" -P \"";
+ std::string cleanArgs =
+ cmStrCat("-E chdir \"", lgen->GetCurrentBinaryDirectory(),
+ "\" \"", cmSystemTools::GetCMakeCommand(), "\" -P \"");
cmGeneratorTarget* gt = target;
cleanArgs += lgen->GetTargetDirectory(gt);
cleanArgs += "/cmake_clean.cmake\"";
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index 5136660fa..ff4c59eeb 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExternalMakefileProjectGenerator.h"
-
#include <iosfwd>
#include <set>
#include <string>
#include <vector>
+#include "cmExternalMakefileProjectGenerator.h"
+
class cmLocalGenerator;
class cmMakefile;
class cmSourceGroup;
@@ -43,6 +43,9 @@ private:
// create .project file in the source tree
void CreateSourceProjectFile();
+ // create .settings/org.eclipse.core.resources.prefs
+ void CreateSettingsResourcePrefsFile();
+
// create .project file
void CreateProjectFile();
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index 877f10969..e8c9dd002 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExtraKateGenerator.h"
+#include <cstring>
+#include <ostream>
+#include <set>
+#include <vector>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -9,13 +14,9 @@
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <ostream>
-#include <set>
-#include <string.h>
-#include <vector>
-
cmExtraKateGenerator::cmExtraKateGenerator() = default;
cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
@@ -53,8 +54,7 @@ void cmExtraKateGenerator::Generate()
void cmExtraKateGenerator::CreateKateProjectFile(
const cmLocalGenerator* lg) const
{
- std::string filename = lg->GetBinaryDirectory();
- filename += "/.kateproject";
+ std::string filename = cmStrCat(lg->GetBinaryDirectory(), "/.kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -164,8 +164,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
case cmStateEnums::OBJECT_LIBRARY: {
this->AppendTarget(fout, targetName, make, makeArgs, currentDir,
homeOutputDir);
- std::string fastTarget = targetName;
- fastTarget += "/fast";
+ std::string fastTarget = cmStrCat(targetName, "/fast");
this->AppendTarget(fout, fastTarget, make, makeArgs, currentDir,
homeOutputDir);
@@ -208,10 +207,8 @@ void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
void cmExtraKateGenerator::CreateDummyKateProjectFile(
const cmLocalGenerator* lg) const
{
- std::string filename = lg->GetBinaryDirectory();
- filename += "/";
- filename += this->ProjectName;
- filename += ".kateproject";
+ std::string filename =
+ cmStrCat(lg->GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -224,20 +221,17 @@ void cmExtraKateGenerator::CreateDummyKateProjectFile(
std::string cmExtraKateGenerator::GenerateFilesString(
const cmLocalGenerator* lg) const
{
- std::string s = lg->GetSourceDirectory();
- s += "/.git";
+ std::string s = cmStrCat(lg->GetSourceDirectory(), "/.git");
if (cmSystemTools::FileExists(s)) {
return "\"git\": 1 ";
}
- s = lg->GetSourceDirectory();
- s += "/.svn";
+ s = cmStrCat(lg->GetSourceDirectory(), "/.svn");
if (cmSystemTools::FileExists(s)) {
return "\"svn\": 1 ";
}
- s = lg->GetSourceDirectory();
- s += "/";
+ s = cmStrCat(lg->GetSourceDirectory(), '/');
std::set<std::string> files;
std::string tmp;
@@ -260,7 +254,7 @@ std::string cmExtraKateGenerator::GenerateFilesString(
continue;
}
- tmp = sf->GetFullPath();
+ tmp = sf->ResolveFullPath();
files.insert(tmp);
}
}
diff --git a/Source/cmExtraKateGenerator.h b/Source/cmExtraKateGenerator.h
index a4355f00c..be1376aa2 100644
--- a/Source/cmExtraKateGenerator.h
+++ b/Source/cmExtraKateGenerator.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExternalMakefileProjectGenerator.h"
-
#include <string>
+#include "cmExternalMakefileProjectGenerator.h"
+
class cmGeneratedFileStream;
class cmLocalGenerator;
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 71c8fcd58..495324cbf 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -2,12 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExtraSublimeTextGenerator.h"
-#include "cmsys/RegularExpression.hxx"
+#include <cstring>
#include <set>
#include <sstream>
-#include <string.h>
#include <utility>
+#include "cmsys/RegularExpression.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -17,6 +18,7 @@
#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -133,8 +135,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile(
// End of build_systems
fout << "\n\t]";
std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- std::vector<std::string> tokens;
- cmSystemTools::ExpandListArgument(this->EnvSettings, tokens);
+ std::vector<std::string> tokens = cmExpandedList(this->EnvSettings);
if (!this->EnvSettings.empty()) {
fout << ",";
@@ -218,8 +219,7 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
this->AppendTarget(fout, targetName, lg, target, make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
- std::string fastTarget = targetName;
- fastTarget += "/fast";
+ std::string fastTarget = cmStrCat(targetName, "/fast");
this->AppendTarget(fout, fastTarget, lg, target, make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
@@ -243,13 +243,13 @@ void cmExtraSublimeTextGenerator::AppendTarget(
target->GetSourceFiles(sourceFiles,
makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* sourceFile : sourceFiles) {
- MapSourceFileFlags::iterator sourceFileFlagsIter =
- sourceFileFlags.find(sourceFile->GetFullPath());
+ auto sourceFileFlagsIter =
+ sourceFileFlags.find(sourceFile->ResolveFullPath());
if (sourceFileFlagsIter == sourceFileFlags.end()) {
sourceFileFlagsIter =
sourceFileFlags
- .insert(MapSourceFileFlags::value_type(sourceFile->GetFullPath(),
- std::vector<std::string>()))
+ .insert(MapSourceFileFlags::value_type(
+ sourceFile->ResolveFullPath(), std::vector<std::string>()))
.first;
}
std::vector<std::string>& flags = sourceFileFlagsIter->second;
@@ -266,7 +266,7 @@ void cmExtraSublimeTextGenerator::AppendTarget(
R"((^|[ ])-[DIOUWfgs][^= ]+(=\"[^"]+\"|=[^"][^ ]+)?)";
flagRegex.compile(regexString);
std::string workString =
- flagsString + " " + definesString + " " + includesString;
+ cmStrCat(flagsString, " ", definesString, " ", includesString);
while (flagRegex.find(workString)) {
std::string::size_type start = flagRegex.start();
if (workString[start] == ' ') {
@@ -310,8 +310,7 @@ void cmExtraSublimeTextGenerator::AppendTarget(
std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
const std::string& make, const char* makefile, const std::string& target)
{
- std::string command = "\"";
- command += make + "\"";
+ std::string command = cmStrCat('"', make, '"');
std::string generator = this->GlobalGenerator->GetName();
if (generator == "NMake Makefiles") {
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
@@ -344,7 +343,7 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* gtgt)
{
std::string flags;
- std::string language = source->GetLanguage();
+ std::string language = source->GetOrDetermineLanguage();
if (language.empty()) {
language = "C";
}
@@ -379,7 +378,7 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
{
std::set<std::string> defines;
cmMakefile* makefile = lg->GetMakefile();
- const std::string& language = source->GetLanguage();
+ const std::string& language = source->GetOrDetermineLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
language);
@@ -392,8 +391,8 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
}
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(config);
+ std::string defPropName =
+ cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
if (const char* config_compile_defs = source->GetProperty(defPropName)) {
lg->AppendDefines(
defines,
@@ -412,7 +411,7 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
{
std::vector<std::string> includes;
cmMakefile* makefile = lg->GetMakefile();
- const std::string& language = source->GetLanguage();
+ const std::string& language = source->GetOrDetermineLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
language);
@@ -444,7 +443,7 @@ bool cmExtraSublimeTextGenerator::Open(const std::string& bindir,
if (!sublExecutable) {
return false;
}
- if (cmSystemTools::IsNOTFOUND(sublExecutable)) {
+ if (cmIsNOTFOUND(sublExecutable)) {
return false;
}
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index bc158f6b4..7e8f2d4ec 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmExternalMakefileProjectGenerator.h"
-
#include <map>
#include <string>
#include <vector>
+#include "cmExternalMakefileProjectGenerator.h"
+
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLocalGenerator;
@@ -24,7 +24,7 @@ class cmExtraSublimeTextGenerator : public cmExternalMakefileProjectGenerator
{
public:
static cmExternalMakefileProjectGeneratorFactory* GetFactory();
- typedef std::map<std::string, std::vector<std::string>> MapSourceFileFlags;
+ using MapSourceFileFlags = std::map<std::string, std::vector<std::string>>;
cmExtraSublimeTextGenerator();
void Generate() override;
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 89629c768..11844e47d 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -2,122 +2,121 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFLTKWrapUICommand.h"
-#include <stddef.h>
+#include <cstddef>
#include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
class cmTarget;
-// cmFLTKWrapUICommand
-bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+static void FinalAction(cmMakefile& makefile, std::string const& name)
+{
+ // people should add the srcs to the target themselves, but the old command
+ // didn't support that, so check and see if they added the files in and if
+ // they didn;t then print a warning and add then anyhow
+ cmTarget* target = makefile.FindLocalNonAliasTarget(name);
+ if (!target) {
+ std::string msg = cmStrCat(
+ "FLTK_WRAP_UI was called with a target that was never created: ", name,
+ ". The problem was found while processing the source directory: ",
+ makefile.GetCurrentSourceDirectory(),
+ ". This FLTK_WRAP_UI call will be ignored.");
+ cmSystemTools::Message(msg, "Warning");
+ }
+}
+
+bool cmFLTKWrapUICommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// what is the current source dir
- std::string cdir = this->Makefile->GetCurrentSourceDirectory();
+ std::string cdir = mf.GetCurrentSourceDirectory();
std::string const& fluid_exe =
- this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");
+ mf.GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");
- // get parameter for the command
- this->Target = args[0]; // Target that will use the generated files
+ // Target that will use the generated files
+ std::string const& target = args[0];
// get the list of GUI files from which .cxx and .h will be generated
- std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory();
+ std::string outputDirectory = mf.GetCurrentBinaryDirectory();
{
// Some of the generated files are *.h so the directory "GUI"
// where they are created have to be added to the include path
std::vector<std::string> outputDirectories;
outputDirectories.push_back(outputDirectory);
- this->Makefile->AddIncludeDirectories(outputDirectories);
+ mf.AddIncludeDirectories(outputDirectories);
}
+ // List of produced files.
+ std::vector<cmSourceFile*> generatedSourcesClasses;
+
for (std::string const& arg : cmMakeRange(args).advance(1)) {
- cmSourceFile* curr = this->Makefile->GetSource(arg);
+ cmSourceFile* curr = mf.GetSource(arg);
// if we should use the source GUI
// to generate .cxx and .h files
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) {
- std::string outName = outputDirectory;
- outName += "/";
- outName += cmSystemTools::GetFilenameWithoutExtension(arg);
- std::string hname = outName;
- hname += ".h";
- std::string origname = cdir + "/" + arg;
+ std::string outName = cmStrCat(
+ outputDirectory, "/", cmSystemTools::GetFilenameWithoutExtension(arg));
+ std::string hname = cmStrCat(outName, ".h");
+ std::string origname = cmStrCat(cdir, "/", arg);
// add starting depends
std::vector<std::string> depends;
depends.push_back(origname);
depends.push_back(fluid_exe);
- std::string cxxres = outName;
- cxxres += ".cxx";
-
- cmCustomCommandLine commandLine;
- commandLine.push_back(fluid_exe);
- commandLine.push_back("-c"); // instructs Fluid to run in command line
- commandLine.push_back("-h"); // optionally rename .h files
- commandLine.push_back(hname);
- commandLine.push_back("-o"); // optionally rename .cxx files
- commandLine.push_back(cxxres);
- commandLine.push_back(origname); // name of the GUI fluid file
- cmCustomCommandLines commandLines;
- commandLines.push_back(commandLine);
+ std::string cxxres = cmStrCat(outName, ".cxx");
+
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine({
+ fluid_exe,
+ "-c", // instructs Fluid to run in command line
+ "-h", // optionally rename .h files
+ hname,
+ "-o", // optionally rename .cxx files
+ cxxres,
+ origname // name of the GUI fluid file
+ });
// Add command for generating the .h and .cxx files
std::string no_main_dependency;
const char* no_comment = nullptr;
const char* no_working_dir = nullptr;
- this->Makefile->AddCustomCommandToOutput(
- cxxres, depends, no_main_dependency, commandLines, no_comment,
- no_working_dir);
- this->Makefile->AddCustomCommandToOutput(
- hname, depends, no_main_dependency, commandLines, no_comment,
- no_working_dir);
-
- cmSourceFile* sf = this->Makefile->GetSource(cxxres);
+ mf.AddCustomCommandToOutput(cxxres, depends, no_main_dependency,
+ commandLines, no_comment, no_working_dir);
+ mf.AddCustomCommandToOutput(hname, depends, no_main_dependency,
+ commandLines, no_comment, no_working_dir);
+
+ cmSourceFile* sf = mf.GetSource(cxxres);
sf->AddDepend(hname);
sf->AddDepend(origname);
- this->GeneratedSourcesClasses.push_back(sf);
+ generatedSourcesClasses.push_back(sf);
}
}
// create the variable with the list of sources in it
- size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
+ size_t lastHeadersClass = generatedSourcesClasses.size();
std::string sourceListValue;
for (size_t classNum = 0; classNum < lastHeadersClass; classNum++) {
if (classNum) {
sourceListValue += ";";
}
- sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath();
+ sourceListValue += generatedSourcesClasses[classNum]->ResolveFullPath();
}
- std::string varName = this->Target;
- varName += "_FLTK_UI_SRCS";
- this->Makefile->AddDefinition(varName, sourceListValue.c_str());
- return true;
-}
+ std::string const varName = target + "_FLTK_UI_SRCS";
+ mf.AddDefinition(varName, sourceListValue);
-void cmFLTKWrapUICommand::FinalPass()
-{
- // people should add the srcs to the target themselves, but the old command
- // didn't support that, so check and see if they added the files in and if
- // they didn;t then print a warning and add then anyhow
- cmTarget* target = this->Makefile->FindLocalNonAliasTarget(this->Target);
- if (!target) {
- std::string msg =
- "FLTK_WRAP_UI was called with a target that was never created: ";
- msg += this->Target;
- msg += ". The problem was found while processing the source directory: ";
- msg += this->Makefile->GetCurrentSourceDirectory();
- msg += ". This FLTK_WRAP_UI call will be ignored.";
- cmSystemTools::Message(msg, "Warning");
- return;
- }
+ mf.AddFinalAction(
+ [target](cmMakefile& makefile) { FinalAction(makefile, target); });
+ return true;
}
diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h
index 044755e5b..bb56dbd44 100644
--- a/Source/cmFLTKWrapUICommand.h
+++ b/Source/cmFLTKWrapUICommand.h
@@ -8,52 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmSourceFile;
-
-/** \class cmFLTKWrapUICommand
- * \brief Create .h and .cxx files rules for FLTK user interfaces files
- *
- * cmFLTKWrapUICommand is used to create wrappers for FLTK classes into
- * normal C++
- */
-class cmFLTKWrapUICommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFLTKWrapUICommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * This is called at the end after all the information
- * specified by the command is accumulated. Most commands do
- * not implement this method. At this point, reading and
- * writing to the cache can be done.
- */
- void FinalPass() override;
- bool HasFinalPass() const override { return true; }
-
-private:
- /**
- * List of produced files.
- */
- std::vector<cmSourceFile*> GeneratedSourcesClasses;
- /**
- * List of Fluid files that provide the source
- * generating .cxx and .h files
- */
- std::string Target;
-};
+bool cmFLTKWrapUICommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmFSPermissions.h b/Source/cmFSPermissions.h
index 7a6e70866..fef72e616 100644
--- a/Source/cmFSPermissions.h
+++ b/Source/cmFSPermissions.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_sys_stat.h"
-
#include <string>
+#include "cm_sys_stat.h"
+
namespace cmFSPermissions {
// Table of permissions flags.
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index ba4266963..a56ad22f6 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -2,25 +2,27 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPI.h"
-#include "cmAlgorithms.h"
+#include <algorithm>
+#include <cassert>
+#include <chrono>
+#include <cstddef>
+#include <ctime>
+#include <iomanip>
+#include <sstream>
+#include <utility>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
+
#include "cmCryptoHash.h"
#include "cmFileAPICMakeFiles.h"
#include "cmFileAPICache.h"
#include "cmFileAPICodemodel.h"
#include "cmGlobalGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmake.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
-
-#include <algorithm>
-#include <cassert>
-#include <chrono>
-#include <ctime>
-#include <iomanip>
-#include <sstream>
-#include <utility>
cmFileAPI::cmFileAPI(cmake* cm)
: CMakeInstance(cm)
@@ -94,7 +96,7 @@ void cmFileAPI::RemoveOldReplyFiles()
std::vector<std::string> files = this->LoadDir(reply_dir);
for (std::string const& f : files) {
if (this->ReplyFiles.find(f) == this->ReplyFiles.end()) {
- std::string file = reply_dir + "/" + f;
+ std::string file = cmStrCat(reply_dir, "/", f);
cmSystemTools::RemoveFile(file);
}
}
@@ -407,9 +409,7 @@ const char* cmFileAPI::ObjectKindName(ObjectKind kind)
std::string cmFileAPI::ObjectName(Object const& o)
{
- std::string name = ObjectKindName(o.Kind);
- name += "-v";
- name += std::to_string(o.Version);
+ std::string name = cmStrCat(ObjectKindName(o.Kind), "-v", o.Version);
return name;
}
@@ -684,7 +684,6 @@ void cmFileAPI::BuildClientRequestCodeModel(
Json::Value cmFileAPI::BuildCodeModel(Object const& object)
{
- using namespace std::placeholders;
Json::Value codemodel = cmFileAPICodemodelDump(*this, object.Version);
codemodel["kind"] = this->ObjectKindName(object.Kind);
@@ -719,7 +718,6 @@ void cmFileAPI::BuildClientRequestCache(
Json::Value cmFileAPI::BuildCache(Object const& object)
{
- using namespace std::placeholders;
Json::Value cache = cmFileAPICacheDump(*this, object.Version);
cache["kind"] = this->ObjectKindName(object.Kind);
@@ -754,7 +752,6 @@ void cmFileAPI::BuildClientRequestCMakeFiles(
Json::Value cmFileAPI::BuildCMakeFiles(Object const& object)
{
- using namespace std::placeholders;
Json::Value cmakeFiles = cmFileAPICMakeFilesDump(*this, object.Version);
cmakeFiles["kind"] = this->ObjectKindName(object.Kind);
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index 602efa8ed..e183e0d97 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -5,16 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
+
class cmake;
class cmFileAPI
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index 5590bc2b3..f41999771 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPICMakeFiles.h"
+#include <string>
+#include <vector>
+
+#include "cm_jsoncpp_value.h"
+
#include "cmFileAPI.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -9,11 +14,6 @@
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cm_jsoncpp_value.h"
-
-#include <string>
-#include <vector>
-
namespace {
class CMakeFiles
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index f96bc90e5..ef7779567 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -2,17 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPICache.h"
-#include "cmFileAPI.h"
-#include "cmState.h"
-#include "cmake.h"
-
-#include "cm_jsoncpp_value.h"
-
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
+#include "cm_jsoncpp_value.h"
+
+#include "cmFileAPI.h"
+#include "cmState.h"
+#include "cmake.h"
+
namespace {
class Cache
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index fecbf63ca..d7993c7d9 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -2,6 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPICodemodel.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <limits>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "cm_jsoncpp_value.h"
+
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileAPI.h"
@@ -21,22 +36,12 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
#include "cmake.h"
-#include "cm_jsoncpp_value.h"
-
-#include <algorithm>
-#include <cassert>
-#include <map>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
namespace {
class Codemodel
@@ -134,6 +139,40 @@ std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild)
return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash;
}
+class JBTIndex
+{
+public:
+ JBTIndex() = default;
+ explicit operator bool() const { return Index != None; }
+ Json::ArrayIndex Index = None;
+ static Json::ArrayIndex const None = static_cast<Json::ArrayIndex>(-1);
+};
+
+template <typename T>
+class JBT
+{
+public:
+ JBT(T v = T(), JBTIndex bt = JBTIndex())
+ : Value(std::move(v))
+ , Backtrace(bt)
+ {
+ }
+ T Value;
+ JBTIndex Backtrace;
+ friend bool operator==(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value == r.Value && l.Backtrace.Index == r.Backtrace.Index;
+ }
+ static bool ValueEq(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value == r.Value;
+ }
+ static bool ValueLess(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value < r.Value;
+ }
+};
+
class BacktraceData
{
std::string TopSource;
@@ -168,7 +207,7 @@ class BacktraceData
public:
BacktraceData(std::string topSource);
- bool Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index);
+ JBTIndex Add(cmListFileBacktrace const& bt);
Json::Value Dump();
};
@@ -177,16 +216,17 @@ BacktraceData::BacktraceData(std::string topSource)
{
}
-bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index)
+JBTIndex BacktraceData::Add(cmListFileBacktrace const& bt)
{
+ JBTIndex index;
if (bt.Empty()) {
- return false;
+ return index;
}
cmListFileContext const* top = &bt.Top();
auto found = this->NodeMap.find(top);
if (found != this->NodeMap.end()) {
- index = found->second;
- return true;
+ index.Index = found->second;
+ return index;
}
Json::Value entry = Json::objectValue;
entry["file"] = this->AddFile(top->FilePath);
@@ -196,13 +236,12 @@ bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index)
if (!top->Name.empty()) {
entry["command"] = this->AddCommand(top->Name);
}
- Json::ArrayIndex parent;
- if (this->Add(bt.Pop(), parent)) {
- entry["parent"] = parent;
+ if (JBTIndex parent = this->Add(bt.Pop())) {
+ entry["parent"] = parent.Index;
}
- index = this->NodeMap[top] = this->Nodes.size();
+ index.Index = this->NodeMap[top] = this->Nodes.size();
this->Nodes.append(std::move(entry)); // NOLINT(*)
- return true;
+ return index;
}
Json::Value BacktraceData::Dump()
@@ -221,32 +260,65 @@ struct CompileData
{
struct IncludeEntry
{
- BT<std::string> Path;
+ JBT<std::string> Path;
bool IsSystem = false;
- IncludeEntry(BT<std::string> path, bool isSystem)
+ IncludeEntry(JBT<std::string> path, bool isSystem)
: Path(std::move(path))
, IsSystem(isSystem)
{
}
+ friend bool operator==(IncludeEntry const& l, IncludeEntry const& r)
+ {
+ return l.Path == r.Path && l.IsSystem == r.IsSystem;
+ }
};
- void SetDefines(std::set<BT<std::string>> const& defines);
-
std::string Language;
std::string Sysroot;
- std::vector<BT<std::string>> Flags;
- std::vector<BT<std::string>> Defines;
+ std::vector<JBT<std::string>> Flags;
+ std::vector<JBT<std::string>> Defines;
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.Includes == r.Includes);
+ }
};
+}
-void CompileData::SetDefines(std::set<BT<std::string>> const& defines)
+namespace std {
+
+template <>
+struct hash<CompileData>
{
- this->Defines.reserve(defines.size());
- for (BT<std::string> const& d : defines) {
- this->Defines.push_back(d);
+ std::size_t operator()(CompileData const& in) const
+ {
+ using std::hash;
+ size_t result =
+ hash<std::string>()(in.Language) ^ hash<std::string>()(in.Sysroot);
+ for (auto const& i : in.Includes) {
+ result = result ^
+ (hash<std::string>()(i.Path.Value) ^
+ hash<Json::ArrayIndex>()(i.Path.Backtrace.Index) ^
+ (i.IsSystem ? std::numeric_limits<size_t>::max() : 0));
+ }
+ for (auto const& i : in.Flags) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ for (auto const& i : in.Defines) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ return result;
}
-}
+};
+
+} // namespace std
+namespace {
class Target
{
cmGeneratorTarget* GT;
@@ -271,24 +343,32 @@ class Target
struct CompileGroup
{
- std::map<Json::Value, Json::ArrayIndex>::iterator Entry;
+ std::unordered_map<CompileData, Json::ArrayIndex>::iterator Entry;
Json::Value SourceIndexes = Json::arrayValue;
};
- std::map<Json::Value, Json::ArrayIndex> CompileGroupMap;
+ std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap;
std::vector<CompileGroup> CompileGroups;
+ template <typename T>
+ JBT<T> ToJBT(BT<T> const& bt)
+ {
+ return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace));
+ }
+
void ProcessLanguages();
void ProcessLanguage(std::string const& lang);
Json::ArrayIndex AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si);
CompileData BuildCompileData(cmSourceFile* sf);
+ CompileData MergeCompileData(CompileData const& fd);
Json::ArrayIndex AddSourceCompileGroup(cmSourceFile* sf,
Json::ArrayIndex si);
void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt);
+ void AddBacktrace(Json::Value& object, JBTIndex bt);
Json::Value DumpPaths();
- Json::Value DumpCompileData(CompileData cd);
+ Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
- Json::Value DumpDefine(BT<std::string> const& def);
+ Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
Json::ArrayIndex si);
@@ -305,8 +385,8 @@ class Target
Json::Value DumpLink();
Json::Value DumpArchive();
Json::Value DumpLinkCommandFragments();
- Json::Value DumpCommandFragments(std::vector<BT<std::string>> const& frags);
- Json::Value DumpCommandFragment(BT<std::string> const& frag,
+ Json::Value DumpCommandFragments(std::vector<JBT<std::string>> const& frags);
+ Json::Value DumpCommandFragment(JBT<std::string> const& frag,
std::string const& role = std::string());
Json::Value DumpDependencies();
Json::Value DumpDependency(cmTargetDepend const& td);
@@ -343,20 +423,17 @@ Json::Value Codemodel::DumpPaths()
Json::Value Codemodel::DumpConfigurations()
{
- std::vector<std::string> configs;
+ Json::Value configurations = Json::arrayValue;
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
auto makefiles = gg->GetMakefiles();
if (!makefiles.empty()) {
- makefiles[0]->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
+ std::vector<std::string> const& configs =
+ makefiles[0]->GetGeneratorConfigs();
+ for (std::string const& config : configs) {
+ configurations.append(this->DumpConfiguration(config));
}
}
- Json::Value configurations = Json::arrayValue;
- for (std::string const& config : configs) {
- configurations.append(this->DumpConfiguration(config));
- }
return configurations;
}
@@ -725,25 +802,32 @@ void Target::ProcessLanguage(std::string const& lang)
{
// FIXME: Add flags from end section of ExpandRuleVariable,
// which may need to be factored out.
- std::string flags;
- lg->GetTargetCompileFlags(this->GT, this->Config, lang, flags);
- cd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ std::vector<BT<std::string>> flags =
+ lg->GetTargetCompileFlags(this->GT, this->Config, lang);
+
+ cd.Flags.reserve(flags.size());
+ for (const BT<std::string>& f : flags) {
+ cd.Flags.emplace_back(this->ToJBT(f));
+ }
}
std::set<BT<std::string>> defines =
lg->GetTargetDefines(this->GT, this->Config, lang);
- cd.SetDefines(defines);
+ cd.Defines.reserve(defines.size());
+ for (BT<std::string> const& d : defines) {
+ cd.Defines.emplace_back(this->ToJBT(d));
+ }
std::vector<BT<std::string>> includePathList =
lg->GetIncludeDirectories(this->GT, lang, this->Config);
for (BT<std::string> const& i : includePathList) {
cd.Includes.emplace_back(
- i, this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
+ this->ToJBT(i),
+ this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
}
}
Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
{
- std::unordered_map<cmSourceGroup const*, Json::ArrayIndex>::iterator i =
- this->SourceGroupsMap.find(sg);
+ auto i = this->SourceGroupsMap.find(sg);
if (i == this->SourceGroupsMap.end()) {
auto sgIndex = static_cast<Json::ArrayIndex>(this->SourceGroups.size());
i = this->SourceGroupsMap.emplace(sg, sgIndex).first;
@@ -759,87 +843,164 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
{
CompileData fd;
- fd.Language = sf->GetLanguage();
+ fd.Language = sf->GetOrDetermineLanguage();
if (fd.Language.empty()) {
return fd;
}
- CompileData const& cd = this->CompileDataMap.at(fd.Language);
-
- fd.Sysroot = cd.Sysroot;
cmLocalGenerator* lg = this->GT->GetLocalGenerator();
cmGeneratorExpressionInterpreter genexInterpreter(lg, this->Config, this->GT,
fd.Language);
- fd.Flags = cd.Flags;
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
- fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ fd.Flags.emplace_back(std::move(flags), JBTIndex());
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
- std::string flags;
- lg->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
- fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ for (BT<std::string> tmpOpt : sf->GetCompileOptions()) {
+ tmpOpt.Value = genexInterpreter.Evaluate(tmpOpt.Value, COMPILE_OPTIONS);
+ // After generator evaluation we need to use the AppendCompileOptions
+ // method so we handle situations where backtrace entries have lists
+ // and properly escape flags.
+ std::string tmp;
+ lg->AppendCompileOptions(tmp, tmpOpt.Value);
+ BT<std::string> opt(tmp, tmpOpt.Backtrace);
+ fd.Flags.emplace_back(this->ToJBT(opt));
+ }
+
+ // Add precompile headers compile options.
+ const std::string pchSource =
+ this->GT->GetPchSource(this->Config, fd.Language);
+
+ if (!pchSource.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ std::string pchOptions;
+ if (sf->ResolveFullPath() == pchSource) {
+ pchOptions =
+ this->GT->GetPchCreateCompileOptions(this->Config, fd.Language);
+ } else {
+ pchOptions =
+ this->GT->GetPchUseCompileOptions(this->Config, fd.Language);
+ }
+
+ BT<std::string> tmpOpt(pchOptions);
+ tmpOpt.Value = genexInterpreter.Evaluate(tmpOpt.Value, COMPILE_OPTIONS);
+
+ // After generator evaluation we need to use the AppendCompileOptions
+ // method so we handle situations where backtrace entries have lists
+ // and properly escape flags.
+ std::string tmp;
+ lg->AppendCompileOptions(tmp, tmpOpt.Value);
+ BT<std::string> opt(tmp, tmpOpt.Backtrace);
+ fd.Flags.emplace_back(this->ToJBT(opt));
}
// Add include directories from source file properties.
{
- std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
- const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
- lg->AppendIncludeDirectories(includes, evaluatedIncludes, *sf);
-
- for (std::string const& include : includes) {
- bool const isSystemInclude = this->GT->IsSystemIncludeDirectory(
- include, this->Config, fd.Language);
- fd.Includes.emplace_back(include, isSystemInclude);
+ for (BT<std::string> tmpInclude : sf->GetIncludeDirectories()) {
+ tmpInclude.Value =
+ genexInterpreter.Evaluate(tmpInclude.Value, INCLUDE_DIRECTORIES);
+
+ // After generator evaluation we need to use the AppendIncludeDirectories
+ // method so we handle situations where backtrace entries have lists.
+ std::vector<std::string> tmp;
+ lg->AppendIncludeDirectories(tmp, tmpInclude.Value, *sf);
+ for (std::string& i : tmp) {
+ bool const isSystemInclude =
+ this->GT->IsSystemIncludeDirectory(i, this->Config, fd.Language);
+ BT<std::string> include(i, tmpInclude.Backtrace);
+ fd.Includes.emplace_back(this->ToJBT(include), isSystemInclude);
}
}
}
- fd.Includes.insert(fd.Includes.end(), cd.Includes.begin(),
- cd.Includes.end());
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- std::set<std::string> fileDefines;
- if (const char* defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
- lg->AppendDefines(fileDefines,
- genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS));
+ std::set<BT<std::string>> fileDefines;
+ for (BT<std::string> tmpDef : sf->GetCompileDefinitions()) {
+ tmpDef.Value =
+ genexInterpreter.Evaluate(tmpDef.Value, COMPILE_DEFINITIONS);
+
+ // After generator evaluation we need to use the AppendDefines method
+ // so we handle situations where backtrace entries have lists.
+ std::set<std::string> tmp;
+ lg->AppendDefines(tmp, tmpDef.Value);
+ for (const std::string& i : tmp) {
+ BT<std::string> def(i, tmpDef.Backtrace);
+ fileDefines.insert(def);
+ }
}
+ std::set<std::string> configFileDefines;
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config);
if (const char* config_defs = sf->GetProperty(defPropName)) {
lg->AppendDefines(
- fileDefines,
+ configFileDefines,
genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
}
- std::set<BT<std::string>> defines;
- defines.insert(fileDefines.begin(), fileDefines.end());
- defines.insert(cd.Defines.begin(), cd.Defines.end());
+ fd.Defines.reserve(fileDefines.size() + configFileDefines.size());
- fd.SetDefines(defines);
+ for (BT<std::string> const& def : fileDefines) {
+ fd.Defines.emplace_back(this->ToJBT(def));
+ }
+
+ for (std::string const& d : configFileDefines) {
+ fd.Defines.emplace_back(d, JBTIndex());
+ }
return fd;
}
+CompileData Target::MergeCompileData(CompileData const& fd)
+{
+ CompileData cd;
+ cd.Language = fd.Language;
+ if (cd.Language.empty()) {
+ return cd;
+ }
+ CompileData const& td = this->CompileDataMap.at(cd.Language);
+
+ // All compile groups share the sysroot of the target.
+ cd.Sysroot = td.Sysroot;
+
+ // 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());
+ cd.Flags.insert(cd.Flags.end(), fd.Flags.begin(), fd.Flags.end());
+
+ // Use source-specific includes followed by target-wide includes.
+ cd.Includes.reserve(fd.Includes.size() + td.Includes.size());
+ cd.Includes.insert(cd.Includes.end(), fd.Includes.begin(),
+ fd.Includes.end());
+ cd.Includes.insert(cd.Includes.end(), td.Includes.begin(),
+ td.Includes.end());
+
+ // Use target-wide defines followed by source-specific defines.
+ cd.Defines.reserve(td.Defines.size() + fd.Defines.size());
+ cd.Defines.insert(cd.Defines.end(), td.Defines.begin(), td.Defines.end());
+ cd.Defines.insert(cd.Defines.end(), fd.Defines.begin(), fd.Defines.end());
+
+ // De-duplicate defines.
+ std::stable_sort(cd.Defines.begin(), cd.Defines.end(),
+ JBT<std::string>::ValueLess);
+ auto end = std::unique(cd.Defines.begin(), cd.Defines.end(),
+ JBT<std::string>::ValueEq);
+ cd.Defines.erase(end, cd.Defines.end());
+
+ return cd;
+}
+
Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf,
Json::ArrayIndex si)
{
- Json::Value compileDataJson =
- this->DumpCompileData(this->BuildCompileData(sf));
- std::map<Json::Value, Json::ArrayIndex>::iterator i =
- this->CompileGroupMap.find(compileDataJson);
+ CompileData compileData = this->BuildCompileData(sf);
+ auto i = this->CompileGroupMap.find(compileData);
if (i == this->CompileGroupMap.end()) {
Json::ArrayIndex cgIndex =
static_cast<Json::ArrayIndex>(this->CompileGroups.size());
- i =
- this->CompileGroupMap.emplace(std::move(compileDataJson), cgIndex).first;
+ i = this->CompileGroupMap.emplace(std::move(compileData), cgIndex).first;
CompileGroup g;
g.Entry = i;
this->CompileGroups.push_back(std::move(g));
@@ -850,9 +1011,15 @@ Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf,
void Target::AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt)
{
- Json::ArrayIndex backtrace;
- if (this->Backtraces.Add(bt, backtrace)) {
- object["backtrace"] = backtrace;
+ if (JBTIndex backtrace = this->Backtraces.Add(bt)) {
+ object["backtrace"] = backtrace.Index;
+ }
+}
+
+void Target::AddBacktrace(Json::Value& object, JBTIndex bt)
+{
+ if (bt) {
+ object["backtrace"] = bt.Index;
}
}
@@ -886,7 +1053,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
{
Json::Value source = Json::objectValue;
- std::string const path = sk.Source.Value->GetFullPath();
+ std::string const path = sk.Source.Value->ResolveFullPath();
source["path"] = RelativeIfUnder(this->TopSource, path);
if (sk.Source.Value->GetIsGenerated()) {
source["isGenerated"] = true;
@@ -914,13 +1081,14 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
case cmGeneratorTarget::SourceKindModuleDefinition:
case cmGeneratorTarget::SourceKindResx:
case cmGeneratorTarget::SourceKindXaml:
+ case cmGeneratorTarget::SourceKindUnityBatched:
break;
}
return source;
}
-Json::Value Target::DumpCompileData(CompileData cd)
+Json::Value Target::DumpCompileData(CompileData const& cd)
{
Json::Value result = Json::objectValue;
@@ -942,7 +1110,7 @@ Json::Value Target::DumpCompileData(CompileData cd)
}
if (!cd.Defines.empty()) {
Json::Value defines = Json::arrayValue;
- for (BT<std::string> const& d : cd.Defines) {
+ for (JBT<std::string> const& d : cd.Defines) {
defines.append(this->DumpDefine(d));
}
result["defines"] = std::move(defines);
@@ -962,7 +1130,7 @@ Json::Value Target::DumpInclude(CompileData::IncludeEntry const& inc)
return include;
}
-Json::Value Target::DumpDefine(BT<std::string> const& def)
+Json::Value Target::DumpDefine(JBT<std::string> const& def)
{
Json::Value define = Json::objectValue;
define["define"] = def.Value;
@@ -998,7 +1166,8 @@ Json::Value Target::DumpCompileGroups()
Json::Value Target::DumpCompileGroup(CompileGroup& cg)
{
- Json::Value group = cg.Entry->first;
+ Json::Value group =
+ this->DumpCompileData(this->MergeCompileData(cg.Entry->first));
group["sourceIndexes"] = std::move(cg.SourceIndexes);
return group;
}
@@ -1078,17 +1247,16 @@ Json::Value Target::DumpArtifacts()
}
// Add Windows-specific artifacts produced by the linker.
+ if (this->GT->HasImportLibrary(this->Config)) {
+ Json::Value artifact = Json::objectValue;
+ artifact["path"] =
+ RelativeIfUnder(this->TopBuild,
+ this->GT->GetFullPath(
+ this->Config, cmStateEnums::ImportLibraryArtifact));
+ artifacts.append(std::move(artifact)); // NOLINT(*)
+ }
if (this->GT->IsDLLPlatform() &&
this->GT->GetType() != cmStateEnums::STATIC_LIBRARY) {
- if (this->GT->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->GT->IsExecutableWithExports()) {
- Json::Value artifact = Json::objectValue;
- artifact["path"] =
- RelativeIfUnder(this->TopBuild,
- this->GT->GetFullPath(
- this->Config, cmStateEnums::ImportLibraryArtifact));
- artifacts.append(std::move(artifact)); // NOLINT(*)
- }
cmGeneratorTarget::OutputInfo const* output =
this->GT->GetOutputInfo(this->Config);
if (output && !output->PdbDir.empty()) {
@@ -1148,21 +1316,18 @@ Json::Value Target::DumpLinkCommandFragments()
Json::Value linkFragments = Json::arrayValue;
std::string linkLanguageFlags;
- std::string linkFlags;
+ std::vector<BT<std::string>> linkFlags;
std::string frameworkPath;
- std::string linkPath;
- std::string linkLibs;
+ std::vector<BT<std::string>> linkPath;
+ std::vector<BT<std::string>> linkLibs;
cmLocalGenerator* lg = this->GT->GetLocalGenerator();
cmLinkLineComputer linkLineComputer(lg,
lg->GetStateSnapshot().GetDirectory());
lg->GetTargetFlags(&linkLineComputer, this->Config, linkLibs,
linkLanguageFlags, linkFlags, frameworkPath, linkPath,
this->GT);
- linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
- frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath);
- linkPath = cmSystemTools::TrimWhitespace(linkPath);
- linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
+ linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
+ frameworkPath = cmTrimWhitespace(frameworkPath);
if (!linkLanguageFlags.empty()) {
linkFragments.append(
@@ -1170,8 +1335,11 @@ Json::Value Target::DumpLinkCommandFragments()
}
if (!linkFlags.empty()) {
- linkFragments.append(
- this->DumpCommandFragment(std::move(linkFlags), "flags"));
+ for (BT<std::string> frag : linkFlags) {
+ frag.Value = cmTrimWhitespace(frag.Value);
+ linkFragments.append(
+ this->DumpCommandFragment(this->ToJBT(frag), "flags"));
+ }
}
if (!frameworkPath.empty()) {
@@ -1180,29 +1348,35 @@ Json::Value Target::DumpLinkCommandFragments()
}
if (!linkPath.empty()) {
- linkFragments.append(
- this->DumpCommandFragment(std::move(linkPath), "libraryPath"));
+ for (BT<std::string> frag : linkPath) {
+ frag.Value = cmTrimWhitespace(frag.Value);
+ linkFragments.append(
+ this->DumpCommandFragment(this->ToJBT(frag), "libraryPath"));
+ }
}
if (!linkLibs.empty()) {
- linkFragments.append(
- this->DumpCommandFragment(std::move(linkLibs), "libraries"));
+ for (BT<std::string> frag : linkLibs) {
+ frag.Value = cmTrimWhitespace(frag.Value);
+ linkFragments.append(
+ this->DumpCommandFragment(this->ToJBT(frag), "libraries"));
+ }
}
return linkFragments;
}
Json::Value Target::DumpCommandFragments(
- std::vector<BT<std::string>> const& frags)
+ std::vector<JBT<std::string>> const& frags)
{
Json::Value commandFragments = Json::arrayValue;
- for (BT<std::string> const& f : frags) {
+ for (JBT<std::string> const& f : frags) {
commandFragments.append(this->DumpCommandFragment(f));
}
return commandFragments;
}
-Json::Value Target::DumpCommandFragment(BT<std::string> const& frag,
+Json::Value Target::DumpCommandFragment(JBT<std::string> const& frag,
std::string const& role)
{
Json::Value fragment = Json::objectValue;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 7a3954e4d..d55b959e8 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2,26 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileCommand.h"
-#include "cm_kwiml.h"
-#include "cm_static_string_view.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cctype>
#include <cmath>
-#include <ctype.h>
-#include <memory> // IWYU pragma: keep
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <set>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
#include <utility>
#include <vector>
+#include <cm/memory>
+
+#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"
#include "cmArgumentParser.h"
#include "cmCryptoHash.h"
+#include "cmExecutionStatus.h"
#include "cmFileCopier.h"
#include "cmFileInstaller.h"
#include "cmFileLockPool.h"
@@ -34,15 +40,19 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmRange.h"
+#include "cmRuntimeDependencyArchive.h"
+#include "cmState.h"
+#include "cmStringAlgorithms.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
-#include "cm_sys_stat.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
+# include "cm_curl.h"
+
# include "cmCurl.h"
# include "cmFileLockResult.h"
-# include "cm_curl.h"
#endif
#if defined(CMAKE_USE_ELF_PARSER)
@@ -53,10 +63,12 @@
# include <windows.h>
#endif
+namespace {
+
#if defined(_WIN32)
// libcurl doesn't support file:// urls for unicode filenames on Windows.
// Convert string from UTF-8 to ACP if this is a file:// URL.
-static std::string fix_file_url_windows(const std::string& url)
+std::string fix_file_url_windows(const std::string& url)
{
std::string ret = url;
if (strncmp(url.c_str(), "file://", 7) == 0) {
@@ -78,137 +90,25 @@ static std::string fix_file_url_windows(const std::string& url)
}
#endif
-// cmLibraryCommand
-bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool HandleWriteImpl(std::vector<std::string> const& args, bool append,
+ cmExecutionStatus& status)
{
- if (args.size() < 2) {
- this->SetError("must be called with at least two arguments.");
- return false;
- }
- std::string const& subCommand = args[0];
- if (subCommand == "WRITE") {
- return this->HandleWriteCommand(args, false);
- }
- if (subCommand == "APPEND") {
- return this->HandleWriteCommand(args, true);
- }
- if (subCommand == "DOWNLOAD") {
- return this->HandleDownloadCommand(args);
- }
- if (subCommand == "UPLOAD") {
- return this->HandleUploadCommand(args);
- }
- if (subCommand == "READ") {
- return this->HandleReadCommand(args);
- }
- if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
- subCommand == "SHA256" || subCommand == "SHA384" ||
- subCommand == "SHA512" || subCommand == "SHA3_224" ||
- subCommand == "SHA3_256" || subCommand == "SHA3_384" ||
- subCommand == "SHA3_512") {
- return this->HandleHashCommand(args);
- }
- if (subCommand == "STRINGS") {
- return this->HandleStringsCommand(args);
- }
- if (subCommand == "GLOB") {
- return this->HandleGlobCommand(args, false);
- }
- if (subCommand == "GLOB_RECURSE") {
- return this->HandleGlobCommand(args, true);
- }
- if (subCommand == "MAKE_DIRECTORY") {
- return this->HandleMakeDirectoryCommand(args);
- }
- if (subCommand == "RENAME") {
- return this->HandleRename(args);
- }
- if (subCommand == "REMOVE") {
- return this->HandleRemove(args, false);
- }
- if (subCommand == "REMOVE_RECURSE") {
- return this->HandleRemove(args, true);
- }
- if (subCommand == "COPY") {
- return this->HandleCopyCommand(args);
- }
- if (subCommand == "INSTALL") {
- return this->HandleInstallCommand(args);
- }
- if (subCommand == "DIFFERENT") {
- return this->HandleDifferentCommand(args);
- }
- if (subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH") {
- return this->HandleRPathChangeCommand(args);
- }
- if (subCommand == "RPATH_CHECK") {
- return this->HandleRPathCheckCommand(args);
- }
- if (subCommand == "RPATH_REMOVE") {
- return this->HandleRPathRemoveCommand(args);
- }
- if (subCommand == "READ_ELF") {
- return this->HandleReadElfCommand(args);
- }
- if (subCommand == "RELATIVE_PATH") {
- return this->HandleRelativePathCommand(args);
- }
- if (subCommand == "TO_CMAKE_PATH") {
- return this->HandleCMakePathCommand(args, false);
- }
- if (subCommand == "TO_NATIVE_PATH") {
- return this->HandleCMakePathCommand(args, true);
- }
- if (subCommand == "TOUCH") {
- return this->HandleTouchCommand(args, true);
- }
- if (subCommand == "TOUCH_NOCREATE") {
- return this->HandleTouchCommand(args, false);
- }
- if (subCommand == "TIMESTAMP") {
- return this->HandleTimestampCommand(args);
- }
- if (subCommand == "GENERATE") {
- return this->HandleGenerateCommand(args);
- }
- if (subCommand == "LOCK") {
- return this->HandleLockCommand(args);
- }
- if (subCommand == "SIZE") {
- return this->HandleSizeCommand(args);
- }
- if (subCommand == "READ_SYMLINK") {
- return this->HandleReadSymlinkCommand(args);
- }
- if (subCommand == "CREATE_LINK") {
- return this->HandleCreateLinkCommand(args);
- }
-
- std::string e = "does not recognize sub-command " + subCommand;
- this->SetError(e);
- return false;
-}
-
-bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
- bool append)
-{
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
i++; // Get rid of subcommand
std::string fileName = *i;
if (!cmsys::SystemTools::FileIsFullPath(*i)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
- fileName += "/" + *i;
+ fileName =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
}
i++;
- if (!this->Makefile->CanIWriteThisFile(fileName)) {
+ if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
std::string e =
"attempted to write a file: " + fileName + " into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -236,21 +136,19 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
cmsys::ofstream file(fileName.c_str(),
append ? std::ios::app : std::ios::out);
if (!file) {
- std::string error = "failed to open for writing (";
- error += cmSystemTools::GetLastSystemError();
- error += "):\n ";
- error += fileName;
- this->SetError(error);
+ std::string error =
+ cmStrCat("failed to open for writing (",
+ cmSystemTools::GetLastSystemError(), "):\n ", fileName);
+ status.SetError(error);
return false;
}
std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
file << message;
if (!file) {
- std::string error = "write failed (";
- error += cmSystemTools::GetLastSystemError();
- error += "):\n ";
- error += fileName;
- this->SetError(error);
+ std::string error =
+ cmStrCat("write failed (", cmSystemTools::GetLastSystemError(), "):\n ",
+ fileName);
+ status.SetError(error);
return false;
}
file.close();
@@ -260,11 +158,24 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
return true;
}
-bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
+bool HandleWriteCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleWriteImpl(args, false, status);
+}
+
+bool HandleAppendCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleWriteImpl(args, true, status);
+}
+
+bool HandleReadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("READ must be called with at least two additional "
- "arguments");
+ status.SetError("READ must be called with at least two additional "
+ "arguments");
return false;
}
@@ -287,8 +198,8 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
std::string fileName = fileNameArg;
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
- fileName += "/" + fileNameArg;
+ fileName = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
+ fileNameArg);
}
// Open the specified file.
@@ -301,11 +212,10 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
#endif
if (!file) {
- std::string error = "failed to open for reading (";
- error += cmSystemTools::GetLastSystemError();
- error += "):\n ";
- error += fileName;
- this->SetError(error);
+ std::string error =
+ cmStrCat("failed to open for reading (",
+ cmSystemTools::GetLastSystemError(), "):\n ", fileName);
+ status.SetError(error);
return false;
}
@@ -357,53 +267,50 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
}
}
}
- this->Makefile->AddDefinition(variable, output.c_str());
+ status.GetMakefile().AddDefinition(variable, output);
return true;
}
-bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
+bool HandleHashCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() != 3) {
- std::ostringstream e;
- e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " requires a file name and output variable"));
return false;
}
- std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
+ std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0]));
if (hash) {
std::string out = hash->HashFile(args[1]);
if (!out.empty()) {
- this->Makefile->AddDefinition(args[2], out.c_str());
+ status.GetMakefile().AddDefinition(args[2], out);
return true;
}
- std::ostringstream e;
- e << args[0] << " failed to read file \"" << args[1]
- << "\": " << cmSystemTools::GetLastSystemError();
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " failed to read file \"", args[1],
+ "\": ", cmSystemTools::GetLastSystemError()));
}
return false;
#else
- std::ostringstream e;
- e << args[0] << " not available during bootstrap";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " not available during bootstrap"));
return false;
#endif
}
-bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
+bool HandleStringsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("STRINGS requires a file name and output variable");
+ status.SetError("STRINGS requires a file name and output variable");
return false;
}
// Get the file to read.
std::string fileName = args[1];
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
- fileName += "/" + args[1];
+ fileName =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
}
// Get the variable in which to store the results.
@@ -466,30 +373,24 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
} else if (arg_mode == arg_limit_input) {
if (sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
limit_input < 0) {
- std::ostringstream e;
- e << "STRINGS option LIMIT_INPUT value \"" << args[i]
- << "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option LIMIT_INPUT value \"",
+ args[i], "\" is not an unsigned integer."));
return false;
}
arg_mode = arg_none;
} else if (arg_mode == arg_limit_output) {
if (sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
limit_output < 0) {
- std::ostringstream e;
- e << "STRINGS option LIMIT_OUTPUT value \"" << args[i]
- << "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option LIMIT_OUTPUT value \"",
+ args[i], "\" is not an unsigned integer."));
return false;
}
arg_mode = arg_none;
} else if (arg_mode == arg_limit_count) {
int count;
if (sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0) {
- std::ostringstream e;
- e << "STRINGS option LIMIT_COUNT value \"" << args[i]
- << "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option LIMIT_COUNT value \"",
+ args[i], "\" is not an unsigned integer."));
return false;
}
limit_count = count;
@@ -497,10 +398,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
} else if (arg_mode == arg_length_minimum) {
int len;
if (sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) {
- std::ostringstream e;
- e << "STRINGS option LENGTH_MINIMUM value \"" << args[i]
- << "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option LENGTH_MINIMUM value \"",
+ args[i], "\" is not an unsigned integer."));
return false;
}
minlen = len;
@@ -508,20 +407,16 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
} else if (arg_mode == arg_length_maximum) {
int len;
if (sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) {
- std::ostringstream e;
- e << "STRINGS option LENGTH_MAXIMUM value \"" << args[i]
- << "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option LENGTH_MAXIMUM value \"",
+ args[i], "\" is not an unsigned integer."));
return false;
}
maxlen = len;
arg_mode = arg_none;
} else if (arg_mode == arg_regex) {
if (!regex.compile(args[i])) {
- std::ostringstream e;
- e << "STRINGS option REGEX value \"" << args[i]
- << "\" could not be compiled.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option REGEX value \"", args[i],
+ "\" could not be compiled."));
return false;
}
have_regex = true;
@@ -538,25 +433,23 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
} else if (args[i] == "UTF-32BE") {
encoding = encoding_utf32be;
} else {
- std::ostringstream e;
- e << "STRINGS option ENCODING \"" << args[i] << "\" not recognized.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("STRINGS option ENCODING \"", args[i],
+ "\" not recognized."));
return false;
}
arg_mode = arg_none;
} else {
- std::ostringstream e;
- e << "STRINGS given unknown argument \"" << args[i] << "\"";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("STRINGS given unknown argument \"", args[i], "\""));
return false;
}
}
if (hex_conversion_enabled) {
// TODO: should work without temp file, but just on a memory buffer
- std::string binaryFileName = this->Makefile->GetCurrentBinaryDirectory();
- binaryFileName += "/CMakeFiles";
- binaryFileName += "/FileCommandStringsBinaryFile";
+ std::string binaryFileName =
+ cmStrCat(status.GetMakefile().GetCurrentBinaryDirectory(),
+ "/CMakeFiles/FileCommandStringsBinaryFile");
if (cmHexFileConverter::TryConvert(fileName, binaryFileName)) {
fileName = binaryFileName;
}
@@ -569,9 +462,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
cmsys::ifstream fin(fileName.c_str());
#endif
if (!fin) {
- std::ostringstream e;
- e << "STRINGS file \"" << fileName << "\" cannot be read.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("STRINGS file \"", fileName, "\" cannot be read."));
return false;
}
@@ -743,17 +635,17 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
}
// Save the output in a makefile variable.
- this->Makefile->AddDefinition(outVar, output.c_str());
+ status.GetMakefile().AddDefinition(outVar, output);
return true;
}
-bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
- bool recurse)
+bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
+ cmExecutionStatus& status)
{
// File commands has at least one argument
assert(args.size() > 1);
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
i++; // Get rid of subcommand
@@ -763,10 +655,10 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
g.SetRecurse(recurse);
bool explicitFollowSymlinks = false;
- cmPolicies::PolicyStatus status =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0009);
+ cmPolicies::PolicyStatus policyStatus =
+ status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0009);
if (recurse) {
- switch (status) {
+ switch (policyStatus) {
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
@@ -784,24 +676,24 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
bool warnConfigureLate = false;
bool warnFollowedSymlinks = false;
const cmake::WorkingMode workingMode =
- this->Makefile->GetCMakeInstance()->GetWorkingMode();
+ status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
while (i != args.end()) {
if (*i == "LIST_DIRECTORIES") {
++i; // skip LIST_DIRECTORIES
if (i != args.end()) {
- if (cmSystemTools::IsOn(*i)) {
+ if (cmIsOn(*i)) {
g.SetListDirs(true);
g.SetRecurseListDirs(true);
- } else if (cmSystemTools::IsOff(*i)) {
+ } else if (cmIsOff(*i)) {
g.SetListDirs(false);
g.SetRecurseListDirs(false);
} else {
- this->SetError("LIST_DIRECTORIES missing bool value.");
+ status.SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
++i;
} else {
- this->SetError("LIST_DIRECTORIES missing bool value.");
+ status.SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
} else if (*i == "FOLLOW_SYMLINKS") {
@@ -810,7 +702,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
explicitFollowSymlinks = true;
g.RecurseThroughSymlinksOn();
if (i == args.end()) {
- this->SetError(
+ status.SetError(
"GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS.");
return false;
}
@@ -818,25 +710,26 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
} else if (*i == "RELATIVE") {
++i; // skip RELATIVE
if (i == args.end()) {
- this->SetError("GLOB requires a directory after the RELATIVE tag.");
+ status.SetError("GLOB requires a directory after the RELATIVE tag.");
return false;
}
g.SetRelative(i->c_str());
++i;
if (i == args.end()) {
- this->SetError("GLOB requires a glob expression after the directory.");
+ status.SetError(
+ "GLOB requires a glob expression after the directory.");
return false;
}
} else if (*i == "CONFIGURE_DEPENDS") {
// Generated build system depends on glob results
if (!configureDepends && warnConfigureLate) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
"CONFIGURE_DEPENDS flag was given after a glob expression was "
"already evaluated.");
}
if (workingMode != cmake::NORMAL_MODE) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"CONFIGURE_DEPENDS is invalid for script and find package modes.");
return false;
@@ -844,14 +737,14 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
configureDepends = true;
++i;
if (i == args.end()) {
- this->SetError(
+ status.SetError(
"GLOB requires a glob expression after CONFIGURE_DEPENDS.");
return false;
}
} else {
std::string expr = *i;
if (!cmsys::SystemTools::FileIsFullPath(*i)) {
- expr = this->Makefile->GetCurrentSourceDirectory();
+ expr = status.GetMakefile().GetCurrentSourceDirectory();
// Handle script mode
if (!expr.empty()) {
expr += "/" + *i;
@@ -867,12 +760,12 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
bool shouldExit = false;
for (cmsys::Glob::Message const& globMessage : globMessages) {
if (globMessage.type == cmsys::Glob::cyclicRecursion) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
"Cyclic recursion detected while globbing for '" + *i + "':\n" +
globMessage.content);
} else {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"Error has occurred while globbing for '" + *i + "' - " +
globMessage.content);
@@ -896,11 +789,11 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
std::sort(foundFiles.begin(), foundFiles.end());
foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
foundFiles.end());
- this->Makefile->GetCMakeInstance()->AddGlobCacheEntry(
+ status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry(
recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
(recurse ? g.GetRecurseThroughSymlinks() : false),
(g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable,
- this->Makefile->GetBacktrace());
+ status.GetMakefile().GetBacktrace());
} else {
warnConfigureLate = true;
}
@@ -908,7 +801,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
}
}
- switch (status) {
+ switch (policyStatus) {
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
@@ -921,7 +814,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
// Possibly unexpected old behavior *and* we actually traversed
// symlinks without being explicitly asked to: warn the author.
if (warnFollowedSymlinks) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0009));
}
@@ -930,12 +823,24 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
std::sort(files.begin(), files.end());
files.erase(std::unique(files.begin(), files.end()), files.end());
- this->Makefile->AddDefinition(variable, cmJoin(files, ";").c_str());
+ status.GetMakefile().AddDefinition(variable, cmJoin(files, ";"));
return true;
}
-bool cmFileCommand::HandleMakeDirectoryCommand(
- std::vector<std::string> const& args)
+bool HandleGlobCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleGlobImpl(args, false, status);
+}
+
+bool HandleGlobRecurseCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleGlobImpl(args, true, status);
+}
+
+bool HandleMakeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// File command has at least one argument
assert(args.size() > 1);
@@ -946,28 +851,28 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
{
const std::string* cdir = &arg;
if (!cmsys::SystemTools::FileIsFullPath(arg)) {
- expr = this->Makefile->GetCurrentSourceDirectory();
- expr += "/" + arg;
+ expr =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
cdir = &expr;
}
- if (!this->Makefile->CanIWriteThisFile(*cdir)) {
+ if (!status.GetMakefile().CanIWriteThisFile(*cdir)) {
std::string e = "attempted to create a directory: " + *cdir +
" into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!cmSystemTools::MakeDirectory(*cdir)) {
std::string error = "problem creating directory: " + *cdir;
- this->SetError(error);
+ status.SetError(error);
return false;
}
}
return true;
}
-bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args,
- bool create)
+bool HandleTouchImpl(std::vector<std::string> const& args, bool create,
+ cmExecutionStatus& status)
{
// File command has at least one argument
assert(args.size() > 1);
@@ -977,27 +882,39 @@ bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args,
{
std::string tfile = arg;
if (!cmsys::SystemTools::FileIsFullPath(tfile)) {
- tfile = this->Makefile->GetCurrentSourceDirectory();
- tfile += "/" + arg;
+ tfile =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
}
- if (!this->Makefile->CanIWriteThisFile(tfile)) {
+ if (!status.GetMakefile().CanIWriteThisFile(tfile)) {
std::string e =
"attempted to touch a file: " + tfile + " in a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!cmSystemTools::Touch(tfile, create)) {
std::string error = "problem touching file: " + tfile;
- this->SetError(error);
+ status.SetError(error);
return false;
}
}
return true;
}
-bool cmFileCommand::HandleDifferentCommand(
- std::vector<std::string> const& args)
+bool HandleTouchCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleTouchImpl(args, true, status);
+}
+
+bool HandleTouchNocreateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleTouchImpl(args, false, status);
+}
+
+bool HandleDifferentCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
/*
FILE(DIFFERENT <variable> FILES <lhs> <rhs>)
@@ -1028,41 +945,41 @@ bool cmFileCommand::HandleDifferentCommand(
file_rhs = args[i].c_str();
doing = DoingNone;
} else {
- std::ostringstream e;
- e << "DIFFERENT given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(cmStrCat("DIFFERENT given unknown argument ", args[i]));
return false;
}
}
if (!var) {
- this->SetError("DIFFERENT not given result variable name.");
+ status.SetError("DIFFERENT not given result variable name.");
return false;
}
if (!file_lhs || !file_rhs) {
- this->SetError("DIFFERENT not given FILES option with two file names.");
+ status.SetError("DIFFERENT not given FILES option with two file names.");
return false;
}
// Compare the files.
const char* result =
cmSystemTools::FilesDiffer(file_lhs, file_rhs) ? "1" : "0";
- this->Makefile->AddDefinition(var, result);
+ status.GetMakefile().AddDefinition(var, result);
return true;
}
-bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args)
+bool HandleCopyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmFileCopier copier(this);
+ cmFileCopier copier(status);
return copier.Run(args);
}
-bool cmFileCommand::HandleRPathChangeCommand(
- std::vector<std::string> const& args)
+bool HandleRPathChangeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
const char* oldRPath = nullptr;
const char* newRPath = nullptr;
+ bool removeEnvironmentRPath = false;
enum Doing
{
DoingNone,
@@ -1078,6 +995,8 @@ bool cmFileCommand::HandleRPathChangeCommand(
doing = DoingNew;
} else if (args[i] == "FILE") {
doing = DoingFile;
+ } else if (args[i] == "INSTALL_REMOVE_ENVIRONMENT_RPATH") {
+ removeEnvironmentRPath = true;
} else if (doing == DoingFile) {
file = args[i];
doing = DoingNone;
@@ -1088,62 +1007,53 @@ bool cmFileCommand::HandleRPathChangeCommand(
newRPath = args[i].c_str();
doing = DoingNone;
} else {
- std::ostringstream e;
- e << "RPATH_CHANGE given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_CHANGE given unknown argument ", args[i]));
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_CHANGE not given FILE option.");
+ status.SetError("RPATH_CHANGE not given FILE option.");
return false;
}
if (!oldRPath) {
- this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
+ status.SetError("RPATH_CHANGE not given OLD_RPATH option.");
return false;
}
if (!newRPath) {
- this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
+ status.SetError("RPATH_CHANGE not given NEW_RPATH option.");
return false;
}
if (!cmSystemTools::FileExists(file, true)) {
- std::ostringstream e;
- e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_CHANGE given FILE \"", file, "\" that does not exist."));
return false;
}
bool success = true;
cmFileTimes const ft(file);
std::string emsg;
bool changed;
- if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed)) {
- std::ostringstream e;
- /* clang-format off */
- e << "RPATH_CHANGE could not write new RPATH:\n"
- << " " << newRPath << "\n"
- << "to the file:\n"
- << " " << file << "\n"
- << emsg;
- /* clang-format on */
- this->SetError(e.str());
+
+ if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath,
+ removeEnvironmentRPath, &emsg, &changed)) {
+ status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n ",
+ newRPath, "\nto the file:\n ", file, "\n",
+ emsg));
success = false;
}
if (success) {
if (changed) {
- std::string message = "Set runtime path of \"";
- message += file;
- message += "\" to \"";
- message += newRPath;
- message += "\"";
- this->Makefile->DisplayStatus(message, -1);
+ std::string message =
+ cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"');
+ status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
}
return success;
}
-bool cmFileCommand::HandleRPathRemoveCommand(
- std::vector<std::string> const& args)
+bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
@@ -1160,20 +1070,18 @@ bool cmFileCommand::HandleRPathRemoveCommand(
file = args[i];
doing = DoingNone;
} else {
- std::ostringstream e;
- e << "RPATH_REMOVE given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_REMOVE given unknown argument ", args[i]));
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_REMOVE not given FILE option.");
+ status.SetError("RPATH_REMOVE not given FILE option.");
return false;
}
if (!cmSystemTools::FileExists(file, true)) {
- std::ostringstream e;
- e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_REMOVE given FILE \"", file, "\" that does not exist."));
return false;
}
bool success = true;
@@ -1181,29 +1089,24 @@ bool cmFileCommand::HandleRPathRemoveCommand(
std::string emsg;
bool removed;
if (!cmSystemTools::RemoveRPath(file, &emsg, &removed)) {
- std::ostringstream e;
- /* clang-format off */
- e << "RPATH_REMOVE could not remove RPATH from file:\n"
- << " " << file << "\n"
- << emsg;
- /* clang-format on */
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_REMOVE could not remove RPATH from file: \n ", file,
+ "\n", emsg));
success = false;
}
if (success) {
if (removed) {
- std::string message = "Removed runtime path from \"";
- message += file;
- message += "\"";
- this->Makefile->DisplayStatus(message, -1);
+ std::string message =
+ cmStrCat("Removed runtime path from \"", file, '"');
+ status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
}
return success;
}
-bool cmFileCommand::HandleRPathCheckCommand(
- std::vector<std::string> const& args)
+bool HandleRPathCheckCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
@@ -1227,18 +1130,17 @@ bool cmFileCommand::HandleRPathCheckCommand(
rpath = args[i].c_str();
doing = DoingNone;
} else {
- std::ostringstream e;
- e << "RPATH_CHECK given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("RPATH_CHECK given unknown argument ", args[i]));
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_CHECK not given FILE option.");
+ status.SetError("RPATH_CHECK not given FILE option.");
return false;
}
if (!rpath) {
- this->SetError("RPATH_CHECK not given RPATH option.");
+ status.SetError("RPATH_CHECK not given RPATH option.");
return false;
}
@@ -1253,11 +1155,12 @@ bool cmFileCommand::HandleRPathCheckCommand(
return true;
}
-bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
+bool HandleReadElfCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 4) {
- this->SetError("READ_ELF must be called with at least three additional "
- "arguments.");
+ status.SetError("READ_ELF must be called with at least three additional "
+ "arguments.");
return false;
}
@@ -1277,9 +1180,8 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2));
if (!cmSystemTools::FileExists(fileNameArg, true)) {
- std::ostringstream e;
- e << "READ_ELF given FILE \"" << fileNameArg << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg,
+ "\" that does not exist."));
return false;
}
@@ -1290,14 +1192,14 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
std::string rpath(se_rpath->Value);
std::replace(rpath.begin(), rpath.end(), ':', ';');
- this->Makefile->AddDefinition(arguments.RPath, rpath.c_str());
+ status.GetMakefile().AddDefinition(arguments.RPath, rpath);
}
}
if (!arguments.RunPath.empty()) {
if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
std::string runpath(se_runpath->Value);
std::replace(runpath.begin(), runpath.end(), ':', ';');
- this->Makefile->AddDefinition(arguments.RunPath, runpath.c_str());
+ status.GetMakefile().AddDefinition(arguments.RunPath, runpath);
}
}
@@ -1305,25 +1207,26 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
#else
std::string error = "ELF parser not available on this platform.";
if (arguments.Error.empty()) {
- this->SetError(error);
+ status.SetError(error);
return false;
}
- this->Makefile->AddDefinition(arguments.Error, error.c_str());
+ status.GetMakefile().AddDefinition(arguments.Error, error);
return true;
#endif
}
-bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
+bool HandleInstallCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmFileInstaller installer(this);
+ cmFileInstaller installer(status);
return installer.Run(args);
}
-bool cmFileCommand::HandleRelativePathCommand(
- std::vector<std::string> const& args)
+bool HandleRelativePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 4) {
- this->SetError("RELATIVE_PATH called with incorrect number of arguments");
+ status.SetError("RELATIVE_PATH called with incorrect number of arguments");
return false;
}
@@ -1335,58 +1238,52 @@ bool cmFileCommand::HandleRelativePathCommand(
std::string errstring =
"RELATIVE_PATH must be passed a full path to the directory: " +
directoryName;
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
if (!cmSystemTools::FileIsFullPath(fileName)) {
std::string errstring =
"RELATIVE_PATH must be passed a full path to the file: " + fileName;
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
std::string res = cmSystemTools::RelativePath(directoryName, fileName);
- this->Makefile->AddDefinition(outVar, res.c_str());
+ status.GetMakefile().AddDefinition(outVar, res);
return true;
}
-bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
+bool HandleRename(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("RENAME given incorrect number of arguments.");
+ status.SetError("RENAME given incorrect number of arguments.");
return false;
}
// Compute full path for old and new names.
std::string oldname = args[1];
if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
- oldname = this->Makefile->GetCurrentSourceDirectory();
- oldname += "/" + args[1];
+ oldname =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
}
std::string newname = args[2];
if (!cmsys::SystemTools::FileIsFullPath(newname)) {
- newname = this->Makefile->GetCurrentSourceDirectory();
- newname += "/" + args[2];
+ newname =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
}
if (!cmSystemTools::RenameFile(oldname, newname)) {
std::string err = cmSystemTools::GetLastSystemError();
- std::ostringstream e;
- /* clang-format off */
- e << "RENAME failed to rename\n"
- << " " << oldname << "\n"
- << "to\n"
- << " " << newname << "\n"
- << "because: " << err << "\n";
- /* clang-format on */
- this->SetError(e.str());
+ status.SetError(cmStrCat("RENAME failed to rename\n ", oldname,
+ "\nto\n ", newname, "\nbecause: ", err, "\n"));
return false;
}
return true;
}
-bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
- bool recurse)
+bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
+ cmExecutionStatus& status)
{
std::string message;
@@ -1397,18 +1294,18 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
std::string fileName = arg;
if (fileName.empty()) {
std::string const r = recurse ? "REMOVE_RECURSE" : "REMOVE";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- "Ignoring empty file name in " + r + ".");
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING, "Ignoring empty file name in " + r + ".");
continue;
}
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
- fileName += "/" + arg;
+ fileName =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
}
if (cmSystemTools::FileIsDirectory(fileName) &&
!cmSystemTools::FileIsSymlink(fileName) && recurse) {
- cmSystemTools::RemoveADirectory(fileName);
+ cmSystemTools::RepeatedRemoveDirectory(fileName);
} else {
cmSystemTools::RemoveFile(fileName);
}
@@ -1416,7 +1313,18 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
return true;
}
-namespace {
+bool HandleRemove(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleRemoveImpl(args, false, status);
+}
+
+bool HandleRemoveRecurse(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleRemoveImpl(args, true, status);
+}
+
std::string ToNativePath(const std::string& path)
{
const auto& outPath = cmSystemTools::ConvertToOutputPath(path);
@@ -1433,14 +1341,14 @@ std::string ToCMakePath(const std::string& path)
cmSystemTools::ConvertToUnixSlashes(temp);
return temp;
}
-}
-bool cmFileCommand::HandleCMakePathCommand(
- std::vector<std::string> const& args, bool nativePath)
+bool HandlePathCommand(std::vector<std::string> const& args,
+ std::string (*convert)(std::string const&),
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
- "called with exactly three arguments.");
+ status.SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
+ "called with exactly three arguments.");
return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1450,18 +1358,27 @@ bool cmFileCommand::HandleCMakePathCommand(
#endif
std::vector<std::string> path = cmSystemTools::SplitString(args[1], pathSep);
- std::string value = cmJoin(
- cmMakeRange(path).transform(nativePath ? ToNativePath : ToCMakePath), ";");
- this->Makefile->AddDefinition(args[2], value.c_str());
+ std::string value = cmJoin(cmMakeRange(path).transform(convert), ";");
+ status.GetMakefile().AddDefinition(args[2], value);
return true;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+bool HandleCMakePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandlePathCommand(args, ToCMakePath, status);
+}
-// Stuff for curl download/upload
-typedef std::vector<char> cmFileCommandVectorOfChar;
+bool HandleNativePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandlePathCommand(args, ToNativePath, status);
+}
-namespace {
+#if !defined(CMAKE_BOOTSTRAP)
+
+// Stuff for curl download/upload
+using cmFileCommandVectorOfChar = std::vector<char>;
size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data)
{
@@ -1513,11 +1430,10 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
class cURLProgressHelper
{
public:
- cURLProgressHelper(cmFileCommand* fc, const char* text)
+ cURLProgressHelper(cmMakefile* mf, const char* text)
+ : Makefile(mf)
+ , Text(text)
{
- this->CurrentPercentage = -1;
- this->FileCommand = fc;
- this->Text = text;
}
bool UpdatePercentage(double value, double total, std::string& status)
@@ -1535,20 +1451,18 @@ public:
bool updated = (OldPercentage != this->CurrentPercentage);
if (updated) {
- std::ostringstream oss;
- oss << "[" << this->Text << " " << this->CurrentPercentage
- << "% complete]";
- status = oss.str();
+ status =
+ cmStrCat("[", this->Text, " ", this->CurrentPercentage, "% complete]");
}
return updated;
}
- cmFileCommand* GetFileCommand() { return this->FileCommand; }
+ cmMakefile* GetMakefile() { return this->Makefile; }
private:
- long CurrentPercentage;
- cmFileCommand* FileCommand;
+ long CurrentPercentage = -1;
+ cmMakefile* Makefile;
std::string Text;
};
@@ -1562,8 +1476,7 @@ int cmFileDownloadProgressCallback(void* clientp, double dltotal, double dlnow,
std::string status;
if (helper->UpdatePercentage(dlnow, dltotal, status)) {
- cmFileCommand* fc = helper->GetFileCommand();
- cmMakefile* mf = fc->GetMakefile();
+ cmMakefile* mf = helper->GetMakefile();
mf->DisplayStatus(status, -1);
}
@@ -1580,16 +1493,12 @@ int cmFileUploadProgressCallback(void* clientp, double dltotal, double dlnow,
std::string status;
if (helper->UpdatePercentage(ulnow, ultotal, status)) {
- cmFileCommand* fc = helper->GetFileCommand();
- cmMakefile* mf = fc->GetMakefile();
+ cmMakefile* mf = helper->GetMakefile();
mf->DisplayStatus(status, -1);
}
return 0;
}
-}
-
-namespace {
class cURLEasyGuard
{
@@ -1614,7 +1523,7 @@ public:
private:
::CURL* Easy;
};
-}
+
#endif
#define check_curl_result(result, errstr) \
@@ -1622,17 +1531,18 @@ private:
if (result != CURLE_OK) { \
std::string e(errstr); \
e += ::curl_easy_strerror(result); \
- this->SetError(e); \
+ status.SetError(e); \
return false; \
} \
} while (false)
-bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
+bool HandleDownloadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- std::vector<std::string>::const_iterator i = args.begin();
+#if !defined(CMAKE_BOOTSTRAP)
+ auto i = args.begin();
if (args.size() < 3) {
- this->SetError("DOWNLOAD must be called with at least three arguments.");
+ status.SetError("DOWNLOAD must be called with at least three arguments.");
return false;
}
++i; // Get rid of subcommand
@@ -1645,11 +1555,12 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
long inactivity_timeout = 0;
std::string logVar;
std::string statusVar;
- bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
- const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
- std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY");
+ const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
+ std::string netrc_level =
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
- this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");
std::string expectedHash;
std::string hashMatchMSG;
std::unique_ptr<cmCryptoHash> hash;
@@ -1664,7 +1575,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
timeout = atol(i->c_str());
} else {
- this->SetError("DOWNLOAD missing time for TIMEOUT.");
+ status.SetError("DOWNLOAD missing time for TIMEOUT.");
return false;
}
} else if (*i == "INACTIVITY_TIMEOUT") {
@@ -1672,29 +1583,29 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
inactivity_timeout = atol(i->c_str());
} else {
- this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
+ status.SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
return false;
}
} else if (*i == "LOG") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing VAR for LOG.");
+ status.SetError("DOWNLOAD missing VAR for LOG.");
return false;
}
logVar = *i;
} else if (*i == "STATUS") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing VAR for STATUS.");
+ status.SetError("DOWNLOAD missing VAR for STATUS.");
return false;
}
statusVar = *i;
} else if (*i == "TLS_VERIFY") {
++i;
if (i != args.end()) {
- tls_verify = cmSystemTools::IsOn(*i);
+ tls_verify = cmIsOn(*i);
} else {
- this->SetError("TLS_VERIFY missing bool value.");
+ status.SetError("TLS_VERIFY missing bool value.");
return false;
}
} else if (*i == "TLS_CAINFO") {
@@ -1702,7 +1613,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
cainfo = i->c_str();
} else {
- this->SetError("TLS_CAFILE missing file value.");
+ status.SetError("TLS_CAFILE missing file value.");
return false;
}
} else if (*i == "NETRC_FILE") {
@@ -1710,7 +1621,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
netrc_file = *i;
} else {
- this->SetError("DOWNLOAD missing file value for NETRC_FILE.");
+ status.SetError("DOWNLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
@@ -1718,13 +1629,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
netrc_level = *i;
} else {
- this->SetError("DOWNLOAD missing level value for NETRC.");
+ status.SetError("DOWNLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "EXPECTED_MD5") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
+ status.SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
return false;
}
hash = cm::make_unique<cmCryptoHash>(cmCryptoHash::AlgoMD5);
@@ -1735,46 +1646,44 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
} else if (*i == "EXPECTED_HASH") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
+ status.SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
return false;
}
std::string::size_type pos = i->find("=");
if (pos == std::string::npos) {
std::string err =
- "DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ";
- err += *i;
- this->SetError(err);
+ cmStrCat("DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ", *i);
+ status.SetError(err);
return false;
}
std::string algo = i->substr(0, pos);
expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1));
- hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo.c_str()));
+ hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo));
if (!hash) {
- std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: ";
- err += algo;
- this->SetError(err);
+ std::string err =
+ cmStrCat("DOWNLOAD EXPECTED_HASH given unknown ALGO: ", algo);
+ status.SetError(err);
return false;
}
hashMatchMSG = algo + " hash";
} else if (*i == "USERPWD") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing string for USERPWD.");
+ status.SetError("DOWNLOAD missing string for USERPWD.");
return false;
}
userpwd = *i;
} else if (*i == "HTTPHEADER") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing string for HTTPHEADER.");
+ status.SetError("DOWNLOAD missing string for HTTPHEADER.");
return false;
}
curl_headers.push_back(*i);
} else {
// Do not return error for compatibility reason.
- std::string err = "Unexpected argument: ";
- err += *i;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err);
+ std::string err = cmStrCat("Unexpected argument: ", *i);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err);
}
++i;
}
@@ -1786,13 +1695,10 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string msg;
std::string actualHash = hash->HashFile(file);
if (actualHash == expectedHash) {
- msg = "returning early; file already exists with expected ";
- msg += hashMatchMSG;
- msg += "\"";
+ msg = cmStrCat("returning early; file already exists with expected ",
+ hashMatchMSG, '"');
if (!statusVar.empty()) {
- std::ostringstream result;
- result << 0 << ";\"" << msg;
- this->Makefile->AddDefinition(statusVar, result.str().c_str());
+ status.GetMakefile().AddDefinition(statusVar, cmStrCat(0, ";\"", msg));
}
return true;
}
@@ -1805,13 +1711,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
"' - Specify file by full path name and verify that you "
"have directory creation and file write privileges.";
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
cmsys::ofstream fout(file.c_str(), std::ios::binary);
if (!fout) {
- this->SetError("DOWNLOAD cannot open file for write.");
+ status.SetError("DOWNLOAD cannot open file for write.");
return false;
}
@@ -1823,7 +1729,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
if (!curl) {
- this->SetError("DOWNLOAD error initializing curl.");
+ status.SetError("DOWNLOAD error initializing curl.");
return false;
}
@@ -1857,7 +1763,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
// command arg comes first
std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
if (!cainfo_err.empty()) {
- this->SetError(cainfo_err);
+ status.SetError(cainfo_err);
return false;
}
@@ -1867,7 +1773,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
- this->SetError(netrc_option_err);
+ status.SetError(netrc_option_err);
return false;
}
@@ -1903,7 +1809,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
// scope intentionally, rather than inside the "if(showProgress)"
// block...
//
- cURLProgressHelper helper(this, "download");
+ cURLProgressHelper helper(&status.GetMakefile(), "download");
if (showProgress) {
res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
@@ -1938,10 +1844,9 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
::curl_easy_cleanup(curl);
if (!statusVar.empty()) {
- std::ostringstream result;
- result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
- << "\"";
- this->Makefile->AddDefinition(statusVar, result.str().c_str());
+ status.GetMakefile().AddDefinition(
+ statusVar,
+ cmStrCat(static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\""));
}
::curl_global_cleanup();
@@ -1956,51 +1861,57 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (hash) {
std::string actualHash = hash->HashFile(file);
if (actualHash.empty()) {
- this->SetError("DOWNLOAD cannot compute hash on downloaded file");
+ status.SetError("DOWNLOAD cannot compute hash on downloaded file");
return false;
}
if (expectedHash != actualHash) {
- std::ostringstream oss;
- oss << "DOWNLOAD HASH mismatch" << std::endl
- << " for file: [" << file << "]" << std::endl
- << " expected hash: [" << expectedHash << "]" << std::endl
- << " actual hash: [" << actualHash << "]" << std::endl
- << " status: [" << static_cast<int>(res) << ";\""
- << ::curl_easy_strerror(res) << "\"]" << std::endl;
-
if (!statusVar.empty() && res == 0) {
- std::string status = "1;HASH mismatch: "
- "expected: " +
- expectedHash + " actual: " + actualHash;
- this->Makefile->AddDefinition(statusVar, status.c_str());
+ status.GetMakefile().AddDefinition(statusVar,
+ "1;HASH mismatch: "
+ "expected: " +
+ expectedHash +
+ " actual: " + actualHash);
}
- this->SetError(oss.str());
+ status.SetError(cmStrCat("DOWNLOAD HASH mismatch\n"
+ " for file: [",
+ file,
+ "]\n"
+ " expected hash: [",
+ expectedHash,
+ "]\n"
+ " actual hash: [",
+ actualHash,
+ "]\n"
+ " status: [",
+ static_cast<int>(res), ";\"",
+ ::curl_easy_strerror(res), "\"]\n"));
return false;
}
}
if (!logVar.empty()) {
chunkDebug.push_back(0);
- this->Makefile->AddDefinition(logVar, chunkDebug.data());
+ status.GetMakefile().AddDefinition(logVar, chunkDebug.data());
}
return true;
#else
- this->SetError("DOWNLOAD not supported by bootstrap cmake.");
+ status.SetError("DOWNLOAD not supported by bootstrap cmake.");
return false;
#endif
}
-bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
+bool HandleUploadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() < 3) {
- this->SetError("UPLOAD must be called with at least three arguments.");
+ status.SetError("UPLOAD must be called with at least three arguments.");
return false;
}
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
++i;
std::string filename = *i;
++i;
@@ -2013,9 +1924,10 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
std::string statusVar;
bool showProgress = false;
std::string userpwd;
- std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ std::string netrc_level =
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
- this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");
std::vector<std::string> curl_headers;
@@ -2025,7 +1937,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
timeout = atol(i->c_str());
} else {
- this->SetError("UPLOAD missing time for TIMEOUT.");
+ status.SetError("UPLOAD missing time for TIMEOUT.");
return false;
}
} else if (*i == "INACTIVITY_TIMEOUT") {
@@ -2033,20 +1945,20 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
inactivity_timeout = atol(i->c_str());
} else {
- this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
+ status.SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
return false;
}
} else if (*i == "LOG") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing VAR for LOG.");
+ status.SetError("UPLOAD missing VAR for LOG.");
return false;
}
logVar = *i;
} else if (*i == "STATUS") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing VAR for STATUS.");
+ status.SetError("UPLOAD missing VAR for STATUS.");
return false;
}
statusVar = *i;
@@ -2057,7 +1969,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
netrc_file = *i;
} else {
- this->SetError("UPLOAD missing file value for NETRC_FILE.");
+ status.SetError("UPLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
@@ -2065,28 +1977,27 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
if (i != args.end()) {
netrc_level = *i;
} else {
- this->SetError("UPLOAD missing level value for NETRC.");
+ status.SetError("UPLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "USERPWD") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing string for USERPWD.");
+ status.SetError("UPLOAD missing string for USERPWD.");
return false;
}
userpwd = *i;
} else if (*i == "HTTPHEADER") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing string for HTTPHEADER.");
+ status.SetError("UPLOAD missing string for HTTPHEADER.");
return false;
}
curl_headers.push_back(*i);
} else {
// Do not return error for compatibility reason.
- std::string err = "Unexpected argument: ";
- err += *i;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err);
+ std::string err = cmStrCat("Unexpected argument: ", *i);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err);
}
++i;
@@ -2096,9 +2007,9 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
//
FILE* fin = cmsys::SystemTools::Fopen(filename, "rb");
if (!fin) {
- std::string errStr = "UPLOAD cannot open file '";
- errStr += filename + "' for reading.";
- this->SetError(errStr);
+ std::string errStr =
+ cmStrCat("UPLOAD cannot open file '", filename, "' for reading.");
+ status.SetError(errStr);
return false;
}
@@ -2112,7 +2023,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
if (!curl) {
- this->SetError("UPLOAD error initializing curl.");
+ status.SetError("UPLOAD error initializing curl.");
fclose(fin);
return false;
}
@@ -2171,7 +2082,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// scope intentionally, rather than inside the "if(showProgress)"
// block...
//
- cURLProgressHelper helper(this, "upload");
+ cURLProgressHelper helper(&status.GetMakefile(), "upload");
if (showProgress) {
res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
@@ -2206,7 +2117,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
- this->SetError(netrc_option_err);
+ status.SetError(netrc_option_err);
return false;
}
@@ -2225,10 +2136,9 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
::curl_easy_cleanup(curl);
if (!statusVar.empty()) {
- std::ostringstream result;
- result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
- << "\"";
- this->Makefile->AddDefinition(statusVar, result.str().c_str());
+ status.GetMakefile().AddDefinition(
+ statusVar,
+ cmStrCat(static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\""));
}
::curl_global_cleanup();
@@ -2253,22 +2163,22 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
log += "\n";
}
- this->Makefile->AddDefinition(logVar, log.c_str());
+ status.GetMakefile().AddDefinition(logVar, log);
}
return true;
#else
- this->SetError("UPLOAD not supported by bootstrap cmake.");
+ status.SetError("UPLOAD not supported by bootstrap cmake.");
return false;
#endif
}
-void cmFileCommand::AddEvaluationFile(const std::string& inputName,
- const std::string& outputExpr,
- const std::string& condition,
- bool inputIsContent)
+void AddEvaluationFile(const std::string& inputName,
+ const std::string& outputExpr,
+ const std::string& condition, bool inputIsContent,
+ cmExecutionStatus& status)
{
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
cmGeneratorExpression outputGe(lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> outputCge =
@@ -2278,52 +2188,54 @@ void cmFileCommand::AddEvaluationFile(const std::string& inputName,
std::unique_ptr<cmCompiledGeneratorExpression> conditionCge =
conditionGe.Parse(condition);
- this->Makefile->AddEvaluationFile(inputName, std::move(outputCge),
- std::move(conditionCge), inputIsContent);
+ status.GetMakefile().AddEvaluationFile(
+ inputName, std::move(outputCge), std::move(conditionCge), inputIsContent);
}
-bool cmFileCommand::HandleGenerateCommand(std::vector<std::string> const& args)
+bool HandleGenerateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 5) {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
if (args[1] != "OUTPUT") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
std::string condition;
if (args.size() > 5) {
if (args[5] != "CONDITION") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
if (args.size() != 7) {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
condition = args[6];
if (condition.empty()) {
- this->SetError("CONDITION of sub-command GENERATE must not be empty if "
- "specified.");
+ status.SetError("CONDITION of sub-command GENERATE must not be empty if "
+ "specified.");
return false;
}
}
std::string output = args[2];
const bool inputIsContent = args[3] != "INPUT";
if (inputIsContent && args[3] != "CONTENT") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
std::string input = args[4];
- this->AddEvaluationFile(input, output, condition, inputIsContent);
+ AddEvaluationFile(input, output, condition, inputIsContent, status);
return true;
}
-bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
+bool HandleLockCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Default values
bool directory = false;
bool release = false;
@@ -2339,7 +2251,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
// Parse arguments
if (args.size() < 2) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"sub-command LOCK requires at least two arguments.");
return false;
@@ -2355,7 +2267,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
++i;
const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD";
if (i >= args.size()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, merr);
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, merr);
return false;
}
if (args[i] == "FUNCTION") {
@@ -2365,16 +2277,16 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
} else if (args[i] == "PROCESS") {
guard = GUARD_PROCESS;
} else {
- std::ostringstream e;
- e << merr << ", but got:\n \"" << args[i] << "\".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(merr, ", but got:\n \"", args[i], "\"."));
return false;
}
} else if (args[i] == "RESULT_VARIABLE") {
++i;
if (i >= args.size()) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"expected variable name after RESULT_VARIABLE");
return false;
@@ -2383,24 +2295,24 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
} else if (args[i] == "TIMEOUT") {
++i;
if (i >= args.size()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "expected timeout value after TIMEOUT");
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR, "expected timeout value after TIMEOUT");
return false;
}
long scanned;
- if (!cmSystemTools::StringToLong(args[i].c_str(), &scanned) ||
- scanned < 0) {
- std::ostringstream e;
- e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ if (!cmStrToLong(args[i], &scanned) || scanned < 0) {
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("TIMEOUT value \"", args[i],
+ "\" is not an unsigned integer."));
return false;
}
timeout = static_cast<unsigned long>(scanned);
} else {
- std::ostringstream e;
- e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n";
- e << "but got: \"" << args[i] << "\".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or ",
+ "TIMEOUT\nbut got: \"", args[i], "\"."));
return false;
}
}
@@ -2410,7 +2322,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
}
if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
+ path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path;
}
// Unify path (remove '//', '/../', ...)
@@ -2419,18 +2331,19 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
// Create file and directories if needed
std::string parentDir = cmSystemTools::GetParentDirectory(path);
if (!cmSystemTools::MakeDirectory(parentDir)) {
- std::ostringstream e;
- e << "directory\n \"" << parentDir << "\"\ncreation failed ";
- e << "(check permissions).";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("directory\n \"", parentDir,
+ "\"\ncreation failed (check permissions)."));
cmSystemTools::SetFatalErrorOccured();
return false;
}
FILE* file = cmsys::SystemTools::Fopen(path, "w");
if (!file) {
- std::ostringstream e;
- e << "file\n \"" << path << "\"\ncreation failed (check permissions).";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("file\n \"", path,
+ "\"\ncreation failed (check permissions)."));
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2438,7 +2351,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
// Actual lock/unlock
cmFileLockPool& lockPool =
- this->Makefile->GetGlobalGenerator()->GetFileLockPool();
+ status.GetMakefile().GetGlobalGenerator()->GetFileLockPool();
cmFileLockResult fileLockResult(cmFileLockResult::MakeOk());
if (release) {
@@ -2463,34 +2376,34 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
const std::string result = fileLockResult.GetOutputMessage();
if (resultVariable.empty() && !fileLockResult.IsOk()) {
- std::ostringstream e;
- e << "error locking file\n \"" << path << "\"\n" << result << ".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("error locking file\n \"", path, "\"\n", result, "."));
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!resultVariable.empty()) {
- this->Makefile->AddDefinition(resultVariable, result.c_str());
+ status.GetMakefile().AddDefinition(resultVariable, result);
}
return true;
#else
static_cast<void>(args);
- this->SetError("sub-command LOCK not implemented in bootstrap cmake");
+ status.SetError("sub-command LOCK not implemented in bootstrap cmake");
return false;
#endif
}
-bool cmFileCommand::HandleTimestampCommand(
- std::vector<std::string> const& args)
+bool HandleTimestampCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("sub-command TIMESTAMP requires at least two arguments.");
+ status.SetError("sub-command TIMESTAMP requires at least two arguments.");
return false;
}
if (args.size() > 5) {
- this->SetError("sub-command TIMESTAMP takes at most four arguments.");
+ status.SetError("sub-command TIMESTAMP takes at most four arguments.");
return false;
}
@@ -2512,7 +2425,7 @@ bool cmFileCommand::HandleTimestampCommand(
} else {
std::string e = " TIMESTAMP sub-command does not recognize option " +
args[argsIndex] + ".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
}
@@ -2520,17 +2433,17 @@ bool cmFileCommand::HandleTimestampCommand(
cmTimestamp timestamp;
std::string result =
timestamp.FileModificationTime(filename.c_str(), formatString, utcFlag);
- this->Makefile->AddDefinition(outputVariable, result.c_str());
+ status.GetMakefile().AddDefinition(outputVariable, result);
return true;
}
-bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args)
+bool HandleSizeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- std::ostringstream e;
- e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " requires a file name and output variable"));
return false;
}
@@ -2541,26 +2454,23 @@ bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args)
const std::string& outputVariable = args[argsIndex++];
if (!cmSystemTools::FileExists(filename, true)) {
- std::ostringstream e;
- e << "SIZE requested of path that is not readable:\n " << filename;
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("SIZE requested of path that is not readable:\n ", filename));
return false;
}
- this->Makefile->AddDefinition(
- outputVariable,
- std::to_string(cmSystemTools::FileLength(filename)).c_str());
+ status.GetMakefile().AddDefinition(
+ outputVariable, std::to_string(cmSystemTools::FileLength(filename)));
return true;
}
-bool cmFileCommand::HandleReadSymlinkCommand(
- std::vector<std::string> const& args)
+bool HandleReadSymlinkCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- std::ostringstream e;
- e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " requires a file name and output variable"));
return false;
}
@@ -2569,24 +2479,22 @@ bool cmFileCommand::HandleReadSymlinkCommand(
std::string result;
if (!cmSystemTools::ReadSymlink(filename, result)) {
- std::ostringstream e;
- e << "READ_SYMLINK requested of path that is not a symlink:\n "
- << filename;
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "READ_SYMLINK requested of path that is not a symlink:\n ", filename));
return false;
}
- this->Makefile->AddDefinition(outputVariable, result.c_str());
+ status.GetMakefile().AddDefinition(outputVariable, result);
return true;
}
-bool cmFileCommand::HandleCreateLinkCommand(
- std::vector<std::string> const& args)
+bool HandleCreateLinkCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("CREATE_LINK must be called with at least two additional "
- "arguments");
+ status.SetError("CREATE_LINK must be called with at least two additional "
+ "arguments");
return false;
}
@@ -2611,7 +2519,7 @@ bool cmFileCommand::HandleCreateLinkCommand(
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
if (!unconsumedArgs.empty()) {
- this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
+ status.SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
return false;
}
@@ -2622,10 +2530,10 @@ bool cmFileCommand::HandleCreateLinkCommand(
if (fileName == newFileName) {
result = "CREATE_LINK cannot use same file and newfile";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result.c_str());
+ status.GetMakefile().AddDefinition(arguments.Result, result);
return true;
}
- this->SetError(result);
+ status.SetError(result);
return false;
}
@@ -2633,10 +2541,10 @@ bool cmFileCommand::HandleCreateLinkCommand(
if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) {
result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result.c_str());
+ status.GetMakefile().AddDefinition(arguments.Result, result);
return true;
}
- this->SetError(result);
+ status.SetError(result);
return false;
}
@@ -2650,10 +2558,10 @@ bool cmFileCommand::HandleCreateLinkCommand(
<< cmSystemTools::GetLastSystemError() << "\n";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, e.str().c_str());
+ status.GetMakefile().AddDefinition(arguments.Result, e.str());
return true;
}
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -2680,13 +2588,235 @@ bool cmFileCommand::HandleCreateLinkCommand(
result = "0";
} else if (arguments.Result.empty()) {
// The operation failed and the result is not reported in a variable.
- this->SetError(result);
+ status.SetError(result);
return false;
}
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result.c_str());
+ status.GetMakefile().AddDefinition(arguments.Result, result);
}
return true;
}
+
+bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ static const std::set<std::string> supportedPlatforms = { "Windows", "Linux",
+ "Darwin" };
+ std::string platform =
+ status.GetMakefile().GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
+ if (!supportedPlatforms.count(platform)) {
+ status.SetError(
+ cmStrCat("GET_RUNTIME_DEPENDENCIES is not supported on system \"",
+ platform, "\""));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (status.GetMakefile().GetState()->GetMode() == cmState::Project) {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "You have used file(GET_RUNTIME_DEPENDENCIES)"
+ " in project mode. This is probably not what "
+ "you intended to do. Instead, please consider"
+ " using it in an install(CODE) or "
+ "install(SCRIPT) command. For example:"
+ "\n install(CODE [["
+ "\n file(GET_RUNTIME_DEPENDENCIES"
+ "\n # ..."
+ "\n )"
+ "\n ]])");
+ }
+
+ struct Arguments
+ {
+ std::string ResolvedDependenciesVar;
+ std::string UnresolvedDependenciesVar;
+ std::string ConflictingDependenciesPrefix;
+ std::string BundleExecutable;
+ std::vector<std::string> Executables;
+ std::vector<std::string> Libraries;
+ std::vector<std::string> Directories;
+ std::vector<std::string> Modules;
+ std::vector<std::string> PreIncludeRegexes;
+ std::vector<std::string> PreExcludeRegexes;
+ std::vector<std::string> PostIncludeRegexes;
+ std::vector<std::string> PostExcludeRegexes;
+ };
+
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("RESOLVED_DEPENDENCIES_VAR"_s, &Arguments::ResolvedDependenciesVar)
+ .Bind("UNRESOLVED_DEPENDENCIES_VAR"_s,
+ &Arguments::UnresolvedDependenciesVar)
+ .Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s,
+ &Arguments::ConflictingDependenciesPrefix)
+ .Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable)
+ .Bind("EXECUTABLES"_s, &Arguments::Executables)
+ .Bind("LIBRARIES"_s, &Arguments::Libraries)
+ .Bind("MODULES"_s, &Arguments::Modules)
+ .Bind("DIRECTORIES"_s, &Arguments::Directories)
+ .Bind("PRE_INCLUDE_REGEXES"_s, &Arguments::PreIncludeRegexes)
+ .Bind("PRE_EXCLUDE_REGEXES"_s, &Arguments::PreExcludeRegexes)
+ .Bind("POST_INCLUDE_REGEXES"_s, &Arguments::PostIncludeRegexes)
+ .Bind("POST_EXCLUDE_REGEXES"_s, &Arguments::PostExcludeRegexes);
+
+ 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;
+ }
+ argIt = keywordsMissingValues.begin();
+ if (argIt != keywordsMissingValues.end()) {
+ status.SetError(cmStrCat("Keyword missing value: ", *argIt));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ cmRuntimeDependencyArchive archive(
+ status, parsedArgs.Directories, parsedArgs.BundleExecutable,
+ parsedArgs.PreIncludeRegexes, parsedArgs.PreExcludeRegexes,
+ parsedArgs.PostIncludeRegexes, parsedArgs.PostExcludeRegexes);
+ if (!archive.Prepare()) {
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!archive.GetRuntimeDependencies(
+ parsedArgs.Executables, parsedArgs.Libraries, parsedArgs.Modules)) {
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ std::vector<std::string> deps;
+ std::vector<std::string> unresolvedDeps;
+ std::vector<std::string> conflictingDeps;
+ for (auto const& val : archive.GetResolvedPaths()) {
+ bool unique = true;
+ auto it = val.second.begin();
+ assert(it != val.second.end());
+ auto const& firstPath = *it;
+ while (++it != val.second.end()) {
+ if (!cmSystemTools::SameFile(firstPath, *it)) {
+ unique = false;
+ break;
+ }
+ }
+
+ if (unique) {
+ deps.push_back(firstPath);
+ } else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
+ conflictingDeps.push_back(val.first);
+ std::vector<std::string> paths;
+ paths.insert(paths.begin(), val.second.begin(), val.second.end());
+ std::string varName =
+ parsedArgs.ConflictingDependenciesPrefix + "_" + val.first;
+ std::string pathsStr = cmJoin(paths, ";");
+ status.GetMakefile().AddDefinition(varName, pathsStr);
+ } else {
+ std::ostringstream e;
+ e << "Multiple conflicting paths found for " << val.first << ":";
+ for (auto const& path : val.second) {
+ e << "\n " << path;
+ }
+ status.SetError(e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+ if (!archive.GetUnresolvedPaths().empty()) {
+ if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
+ unresolvedDeps.insert(unresolvedDeps.begin(),
+ archive.GetUnresolvedPaths().begin(),
+ archive.GetUnresolvedPaths().end());
+ } else {
+ auto it = archive.GetUnresolvedPaths().begin();
+ assert(it != archive.GetUnresolvedPaths().end());
+ status.SetError(cmStrCat("Could not resolve file ", *it));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
+ if (!parsedArgs.ResolvedDependenciesVar.empty()) {
+ std::string val = cmJoin(deps, ";");
+ status.GetMakefile().AddDefinition(parsedArgs.ResolvedDependenciesVar,
+ val);
+ }
+ if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
+ std::string val = cmJoin(unresolvedDeps, ";");
+ status.GetMakefile().AddDefinition(parsedArgs.UnresolvedDependenciesVar,
+ val);
+ }
+ if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
+ std::string val = cmJoin(conflictingDeps, ";");
+ status.GetMakefile().AddDefinition(
+ parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val);
+ }
+ return true;
+}
+
+} // namespace
+
+bool cmFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 2) {
+ status.SetError("must be called with at least two arguments.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "WRITE"_s, HandleWriteCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "DOWNLOAD"_s, HandleDownloadCommand },
+ { "UPLOAD"_s, HandleUploadCommand },
+ { "READ"_s, HandleReadCommand },
+ { "MD5"_s, HandleHashCommand },
+ { "SHA1"_s, HandleHashCommand },
+ { "SHA224"_s, HandleHashCommand },
+ { "SHA256"_s, HandleHashCommand },
+ { "SHA384"_s, HandleHashCommand },
+ { "SHA512"_s, HandleHashCommand },
+ { "SHA3_224"_s, HandleHashCommand },
+ { "SHA3_256"_s, HandleHashCommand },
+ { "SHA3_384"_s, HandleHashCommand },
+ { "SHA3_512"_s, HandleHashCommand },
+ { "STRINGS"_s, HandleStringsCommand },
+ { "GLOB"_s, HandleGlobCommand },
+ { "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
+ { "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
+ { "RENAME"_s, HandleRename },
+ { "REMOVE"_s, HandleRemove },
+ { "REMOVE_RECURSE"_s, HandleRemoveRecurse },
+ { "COPY"_s, HandleCopyCommand },
+ { "INSTALL"_s, HandleInstallCommand },
+ { "DIFFERENT"_s, HandleDifferentCommand },
+ { "RPATH_CHANGE"_s, HandleRPathChangeCommand },
+ { "CHRPATH"_s, HandleRPathChangeCommand },
+ { "RPATH_CHECK"_s, HandleRPathCheckCommand },
+ { "RPATH_REMOVE"_s, HandleRPathRemoveCommand },
+ { "READ_ELF"_s, HandleReadElfCommand },
+ { "RELATIVE_PATH"_s, HandleRelativePathCommand },
+ { "TO_CMAKE_PATH"_s, HandleCMakePathCommand },
+ { "TO_NATIVE_PATH"_s, HandleNativePathCommand },
+ { "TOUCH"_s, HandleTouchCommand },
+ { "TOUCH_NOCREATE"_s, HandleTouchNocreateCommand },
+ { "TIMESTAMP"_s, HandleTimestampCommand },
+ { "GENERATE"_s, HandleGenerateCommand },
+ { "LOCK"_s, HandleLockCommand },
+ { "SIZE"_s, HandleSizeCommand },
+ { "READ_SYMLINK"_s, HandleReadSymlinkCommand },
+ { "CREATE_LINK"_s, HandleCreateLinkCommand },
+ { "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
+ };
+
+ return subcommand(args[0], args, status);
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 12c511514..8c9b21990 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -8,65 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmFileCommand
- * \brief Command for manipulation of files
- *
- */
-class cmFileCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFileCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool HandleRename(std::vector<std::string> const& args);
- bool HandleRemove(std::vector<std::string> const& args, bool recurse);
- bool HandleWriteCommand(std::vector<std::string> const& args, bool append);
- bool HandleReadCommand(std::vector<std::string> const& args);
- bool HandleHashCommand(std::vector<std::string> const& args);
- bool HandleStringsCommand(std::vector<std::string> const& args);
- bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
- bool HandleTouchCommand(std::vector<std::string> const& args, bool create);
- bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
-
- bool HandleRelativePathCommand(std::vector<std::string> const& args);
- bool HandleCMakePathCommand(std::vector<std::string> const& args,
- bool nativePath);
- bool HandleReadElfCommand(std::vector<std::string> const& args);
- bool HandleRPathChangeCommand(std::vector<std::string> const& args);
- bool HandleRPathCheckCommand(std::vector<std::string> const& args);
- bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
- bool HandleDifferentCommand(std::vector<std::string> const& args);
-
- bool HandleCopyCommand(std::vector<std::string> const& args);
- bool HandleInstallCommand(std::vector<std::string> const& args);
- bool HandleDownloadCommand(std::vector<std::string> const& args);
- bool HandleUploadCommand(std::vector<std::string> const& args);
-
- bool HandleTimestampCommand(std::vector<std::string> const& args);
- bool HandleGenerateCommand(std::vector<std::string> const& args);
- bool HandleLockCommand(std::vector<std::string> const& args);
- bool HandleSizeCommand(std::vector<std::string> const& args);
- bool HandleReadSymlinkCommand(std::vector<std::string> const& args);
- bool HandleCreateLinkCommand(std::vector<std::string> const& args);
-
-private:
- void AddEvaluationFile(const std::string& inputName,
- const std::string& outputExpr,
- const std::string& condition, bool inputIsContent);
-};
+bool cmFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 49e8cd5b3..627e05b58 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -3,26 +3,28 @@
#include "cmFileCopier.h"
+#include "cmsys/Directory.hxx"
+#include "cmsys/Glob.hxx"
+
+#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
-#include "cmFileCommand.h"
#include "cmFileTimes.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/Glob.hxx"
#ifdef _WIN32
# include "cmsys/FStream.hxx"
#endif
+#include <cstring>
#include <sstream>
-#include <string.h>
using namespace cmFSPermissions;
-cmFileCopier::cmFileCopier(cmFileCommand* command, const char* name)
- : FileCommand(command)
- , Makefile(command->GetMakefile())
+cmFileCopier::cmFileCopier(cmExecutionStatus& status, const char* name)
+ : Status(status)
+ , Makefile(&status.GetMakefile())
, Name(name)
, Always(false)
, MatchlessFiles(true)
@@ -90,8 +92,9 @@ bool cmFileCopier::SetPermissions(const std::string& toFile,
if (!cmSystemTools::SetPermissions(toFile, permissions)) {
std::ostringstream e;
- e << this->Name << " cannot set permissions on \"" << toFile << "\"";
- this->FileCommand->SetError(e.str());
+ e << this->Name << " cannot set permissions on \"" << toFile
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
}
@@ -105,7 +108,7 @@ bool cmFileCopier::CheckPermissions(std::string const& arg,
if (!cmFSPermissions::stringToModeT(arg, permissions)) {
std::ostringstream e;
e << this->Name << " given invalid permission \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
return true;
@@ -120,8 +123,9 @@ bool cmFileCopier::ReportMissing(const std::string& fromFile)
{
// The input file does not exist and installation is not optional.
std::ostringstream e;
- e << this->Name << " cannot find \"" << fromFile << "\".";
- this->FileCommand->SetError(e.str());
+ e << this->Name << " cannot find \"" << fromFile
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
@@ -129,7 +133,7 @@ void cmFileCopier::NotBeforeMatch(std::string const& arg)
{
std::ostringstream e;
e << "option " << arg << " may not appear before PATTERN or REGEX.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
@@ -137,7 +141,7 @@ void cmFileCopier::NotAfterMatch(std::string const& arg)
{
std::ostringstream e;
e << "option " << arg << " may not appear after PATTERN or REGEX.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
@@ -170,15 +174,12 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode)
const char* default_dir_install_permissions = this->Makefile->GetDefinition(
"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (default_dir_install_permissions && *default_dir_install_permissions) {
- std::vector<std::string> items;
- cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
+ std::vector<std::string> items =
+ cmExpandedList(default_dir_install_permissions);
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
- std::ostringstream e;
- e << this->FileCommand->GetError()
- << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "
- "variable.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(
+ " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable.");
return false;
}
}
@@ -197,7 +198,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
if (!this->CheckKeyword(args[i]) && !this->CheckValue(args[i])) {
std::ostringstream e;
e << "called with unknown argument \"" << args[i] << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -211,7 +212,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
if (this->Destination.empty()) {
std::ostringstream e;
e << this->Name << " given no DESTINATION";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -314,8 +315,8 @@ bool cmFileCopier::CheckValue(std::string const& arg)
if (arg.empty() || cmSystemTools::FileIsFullPath(arg)) {
this->Destination = arg;
} else {
- this->Destination = this->Makefile->GetCurrentBinaryDirectory();
- this->Destination += "/" + arg;
+ this->Destination =
+ cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', arg);
}
this->Doing = DoingNone;
break;
@@ -323,8 +324,8 @@ bool cmFileCopier::CheckValue(std::string const& arg)
if (cmSystemTools::FileIsFullPath(arg)) {
this->FilesFromDir = arg;
} else {
- this->FilesFromDir = this->Makefile->GetCurrentSourceDirectory();
- this->FilesFromDir += "/" + arg;
+ this->FilesFromDir =
+ cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', arg);
}
cmSystemTools::ConvertToUnixSlashes(this->FilesFromDir);
this->Doing = DoingNone;
@@ -334,9 +335,8 @@ bool cmFileCopier::CheckValue(std::string const& arg)
// leading slash and trailing end-of-string in the matched
// string to make sure the pattern matches only whole file
// names.
- std::string regex = "/";
- regex += cmsys::Glob::PatternToRegex(arg, false);
- regex += "$";
+ std::string regex =
+ cmStrCat('/', cmsys::Glob::PatternToRegex(arg, false), '$');
this->MatchRules.emplace_back(regex);
this->CurrentMatchRule = &*(this->MatchRules.end() - 1);
if (this->CurrentMatchRule->Regex.is_valid()) {
@@ -344,7 +344,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
} else {
std::ostringstream e;
e << "could not compile PATTERN \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
} break;
@@ -356,7 +356,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
} else {
std::ostringstream e;
e << "could not compile REGEX \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
break;
@@ -399,8 +399,8 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
file += "/";
file += f;
} else if (!this->FilesFromDir.empty()) {
- this->FileCommand->SetError("option FILES_FROM_DIR requires all files "
- "to be specified as relative paths.");
+ this->Status.SetError("option FILES_FROM_DIR requires all files "
+ "to be specified as relative paths.");
return false;
} else {
file = f;
@@ -447,9 +447,8 @@ bool cmFileCopier::Install(const std::string& fromFile,
const std::string& toFile)
{
if (fromFile.empty()) {
- std::ostringstream e;
- e << "INSTALL encountered an empty string input file name.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(
+ "INSTALL encountered an empty string input file name.");
return false;
}
@@ -493,7 +492,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) {
if (!cmSystemTools::FileIsFullPath(newFromFile)) {
std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile);
- newFromFile = fromFilePath + "/" + newFromFile;
+ newFromFile = cmStrCat(fromFilePath, "/", newFromFile);
}
std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile);
@@ -516,14 +515,15 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) {
std::ostringstream e;
- e << this->Name << " cannot create symlink \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ e << this->Name << " cannot create symlink \"" << toFile
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
}
fromFile = newFromFile;
- toFile = toFilePath + "/" + symlinkTarget;
+ toFile = cmStrCat(toFilePath, "/", symlinkTarget);
}
return true;
@@ -537,8 +537,9 @@ bool cmFileCopier::InstallSymlink(const std::string& fromFile,
if (!cmSystemTools::ReadSymlink(fromFile, symlinkTarget)) {
std::ostringstream e;
e << this->Name << " cannot read symlink \"" << fromFile
- << "\" to duplicate at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ << "\" to duplicate at \"" << toFile
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
@@ -568,8 +569,9 @@ bool cmFileCopier::InstallSymlink(const std::string& fromFile,
if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) {
std::ostringstream e;
e << this->Name << " cannot duplicate symlink \"" << fromFile
- << "\" at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ << "\" at \"" << toFile
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
}
@@ -597,8 +599,8 @@ bool cmFileCopier::InstallFile(const std::string& fromFile,
if (copy && !cmSystemTools::CopyAFile(fromFile, toFile, true)) {
std::ostringstream e;
e << this->Name << " cannot copy file \"" << fromFile << "\" to \""
- << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ << toFile << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
@@ -613,8 +615,8 @@ bool cmFileCopier::InstallFile(const std::string& fromFile,
if (!cmFileTimes::Copy(fromFile, toFile)) {
std::ostringstream e;
e << this->Name << " cannot set modification time on \"" << toFile
- << "\"";
- this->FileCommand->SetError(e.str());
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
}
@@ -650,8 +652,8 @@ bool cmFileCopier::InstallDirectory(const std::string& source,
if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) {
std::ostringstream e;
e << this->Name << " cannot make directory \"" << destination
- << "\": " << cmSystemTools::GetLastSystemError();
- this->FileCommand->SetError(e.str());
+ << "\": " << cmSystemTools::GetLastSystemError() << ".";
+ this->Status.SetError(e.str());
return false;
}
@@ -696,12 +698,8 @@ bool cmFileCopier::InstallDirectory(const std::string& source,
for (unsigned long fileNum = 0; fileNum < numFiles; ++fileNum) {
if (!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
strcmp(dir.GetFile(fileNum), "..") == 0)) {
- std::string fromPath = source;
- fromPath += "/";
- fromPath += dir.GetFile(fileNum);
- std::string toPath = destination;
- toPath += "/";
- toPath += dir.GetFile(fileNum);
+ std::string fromPath = cmStrCat(source, '/', dir.GetFile(fileNum));
+ std::string toPath = cmStrCat(destination, '/', dir.GetFile(fileNum));
if (!this->Install(fromPath, toPath)) {
return false;
}
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index a79a60b90..612a57fef 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -5,26 +5,28 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTimeCache.h"
-#include "cm_sys_stat.h"
-#include "cmsys/RegularExpression.hxx"
-
#include <string>
#include <vector>
-class cmFileCommand;
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_sys_stat.h"
+
+#include "cmFileTimeCache.h"
+
+class cmExecutionStatus;
class cmMakefile;
// File installation helper class.
struct cmFileCopier
{
- cmFileCopier(cmFileCommand* command, const char* name = "COPY");
+ cmFileCopier(cmExecutionStatus& status, const char* name = "COPY");
virtual ~cmFileCopier();
bool Run(std::vector<std::string> const& args);
protected:
- cmFileCommand* FileCommand;
+ cmExecutionStatus& Status;
cmMakefile* Makefile;
const char* Name;
bool Always;
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index d4f76fd86..c89be9628 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -3,19 +3,20 @@
#include "cmFileInstaller.h"
-#include "cmFSPermissions.h"
-#include "cmFileCommand.h"
-#include "cmMakefile.h"
-#include "cmSystemTools.h"
+#include <sstream>
#include "cm_sys_stat.h"
-#include <sstream>
+#include "cmExecutionStatus.h"
+#include "cmFSPermissions.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
using namespace cmFSPermissions;
-cmFileInstaller::cmFileInstaller(cmFileCommand* command)
- : cmFileCopier(command, "INSTALL")
+cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
+ : cmFileCopier(status, "INSTALL")
, InstallType(cmInstallType_FILES)
, Optional(false)
, MessageAlways(false)
@@ -28,7 +29,7 @@ cmFileInstaller::cmFileInstaller(cmFileCommand* command)
// Check whether to copy files always or only if they have changed.
std::string install_always;
if (cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS", install_always)) {
- this->Always = cmSystemTools::IsOn(install_always);
+ this->Always = cmIsOn(install_always);
}
// Get the current manifest.
this->Manifest =
@@ -38,7 +39,7 @@ cmFileInstaller::~cmFileInstaller()
{
// Save the updated install manifest.
this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
- this->Manifest.c_str());
+ this->Manifest);
}
void cmFileInstaller::ManifestAppend(std::string const& file)
@@ -58,8 +59,8 @@ void cmFileInstaller::ReportCopy(const std::string& toFile, Type type,
bool copy)
{
if (!this->MessageNever && (copy || !this->MessageLazy)) {
- std::string message = (copy ? "Installing: " : "Up-to-date: ");
- message += toFile;
+ std::string message =
+ cmStrCat((copy ? "Installing: " : "Up-to-date: "), toFile);
this->Makefile->DisplayStatus(message, -1);
}
if (type != TypeDir) {
@@ -111,19 +112,19 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
if (!this->Rename.empty()) {
if (!this->FilesFromDir.empty()) {
- this->FileCommand->SetError("INSTALL option RENAME may not be "
- "combined with FILES_FROM_DIR.");
+ this->Status.SetError("INSTALL option RENAME may not be "
+ "combined with FILES_FROM_DIR.");
return false;
}
if (this->InstallType != cmInstallType_FILES &&
this->InstallType != cmInstallType_PROGRAMS) {
- this->FileCommand->SetError("INSTALL option RENAME may be used "
- "only with FILES or PROGRAMS.");
+ this->Status.SetError("INSTALL option RENAME may be used "
+ "only with FILES or PROGRAMS.");
return false;
}
if (this->Files.size() > 1) {
- this->FileCommand->SetError("INSTALL option RENAME may be used "
- "only with one file.");
+ this->Status.SetError("INSTALL option RENAME may be used "
+ "only with one file.");
return false;
}
}
@@ -134,9 +135,9 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
if (((this->MessageAlways ? 1 : 0) + (this->MessageLazy ? 1 : 0) +
(this->MessageNever ? 1 : 0)) > 1) {
- this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
- "MESSAGE_LAZY, and MESSAGE_NEVER "
- "are mutually exclusive.");
+ this->Status.SetError("INSTALL options MESSAGE_ALWAYS, "
+ "MESSAGE_LAZY, and MESSAGE_NEVER "
+ "are mutually exclusive.");
return false;
}
@@ -213,7 +214,7 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
e << "INSTALL called with old-style " << arg << " argument. "
<< "This script was generated with an older version of CMake. "
<< "Re-run this cmake version on your build tree.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
} else {
return this->cmFileCopier::CheckKeyword(arg);
@@ -257,7 +258,7 @@ bool cmFileInstaller::GetTargetTypeFromString(const std::string& stype)
} else {
std::ostringstream e;
e << "Option TYPE given unknown value \"" << stype << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
return true;
@@ -269,8 +270,8 @@ bool cmFileInstaller::HandleInstallDestination()
// allow for / to be a valid destination
if (destination.size() < 2 && destination != "/") {
- this->FileCommand->SetError("called with inappropriate arguments. "
- "No DESTINATION provided or .");
+ this->Status.SetError("called with inappropriate arguments. "
+ "No DESTINATION provided or .");
return false;
}
@@ -300,7 +301,7 @@ bool cmFileInstaller::HandleInstallDestination()
if (relative) {
// This is relative path on unix or windows. Since we are doing
// destdir, this case does not make sense.
- this->FileCommand->SetError(
+ this->Status.SetError(
"called with relative DESTINATION. This "
"does not make sense when using DESTDIR. Specify "
"absolute path or remove DESTDIR environment variable.");
@@ -310,12 +311,12 @@ bool cmFileInstaller::HandleInstallDestination()
if (ch2 == '/') {
// looks like a network path.
std::string message =
- "called with network path DESTINATION. This "
- "does not make sense when using DESTDIR. Specify local "
- "absolute path or remove DESTDIR environment variable."
- "\nDESTINATION=\n";
- message += destination;
- this->FileCommand->SetError(message);
+ cmStrCat("called with network path DESTINATION. This "
+ "does not make sense when using DESTDIR. Specify local "
+ "absolute path or remove DESTDIR environment variable."
+ "\nDESTINATION=\n",
+ destination);
+ this->Status.SetError(message);
return false;
}
}
@@ -335,14 +336,14 @@ bool cmFileInstaller::HandleInstallDestination()
if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) {
std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges.";
- this->FileCommand->SetError(errstring);
+ this->Status.SetError(errstring);
return false;
}
}
if (!cmSystemTools::FileIsDirectory(destination)) {
std::string errstring =
"INSTALL destination: " + destination + " is not a directory.";
- this->FileCommand->SetError(errstring);
+ this->Status.SetError(errstring);
return false;
}
}
diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h
index 312529aa8..537cd53cb 100644
--- a/Source/cmFileInstaller.h
+++ b/Source/cmFileInstaller.h
@@ -5,18 +5,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileCopier.h"
-
-#include "cmInstallType.h"
-
#include <string>
#include <vector>
-class cmFileCommand;
+#include "cmFileCopier.h"
+#include "cmInstallType.h"
+
+class cmExecutionStatus;
struct cmFileInstaller : public cmFileCopier
{
- cmFileInstaller(cmFileCommand* command);
+ cmFileInstaller(cmExecutionStatus& status);
~cmFileInstaller() override;
protected:
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index 1e472da63..e90f57140 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -2,8 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileLock.h"
+#include <cassert>
+
#include "cmFileLockResult.h"
-#include <assert.h>
// Common implementation
diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx
index d700a79c3..8db2db210 100644
--- a/Source/cmFileLockPool.cxx
+++ b/Source/cmFileLockPool.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileLockPool.h"
-#include <assert.h>
+#include <cassert>
#include "cmAlgorithms.h"
#include "cmFileLock.h"
diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h
index 41203baac..dae68dd01 100644
--- a/Source/cmFileLockPool.h
+++ b/Source/cmFileLockPool.h
@@ -72,17 +72,17 @@ private:
bool IsAlreadyLocked(const std::string& filename) const;
private:
- typedef std::vector<cmFileLock*> List;
- typedef List::iterator It;
- typedef List::const_iterator CIt;
+ using List = std::vector<cmFileLock*>;
+ using It = List::iterator;
+ using CIt = List::const_iterator;
List Locks;
};
- typedef std::vector<ScopePool*> List;
+ using List = std::vector<ScopePool*>;
- typedef List::iterator It;
- typedef List::const_iterator CIt;
+ using It = List::iterator;
+ using CIt = List::const_iterator;
List FunctionScopes;
List FileScopes;
diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx
index 9ca5d8a06..9d5a6c67a 100644
--- a/Source/cmFileLockResult.cxx
+++ b/Source/cmFileLockResult.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileLockResult.h"
-#include <errno.h>
-#include <string.h>
+#include <cerrno>
+#include <cstring>
#define WINMSG_BUF_LEN (1024)
cmFileLockResult cmFileLockResult::MakeOk()
{
- return cmFileLockResult(OK, 0);
+ return { OK, 0 };
}
cmFileLockResult cmFileLockResult::MakeSystem()
@@ -18,27 +18,27 @@ cmFileLockResult cmFileLockResult::MakeSystem()
#else
const Error lastError = errno;
#endif
- return cmFileLockResult(SYSTEM, lastError);
+ return { SYSTEM, lastError };
}
cmFileLockResult cmFileLockResult::MakeTimeout()
{
- return cmFileLockResult(TIMEOUT, 0);
+ return { TIMEOUT, 0 };
}
cmFileLockResult cmFileLockResult::MakeAlreadyLocked()
{
- return cmFileLockResult(ALREADY_LOCKED, 0);
+ return { ALREADY_LOCKED, 0 };
}
cmFileLockResult cmFileLockResult::MakeInternal()
{
- return cmFileLockResult(INTERNAL, 0);
+ return { INTERNAL, 0 };
}
cmFileLockResult cmFileLockResult::MakeNoFunction()
{
- return cmFileLockResult(NO_FUNCTION, 0);
+ return { NO_FUNCTION, 0 };
}
bool cmFileLockResult::IsOk() const
diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h
index 8b4929ae1..81c19064d 100644
--- a/Source/cmFileLockResult.h
+++ b/Source/cmFileLockResult.h
@@ -19,9 +19,9 @@ class cmFileLockResult
{
public:
#if defined(_WIN32)
- typedef DWORD Error;
+ using Error = DWORD;
#else
- typedef int Error;
+ using Error = int;
#endif
/**
diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx
index 1bf5013ad..1456ea8c1 100644
--- a/Source/cmFileLockUnix.cxx
+++ b/Source/cmFileLockUnix.cxx
@@ -1,13 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFileLock.h"
+#include <cerrno> // errno
+#include <cstdio> // SEEK_SET
-#include "cmSystemTools.h"
-#include <errno.h> // errno
#include <fcntl.h>
-#include <stdio.h> // SEEK_SET
#include <unistd.h>
+#include "cmFileLock.h"
+#include "cmSystemTools.h"
+
cmFileLock::cmFileLock() = default;
cmFileLockResult cmFileLock::Release()
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx
index a61d360ab..b8e435aa5 100644
--- a/Source/cmFileLockWin32.cxx
+++ b/Source/cmFileLockWin32.cxx
@@ -1,9 +1,9 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFileLock.h"
+#include <windows.h> // CreateFileW
+#include "cmFileLock.h"
#include "cmSystemTools.h"
-#include <windows.h> // CreateFileW
cmFileLock::cmFileLock()
{
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
index 56ee739b0..ac8a37eee 100644
--- a/Source/cmFileMonitor.cxx
+++ b/Source/cmFileMonitor.cxx
@@ -2,14 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileMonitor.h"
-#include "cmAlgorithms.h"
-#include "cmsys/SystemTools.hxx"
-
#include <cassert>
-#include <stddef.h>
+#include <cstddef>
#include <unordered_map>
#include <utility>
+#include "cmsys/SystemTools.hxx"
+
+#include "cmAlgorithms.h"
+
namespace {
void on_directory_change(uv_fs_event_t* handle, const char* filename,
int events, int status);
diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx
index 47a223a20..bb3f610d1 100644
--- a/Source/cmFilePathChecksum.cxx
+++ b/Source/cmFilePathChecksum.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFilePathChecksum.h"
+#include <vector>
+
#include "cmBase32.h"
#include "cmCryptoHash.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include <vector>
-
cmFilePathChecksum::cmFilePathChecksum() = default;
cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir,
diff --git a/Source/cmFilePathChecksum.h b/Source/cmFilePathChecksum.h
index 30881ce90..b7d5cd24c 100644
--- a/Source/cmFilePathChecksum.h
+++ b/Source/cmFilePathChecksum.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <array>
-#include <stddef.h>
+#include <cstddef>
#include <string>
#include <utility>
diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx
index 253457ff2..96c70fef6 100644
--- a/Source/cmFileTime.cxx
+++ b/Source/cmFileTime.cxx
@@ -2,15 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileTime.h"
+#include <ctime>
#include <string>
-#include <time.h>
// Use a platform-specific API to get file times efficiently.
#if !defined(_WIN32) || defined(__CYGWIN__)
# include "cm_sys_stat.h"
#else
-# include "cmsys/Encoding.hxx"
# include <windows.h>
+
+# include "cmsys/Encoding.hxx"
#endif
bool cmFileTime::Load(std::string const& fileName)
diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h
index d4de4e033..e9a85598a 100644
--- a/Source/cmFileTime.h
+++ b/Source/cmFileTime.h
@@ -14,7 +14,7 @@
class cmFileTime
{
public:
- typedef long long NSC;
+ using NSC = long long;
static constexpr NSC NsPerS = 1000000000;
cmFileTime() = default;
diff --git a/Source/cmFileTimeCache.cxx b/Source/cmFileTimeCache.cxx
index 24d6bf6e1..0d1dae5e8 100644
--- a/Source/cmFileTimeCache.cxx
+++ b/Source/cmFileTimeCache.cxx
@@ -38,7 +38,8 @@ bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2,
int* result)
{
// Get the modification time for each file.
- cmFileTime ft1, ft2;
+ cmFileTime ft1;
+ cmFileTime ft2;
if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
// Compare the two modification times.
*result = ft1.Compare(ft2);
@@ -52,7 +53,8 @@ bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2,
bool cmFileTimeCache::DifferS(std::string const& f1, std::string const& f2)
{
// Get the modification time for each file.
- cmFileTime ft1, ft2;
+ cmFileTime ft1;
+ cmFileTime ft2;
if (this->Load(f1, ft1) && this->Load(f2, ft2)) {
// Compare the two modification times.
return ft1.DifferS(ft2);
diff --git a/Source/cmFileTimeCache.h b/Source/cmFileTimeCache.h
index 4f1a3a253..83b77b651 100644
--- a/Source/cmFileTimeCache.h
+++ b/Source/cmFileTimeCache.h
@@ -5,10 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTime.h" // IWYU pragma: keep
#include <string>
#include <unordered_map>
+#include "cmFileTime.h" // IWYU pragma: keep
+
/** \class cmFileTimeCache
* \brief Caches file modification times in an internal map for fast lookups.
*/
diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx
index fd4f6797f..d8fe24c5b 100644
--- a/Source/cmFileTimes.cxx
+++ b/Source/cmFileTimes.cxx
@@ -2,14 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileTimes.h"
-#include "cmAlgorithms.h"
-#include "cm_sys_stat.h"
-
#include <utility>
+#include <cm/memory>
+
+#include "cm_sys_stat.h"
+
#if defined(_WIN32)
-# include "cmSystemTools.h"
# include <windows.h>
+
+# include "cmSystemTools.h"
#else
# include <utime.h>
#endif
diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h
index cbf0fe20a..191d89e94 100644
--- a/Source/cmFileTimes.h
+++ b/Source/cmFileTimes.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
/** \class cmFileTimes
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 42aff0438..7d741182d 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindBase.h"
+#include <cstddef>
#include <deque>
#include <iostream>
#include <map>
-#include <stddef.h>
#include "cmAlgorithms.h"
#include "cmMakefile.h"
@@ -13,9 +13,13 @@
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-cmFindBase::cmFindBase()
+class cmExecutionStatus;
+
+cmFindBase::cmFindBase(cmExecutionStatus& status)
+ : cmFindCommon(status)
{
this->AlreadyInCache = false;
this->AlreadyInCacheWithoutMetaInfo = false;
@@ -67,6 +71,9 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
this->AlreadyInCache = false;
+ // Find what search path locations have been enabled/disable
+ this->SelectDefaultSearchModes();
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -185,9 +192,7 @@ void cmFindBase::FillCMakeEnvironmentPath()
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
// Add CMAKE_*_PATH environment variables
- std::string var = "CMAKE_";
- var += this->CMakePathName;
- var += "_PATH";
+ std::string var = cmStrCat("CMAKE_", this->CMakePathName, "_PATH");
paths.AddEnvPrefixPath("CMAKE_PREFIX_PATH");
paths.AddEnvPath(var);
@@ -219,9 +224,7 @@ void cmFindBase::FillCMakeVariablePath()
// Add CMake variables of the same name as the previous environment
// variables CMAKE_*_PATH to be used most of the time with -D
// command line options
- std::string var = "CMAKE_";
- var += this->CMakePathName;
- var += "_PATH";
+ std::string var = cmStrCat("CMAKE_", this->CMakePathName, "_PATH");
paths.AddCMakePrefixPath("CMAKE_PREFIX_PATH");
paths.AddCMakePath(var);
@@ -253,9 +256,7 @@ void cmFindBase::FillCMakeSystemVariablePath()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem];
- std::string var = "CMAKE_SYSTEM_";
- var += this->CMakePathName;
- var += "_PATH";
+ std::string var = cmStrCat("CMAKE_SYSTEM_", this->CMakePathName, "_PATH");
paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
paths.AddCMakePath(var);
@@ -320,7 +321,7 @@ bool cmFindBase::CheckForVariableInCache()
this->Makefile->GetDefinition(this->VariableName)) {
cmState* state = this->Makefile->GetState();
const char* cacheEntry = state->GetCacheEntryValue(this->VariableName);
- bool found = !cmSystemTools::IsNOTFOUND(cacheValue);
+ bool found = !cmIsNOTFOUND(cacheValue);
bool cached = cacheEntry != nullptr;
if (found) {
// If the user specifies the entry on the command line without a
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index 88b5b6c18..f75db5ff3 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -10,6 +10,8 @@
#include "cmFindCommon.h"
+class cmExecutionStatus;
+
/** \class cmFindBase
* \brief Base class for most FIND_XXX commands.
*
@@ -19,7 +21,9 @@
class cmFindBase : public cmFindCommon
{
public:
- cmFindBase();
+ cmFindBase(cmExecutionStatus& status);
+ virtual ~cmFindBase() = default;
+
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 954558f4d..badec55a8 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -3,11 +3,14 @@
#include "cmFindCommon.h"
#include <algorithm>
-#include <string.h>
+#include <array>
+#include <cstring>
#include <utility>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL");
@@ -22,7 +25,9 @@ cmFindCommon::PathLabel cmFindCommon::PathLabel::SystemEnvironment(
cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeSystem("CMAKE_SYSTEM");
cmFindCommon::PathLabel cmFindCommon::PathLabel::Guess("GUESS");
-cmFindCommon::cmFindCommon()
+cmFindCommon::cmFindCommon(cmExecutionStatus& status)
+ : Makefile(&status.GetMakefile())
+ , Status(status)
{
this->FindRootPathMode = RootPathModeBoth;
this->NoDefaultPath = false;
@@ -49,7 +54,10 @@ cmFindCommon::cmFindCommon()
this->InitializeSearchPathGroups();
}
-cmFindCommon::~cmFindCommon() = default;
+void cmFindCommon::SetError(std::string const& e)
+{
+ this->Status.SetError(e);
+}
void cmFindCommon::InitializeSearchPathGroups()
{
@@ -90,8 +98,8 @@ void cmFindCommon::InitializeSearchPathGroups()
void cmFindCommon::SelectDefaultRootPathMode()
{
// Check the policy variable for this find command type.
- std::string findRootPathVar = "CMAKE_FIND_ROOT_PATH_MODE_";
- findRootPathVar += this->CMakePathName;
+ std::string findRootPathVar =
+ cmStrCat("CMAKE_FIND_ROOT_PATH_MODE_", this->CMakePathName);
std::string rootPathMode =
this->Makefile->GetSafeDefinition(findRootPathVar);
if (rootPathMode == "NEVER") {
@@ -144,6 +152,26 @@ void cmFindCommon::SelectDefaultMacMode()
}
}
+void cmFindCommon::SelectDefaultSearchModes()
+{
+ const std::array<std::pair<bool&, std::string>, 5> search_paths = {
+ { { this->NoPackageRootPath, "CMAKE_FIND_USE_PACKAGE_ROOT_PATH" },
+ { this->NoCMakePath, "CMAKE_FIND_USE_CMAKE_PATH" },
+ { this->NoCMakeEnvironmentPath,
+ "CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH" },
+ { this->NoSystemEnvironmentPath,
+ "CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH" },
+ { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } }
+ };
+
+ for (auto& path : search_paths) {
+ const char* def = this->Makefile->GetDefinition(path.second);
+ if (def) {
+ path.first = !cmIsOn(def);
+ }
+ }
+}
+
void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
{
#if 0
@@ -174,7 +202,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
// Construct the list of path roots with no trailing slashes.
std::vector<std::string> roots;
if (rootPath) {
- cmSystemTools::ExpandListArgument(rootPath, roots);
+ cmExpandList(rootPath, roots);
}
if (sysrootCompile) {
roots.emplace_back(sysrootCompile);
@@ -207,8 +235,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
rootedDir = up;
} else if (!up.empty() && up[0] != '~') {
// Start with the new root.
- rootedDir = r;
- rootedDir += "/";
+ rootedDir = cmStrCat(r, '/');
// Append the original path with its old root removed.
rootedDir += cmSystemTools::SplitPathRootComponent(up);
@@ -240,7 +267,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
continue;
}
- cmSystemTools::ExpandListArgument(ignorePath, ignore);
+ cmExpandList(ignorePath, ignore);
}
for (std::string& i : ignore) {
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 89ff1741d..8177eacd6 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -10,10 +10,12 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
#include "cmPathLabel.h"
#include "cmSearchPath.h"
+class cmExecutionStatus;
+class cmMakefile;
+
/** \class cmFindCommon
* \brief Base class for FIND_XXX implementations.
*
@@ -21,11 +23,12 @@
* cmFindProgramCommand, cmFindPathCommand, cmFindLibraryCommand,
* cmFindFileCommand, and cmFindPackageCommand.
*/
-class cmFindCommon : public cmCommand
+class cmFindCommon
{
public:
- cmFindCommon();
- ~cmFindCommon() override;
+ cmFindCommon(cmExecutionStatus& status);
+
+ void SetError(std::string const& e);
protected:
friend class cmSearchPath;
@@ -90,6 +93,9 @@ protected:
/** Compute the current default bundle/framework search policy. */
void SelectDefaultMacMode();
+ /** Compute the current default search modes based on global variables. */
+ void SelectDefaultSearchModes();
+
// Path arguments prior to path manipulation routines
std::vector<std::string> UserHintsArgs;
std::vector<std::string> UserGuessArgs;
@@ -124,6 +130,9 @@ protected:
bool SearchAppBundleFirst;
bool SearchAppBundleOnly;
bool SearchAppBundleLast;
+
+ cmMakefile* Makefile;
+ cmExecutionStatus& Status;
};
#endif
diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx
index 9840c4f49..29a2bc49e 100644
--- a/Source/cmFindFileCommand.cxx
+++ b/Source/cmFindFileCommand.cxx
@@ -2,7 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindFileCommand.h"
-cmFindFileCommand::cmFindFileCommand()
+class cmExecutionStatus;
+
+cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status)
+ : cmFindPathCommand(status)
{
this->IncludeFileInPath = true;
}
+
+bool cmFindFile(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return cmFindFileCommand(status).InitialPass(args);
+}
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index 430944942..7dc6e5569 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -5,9 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+#include <vector>
+
#include "cmFindPathCommand.h"
-class cmCommand;
+class cmExecutionStatus;
/** \class cmFindFileCommand
* \brief Define a command to search for an executable program.
@@ -20,11 +23,10 @@ class cmCommand;
class cmFindFileCommand : public cmFindPathCommand
{
public:
- cmFindFileCommand();
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFindFileCommand; }
+ cmFindFileCommand(cmExecutionStatus& status);
};
+bool cmFindFile(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
#endif
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 73d602de7..20221b12e 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -2,30 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindLibraryCommand.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include <cstdio>
+#include <cstring>
#include <set>
-#include <stdio.h>
-#include <string.h>
#include <utility>
+#include "cmsys/RegularExpression.hxx"
+
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
-cmFindLibraryCommand::cmFindLibraryCommand()
+cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
+ : cmFindBase(status)
{
this->EnvironmentPath = "LIB";
this->NamesPerDirAllowed = true;
}
// cmFindLibraryCommand
-bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn,
- cmExecutionStatus&)
+bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->VariableDocumentation = "Path to a library.";
this->CMakePathName = "LIBRARY";
@@ -190,7 +192,7 @@ struct cmFindLibraryHelper
std::string SuffixRegexStr;
// Keep track of the best library file found so far.
- typedef std::vector<std::string>::size_type size_type;
+ using size_type = std::vector<std::string>::size_type;
std::string BestPath;
// Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
@@ -237,8 +239,8 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf)
this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
std::string const& suffixes_list =
this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES");
- cmSystemTools::ExpandListArgument(prefixes_list, this->Prefixes, true);
- cmSystemTools::ExpandListArgument(suffixes_list, this->Suffixes, true);
+ cmExpandList(prefixes_list, this->Prefixes, true);
+ cmExpandList(suffixes_list, this->Suffixes, true);
this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
this->RegexFromList(this->SuffixRegexStr, this->Suffixes);
@@ -311,8 +313,7 @@ void cmFindLibraryHelper::AddName(std::string const& name)
entry.Raw = name;
// Build a regular expression to match library names.
- std::string regex = "^";
- regex += this->PrefixRegexStr;
+ std::string regex = cmStrCat('^', this->PrefixRegexStr);
this->RegexFromLiteral(regex, name);
regex += this->SuffixRegexStr;
if (this->OpenBSD) {
@@ -348,8 +349,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
// one cannot tell just from the library name whether it is a static
// library or an import library).
if (name.TryRaw) {
- this->TestPath = path;
- this->TestPath += name.Raw;
+ this->TestPath = cmStrCat(path, name.Raw);
if (cmSystemTools::FileExists(this->TestPath, true)) {
this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
cmSystemTools::ConvertToUnixSlashes(this->BestPath);
@@ -374,8 +374,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
std::string const& testName = origName;
#endif
if (name.Regex.find(testName)) {
- this->TestPath = path;
- this->TestPath += origName;
+ this->TestPath = cmStrCat(path, origName);
if (!cmSystemTools::FileIsDirectory(this->TestPath)) {
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
@@ -465,9 +464,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
// Search for all names in each search path.
for (std::string const& d : this->SearchPaths) {
for (std::string const& n : this->Names) {
- fwPath = d;
- fwPath += n;
- fwPath += ".framework";
+ fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
return cmSystemTools::CollapseFullPath(fwPath);
}
@@ -484,9 +481,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
// Search for each name in all search paths.
for (std::string const& n : this->Names) {
for (std::string const& d : this->SearchPaths) {
- fwPath = d;
- fwPath += n;
- fwPath += ".framework";
+ fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
return cmSystemTools::CollapseFullPath(fwPath);
}
@@ -496,3 +491,9 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
// No framework found.
return "";
}
+
+bool cmFindLibrary(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return cmFindLibraryCommand(status).InitialPass(args);
+}
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
index fb8a7002d..b2f71b3b8 100644
--- a/Source/cmFindLibraryCommand.h
+++ b/Source/cmFindLibraryCommand.h
@@ -10,7 +10,6 @@
#include "cmFindBase.h"
-class cmCommand;
class cmExecutionStatus;
/** \class cmFindLibraryCommand
@@ -23,18 +22,9 @@ class cmExecutionStatus;
class cmFindLibraryCommand : public cmFindBase
{
public:
- cmFindLibraryCommand();
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFindLibraryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ cmFindLibraryCommand(cmExecutionStatus& status);
+
+ bool InitialPass(std::vector<std::string> const& args);
protected:
void AddArchitecturePaths(const char* suffix);
@@ -52,4 +42,7 @@ private:
std::string FindFrameworkLibraryDirsPerName();
};
+bool cmFindLibrary(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
#endif
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 171fa77dc..2b11b62a2 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -2,23 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindPackageCommand.h"
-#include "cmSystemTools.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-#include "cmsys/String.h"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
+#include <cstring>
#include <deque>
#include <functional>
#include <iterator>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
-#include <string.h>
#include <utility>
+#include <cm/memory>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
+
#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -27,6 +28,8 @@
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
#include "cmVersion.h"
#if defined(__HAIKU__)
@@ -83,7 +86,8 @@ void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
// else do not sort
}
-cmFindPackageCommand::cmFindPackageCommand()
+cmFindPackageCommand::cmFindPackageCommand(cmExecutionStatus& status)
+ : cmFindCommon(status)
{
this->CMakePathName = "PACKAGE";
this->Quiet = false;
@@ -141,8 +145,7 @@ void cmFindPackageCommand::AppendSearchPathGroups()
std::make_pair(PathLabel::SystemRegistry, cmSearchPath(this)));
}
-bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
{
if (args.empty()) {
this->SetError("called with incorrect number of arguments");
@@ -188,12 +191,23 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
}
// Check if User Package Registry should be disabled
- if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) {
+ // The `CMAKE_FIND_USE_PACKAGE_REGISTRY` has
+ // priority over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
+ if (const char* def =
+ this->Makefile->GetDefinition("CMAKE_FIND_USE_PACKAGE_REGISTRY")) {
+ this->NoUserRegistry = !cmIsOn(def);
+ } else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) {
this->NoUserRegistry = true;
}
// Check if System Package Registry should be disabled
- if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY")) {
+ // The `CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` has
+ // priority over the deprecated CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+ if (const char* def = this->Makefile->GetDefinition(
+ "CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY")) {
+ this->NoSystemRegistry = !cmIsOn(def);
+ } else if (this->Makefile->IsOn(
+ "CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY")) {
this->NoSystemRegistry = true;
}
@@ -219,6 +233,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
}
+ // Find what search path locations have been enabled/disable
+ this->SelectDefaultSearchModes();
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -338,11 +355,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
} else if (doing == DoingConfigs) {
if (args[i].find_first_of(":/\\") != std::string::npos ||
cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake") {
- std::ostringstream e;
- e << "given CONFIGS option followed by invalid file name \"" << args[i]
- << "\". The names given must be file names without "
- << "a path and with a \".cmake\" extension.";
- this->SetError(e.str());
+ this->SetError(cmStrCat(
+ "given CONFIGS option followed by invalid file name \"", args[i],
+ "\". The names given must be file names without "
+ "a path and with a \".cmake\" extension."));
return false;
}
this->Configs.push_back(args[i]);
@@ -350,9 +366,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
haveVersion = true;
this->Version = args[i];
} else {
- std::ostringstream e;
- e << "called with invalid argument \"" << args[i] << "\"";
- this->SetError(e.str());
+ this->SetError(
+ cmStrCat("called with invalid argument \"", args[i], "\""));
return false;
}
}
@@ -362,10 +377,10 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
optionalComponents.begin(), optionalComponents.end(),
std::back_inserter(doubledComponents));
if (!doubledComponents.empty()) {
- std::ostringstream e;
- e << "called with components that are both required and optional:\n";
- e << cmWrap(" ", doubledComponents, "", "\n") << "\n";
- this->SetError(e.str());
+ this->SetError(
+ cmStrCat("called with components that are both required and "
+ "optional:\n",
+ cmWrap(" ", doubledComponents, "", "\n"), "\n"));
return false;
}
@@ -398,19 +413,16 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
if (this->Version.empty() || components.empty()) {
// Check whether we are recursing inside "Find<name>.cmake" within
// another find_package(<name>) call.
- std::string mod = this->Name;
- mod += "_FIND_MODULE";
+ std::string mod = cmStrCat(this->Name, "_FIND_MODULE");
if (this->Makefile->IsOn(mod)) {
if (this->Version.empty()) {
// Get version information from the outer call if necessary.
// Requested version string.
- std::string ver = this->Name;
- ver += "_FIND_VERSION";
+ std::string ver = cmStrCat(this->Name, "_FIND_VERSION");
this->Version = this->Makefile->GetSafeDefinition(ver);
// Whether an exact version is required.
- std::string exact = this->Name;
- exact += "_FIND_VERSION_EXACT";
+ std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
this->VersionExact = this->Makefile->IsOn(exact);
}
if (components.empty()) {
@@ -448,15 +460,14 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
}
}
- std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
- disableFindPackageVar += this->Name;
+ std::string disableFindPackageVar =
+ cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
if (this->Makefile->IsOn(disableFindPackageVar)) {
if (this->Required) {
- std::ostringstream e;
- e << "for module " << this->Name << " called with REQUIRED, but "
- << disableFindPackageVar
- << " is enabled. A REQUIRED package cannot be disabled.";
- this->SetError(e.str());
+ this->SetError(
+ cmStrCat("for module ", this->Name, " called with REQUIRED, but ",
+ disableFindPackageVar,
+ " is enabled. A REQUIRED package cannot be disabled."));
return false;
}
@@ -488,7 +499,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
// NEW behavior is to honor the <pkg>_ROOT variables.
std::string const rootVar = this->Name + "_ROOT";
if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) {
- cmSystemTools::ExpandListArgument(pkgRoot, rootPaths, false);
+ cmExpandList(pkgRoot, rootPaths, false);
}
cmSystemTools::GetPath(rootPaths, rootVar.c_str());
} break;
@@ -579,8 +590,7 @@ bool cmFindPackageCommand::FindPackageUsingModuleMode()
bool cmFindPackageCommand::FindPackageUsingConfigMode()
{
- this->Variable = this->Name;
- this->Variable += "_DIR";
+ this->Variable = cmStrCat(this->Name, "_DIR");
// Add the default name.
if (this->Names.empty()) {
@@ -590,12 +600,10 @@ bool cmFindPackageCommand::FindPackageUsingConfigMode()
// Add the default configs.
if (this->Configs.empty()) {
for (std::string const& n : this->Names) {
- std::string config = n;
- config += "Config.cmake";
+ std::string config = cmStrCat(n, "Config.cmake");
this->Configs.push_back(config);
- config = cmSystemTools::LowerCase(n);
- config += "-config.cmake";
+ config = cmStrCat(cmSystemTools::LowerCase(n), "-config.cmake");
this->Configs.push_back(std::move(config));
}
}
@@ -624,24 +632,21 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
if (this->Quiet) {
// Tell the module that is about to be read that it should find
// quietly.
- std::string quietly = this->Name;
- quietly += "_FIND_QUIETLY";
+ std::string quietly = cmStrCat(this->Name, "_FIND_QUIETLY");
this->AddFindDefinition(quietly, "1");
}
if (this->Required) {
// Tell the module that is about to be read that it should report
// a fatal error if the package is not found.
- std::string req = this->Name;
- req += "_FIND_REQUIRED";
+ std::string req = cmStrCat(this->Name, "_FIND_REQUIRED");
this->AddFindDefinition(req, "1");
}
if (!this->Version.empty()) {
// Tell the module that is about to be read what version of the
// package has been requested.
- std::string ver = this->Name;
- ver += "_FIND_VERSION";
+ std::string ver = cmStrCat(this->Name, "_FIND_VERSION");
this->AddFindDefinition(ver, this->Version.c_str());
char buf[64];
sprintf(buf, "%u", this->VersionMajor);
@@ -656,8 +661,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
this->AddFindDefinition(ver + "_COUNT", buf);
// Tell the module whether an exact version has been requested.
- std::string exact = this->Name;
- exact += "_FIND_VERSION_EXACT";
+ std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
this->AddFindDefinition(exact, this->VersionExact ? "1" : "0");
}
}
@@ -671,7 +675,9 @@ void cmFindPackageCommand::AddFindDefinition(const std::string& var,
} else {
this->OriginalDefs[var].exists = false;
}
- this->Makefile->AddDefinition(var, val);
+ if (val) {
+ this->Makefile->AddDefinition(var, val);
+ }
}
void cmFindPackageCommand::RestoreFindDefinitions()
@@ -679,7 +685,7 @@ void cmFindPackageCommand::RestoreFindDefinitions()
for (auto const& i : this->OriginalDefs) {
OriginalDef const& od = i.second;
if (od.exists) {
- this->Makefile->AddDefinition(i.first, od.value.c_str());
+ this->Makefile->AddDefinition(i.first, od.value);
} else {
this->Makefile->RemoveDefinition(i.first);
}
@@ -688,9 +694,7 @@ void cmFindPackageCommand::RestoreFindDefinitions()
bool cmFindPackageCommand::FindModule(bool& found)
{
- std::string module = "Find";
- module += this->Name;
- module += ".cmake";
+ std::string module = cmStrCat("Find", this->Name, ".cmake");
bool system = false;
std::string mfile = this->Makefile->GetModulesFile(module, system);
if (!mfile.empty()) {
@@ -701,9 +705,9 @@ bool cmFindPackageCommand::FindModule(bool& found)
this->Makefile->GetPolicyStatus(it->second);
switch (status) {
case cmPolicies::WARN: {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(it->second) << "\n";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(it->second), "\n"));
CM_FALLTHROUGH;
}
case cmPolicies::OLD:
@@ -719,8 +723,7 @@ bool cmFindPackageCommand::FindModule(bool& found)
// Load the module we found, and set "<name>_FIND_MODULE" to true
// while inside it.
found = true;
- std::string var = this->Name;
- var += "_FIND_MODULE";
+ std::string var = cmStrCat(this->Name, "_FIND_MODULE");
this->Makefile->AddDefinition(var, "1");
bool result = this->ReadListFile(mfile, DoPolicyScope);
this->Makefile->RemoveDefinition(var);
@@ -734,19 +737,13 @@ bool cmFindPackageCommand::HandlePackageMode(
{
this->ConsideredConfigs.clear();
- // Support old capitalization behavior.
- std::string upperDir = cmSystemTools::UpperCase(this->Name);
- std::string upperFound = cmSystemTools::UpperCase(this->Name);
- upperDir += "_DIR";
- upperFound += "_FOUND";
-
// Try to find the config file.
const char* def = this->Makefile->GetDefinition(this->Variable);
// Try to load the config file if the directory is known
bool fileFound = false;
if (this->UseConfigFiles) {
- if (!cmSystemTools::IsOff(def)) {
+ if (!cmIsOff(def)) {
// Get the directory from the variable value.
std::string dir = def;
cmSystemTools::ConvertToUnixSlashes(dir);
@@ -766,7 +763,7 @@ bool cmFindPackageCommand::HandlePackageMode(
}
// Search for the config file if it is not already found.
- if (cmSystemTools::IsOff(def) || !fileFound) {
+ if (cmIsOff(def) || !fileFound) {
fileFound = this->FindConfig();
}
@@ -779,10 +776,8 @@ bool cmFindPackageCommand::HandlePackageMode(
}
}
- std::string foundVar = this->Name;
- foundVar += "_FOUND";
- std::string notFoundMessageVar = this->Name;
- notFoundMessageVar += "_NOT_FOUND_MESSAGE";
+ std::string foundVar = cmStrCat(this->Name, "_FOUND");
+ std::string notFoundMessageVar = cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
std::string notFoundMessage;
// If the directory for the config file was found, try to read the file.
@@ -856,8 +851,7 @@ bool cmFindPackageCommand::HandlePackageMode(
// If there are files in ConsideredConfigs, it means that FooConfig.cmake
// have been found, but they didn't have appropriate versions.
else if (!this->ConsideredConfigs.empty()) {
- std::vector<ConfigFileInfo>::const_iterator duplicate_end =
- cmRemoveDuplicates(this->ConsideredConfigs);
+ auto duplicate_end = cmRemoveDuplicates(this->ConsideredConfigs);
e << "Could not find a configuration file for package \"" << this->Name
<< "\" that "
<< (this->VersionExact ? "exactly matches" : "is compatible with")
@@ -872,9 +866,8 @@ bool cmFindPackageCommand::HandlePackageMode(
} else {
std::string requestedVersionString;
if (!this->Version.empty()) {
- requestedVersionString = " (requested version ";
- requestedVersionString += this->Version;
- requestedVersionString += ")";
+ requestedVersionString =
+ cmStrCat(" (requested version ", this->Version, ')');
}
if (this->UseConfigFiles) {
@@ -945,10 +938,10 @@ bool cmFindPackageCommand::HandlePackageMode(
}
// output result if in config mode but not in quiet mode
else if (!this->Quiet) {
- std::ostringstream aw;
- aw << "Could NOT find " << this->Name << " (missing: " << this->Name
- << "_DIR)";
- this->Makefile->DisplayStatus(aw.str(), -1);
+ this->Makefile->DisplayStatus(cmStrCat("Could NOT find ", this->Name,
+ " (missing: ", this->Name,
+ "_DIR)"),
+ -1);
}
}
@@ -956,18 +949,17 @@ bool cmFindPackageCommand::HandlePackageMode(
this->Makefile->AddDefinition(foundVar, found ? "1" : "0");
// Set a variable naming the configuration file that was found.
- std::string fileVar = this->Name;
- fileVar += "_CONFIG";
+ std::string fileVar = cmStrCat(this->Name, "_CONFIG");
if (found) {
- this->Makefile->AddDefinition(fileVar, this->FileFound.c_str());
+ this->Makefile->AddDefinition(fileVar, this->FileFound);
} else {
this->Makefile->RemoveDefinition(fileVar);
}
- std::string consideredConfigsVar = this->Name;
- consideredConfigsVar += "_CONSIDERED_CONFIGS";
- std::string consideredVersionsVar = this->Name;
- consideredVersionsVar += "_CONSIDERED_VERSIONS";
+ std::string consideredConfigsVar =
+ cmStrCat(this->Name, "_CONSIDERED_CONFIGS");
+ std::string consideredVersionsVar =
+ cmStrCat(this->Name, "_CONSIDERED_VERSIONS");
std::string consideredConfigFiles;
std::string consideredVersions;
@@ -981,11 +973,9 @@ bool cmFindPackageCommand::HandlePackageMode(
sep = ";";
}
- this->Makefile->AddDefinition(consideredConfigsVar,
- consideredConfigFiles.c_str());
+ this->Makefile->AddDefinition(consideredConfigsVar, consideredConfigFiles);
- this->Makefile->AddDefinition(consideredVersionsVar,
- consideredVersions.c_str());
+ this->Makefile->AddDefinition(consideredVersionsVar, consideredVersions);
return result;
}
@@ -1031,9 +1021,8 @@ bool cmFindPackageCommand::FindConfig()
init = this->Variable + "-NOTFOUND";
}
std::string help =
- "The directory containing a CMake configuration file for ";
- help += this->Name;
- help += ".";
+ 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);
@@ -1080,9 +1069,7 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
return true;
}
- std::string e = "Error reading CMake code from \"";
- e += f;
- e += "\".";
+ std::string e = cmStrCat("Error reading CMake code from \"", f, "\".");
this->SetError(e);
return false;
}
@@ -1095,8 +1082,8 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
if (foundProp && *foundProp) {
std::string tmp = foundProp;
- cmSystemTools::ExpandListArgument(tmp, foundContents, false);
- std::vector<std::string>::iterator nameIt =
+ cmExpandList(tmp, foundContents, false);
+ auto nameIt =
std::find(foundContents.begin(), foundContents.end(), this->Name);
if (nameIt != foundContents.end()) {
foundContents.erase(nameIt);
@@ -1109,8 +1096,8 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
if (notFoundProp && *notFoundProp) {
std::string tmp = notFoundProp;
- cmSystemTools::ExpandListArgument(tmp, notFoundContents, false);
- std::vector<std::string>::iterator nameIt =
+ cmExpandList(tmp, notFoundContents, false);
+ auto nameIt =
std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
if (nameIt != notFoundContents.end()) {
notFoundContents.erase(nameIt);
@@ -1134,45 +1121,38 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
void cmFindPackageCommand::AppendSuccessInformation()
{
{
- std::string transitivePropName = "_CMAKE_";
- transitivePropName += this->Name + "_TRANSITIVE_DEPENDENCY";
+ std::string transitivePropName =
+ cmStrCat("_CMAKE_", this->Name, "_TRANSITIVE_DEPENDENCY");
this->Makefile->GetState()->SetGlobalProperty(transitivePropName, "False");
}
- std::string found = this->Name;
- found += "_FOUND";
+ std::string found = cmStrCat(this->Name, "_FOUND");
std::string upperFound = cmSystemTools::UpperCase(found);
const char* upperResult = this->Makefile->GetDefinition(upperFound);
const char* result = this->Makefile->GetDefinition(found);
- bool packageFound =
- ((cmSystemTools::IsOn(result)) || (cmSystemTools::IsOn(upperResult)));
+ bool packageFound = ((cmIsOn(result)) || (cmIsOn(upperResult)));
this->AppendToFoundProperty(packageFound);
// Record whether the find was quiet or not, so this can be used
// e.g. in FeatureSummary.cmake
- std::string quietInfoPropName = "_CMAKE_";
- quietInfoPropName += this->Name;
- quietInfoPropName += "_QUIET";
+ std::string quietInfoPropName = cmStrCat("_CMAKE_", this->Name, "_QUIET");
this->Makefile->GetState()->SetGlobalProperty(
quietInfoPropName, this->Quiet ? "TRUE" : "FALSE");
// set a global property to record the required version of this package
- std::string versionInfoPropName = "_CMAKE_";
- versionInfoPropName += this->Name;
- versionInfoPropName += "_REQUIRED_VERSION";
+ std::string versionInfoPropName =
+ cmStrCat("_CMAKE_", this->Name, "_REQUIRED_VERSION");
std::string versionInfo;
if (!this->Version.empty()) {
- versionInfo = this->VersionExact ? "==" : ">=";
- versionInfo += " ";
- versionInfo += this->Version;
+ versionInfo =
+ cmStrCat(this->VersionExact ? "==" : ">=", ' ', this->Version);
}
this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName,
versionInfo.c_str());
if (this->Required) {
- std::string requiredInfoPropName = "_CMAKE_";
- requiredInfoPropName += this->Name;
- requiredInfoPropName += "_TYPE";
+ std::string requiredInfoPropName =
+ cmStrCat("_CMAKE_", this->Name, "_TYPE");
this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName,
"REQUIRED");
}
@@ -1222,8 +1202,7 @@ void cmFindPackageCommand::FillPrefixesPackageRoot()
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
// Add the PACKAGE_ROOT_PATH from each enclosing find_package call.
- for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths =
- this->Makefile->FindPackageRootPathStack.rbegin();
+ for (auto pkgPaths = this->Makefile->FindPackageRootPathStack.rbegin();
pkgPaths != this->Makefile->FindPackageRootPathStack.rend();
++pkgPaths) {
for (std::string const& path : *pkgPaths) {
@@ -1282,9 +1261,7 @@ void cmFindPackageCommand::FillPrefixesUserRegistry()
char dir[B_PATH_NAME_LENGTH];
if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, dir, sizeof(dir)) ==
B_OK) {
- std::string fname = dir;
- fname += "/cmake/packages/";
- fname += Name;
+ std::string fname = cmStrCat(dir, "/cmake/packages/", Name);
this->LoadPackageRegistryDir(fname,
this->LabeledPaths[PathLabel::UserRegistry]);
}
@@ -1425,9 +1402,7 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
std::string fname;
for (unsigned long i = 0; i < files.GetNumberOfFiles(); ++i) {
- fname = dir;
- fname += "/";
- fname += files.GetFile(i);
+ fname = cmStrCat(dir, '/', files.GetFile(i));
if (!cmSystemTools::FileIsDirectory(fname)) {
// Hold this file hostage until it behaves.
@@ -1542,9 +1517,7 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
}
for (std::string const& c : this->Configs) {
- file = dir;
- file += "/";
- file += c;
+ file = cmStrCat(dir, '/', c);
if (this->DebugMode) {
fprintf(stderr, "Checking file [%s]\n", file.c_str());
}
@@ -1570,16 +1543,14 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
std::string version_file_base = config_file.substr(0, pos);
// Look for foo-config-version.cmake
- std::string version_file = version_file_base;
- version_file += "-version.cmake";
+ std::string version_file = cmStrCat(version_file_base, "-version.cmake");
if (!haveResult && cmSystemTools::FileExists(version_file, true)) {
result = this->CheckVersionFile(version_file, version);
haveResult = true;
}
// Look for fooConfigVersion.cmake
- version_file = version_file_base;
- version_file += "Version.cmake";
+ version_file = cmStrCat(version_file_base, "Version.cmake");
if (!haveResult && cmSystemTools::FileExists(version_file, true)) {
result = this->CheckVersionFile(version_file, version);
haveResult = true;
@@ -1614,8 +1585,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
this->Makefile->RemoveDefinition("PACKAGE_VERSION_EXACT");
// Set the input variables.
- this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name.c_str());
- this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version.c_str());
+ this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version);
char buf[64];
sprintf(buf, "%u", this->VersionMajor);
this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MAJOR", buf);
@@ -1687,12 +1658,11 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
void cmFindPackageCommand::StoreVersionFound()
{
// Store the whole version string.
- std::string ver = this->Name;
- ver += "_VERSION";
+ std::string ver = cmStrCat(this->Name, "_VERSION");
if (this->VersionFound.empty()) {
this->Makefile->RemoveDefinition(ver);
} else {
- this->Makefile->AddDefinition(ver, this->VersionFound.c_str());
+ this->Makefile->AddDefinition(ver, this->VersionFound);
}
// Store the version components.
@@ -2036,8 +2006,7 @@ private:
bool Search(std::string const& parent, cmFileList& lister) override
{
// Glob the set of matching files.
- std::string expr = parent;
- expr += this->Pattern;
+ std::string expr = cmStrCat(parent, this->Pattern);
cmsys::Glob g;
if (!g.FindFiles(expr)) {
return false;
@@ -2315,3 +2284,9 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
}
// TODO: Debug cmsys::Glob double slash problem.
+
+bool cmFindPackage(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return cmFindPackageCommand(status).InitialPass(args);
+}
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 316ca0f3d..85fe7b6e5 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -4,9 +4,7 @@
#define cmFindPackageCommand_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmPolicies.h"
-#include "cm_kwiml.h"
#include <cstddef>
#include <functional>
#include <map>
@@ -14,6 +12,11 @@
#include <string>
#include <vector>
+#include "cm_kwiml.h"
+
+#include "cmFindCommon.h"
+#include "cmPolicies.h"
+
// IWYU insists we should forward-declare instead of including <functional>,
// but we cannot forward-declare reliably because some C++ standard libraries
// put the template in an inline namespace.
@@ -25,9 +28,6 @@ namespace std {
/* clang-format on */
#endif
-#include "cmFindCommon.h"
-
-class cmCommand;
class cmExecutionStatus;
class cmSearchPath;
@@ -60,19 +60,9 @@ public:
std::vector<std::string>::iterator end, SortOrderType order,
SortDirectionType dir);
- cmFindPackageCommand();
+ cmFindPackageCommand(cmExecutionStatus& status);
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFindPackageCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ bool InitialPass(std::vector<std::string> const& args);
private:
class PathLabel : public cmFindCommon::PathLabel
@@ -230,8 +220,8 @@ namespace std {
template <>
struct hash<cmFindPackageCommand::ConfigFileInfo>
{
- typedef cmFindPackageCommand::ConfigFileInfo argument_type;
- typedef size_t result_type;
+ using argument_type = cmFindPackageCommand::ConfigFileInfo;
+ using result_type = size_t;
result_type operator()(argument_type const& s) const noexcept
{
@@ -241,4 +231,7 @@ struct hash<cmFindPackageCommand::ConfigFileInfo>
};
}
+bool cmFindPackage(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
#endif
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 38ff2ed51..f5e263108 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -6,19 +6,20 @@
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
-cmFindPathCommand::cmFindPathCommand()
+cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
+ : cmFindBase(status)
{
this->EnvironmentPath = "INCLUDE";
this->IncludeFileInPath = false;
}
// cmFindPathCommand
-bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn,
- cmExecutionStatus&)
+bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->VariableDocumentation = "Path to a file.";
this->CMakePathName = "INCLUDE";
@@ -88,12 +89,8 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file,
frameWorkName.clear();
}
if (!frameWorkName.empty()) {
- std::string fpath = dir;
- fpath += frameWorkName;
- fpath += ".framework";
- std::string intPath = fpath;
- intPath += "/Headers/";
- intPath += fileName;
+ std::string fpath = cmStrCat(dir, frameWorkName, ".framework");
+ std::string intPath = cmStrCat(fpath, "/Headers/", fileName);
if (cmSystemTools::FileExists(intPath)) {
if (this->IncludeFileInPath) {
return intPath;
@@ -104,9 +101,7 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file,
}
// if it is not found yet or not a framework header, then do a glob search
// for all frameworks in the directory: dir/*.framework/Headers/<file>
- std::string glob = dir;
- glob += "*.framework/Headers/";
- glob += file;
+ std::string glob = cmStrCat(dir, "*.framework/Headers/", file);
cmsys::Glob globIt;
globIt.FindFiles(glob);
std::vector<std::string> files = globIt.GetFiles();
@@ -126,8 +121,7 @@ std::string cmFindPathCommand::FindNormalHeader()
std::string tryPath;
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
- tryPath = sp;
- tryPath += n;
+ tryPath = cmStrCat(sp, n);
if (cmSystemTools::FileExists(tryPath)) {
if (this->IncludeFileInPath) {
return tryPath;
@@ -151,3 +145,9 @@ std::string cmFindPathCommand::FindFrameworkHeader()
}
return "";
}
+
+bool cmFindPath(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return cmFindPathCommand(status).InitialPass(args);
+}
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index cb0db4c46..8d1ea8b60 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -10,7 +10,6 @@
#include "cmFindBase.h"
-class cmCommand;
class cmExecutionStatus;
/** \class cmFindPathCommand
@@ -23,18 +22,9 @@ class cmExecutionStatus;
class cmFindPathCommand : public cmFindBase
{
public:
- cmFindPathCommand();
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFindPathCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ cmFindPathCommand(cmExecutionStatus& status);
+
+ bool InitialPass(std::vector<std::string> const& args);
bool IncludeFileInPath;
@@ -46,4 +36,7 @@ private:
std::string FindFrameworkHeader();
};
+bool cmFindPath(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
#endif
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 782f746ef..e0a3fbfcf 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
@@ -71,11 +72,10 @@ struct cmFindProgramHelper
bool CheckDirectoryForName(std::string const& path, std::string const& name)
{
for (std::string const& ext : this->Extensions) {
- if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) {
+ if (!ext.empty() && cmHasSuffix(name, ext)) {
continue;
}
- this->TestNameExt = name;
- this->TestNameExt += ext;
+ this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
@@ -88,14 +88,14 @@ struct cmFindProgramHelper
}
};
-cmFindProgramCommand::cmFindProgramCommand()
+cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
+ : cmFindBase(status)
{
this->NamesPerDirAllowed = true;
}
// cmFindProgramCommand
-bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn,
- cmExecutionStatus&)
+bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->VariableDocumentation = "Path to a program.";
this->CMakePathName = "PROGRAM";
@@ -270,3 +270,9 @@ std::string cmFindProgramCommand::GetBundleExecutable(
return executable;
}
+
+bool cmFindProgram(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return cmFindProgramCommand(status).InitialPass(args);
+}
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index 147936cc0..043b43c5e 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -10,7 +10,6 @@
#include "cmFindBase.h"
-class cmCommand;
class cmExecutionStatus;
/** \class cmFindProgramCommand
@@ -24,18 +23,9 @@ class cmExecutionStatus;
class cmFindProgramCommand : public cmFindBase
{
public:
- cmFindProgramCommand();
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFindProgramCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
+ cmFindProgramCommand(cmExecutionStatus& status);
+
+ bool InitialPass(std::vector<std::string> const& args);
private:
std::string FindProgram();
@@ -46,4 +36,7 @@ private:
std::string GetBundleExecutable(std::string const& bundlePath);
};
+bool cmFindProgram(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
#endif
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 08003eb71..44392baa7 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -2,21 +2,50 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmForEachCommand.h"
-#include <memory> // IWYU pragma: keep
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+namespace {
+bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile);
+
+class cmForEachFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmForEachFunctionBlocker(cmMakefile* mf);
+ ~cmForEachFunctionBlocker() override;
+
+ cm::string_view StartCommandName() const override { return "foreach"_s; }
+ cm::string_view EndCommandName() const override { return "endforeach"_s; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+ std::vector<std::string> Args;
+
+private:
+ cmMakefile* Makefile;
+};
+
cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf)
: Makefile(mf)
- , Depth(0)
{
this->Makefile->PushLoopBlock();
}
@@ -26,102 +55,71 @@ cmForEachFunctionBlocker::~cmForEachFunctionBlocker()
this->Makefile->PopLoopBlock();
}
-bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
{
- if (lff.Name.Lower == "foreach") {
- // record the number of nested foreach commands
- this->Depth++;
- } else if (lff.Name.Lower == "endforeach") {
- // if this is the endofreach for this statement
- if (!this->Depth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
- }
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments);
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+}
- // at end of for each execute recorded commands
- // store the old value
- std::string oldDef;
- if (mf.GetDefinition(this->Args[0])) {
- oldDef = mf.GetDefinition(this->Args[0]);
- }
+bool cmForEachFunctionBlocker::Replay(
+ std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
+{
+ cmMakefile& mf = inStatus.GetMakefile();
+ // at end of for each execute recorded commands
+ // store the old value
+ std::string oldDef;
+ if (mf.GetDefinition(this->Args[0])) {
+ oldDef = mf.GetDefinition(this->Args[0]);
+ }
- for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
- // set the variable to the loop value
- mf.AddDefinition(this->Args[0], arg.c_str());
- // Invoke all the functions that were collected in the block.
- cmExecutionStatus status;
- for (cmListFileFunction const& func : this->Functions) {
- status.Clear();
- mf.ExecuteCommand(func, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef.c_str());
- return true;
- }
- if (status.GetBreakInvoked()) {
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef.c_str());
- return true;
- }
- if (status.GetContinueInvoked()) {
- break;
- }
- if (cmSystemTools::GetFatalErrorOccured()) {
- return true;
- }
- }
+ for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
+ // set the variable to the loop value
+ mf.AddDefinition(this->Args[0], arg);
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& func : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(func, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ return true;
}
-
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef.c_str());
- return true;
}
- // close out a nested foreach
- this->Depth--;
}
- // record the command
- this->Functions.push_back(lff);
-
- // always return true
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
return true;
}
-
-bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
-{
- if (lff.Name.Lower == "endforeach") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
- // if the endforeach has arguments then make sure
- // they match the begin foreach arguments
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
- }
- }
- return false;
}
-bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmForEachCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
if (args.size() > 1 && args[1] == "IN") {
- return this->HandleInMode(args);
+ return HandleInMode(args, status.GetMakefile());
}
// create a function blocker
- auto f = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
+ auto fb = cm::make_unique<cmForEachFunctionBlocker>(&status.GetMakefile());
if (args.size() > 1) {
if (args[1] == "RANGE") {
int start = 0;
@@ -148,10 +146,9 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
}
if ((start > stop && step > 0) || (start < stop && step < 0) ||
step == 0) {
- std::ostringstream str;
- str << "called with incorrect range specification: start ";
- str << start << ", stop " << stop << ", step " << step;
- this->SetError(str.str());
+ status.SetError(
+ cmStrCat("called with incorrect range specification: start ", start,
+ ", stop ", stop, ", step ", step));
return false;
}
std::vector<std::string> range;
@@ -168,23 +165,23 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
break;
}
}
- f->Args = range;
+ fb->Args = range;
} else {
- f->Args = args;
+ fb->Args = args;
}
} else {
- f->Args = args;
+ fb->Args = args;
}
- this->Makefile->AddFunctionBlocker(f.release());
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
return true;
}
-bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
+namespace {
+bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile)
{
- std::unique_ptr<cmForEachFunctionBlocker> f(
- new cmForEachFunctionBlocker(this->Makefile));
- f->Args.push_back(args[0]);
+ auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
+ fb->Args.push_back(args[0]);
enum Doing
{
@@ -195,26 +192,26 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
Doing doing = DoingNone;
for (unsigned int i = 2; i < args.size(); ++i) {
if (doing == DoingItems) {
- f->Args.push_back(args[i]);
+ fb->Args.push_back(args[i]);
} else if (args[i] == "LISTS") {
doing = DoingLists;
} else if (args[i] == "ITEMS") {
doing = DoingItems;
} else if (doing == DoingLists) {
- const char* value = this->Makefile->GetDefinition(args[i]);
+ const char* value = makefile.GetDefinition(args[i]);
if (value && *value) {
- cmSystemTools::ExpandListArgument(value, f->Args, true);
+ cmExpandList(value, fb->Args, true);
}
} else {
- std::ostringstream e;
- e << "Unknown argument:\n"
- << " " << args[i] << "\n";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Unknown argument:\n", " ", args[i], "\n"));
return true;
}
}
- this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass unique_ptr
+ makefile.AddFunctionBlocker(std::move(fb));
return true;
}
+}
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 5131a4f18..1feb965ce 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -8,48 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmForEachFunctionBlocker : public cmFunctionBlocker
-{
-public:
- cmForEachFunctionBlocker(cmMakefile* mf);
- ~cmForEachFunctionBlocker() override;
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
-
-private:
- cmMakefile* Makefile;
- int Depth;
-};
/// Starts foreach() ... endforeach() block
-class cmForEachCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmForEachCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandleInMode(std::vector<std::string> const& args);
-};
-
+bool cmForEachCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 6a33be571..6f97b4243 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -12,10 +12,10 @@
# include <vector>
#endif
-#include <stddef.h> /* size_t */
+#include <cstddef> /* size_t */
/* Forward declare parser object type. */
-typedef struct cmFortranParser_s cmFortranParser;
+using cmFortranParser = struct cmFortranParser_s;
/* Functions to enter/exit #include'd files in order. */
bool cmFortranParser_FilePush(cmFortranParser* parser, const char* fname);
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index e8b1da83c..054a2a93e 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -1,16 +1,17 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFortranParser.h"
-#include "cmSystemTools.h"
-
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
#include <set>
#include <stack>
-#include <stdio.h>
#include <string>
#include <utility>
#include <vector>
+#include "cmFortranParser.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
bool cmFortranParser_s::FindIncludeFile(const char* dir,
const char* includeName,
std::string& fileName)
@@ -22,9 +23,7 @@ bool cmFortranParser_s::FindIncludeFile(const char* dir,
}
// Check for the file in the directory containing the including
// file.
- std::string fullName = dir;
- fullName += "/";
- fullName += includeName;
+ std::string fullName = cmStrCat(dir, '/', includeName);
if (cmSystemTools::FileExists(fullName, true)) {
fileName = fullName;
return true;
@@ -32,9 +31,7 @@ bool cmFortranParser_s::FindIncludeFile(const char* dir,
// Search the include path for the file.
for (std::string const& i : this->IncludePath) {
- fullName = i;
- fullName += "/";
- fullName += includeName;
+ fullName = cmStrCat(i, '/', includeName);
if (cmSystemTools::FileExists(fullName, true)) {
fileName = fullName;
return true;
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
new file mode 100644
index 000000000..5778a7152
--- /dev/null
+++ b/Source/cmFunctionBlocker.cxx
@@ -0,0 +1,46 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFunctionBlocker.h"
+
+#include <cassert>
+#include <sstream>
+#include <utility>
+
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+
+bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
+ cmExecutionStatus& status)
+{
+ if (lff.Name.Lower == this->StartCommandName()) {
+ this->ScopeDepth++;
+ } else if (lff.Name.Lower == this->EndCommandName()) {
+ this->ScopeDepth--;
+ if (this->ScopeDepth == 0U) {
+ cmMakefile& mf = status.GetMakefile();
+ auto self = mf.RemoveFunctionBlocker();
+ assert(self.get() == this);
+
+ if (!this->ArgumentsMatch(lff, mf)) {
+ cmListFileContext const& lfc = this->GetStartingContext();
+ cmListFileContext closingContext =
+ cmListFileContext::FromCommandContext(lff, lfc.FilePath);
+ std::ostringstream e;
+ /* clang-format off */
+ e << "A logical block opening on the line\n"
+ << " " << lfc << "\n"
+ << "closes on the line\n"
+ << " " << closingContext << "\n"
+ << "with mis-matching arguments.";
+ /* clang-format on */
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ }
+
+ return this->Replay(std::move(this->Functions), status);
+ }
+ }
+
+ this->Functions.push_back(lff);
+ return true;
+}
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index cd6b05db4..59bb8927f 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -3,6 +3,12 @@
#ifndef cmFunctionBlocker_h
#define cmFunctionBlocker_h
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <vector>
+
+#include <cm/string_view>
+
#include "cmListFileCache.h"
class cmExecutionStatus;
@@ -14,17 +20,8 @@ public:
/**
* should a function be blocked
*/
- virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus& status) = 0;
-
- /**
- * should this function blocker be removed, useful when one function adds a
- * blocker and another must remove it
- */
- virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile&)
- {
- return false;
- }
+ bool IsFunctionBlocked(cmListFileFunction const& lff,
+ cmExecutionStatus& status);
virtual ~cmFunctionBlocker() = default;
@@ -39,7 +36,19 @@ public:
}
private:
+ virtual cm::string_view StartCommandName() const = 0;
+ virtual cm::string_view EndCommandName() const = 0;
+
+ virtual bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const = 0;
+
+ virtual bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) = 0;
+
+private:
cmListFileContext StartingContext;
+ std::vector<cmListFileFunction> Functions;
+ unsigned int ScopeDepth = 1;
};
#endif
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 9067a5f64..b3ddfe01f 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -3,106 +3,96 @@
#include "cmFunctionCommand.h"
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
+namespace {
// define the class for function commands
-class cmFunctionHelperCommand : public cmCommand
+class cmFunctionHelperCommand
{
public:
/**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmFunctionHelperCommand* newC = new cmFunctionHelperCommand;
- // we must copy when we clone
- newC->Args = this->Args;
- newC->Functions = this->Functions;
- newC->Policies = this->Policies;
- newC->FilePath = this->FilePath;
- return newC;
- }
-
- /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const;
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
cmPolicies::PolicyMap Policies;
std::string FilePath;
};
+}
-bool cmFunctionHelperCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmFunctionHelperCommand::operator()(
+ std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const
{
+ cmMakefile& makefile = inStatus.GetMakefile();
+
// Expand the argument list to the function.
std::vector<std::string> expandedArgs;
- this->Makefile->ExpandArguments(args, expandedArgs);
+ makefile.ExpandArguments(args, expandedArgs);
// make sure the number of arguments passed is at least the number
// required by the signature
if (expandedArgs.size() < this->Args.size() - 1) {
- std::string errorMsg =
- "Function invoked with incorrect arguments for function named: ";
- errorMsg += this->Args[0];
- this->SetError(errorMsg);
+ std::string errorMsg = cmStrCat(
+ "Function invoked with incorrect arguments for function named: ",
+ this->Args[0]);
+ inStatus.SetError(errorMsg);
return false;
}
- cmMakefile::FunctionPushPop functionScope(this->Makefile, this->FilePath,
+ cmMakefile::FunctionPushPop functionScope(&makefile, this->FilePath,
this->Policies);
// set the value of argc
- std::ostringstream strStream;
- strStream << expandedArgs.size();
- this->Makefile->AddDefinition("ARGC", strStream.str().c_str());
- this->Makefile->MarkVariableAsUsed("ARGC");
+ makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size()));
+ makefile.MarkVariableAsUsed("ARGC");
// set the values for ARGV0 ARGV1 ...
for (unsigned int t = 0; t < expandedArgs.size(); ++t) {
std::ostringstream tmpStream;
tmpStream << "ARGV" << t;
- this->Makefile->AddDefinition(tmpStream.str(), expandedArgs[t].c_str());
- this->Makefile->MarkVariableAsUsed(tmpStream.str());
+ makefile.AddDefinition(tmpStream.str(), expandedArgs[t]);
+ makefile.MarkVariableAsUsed(tmpStream.str());
}
// define the formal arguments
for (unsigned int j = 1; j < this->Args.size(); ++j) {
- this->Makefile->AddDefinition(this->Args[j], expandedArgs[j - 1].c_str());
+ makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]);
}
// define ARGV and ARGN
std::string argvDef = cmJoin(expandedArgs, ";");
- std::vector<std::string>::const_iterator eit =
- expandedArgs.begin() + (this->Args.size() - 1);
+ auto eit = expandedArgs.begin() + (this->Args.size() - 1);
std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
- this->Makefile->AddDefinition("ARGV", argvDef.c_str());
- this->Makefile->MarkVariableAsUsed("ARGV");
- this->Makefile->AddDefinition("ARGN", argnDef.c_str());
- this->Makefile->MarkVariableAsUsed("ARGN");
+ makefile.AddDefinition("ARGV", argvDef);
+ makefile.MarkVariableAsUsed("ARGV");
+ makefile.AddDefinition("ARGN", argnDef);
+ makefile.MarkVariableAsUsed("ARGN");
// Invoke all the functions that were collected in the block.
// for each function
for (cmListFileFunction const& func : this->Functions) {
- cmExecutionStatus status;
- if (!this->Makefile->ExecuteCommand(func, status) ||
- status.GetNestedError()) {
+ cmExecutionStatus status(makefile);
+ if (!makefile.ExecuteCommand(func, status) || status.GetNestedError()) {
// The error message should have already included the call stack
// so we do not need to report an error here.
functionScope.Quiet();
@@ -118,66 +108,57 @@ bool cmFunctionHelperCommand::InvokeInitialPass(
return true;
}
-bool cmFunctionFunctionBlocker::IsFunctionBlocked(
- const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus&)
+class cmFunctionFunctionBlocker : public cmFunctionBlocker
{
- // record commands until we hit the ENDFUNCTION
- // at the ENDFUNCTION call we shift gears and start looking for invocations
- if (lff.Name.Lower == "function") {
- this->Depth++;
- } else if (lff.Name.Lower == "endfunction") {
- // if this is the endfunction for this function then execute
- if (!this->Depth) {
- // create a new command and add it to cmake
- cmFunctionHelperCommand* f = new cmFunctionHelperCommand();
- f->Args = this->Args;
- f->Functions = this->Functions;
- f->FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f->Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], f);
- // remove the function blocker now that the function is defined
- mf.RemoveFunctionBlocker(this, lff);
- return true;
- }
- // decrement for each nested function that ends
- this->Depth--;
- }
+public:
+ cm::string_view StartCommandName() const override { return "function"_s; }
+ cm::string_view EndCommandName() const override { return "endfunction"_s; }
- // if it wasn't an endfunction and we are not executing then we must be
- // recording
- this->Functions.push_back(lff);
- return true;
-}
+ bool ArgumentsMatch(cmListFileFunction const&,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) override;
-bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
+ std::vector<std::string> Args;
+};
+
+bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
{
- if (lff.Name.Lower == "endfunction") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments,
- this->GetStartingContext().FilePath.c_str());
- // if the endfunction has arguments then make sure
- // they match the ones in the opening function command
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
- }
- }
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+}
- return false;
+bool cmFunctionFunctionBlocker::Replay(
+ std::vector<cmListFileFunction> functions, cmExecutionStatus& status)
+{
+ cmMakefile& mf = status.GetMakefile();
+ // create a new command and add it to cmake
+ cmFunctionHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = std::move(functions);
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
+ mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ return true;
}
-bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmFunctionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// create a function blocker
- cmFunctionFunctionBlocker* f = new cmFunctionFunctionBlocker();
- cmAppend(f->Args, args);
- this->Makefile->AddFunctionBlocker(f);
+ {
+ auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
+ cmAppend(fb->Args, args);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
+ }
return true;
}
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index 8b37df032..d6b549c67 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -8,40 +8,10 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmFunctionFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
- int Depth = 0;
-};
/// Starts function() ... endfunction() block
-class cmFunctionCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmFunctionCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmFunctionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2f47788f8..2af04b691 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -2,18 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratedFileStream.h"
-#include <stdio.h>
+#include <cstdio>
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_codecvt.hxx"
# include "cm_zlib.h"
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
imbue(std::locale(getloc(), new codecvt(encoding)));
}
@@ -32,7 +33,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
cmSystemTools::Error("Cannot open file for write: " + this->TempName);
cmSystemTools::ReportLastSystemError("");
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
imbue(std::locale(getloc(), new codecvt(encoding)));
}
@@ -149,7 +150,7 @@ bool cmGeneratedFileStreamBase::Close()
// The destination is to be replaced. Rename the temporary to the
// destination atomically.
if (this->Compress) {
- std::string gzname = this->TempName + ".temp.gz";
+ std::string gzname = cmStrCat(this->TempName, ".temp.gz");
if (this->CompressFile(this->TempName, gzname)) {
this->RenameFile(gzname, resname);
}
@@ -169,7 +170,7 @@ bool cmGeneratedFileStreamBase::Close()
return replaced;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
std::string const& newname)
{
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 5b1eb5153..a9088ac8a 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -5,10 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_codecvt.hxx"
-#include "cmsys/FStream.hxx"
#include <string>
+#include "cmsys/FStream.hxx"
+
+#include "cm_codecvt.hxx"
+
// This is the first base class of cmGeneratedFileStream. It will be
// created before and destroyed after the ofstream portion and can
// therefore be used to manage the temporary file.
@@ -72,8 +74,8 @@ class cmGeneratedFileStream
, public cmsys::ofstream
{
public:
- typedef cmsys::ofstream Stream;
- typedef codecvt::Encoding Encoding;
+ using Stream = cmsys::ofstream;
+ using Encoding = codecvt::Encoding;
/**
* This constructor prepares a default stream. The open method must
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 175a26d2e..b7f7d1d9b 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -2,17 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpression.h"
-#include "cmsys/RegularExpression.hxx"
-#include <memory> // IWYU pragma: keep
+#include <cassert>
+#include <memory>
#include <utility>
-#include "assert.h"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
@@ -20,40 +22,56 @@ cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
{
}
+cmGeneratorExpression::~cmGeneratorExpression() = default;
+
std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
- std::string const& input)
+ std::string input) const
{
return std::unique_ptr<cmCompiledGeneratorExpression>(
- new cmCompiledGeneratorExpression(this->Backtrace, input));
+ new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
}
std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
- const char* input)
+ const char* input) const
{
return this->Parse(std::string(input ? input : ""));
}
-cmGeneratorExpression::~cmGeneratorExpression() = default;
-
-const std::string& cmCompiledGeneratorExpression::Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet,
- const cmGeneratorTarget* headTarget,
+std::string cmGeneratorExpression::Evaluate(
+ std::string input, cmLocalGenerator* lg, const std::string& config,
+ cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::string const& language) const
+ cmGeneratorTarget const* currentTarget, std::string const& language)
{
- return this->Evaluate(lg, config, quiet, headTarget, headTarget, dagChecker,
+ if (Find(input) != std::string::npos) {
+ cmCompiledGeneratorExpression cge(cmListFileBacktrace(), std::move(input));
+ return cge.Evaluate(lg, config, headTarget, dagChecker, currentTarget,
language);
+ }
+ 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, bool quiet,
- const cmGeneratorTarget* headTarget, const cmGeneratorTarget* currentTarget,
+ cmLocalGenerator* lg, const std::string& config,
+ const cmGeneratorTarget* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::string const& language) const
+ const cmGeneratorTarget* currentTarget, std::string const& language) const
{
cmGeneratorExpressionContext context(
- lg, config, quiet, headTarget, currentTarget ? currentTarget : headTarget,
- this->EvaluateForBuildsystem, this->Backtrace, language);
+ lg, config, this->Quiet, headTarget,
+ currentTarget ? currentTarget : headTarget, this->EvaluateForBuildsystem,
+ this->Backtrace, language);
return this->EvaluateWithContext(context, dagChecker);
}
@@ -96,9 +114,10 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace backtrace, std::string input)
: Backtrace(std::move(backtrace))
, Input(std::move(input))
+ , EvaluateForBuildsystem(false)
+ , Quiet(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
- , EvaluateForBuildsystem(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
@@ -294,7 +313,7 @@ void cmGeneratorExpression::Split(const std::string& input,
preGenex = input.substr(startPos + 1, pos - startPos - 1);
}
if (!part.empty()) {
- cmSystemTools::ExpandListArgument(part, output);
+ cmExpandList(part, output);
}
}
pos += 2;
@@ -327,7 +346,7 @@ void cmGeneratorExpression::Split(const std::string& input,
lastPos = pos;
}
if (lastPos < input.size()) {
- cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
+ cmExpandList(input.substr(lastPos), output);
}
}
@@ -369,20 +388,17 @@ bool cmGeneratorExpression::IsValidTargetName(const std::string& input)
void cmCompiledGeneratorExpression::GetMaxLanguageStandard(
const cmGeneratorTarget* tgt, std::map<std::string, std::string>& mapping)
{
- typedef std::map<cmGeneratorTarget const*,
- std::map<std::string, std::string>>
- MapType;
- MapType::const_iterator it = this->MaxLanguageStandard.find(tgt);
+ auto it = this->MaxLanguageStandard.find(tgt);
if (it != this->MaxLanguageStandard.end()) {
mapping = it->second;
}
}
const std::string& cmGeneratorExpressionInterpreter::Evaluate(
- const char* expression, const std::string& property)
+ std::string expression, const std::string& property)
{
this->CompiledGeneratorExpression =
- this->GeneratorExpression.Parse(expression);
+ this->GeneratorExpression.Parse(std::move(expression));
// Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
cmGeneratorExpressionDAGChecker dagChecker(
@@ -391,6 +407,12 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
nullptr);
return this->CompiledGeneratorExpression->Evaluate(
- this->LocalGenerator, this->Config, false, this->HeadTarget, &dagChecker,
+ this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
this->Language);
}
+
+const std::string& cmGeneratorExpressionInterpreter::Evaluate(
+ const char* expression, const std::string& property)
+{
+ return this->Evaluate(std::string(expression ? expression : ""), property);
+}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index fd36c4bcb..4bd1c9f88 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -5,15 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmListFileCache.h"
-
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
+#include "cmListFileCache.h"
+
class cmCompiledGeneratorExpression;
class cmGeneratorTarget;
class cmLocalGenerator;
@@ -41,8 +41,22 @@ public:
cmGeneratorExpression& operator=(cmGeneratorExpression const&) = delete;
std::unique_ptr<cmCompiledGeneratorExpression> Parse(
- std::string const& input);
- std::unique_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
+ 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,
+ cmGeneratorTarget const* headTarget = nullptr,
+ 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
{
@@ -87,15 +101,10 @@ public:
cmCompiledGeneratorExpression const&) = delete;
const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet = false,
+ cmLocalGenerator* lg, const std::string& config,
cmGeneratorTarget const* headTarget = nullptr,
- cmGeneratorTarget const* currentTarget = nullptr,
cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
- std::string const& language = std::string()) const;
- const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet,
- cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
+ cmGeneratorTarget const* currentTarget = nullptr,
std::string const& language = std::string()) const;
/** Get set of targets found during evaluations. */
@@ -135,6 +144,8 @@ public:
this->EvaluateForBuildsystem = eval;
}
+ void SetQuiet(bool quiet) { this->Quiet = quiet; }
+
void GetMaxLanguageStandard(cmGeneratorTarget const* tgt,
std::map<std::string, std::string>& mapping);
@@ -152,6 +163,8 @@ private:
std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
const std::string Input;
bool NeedsEvaluation;
+ bool EvaluateForBuildsystem;
+ bool Quiet;
mutable std::set<cmGeneratorTarget*> DependTargets;
mutable std::set<cmGeneratorTarget const*> AllTargetsSeen;
@@ -163,7 +176,6 @@ private:
mutable bool HadContextSensitiveCondition;
mutable bool HadHeadSensitiveCondition;
mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
- bool EvaluateForBuildsystem;
};
class cmGeneratorExpressionInterpreter
@@ -172,11 +184,11 @@ public:
cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
std::string config,
cmGeneratorTarget const* headTarget,
- std::string lang = std::string())
+ std::string language = std::string())
: LocalGenerator(localGenerator)
, Config(std::move(config))
, HeadTarget(headTarget)
- , Language(std::move(lang))
+ , Language(std::move(language))
{
}
@@ -185,13 +197,10 @@ public:
cmGeneratorExpressionInterpreter& operator=(
cmGeneratorExpressionInterpreter const&) = delete;
+ const std::string& Evaluate(std::string expression,
+ const std::string& property);
const std::string& Evaluate(const char* expression,
const std::string& property);
- const std::string& Evaluate(const std::string& expression,
- const std::string& property)
- {
- return this->Evaluate(expression.c_str(), property);
- }
protected:
cmGeneratorExpression GeneratorExpression;
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 6e076bf54..4709fa024 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -3,12 +3,12 @@
#ifndef cmGeneratorExpressionContext_h
#define cmGeneratorExpressionContext_h
-#include "cmListFileCache.h"
-
#include <map>
#include <set>
#include <string>
+#include "cmListFileCache.h"
+
class cmGeneratorTarget;
class cmLocalGenerator;
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 728f2a4fd..643ba346d 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -2,18 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionDAGChecker.h"
-#include "cmAlgorithms.h"
+#include <cstring>
+#include <sstream>
+#include <utility>
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmake.h"
-#include <sstream>
-#include <string.h>
-#include <utility>
-
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmListFileBacktrace backtrace, cmGeneratorTarget const* target,
std::string property, const GeneratorExpressionContent* content,
@@ -59,8 +59,7 @@ void cmGeneratorExpressionDAGChecker::Initialize()
TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*)
#undef TEST_TRANSITIVE_PROPERTY_METHOD
{
- std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator
- it = top->Seen.find(this->Target);
+ auto it = top->Seen.find(this->Target);
if (it != top->Seen.end()) {
const std::set<std::string>& propSet = it->second;
if (propSet.find(this->Property) != propSet.end()) {
@@ -68,9 +67,7 @@ void cmGeneratorExpressionDAGChecker::Initialize()
return;
}
}
- const_cast<cmGeneratorExpressionDAGChecker*>(top)
- ->Seen[this->Target]
- .insert(this->Property);
+ top->Seen[this->Target].insert(this->Property);
}
}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index e1fba5e5c..f2c49bbf2 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmListFileCache.h"
-
#include <map>
#include <set>
#include <string>
+#include "cmListFileCache.h"
+
struct GeneratorExpressionContent;
struct cmGeneratorExpressionContext;
class cmGeneratorTarget;
@@ -29,7 +29,8 @@ class cmGeneratorTarget;
SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \
SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \
SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \
- SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS)
+ SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \
+ SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS)
#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
@@ -88,7 +89,7 @@ private:
const cmGeneratorExpressionDAGChecker* const Parent;
cmGeneratorTarget const* Target;
const std::string Property;
- std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
+ mutable std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
const GeneratorExpressionContent* const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 326cb0e55..9e8707d9d 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -2,11 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionEvaluationFile.h"
-#include "cmsys/FStream.hxx"
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
#include <utility>
+#include "cmsys/FStream.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -37,8 +38,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(
{
std::string rawCondition = this->Condition->GetInput();
if (!rawCondition.empty()) {
- std::string condResult = this->Condition->Evaluate(
- lg, config, false, nullptr, nullptr, nullptr, lang);
+ std::string condResult =
+ this->Condition->Evaluate(lg, config, nullptr, nullptr, nullptr, lang);
if (condResult == "0") {
return;
}
@@ -54,9 +55,9 @@ void cmGeneratorExpressionEvaluationFile::Generate(
}
std::string outputFileName = this->OutputFileExpr->Evaluate(
- lg, config, false, nullptr, nullptr, nullptr, lang);
- const std::string& outputContent = inputExpression->Evaluate(
- lg, config, false, nullptr, nullptr, nullptr, lang);
+ lg, config, nullptr, nullptr, nullptr, lang);
+ const std::string& outputContent =
+ inputExpression->Evaluate(lg, config, nullptr, nullptr, nullptr, lang);
if (cmSystemTools::FileIsFullPath(outputFileName)) {
outputFileName = cmSystemTools::CollapseFullPath(outputFileName);
@@ -64,8 +65,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(
outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg);
}
- std::map<std::string, std::string>::iterator it =
- outputFiles.find(outputFileName);
+ auto it = outputFiles.find(outputFileName);
if (it != outputFiles.end()) {
if (it->second == outputContent) {
@@ -101,8 +101,8 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
gg->GetEnabledLanguages(enabledLanguages);
for (std::string const& le : enabledLanguages) {
- std::string name = this->OutputFileExpr->Evaluate(
- lg, config, false, nullptr, nullptr, nullptr, le);
+ std::string name = this->OutputFileExpr->Evaluate(lg, config, nullptr,
+ nullptr, nullptr, le);
cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(
name, false, cmSourceFileLocationKind::Known);
// Tell TraceDependencies that the file is not expected to exist
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 89a239057..c3bc4c85b 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -6,13 +6,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
+#include "cm_sys_stat.h"
+
#include "cmGeneratorExpression.h"
#include "cmPolicies.h"
-#include "cm_sys_stat.h"
class cmLocalGenerator;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 744201899..e0ae170c0 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionEvaluator.h"
+#include <algorithm>
+#include <sstream>
+
#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionNode.h"
-#include <algorithm>
-#include <sstream>
-
GeneratorExpressionContent::GeneratorExpressionContent(
const char* startContent, size_t length)
: StartContent(startContent)
@@ -30,9 +30,7 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
{
std::string result;
- const std::vector<
- std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
- this->ParamChildren.end();
+ const auto pend = this->ParamChildren.end();
for (; pit != pend; ++pit) {
for (cmGeneratorExpressionEvaluator* pExprEval : *pit) {
if (node->RequiresLiteralInput()) {
@@ -116,11 +114,8 @@ std::string GeneratorExpressionContent::EvaluateParameters(
{
const int numExpected = node->NumExpectedParameters();
{
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit = this->ParamChildren.begin();
- const std::vector<
- std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
- this->ParamChildren.end();
+ auto pit = this->ParamChildren.begin();
+ const auto pend = this->ParamChildren.end();
const bool acceptsArbitraryContent =
node->AcceptsArbitraryContentParameter();
int counter = 1;
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 453015262..b10bb5bda 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stddef.h>
+#include <cstddef>
#include <string>
#include <utility>
#include <vector>
diff --git a/Source/cmGeneratorExpressionLexer.h b/Source/cmGeneratorExpressionLexer.h
index bf2430818..9e0194861 100644
--- a/Source/cmGeneratorExpressionLexer.h
+++ b/Source/cmGeneratorExpressionLexer.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stddef.h>
+#include <cstddef>
#include <string>
#include <vector>
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index a60c75cd9..66f1c71f4 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2,6 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionNode.h"
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <utility>
+
+#include <cm/iterator>
+
+#include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
+
+#include "cm_static_string_view.hxx"
+
#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
@@ -19,39 +37,25 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmString.hxx"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include "cm_static_string_view.hxx"
-#include "cm_string_view.hxx"
#include "cmake.h"
-#include "cmsys/RegularExpression.hxx"
-#include "cmsys/String.h"
-
-#include <algorithm>
-#include <assert.h>
-#include <errno.h>
-#include <iterator>
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <set>
-#include <sstream>
-#include <stdlib.h>
-#include <string.h>
-#include <utility>
-
std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
std::string const& prop, cmLocalGenerator* lg,
cmGeneratorExpressionContext* context, cmGeneratorTarget const* headTarget,
- cmGeneratorTarget const* currentTarget,
- cmGeneratorExpressionDAGChecker* dagChecker)
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ cmGeneratorTarget const* currentTarget)
{
cmGeneratorExpression ge(context->Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
+ cge->SetQuiet(context->Quiet);
std::string result =
- cge->Evaluate(lg, context->Config, context->Quiet, headTarget,
- currentTarget, dagChecker, context->Language);
+ cge->Evaluate(lg, context->Config, headTarget, dagChecker, currentTarget,
+ context->Language);
if (cge->GetHadContextSensitiveCondition()) {
context->HadContextSensitiveCondition = true;
}
@@ -168,7 +172,7 @@ static const struct BoolNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- return !cmSystemTools::IsOff(parameters.front()) ? "1" : "0";
+ return !cmIsOff(parameters.front()) ? "1" : "0";
}
} boolNode;
@@ -274,17 +278,18 @@ static const struct InListNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> values, checkValues;
+ std::vector<std::string> values;
+ std::vector<std::string> checkValues;
bool check = false;
switch (context->LG->GetPolicyStatus(cmPolicies::CMP0085)) {
case cmPolicies::WARN:
if (parameters.front().empty()) {
check = true;
- cmSystemTools::ExpandListArgument(parameters[1], checkValues, true);
+ cmExpandList(parameters[1], checkValues, true);
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
- cmSystemTools::ExpandListArgument(parameters[1], values);
+ cmExpandList(parameters[1], values);
if (check && values != checkValues) {
std::ostringstream e;
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0085)
@@ -301,14 +306,11 @@ static const struct InListNode : public cmGeneratorExpressionNode
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
- cmSystemTools::ExpandListArgument(parameters[1], values, true);
+ cmExpandList(parameters[1], values, true);
break;
}
- return std::find(values.cbegin(), values.cend(), parameters.front()) ==
- values.cend()
- ? "0"
- : "1";
+ return cmContains(values, parameters.front()) ? "1" : "0";
}
} inListNode;
@@ -346,8 +348,9 @@ static const struct FilterNode : public cmGeneratorExpressionNode
return {};
}
- std::vector<std::string> values, result;
- cmSystemTools::ExpandListArgument(parameters.front(), values, true);
+ std::vector<std::string> values;
+ std::vector<std::string> result;
+ cmExpandList(parameters.front(), values, true);
std::copy_if(values.cbegin(), values.cend(), std::back_inserter(result),
[&re, exclude](std::string const& input) {
@@ -375,8 +378,7 @@ static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
"$<REMOVE_DUPLICATES:...> expression requires one parameter");
}
- std::vector<std::string> values;
- cmSystemTools::ExpandListArgument(parameters.front(), values, true);
+ std::vector<std::string> values = cmExpandedList(parameters.front(), true);
auto valuesEnd = cmRemoveDuplicates(values);
auto valuesBegin = values.cbegin();
@@ -477,13 +479,13 @@ protected:
}
return this->EvaluateDependentExpression(
- expression, context->LG, context, context->HeadTarget,
- context->CurrentTarget, &dagChecker);
+ expression, context->LG, context, context->HeadTarget, &dagChecker,
+ context->CurrentTarget);
}
return this->EvaluateDependentExpression(
- expression, context->LG, context, context->HeadTarget,
- context->CurrentTarget, dagCheckerParent);
+ expression, context->LG, context, context->HeadTarget, dagCheckerParent,
+ context->CurrentTarget);
}
};
@@ -684,10 +686,10 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
if (cmsysString_strcasecmp(param.c_str(), compilerId.c_str()) == 0) {
switch (context->LG->GetPolicyStatus(cmPolicies::CMP0044)) {
case cmPolicies::WARN: {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0044);
context->LG->GetCMakeInstance()->IssueMessage(
- MessageType::AUTHOR_WARNING, e.str(), context->Backtrace);
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0044),
+ context->Backtrace);
CM_FALLTHROUGH;
}
case cmPolicies::OLD:
@@ -706,7 +708,8 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
};
static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
- cudaCompilerIdNode("CUDA"), fortranCompilerIdNode("Fortran");
+ cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"),
+ objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran");
struct CompilerVersionNode : public cmGeneratorExpressionNode
{
@@ -770,6 +773,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
static const CompilerVersionNode cCompilerVersionNode("C"),
cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
+ objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"),
fortranCompilerVersionNode("Fortran");
struct PlatformIdNode : public cmGeneratorExpressionNode
@@ -909,15 +913,13 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
// 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 = "MAP_IMPORTED_CONFIG_";
- mapProp += cmSystemTools::UpperCase(context->Config);
+ std::string mapProp = cmStrCat(
+ "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
if (const char* mapValue =
context->CurrentTarget->GetProperty(mapProp)) {
- cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue),
- mappedConfigs);
- return std::find(mappedConfigs.begin(), mappedConfigs.end(),
- cmSystemTools::UpperCase(parameters.front())) !=
- mappedConfigs.end()
+ cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
+ return cmContains(mappedConfigs,
+ cmSystemTools::UpperCase(parameters.front()))
? "1"
: "0";
}
@@ -941,8 +943,7 @@ static const struct JoinNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(parameters.front(), list);
+ std::vector<std::string> list = cmExpandedList(parameters.front());
return cmJoin(list, parameters[1]);
}
} joinNode;
@@ -1038,45 +1039,38 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
}
} languageAndIdNode;
-#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY
-
-static const char* targetPropertyTransitiveWhitelist[] = {
- nullptr CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
-};
-
-#undef TRANSITIVE_PROPERTY_NAME
-
-template <typename T>
std::string getLinkedTargetsContent(
- std::vector<T> const& libraries, cmGeneratorTarget const* target,
- cmGeneratorTarget const* headTarget, cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagChecker,
- const std::string& interfacePropertyName)
-{
- std::string linkedTargetsContent;
- std::string sep;
- std::string depString;
- for (T const& l : 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
- // self-referencing loop.
- if (l.Target && l.Target != target) {
- std::string uniqueName =
- target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target);
- depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," +
- interfacePropertyName + ">";
- sep = ";";
- }
- }
- if (!depString.empty()) {
- linkedTargetsContent =
- cmGeneratorExpressionNode::EvaluateDependentExpression(
- depString, target->GetLocalGenerator(), context, headTarget, target,
- dagChecker);
- }
- linkedTargetsContent =
- cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
- return linkedTargetsContent;
+ cmGeneratorTarget const* target, std::string const& prop,
+ cmGeneratorExpressionContext* context,
+ cmGeneratorExpressionDAGChecker* dagChecker)
+{
+ std::string result;
+ if (cmLinkImplementationLibraries const* impl =
+ target->GetLinkImplementationLibraries(context->Config)) {
+ for (cmLinkImplItem const& lib : impl->Libraries) {
+ if (lib.Target) {
+ // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
+ // caller's property and hand-evaluate it as if it were compiled.
+ // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+ cmGeneratorExpressionContext libContext(
+ target->GetLocalGenerator(), context->Config, context->Quiet, target,
+ target, context->EvaluateForBuildsystem, lib.Backtrace,
+ context->Language);
+ std::string libResult =
+ lib.Target->EvaluateInterfaceProperty(prop, &libContext, dagChecker);
+ if (!libResult.empty()) {
+ if (result.empty()) {
+ result = std::move(libResult);
+ } else {
+ result.reserve(result.size() + 1 + libResult.size());
+ result += ";";
+ result += libResult;
+ }
+ }
+ }
+ }
+ }
+ return result;
}
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
@@ -1116,7 +1110,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
cmGeneratorTarget const* target = nullptr;
- std::string targetName, propertyName;
+ std::string targetName;
+ std::string propertyName;
if (parameters.size() == 2) {
targetName = parameters[0];
@@ -1205,44 +1200,37 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return target->GetLinkerLanguage(context->Config);
}
- cmGeneratorExpressionDAGChecker dagChecker(
- context->Backtrace, target, propertyName, content, dagCheckerParent);
+ std::string interfacePropertyName;
+ bool isInterfaceProperty = false;
- switch (dagChecker.Check()) {
- case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
- dagChecker.ReportError(context, content->GetOriginalExpression());
- return std::string();
- case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
- // No error. We just skip cyclic references.
- return std::string();
- case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
- for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist);
- ++i) {
- if (targetPropertyTransitiveWhitelist[i] == propertyName) {
- // No error. We're not going to find anything new here.
- return std::string();
- }
- }
- case cmGeneratorExpressionDAGChecker::DAG:
- break;
- }
+#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
+ if (propertyName == #prop) { \
+ interfacePropertyName = "INTERFACE_" #prop; \
+ } else if (propertyName == "INTERFACE_" #prop) { \
+ interfacePropertyName = "INTERFACE_" #prop; \
+ isInterfaceProperty = true; \
+ } else
- std::string prop;
- bool haveProp = false;
- if (const char* p = target->GetProperty(propertyName)) {
- prop = p;
- haveProp = true;
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
+ // Note that the above macro terminates with an else
+ /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) {
+ cmPolicies::PolicyStatus polSt =
+ context->LG->GetPolicyStatus(cmPolicies::CMP0043);
+ if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
+ interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
+ }
}
+#undef POPULATE_INTERFACE_PROPERTY_NAME
+
+ bool evaluatingLinkLibraries = false;
if (dagCheckerParent) {
if (dagCheckerParent->EvaluatingGenexExpression() ||
dagCheckerParent->EvaluatingPICExpression()) {
// No check required.
} else if (dagCheckerParent->EvaluatingLinkLibraries()) {
-#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
- (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
- if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(
- TRANSITIVE_PROPERTY_COMPARE) false) { // NOLINT(*)
+ evaluatingLinkLibraries = true;
+ if (!interfacePropertyName.empty()) {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression in link libraries "
@@ -1250,69 +1238,47 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
"over the link libraries, creating a recursion.");
return std::string();
}
-#undef TRANSITIVE_PROPERTY_COMPARE
-
- if (!haveProp) {
- return std::string();
- }
} else {
#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
-
assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
}
}
- std::string linkedTargetsContent;
-
- std::string interfacePropertyName;
- bool isInterfaceProperty = false;
+ if (isInterfaceProperty) {
+ return target->EvaluateInterfaceProperty(propertyName, context,
+ dagCheckerParent);
+ }
-#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
- if (propertyName == #prop) { \
- interfacePropertyName = "INTERFACE_" #prop; \
- } else if (propertyName == "INTERFACE_" #prop) { \
- interfacePropertyName = "INTERFACE_" #prop; \
- isInterfaceProperty = true; \
- } else
+ cmGeneratorExpressionDAGChecker dagChecker(
+ context->Backtrace, target, propertyName, content, dagCheckerParent);
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
- // Note that the above macro terminates with an else
- /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) {
- cmPolicies::PolicyStatus polSt =
- context->LG->GetPolicyStatus(cmPolicies::CMP0043);
- if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
- interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
- }
+ switch (dagChecker.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dagChecker.ReportError(context, content->GetOriginalExpression());
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // We handle transitive properties above. For non-transitive
+ // properties we accept repeats anyway.
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
}
-#undef POPULATE_INTERFACE_PROPERTY_NAME
- cmGeneratorTarget const* headTarget =
- context->HeadTarget && isInterfaceProperty ? context->HeadTarget
- : target;
- if (isInterfaceProperty) {
- if (cmLinkInterfaceLibraries const* iface =
- target->GetLinkInterfaceLibraries(context->Config, headTarget,
- true)) {
- linkedTargetsContent =
- getLinkedTargetsContent(iface->Libraries, target, headTarget,
- context, &dagChecker, interfacePropertyName);
- }
- } else if (!interfacePropertyName.empty()) {
- if (cmLinkImplementationLibraries const* impl =
- target->GetLinkImplementationLibraries(context->Config)) {
- linkedTargetsContent =
- getLinkedTargetsContent(impl->Libraries, target, target, context,
- &dagChecker, interfacePropertyName);
- }
+ std::string result;
+ bool haveProp = false;
+ if (const char* p = target->GetProperty(propertyName)) {
+ result = p;
+ haveProp = true;
+ } else if (evaluatingLinkLibraries) {
+ return std::string();
}
- if (!haveProp) {
- if (target->IsImported() ||
- target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
- return linkedTargetsContent;
- }
+ if (!haveProp && !target->IsImported() &&
+ target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
@@ -1345,8 +1311,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
context->Config);
return propContent ? propContent : "";
}
-
- return linkedTargetsContent;
}
if (!target->IsImported() && dagCheckerParent &&
@@ -1368,15 +1332,17 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return propContent ? propContent : "";
}
}
+
if (!interfacePropertyName.empty()) {
- std::string result = this->EvaluateDependentExpression(
- prop, context->LG, context, headTarget, target, &dagChecker);
+ result = this->EvaluateDependentExpression(result, context->LG, context,
+ target, &dagChecker, target);
+ std::string linkedTargetsContent = getLinkedTargetsContent(
+ target, interfacePropertyName, context, &dagChecker);
if (!linkedTargetsContent.empty()) {
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
- return result;
}
- return prop;
+ return result;
}
} targetPropertyNode;
@@ -1456,7 +1422,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
const char* imp = nullptr;
std::string suffix;
if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
- cmSystemTools::ExpandListArgument(loc, objects);
+ cmExpandList(loc, objects);
}
context->HadContextSensitiveCondition = true;
} else {
@@ -1476,7 +1442,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
for (std::string& o : objects) {
- o = obj_dir + o;
+ o = cmStrCat(obj_dir, o);
}
}
@@ -1512,7 +1478,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
}
context->HadHeadSensitiveCondition = true;
- typedef std::map<std::string, std::vector<std::string>> LangMap;
+ using LangMap = std::map<std::string, std::vector<std::string>>;
static LangMap availableFeatures;
LangMap testedFeatures;
@@ -1534,8 +1500,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
reportError(context, content->GetOriginalExpression(), error);
return std::string();
}
- cmSystemTools::ExpandListArgument(featuresKnown,
- availableFeatures[lang]);
+ cmExpandList(featuresKnown, availableFeatures[lang]);
}
}
@@ -1547,8 +1512,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
"CMAKE_" + lit.first + "_STANDARD_DEFAULT");
for (std::string const& it : lit.second) {
- if (std::find(langAvailable.begin(), langAvailable.end(), it) ==
- langAvailable.end()) {
+ if (!cmContains(langAvailable, it)) {
return "0";
}
if (standardDefault && !*standardDefault) {
@@ -1734,9 +1698,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
"SHARED libraries.");
return std::string();
}
- std::string result = target->GetDirectory(context->Config);
- result += "/";
- result += target->GetSOName(context->Config);
+ std::string result = cmStrCat(target->GetDirectory(context->Config), '/',
+ target->GetSOName(context->Config));
return result;
}
};
@@ -1775,9 +1738,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
return std::string();
}
- std::string result = target->GetPDBDirectory(context->Config);
- result += "/";
- result += target->GetPDBName(context->Config);
+ std::string result = cmStrCat(target->GetPDBDirectory(context->Config),
+ '/', target->GetPDBName(context->Config));
return result;
}
};
@@ -2250,8 +2212,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> listIn;
- cmSystemTools::ExpandListArgument(parameters.front(), listIn);
+ std::vector<std::string> listIn = cmExpandedList(parameters.front());
if (listIn.empty()) {
reportError(context, content->GetOriginalExpression(),
"\"\" is not an absolute path.");
@@ -2285,6 +2246,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "NOT", &notNode },
{ "C_COMPILER_ID", &cCompilerIdNode },
{ "CXX_COMPILER_ID", &cxxCompilerIdNode },
+ { "OBJC_COMPILER_ID", &objcCompilerIdNode },
+ { "OBJCXX_COMPILER_ID", &objcxxCompilerIdNode },
{ "CUDA_COMPILER_ID", &cudaCompilerIdNode },
{ "Fortran_COMPILER_ID", &fortranCompilerIdNode },
{ "VERSION_GREATER", &versionGreaterNode },
@@ -2295,6 +2258,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "C_COMPILER_VERSION", &cCompilerVersionNode },
{ "CXX_COMPILER_VERSION", &cxxCompilerVersionNode },
{ "CUDA_COMPILER_VERSION", &cudaCompilerVersionNode },
+ { "OBJC_COMPILER_VERSION", &objcCompilerVersionNode },
+ { "OBJCXX_COMPILER_VERSION", &objcxxCompilerVersionNode },
{ "Fortran_COMPILER_VERSION", &fortranCompilerVersionNode },
{ "PLATFORM_ID", &platformIdNode },
{ "COMPILE_FEATURES", &compileFeaturesNode },
diff --git a/Source/cmGeneratorExpressionNode.h b/Source/cmGeneratorExpressionNode.h
index 7a369249f..13e8484ef 100644
--- a/Source/cmGeneratorExpressionNode.h
+++ b/Source/cmGeneratorExpressionNode.h
@@ -43,8 +43,8 @@ struct cmGeneratorExpressionNode
static std::string EvaluateDependentExpression(
std::string const& prop, cmLocalGenerator* lg,
cmGeneratorExpressionContext* context, const cmGeneratorTarget* headTarget,
- const cmGeneratorTarget* currentTarget,
- cmGeneratorExpressionDAGChecker* dagChecker);
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ const cmGeneratorTarget* currentTarget);
static const cmGeneratorExpressionNode* GetNode(
const std::string& identifier);
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index 304378dfe..d6cc6ab1c 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -2,13 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionParser.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmGeneratorExpressionEvaluator.h"
-#include <assert.h>
-#include <stddef.h>
-#include <utility>
-
cmGeneratorExpressionParser::cmGeneratorExpressionParser(
std::vector<cmGeneratorExpressionToken> tokens)
: Tokens(std::move(tokens))
@@ -66,8 +66,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
unsigned int nestedLevel = this->NestingLevel;
++this->NestingLevel;
- std::vector<cmGeneratorExpressionToken>::const_iterator startToken =
- this->it - 1;
+ auto startToken = this->it - 1;
std::vector<cmGeneratorExpressionEvaluator*> identifier;
while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression &&
@@ -174,13 +173,9 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
if (!parameters.empty()) {
extendText(result, colonToken);
- typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector;
- typedef std::vector<cmGeneratorExpressionToken> TokenVector;
- std::vector<EvaluatorVector>::const_iterator pit = parameters.begin();
- const std::vector<EvaluatorVector>::const_iterator pend =
- parameters.end();
- std::vector<TokenVector::const_iterator>::const_iterator commaIt =
- commaTokens.begin();
+ auto pit = parameters.begin();
+ const auto pend = parameters.end();
+ auto commaIt = commaTokens.begin();
assert(parameters.size() > commaTokens.size());
for (; pit != pend; ++pit, ++commaIt) {
if (!pit->empty() && !emptyParamTermination) {
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 036a07d1c..171c3ed39 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2,27 +2,35 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorTarget.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
-#include <errno.h>
+#include <cassert>
+#include <cerrno>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <iterator>
-#include <memory> // IWYU pragma: keep
-#include <queue>
+#include <memory>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <unordered_set>
#include <utility>
+#include <cm/string_view>
+
+#include <queue>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
+#include "cmGeneratorExpressionNode.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -31,7 +39,9 @@
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
@@ -76,25 +86,16 @@ public:
virtual ~TargetPropertyEntry() = default;
virtual const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet = false,
- cmGeneratorTarget const* headTarget = nullptr,
- cmGeneratorTarget const* currentTarget = nullptr,
- cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
- std::string const& language = std::string()) const = 0;
- virtual const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet,
+ cmLocalGenerator* lg, const std::string& config,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::string const& language = std::string()) const = 0;
+ std::string const& language) const = 0;
virtual cmListFileBacktrace GetBacktrace() const = 0;
virtual std::string const& GetInput() const = 0;
virtual bool GetHadContextSensitiveCondition() const { return false; }
cmLinkImplItem const& LinkImplItem;
-
-private:
- cmListFileBacktrace Backtrace;
};
cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
@@ -108,23 +109,12 @@ public:
{
}
- const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet = false,
- cmGeneratorTarget const* headTarget = nullptr,
- cmGeneratorTarget const* currentTarget = nullptr,
- cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
- std::string const& language = std::string()) const override
- {
- return this->ge->Evaluate(lg, config, quiet, headTarget, currentTarget,
- dagChecker, language);
- }
- const std::string& Evaluate(
- cmLocalGenerator* lg, const std::string& config, bool quiet,
- cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
- std::string const& language = std::string()) const override
+ const std::string& Evaluate(cmLocalGenerator* lg, const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::string const& language) const override
{
- return this->ge->Evaluate(lg, config, quiet, headTarget, dagChecker,
+ return this->ge->Evaluate(lg, config, headTarget, dagChecker, nullptr,
language);
}
@@ -156,15 +146,7 @@ public:
{
}
- const std::string& Evaluate(cmLocalGenerator*, const std::string&, bool,
- cmGeneratorTarget const*,
- cmGeneratorTarget const*,
- cmGeneratorExpressionDAGChecker*,
- std::string const&) const override
- {
- return this->PropertyValue;
- }
- const std::string& Evaluate(cmLocalGenerator*, const std::string&, bool,
+ const std::string& Evaluate(cmLocalGenerator*, const std::string&,
cmGeneratorTarget const*,
cmGeneratorExpressionDAGChecker*,
std::string const&) const override
@@ -193,7 +175,7 @@ cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry(
return new TargetPropertyEntryGenex(std::move(cge));
}
- return new TargetPropertyEntryString(propertyValue, backtrace);
+ return new TargetPropertyEntryString(propertyValue, std::move(backtrace));
}
void CreatePropertyGeneratorExpressions(
@@ -201,14 +183,69 @@ void CreatePropertyGeneratorExpressions(
std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
bool evaluateForBuildsystem = false)
{
- std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
- for (std::vector<std::string>::const_iterator it = entries.begin();
- it != entries.end(); ++it, ++btIt) {
+ auto btIt = backtraces.begin();
+ for (auto it = entries.begin(); it != entries.end(); ++it, ++btIt) {
items.push_back(
CreateTargetPropertyEntry(*it, *btIt, evaluateForBuildsystem));
}
}
+namespace {
+// Represent a target property entry after evaluating generator expressions
+// and splitting up lists.
+struct EvaluatedTargetPropertyEntry
+{
+ EvaluatedTargetPropertyEntry(cmLinkImplItem const& item,
+ cmListFileBacktrace bt)
+ : LinkImplItem(item)
+ , Backtrace(std::move(bt))
+ {
+ }
+
+ // Move-only.
+ EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default;
+ EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete;
+ EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) =
+ delete;
+ EvaluatedTargetPropertyEntry& operator=(
+ EvaluatedTargetPropertyEntry const&) = delete;
+
+ cmLinkImplItem const& LinkImplItem;
+ cmListFileBacktrace Backtrace;
+ std::vector<std::string> Values;
+ bool ContextDependent = false;
+};
+
+EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+ cmGeneratorTarget::TargetPropertyEntry* entry)
+{
+ EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace());
+ cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config,
+ thisTarget, dagChecker, lang),
+ ee.Values);
+ if (entry->GetHadContextSensitiveCondition()) {
+ ee.ContextDependent = true;
+ }
+ return ee;
+}
+
+std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in)
+{
+ std::vector<EvaluatedTargetPropertyEntry> out;
+ out.reserve(in.size());
+ for (cmGeneratorTarget::TargetPropertyEntry* entry : in) {
+ out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
+ dagChecker, entry));
+ }
+ return out;
+}
+}
+
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
: Target(t)
, FortranModuleDirectoryCreated(false)
@@ -221,6 +258,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
, DebugCompileDefinitionsDone(false)
, DebugLinkOptionsDone(false)
, DebugLinkDirectoriesDone(false)
+ , DebugPrecompileHeadersDone(false)
, DebugSourcesDone(false)
, LinkImplementationLanguageIsContextDependent(true)
, UtilityItemsDone(false)
@@ -255,13 +293,14 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
t->GetLinkDirectoriesBacktraces(),
this->LinkDirectoriesEntries);
+ CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(),
+ t->GetPrecompileHeadersBacktraces(),
+ this->PrecompileHeadersEntries);
+
CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
t->GetSourceBacktraces(),
this->SourceEntries, true);
- this->DLLPlatform =
- !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
-
this->PolicyMap = t->GetPolicyMap();
}
@@ -273,6 +312,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
cmDeleteAll(this->CompileDefinitionsEntries);
cmDeleteAll(this->LinkOptionsEntries);
cmDeleteAll(this->LinkDirectoriesEntries);
+ cmDeleteAll(this->PrecompileHeadersEntries);
cmDeleteAll(this->SourceEntries);
cmDeleteAll(this->LinkInformation);
}
@@ -409,8 +449,7 @@ std::string cmGeneratorTarget::GetOutputName(
{
// Lookup/compute/cache the output name for this configuration.
OutputNameKey key(config, artifact);
- cmGeneratorTarget::OutputNameMapType::iterator i =
- this->OutputNameMap.find(key);
+ auto i = this->OutputNameMap.find(key);
if (i == this->OutputNameMap.end()) {
// Add empty name in map to detect potential recursion.
OutputNameMapType::value_type entry(key, "");
@@ -450,9 +489,8 @@ std::string cmGeneratorTarget::GetOutputName(
}
// Now evaluate genex and update the previously-prepared map entry.
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
- i->second = cge->Evaluate(this->LocalGenerator, config);
+ i->second =
+ cmGeneratorExpression::Evaluate(outName, this->LocalGenerator, config);
} else if (i->second.empty()) {
// An empty map entry indicates we have been called recursively
// from the above block.
@@ -468,12 +506,14 @@ std::string cmGeneratorTarget::GetFilePrefix(
const std::string& config, cmStateEnums::ArtifactType artifact) const
{
if (this->IsImported()) {
- const char* prefix = this->GetFilePrefixInternal(artifact);
+ const char* prefix = this->GetFilePrefixInternal(config, artifact);
return prefix ? prefix : std::string();
}
- std::string prefix, suffix, base;
+ std::string prefix;
+ std::string suffix;
+ std::string base;
this->GetFullNameInternal(config, artifact, prefix, base, suffix);
return prefix;
}
@@ -481,12 +521,14 @@ std::string cmGeneratorTarget::GetFileSuffix(
const std::string& config, cmStateEnums::ArtifactType artifact) const
{
if (this->IsImported()) {
- const char* suffix = this->GetFileSuffixInternal(artifact);
+ const char* suffix = this->GetFileSuffixInternal(config, artifact);
return suffix ? suffix : std::string();
}
- std::string prefix, suffix, base;
+ std::string prefix;
+ std::string suffix;
+ std::string base;
this->GetFullNameInternal(config, artifact, prefix, base, suffix);
return suffix;
}
@@ -495,8 +537,8 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
{
const char* postfix = nullptr;
if (!config.empty()) {
- std::string configProp = cmSystemTools::UpperCase(config);
- configProp += "_POSTFIX";
+ std::string configProp =
+ cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
postfix = this->GetProperty(configProp);
// Mac application bundles and frameworks have no postfix.
if (!this->IsImported() && postfix &&
@@ -508,7 +550,8 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
}
const char* cmGeneratorTarget::GetFilePrefixInternal(
- cmStateEnums::ArtifactType artifact, const std::string& language) const
+ std::string const& config, cmStateEnums::ArtifactType artifact,
+ const std::string& language) const
{
// no prefix for non-main target types.
if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
@@ -523,8 +566,7 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
// Return an empty prefix for the import library if this platform
// does not support import libraries.
- if (isImportedLibraryArtifact &&
- !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
return nullptr;
}
@@ -558,7 +600,8 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
return targetPrefix;
}
const char* cmGeneratorTarget::GetFileSuffixInternal(
- cmStateEnums::ArtifactType artifact, const std::string& language) const
+ std::string const& config, cmStateEnums::ArtifactType artifact,
+ const std::string& language) const
{
// no suffix for non-main target types.
if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
@@ -573,8 +616,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
// Return an empty suffix for the import library if this platform
// does not support import libraries.
- if (isImportedLibraryArtifact &&
- !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
return nullptr;
}
@@ -650,27 +692,27 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
cmSourceFile const* sf) const
{
- SourceEntriesType::const_iterator i = this->SourceDepends.find(sf);
+ auto i = this->SourceDepends.find(sf);
if (i != this->SourceDepends.end()) {
return &i->second.Depends;
}
return nullptr;
}
-static void handleSystemIncludesDep(
- cmLocalGenerator* lg, cmGeneratorTarget const* depTgt,
- const std::string& config, cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::string>& result, bool excludeImported,
- std::string const& language)
+namespace {
+void handleSystemIncludesDep(cmLocalGenerator* lg,
+ cmGeneratorTarget const* depTgt,
+ const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<std::string>& result,
+ bool excludeImported, std::string const& language)
{
if (const char* dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
- cmGeneratorExpression ge;
- cmSystemTools::ExpandListArgument(
- ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, depTgt,
- dagChecker, language),
- result);
+ cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ dagChecker, depTgt, language),
+ result);
}
if (!depTgt->IsImported() || excludeImported) {
return;
@@ -678,13 +720,12 @@ static void handleSystemIncludesDep(
if (const char* dirs =
depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
- cmGeneratorExpression ge;
- cmSystemTools::ExpandListArgument(
- ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, depTgt,
- dagChecker, language),
- result);
+ cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ dagChecker, depTgt, language),
+ result);
}
}
+}
/* clang-format off */
#define IMPLEMENT_VISIT(KIND) \
@@ -720,11 +761,8 @@ void cmGeneratorTarget::ComputeObjectMapping()
return;
}
- std::vector<std::string> configs;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs();
for (std::string const& c : configs) {
std::vector<cmSourceFile const*> sourceFiles;
this->GetObjectSources(sourceFiles, c);
@@ -735,9 +773,8 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
const std::string& config) const
{
if (!config.empty()) {
- std::string featureConfig = feature;
- featureConfig += "_";
- featureConfig += cmSystemTools::UpperCase(config);
+ std::string featureConfig =
+ cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
if (const char* value = this->GetProperty(featureConfig)) {
return value;
}
@@ -771,7 +808,7 @@ bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
std::string const& config) const
{
const char* feature = "INTERPROCEDURAL_OPTIMIZATION";
- const bool result = cmSystemTools::IsOn(this->GetFeature(feature, config));
+ const bool result = cmIsOn(this->GetFeature(feature, config));
if (!result) {
// 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies
@@ -862,8 +899,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
{
const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
- std::set<cmSourceFile const*>::const_iterator it =
- this->ExplicitObjectName.find(file);
+ auto it = this->ExplicitObjectName.find(file);
return it != this->ExplicitObjectName.end();
}
@@ -1044,9 +1080,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
config_upper = cmSystemTools::UpperCase(config);
}
- typedef std::map<std::string, std::vector<std::string>> IncludeCacheType;
- IncludeCacheType::const_iterator iter =
- this->SystemIncludesCache.find(config_upper);
+ using IncludeCacheType = std::map<std::string, std::vector<std::string>>;
+ auto iter = this->SystemIncludesCache.find(config_upper);
if (iter == this->SystemIncludesCache.end()) {
cmGeneratorExpressionDAGChecker dagChecker(
@@ -1056,11 +1091,10 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
std::vector<std::string> result;
for (std::string const& it : this->Target->GetSystemIncludeDirectories()) {
- cmGeneratorExpression ge;
- cmSystemTools::ExpandListArgument(
- ge.Parse(it)->Evaluate(this->LocalGenerator, config, false, this,
- &dagChecker, language),
- result);
+ cmExpandList(cmGeneratorExpression::Evaluate(it, this->LocalGenerator,
+ config, this, &dagChecker,
+ nullptr, language),
+ result);
}
std::vector<cmGeneratorTarget const*> const& deps =
@@ -1087,80 +1121,207 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
return this->Target->GetPropertyAsBool(prop);
}
-static void AddInterfaceEntries(
- cmGeneratorTarget const* thisTarget, std::string const& config,
- std::string const& prop,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
+ std::string const& prop, cmGeneratorExpressionContext* context) const
+{
+ std::string const key = prop + '@' + context->Config;
+ auto i = this->MaybeInterfacePropertyExists.find(key);
+ if (i == this->MaybeInterfacePropertyExists.end()) {
+ // Insert an entry now in case there is a cycle.
+ i = this->MaybeInterfacePropertyExists.emplace(key, false).first;
+ 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;
+
+ // Otherwise, recurse to interface dependencies.
+ if (!maybeInterfaceProp) {
+ cmGeneratorTarget const* headTarget =
+ context->HeadTarget ? context->HeadTarget : this;
+ if (cmLinkInterfaceLibraries const* iface =
+ this->GetLinkInterfaceLibraries(context->Config, headTarget,
+ true)) {
+ if (iface->HadHeadSensitiveCondition) {
+ // With a different head target we may get to a library with
+ // this interface property.
+ maybeInterfaceProp = true;
+ } else {
+ // The transitive interface libraries do not depend on the
+ // head target, so we can follow them.
+ for (cmLinkItem const& lib : iface->Libraries) {
+ if (lib.Target &&
+ lib.Target->MaybeHaveInterfaceProperty(prop, context)) {
+ maybeInterfaceProp = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return i->second;
+}
+
+std::string cmGeneratorTarget::EvaluateInterfaceProperty(
+ std::string const& prop, cmGeneratorExpressionContext* context,
+ cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+{
+ std::string result;
+
+ // If the property does not appear transitively at all, we are done.
+ if (!this->MaybeHaveInterfaceProperty(prop, context)) {
+ return result;
+ }
+
+ // Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled. This is
+ // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
+ // but sufficient for transitive interface properties.
+ cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, this, prop,
+ nullptr, dagCheckerParent);
+ switch (dagChecker.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dagChecker.ReportError(
+ context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
+ 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;
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ cmGeneratorTarget const* headTarget =
+ context->HeadTarget ? context->HeadTarget : this;
+
+ if (const char* p = this->GetProperty(prop)) {
+ result = cmGeneratorExpressionNode::EvaluateDependentExpression(
+ p, context->LG, context, headTarget, &dagChecker, this);
+ }
+
+ if (cmLinkInterfaceLibraries const* iface =
+ this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) {
+ 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
+ // self-referencing loop.
+ if (lib.Target && lib.Target != this) {
+ // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
+ // above property and hand-evaluate it as if it were compiled.
+ // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+ cmGeneratorExpressionContext libContext(
+ context->LG, context->Config, context->Quiet, headTarget, this,
+ context->EvaluateForBuildsystem, context->Backtrace,
+ context->Language);
+ std::string libResult = cmGeneratorExpression::StripEmptyListElements(
+ lib.Target->EvaluateInterfaceProperty(prop, &libContext,
+ &dagChecker));
+ if (!libResult.empty()) {
+ if (result.empty()) {
+ result = std::move(libResult);
+ } else {
+ result.reserve(result.size() + 1 + libResult.size());
+ result += ";";
+ result += libResult;
+ }
+ }
+ context->HadContextSensitiveCondition =
+ context->HadContextSensitiveCondition ||
+ libContext.HadContextSensitiveCondition;
+ context->HadHeadSensitiveCondition =
+ context->HadHeadSensitiveCondition ||
+ libContext.HadHeadSensitiveCondition;
+ }
+ }
+ }
+
+ return result;
+}
+
+namespace {
+void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
+ std::string const& config, std::string const& prop,
+ std::string const& lang,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
{
if (cmLinkImplementationLibraries const* impl =
- thisTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
- std::string uniqueName =
- thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
- lib.Target);
- std::string genex =
- "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">";
- cmGeneratorExpression ge(lib.Backtrace);
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
- cge->SetEvaluateForBuildsystem(true);
- entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+ EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+ // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
+ // caller's property and hand-evaluate it as if it were compiled.
+ // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+ cmGeneratorExpressionContext context(
+ headTarget->GetLocalGenerator(), config, false, headTarget,
+ headTarget, true, lib.Backtrace, lang);
+ cmExpandList(
+ lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker),
+ ee.Values);
+ ee.ContextDependent = context.HadContextSensitiveCondition;
+ entries.emplace_back(std::move(ee));
}
}
}
}
-static void AddObjectEntries(
- cmGeneratorTarget const* thisTarget, std::string const& config,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+void AddObjectEntries(cmGeneratorTarget const* headTarget,
+ std::string const& config,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ std::vector<EvaluatedTargetPropertyEntry>& entries)
{
if (cmLinkImplementationLibraries const* impl =
- thisTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target &&
lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::string uniqueName =
- thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
+ headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
lib.Target);
std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">";
cmGeneratorExpression ge(lib.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
- entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+
+ EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+ cmExpandList(cge->Evaluate(headTarget->GetLocalGenerator(), config,
+ headTarget, dagChecker),
+ ee.Values);
+ if (cge->GetHadContextSensitiveCondition()) {
+ ee.ContextDependent = true;
+ }
+ entries.emplace_back(std::move(ee));
}
}
}
}
-static bool processSources(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& srcs,
- std::unordered_set<std::string>& uniqueSrcs,
- cmGeneratorExpressionDAGChecker* dagChecker, std::string const& config,
- bool debugSources)
+bool processSources(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
+ std::vector<BT<std::string>>& srcs,
+ std::unordered_set<std::string>& uniqueSrcs,
+ bool debugSources)
{
cmMakefile* mf = tgt->Target->GetMakefile();
bool contextDependent = false;
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
- std::string const& targetName = item.AsStr();
- std::vector<std::string> entrySources;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt, tgt,
- dagChecker),
- entrySources);
-
- if (entry->GetHadContextSensitiveCondition()) {
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ if (entry.ContextDependent) {
contextDependent = true;
}
- for (std::string& src : entrySources) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
+ std::string const& targetName = item.AsStr();
+
+ for (std::string& src : entry.Values) {
cmSourceFile* sf = mf->GetOrCreateSource(src);
std::string e;
- std::string fullPath = sf->GetFullPath(&e);
+ std::string fullPath = sf->ResolveFullPath(&e);
if (fullPath.empty()) {
if (!e.empty()) {
cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
@@ -1186,9 +1347,9 @@ static bool processSources(
src = fullPath;
}
std::string usedSources;
- for (std::string const& src : entrySources) {
+ for (std::string const& src : entry.Values) {
if (uniqueSrcs.insert(src).second) {
- srcs.emplace_back(src, entry->GetBacktrace());
+ srcs.emplace_back(src, entry.Backtrace);
if (debugSources) {
usedSources += " * " + src + "\n";
}
@@ -1199,11 +1360,12 @@ static bool processSources(
MessageType::LOG,
std::string("Used sources for target ") + tgt->GetName() + ":\n" +
usedSources,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
return contextDependent;
}
+}
std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
std::string const& config) const
@@ -1220,8 +1382,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmStringRange sourceEntries = this->Target->GetSourceEntries();
for (std::string const& entry : sourceEntries) {
- std::vector<std::string> items;
- cmSystemTools::ExpandListArgument(entry, items);
+ std::vector<std::string> items = cmExpandedList(entry);
for (std::string const& item : items) {
if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") &&
item.back() == '>') {
@@ -1237,12 +1398,11 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
- bool debugSources = !this->DebugSourcesDone &&
- std::find(debugProperties.begin(), debugProperties.end(), "SOURCES") !=
- debugProperties.end();
+ bool debugSources =
+ !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
this->DebugSourcesDone = true;
@@ -1251,28 +1411,31 @@ 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);
+
std::unordered_set<std::string> uniqueSrcs;
bool contextDependentDirectSources =
- processSources(this, this->SourceEntries, files, uniqueSrcs, &dagChecker,
- config, debugSources);
+ processSources(this, entries, files, uniqueSrcs, debugSources);
// Collect INTERFACE_SOURCES of all direct link-dependencies.
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceSourcesEntries;
- AddInterfaceEntries(this, config, "INTERFACE_SOURCES",
- linkInterfaceSourcesEntries);
+ std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+ AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
+ &dagChecker, linkInterfaceSourcesEntries);
std::vector<std::string>::size_type numFilesBefore = files.size();
- bool contextDependentInterfaceSources =
- processSources(this, linkInterfaceSourcesEntries, files, uniqueSrcs,
- &dagChecker, config, debugSources);
+ bool contextDependentInterfaceSources = processSources(
+ this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
// Collect TARGET_OBJECTS of direct object link-dependencies.
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkObjectsEntries;
- AddObjectEntries(this, config, linkObjectsEntries);
+ bool contextDependentObjects = false;
std::vector<std::string>::size_type numFilesBefore2 = files.size();
- bool contextDependentObjects =
- processSources(this, linkObjectsEntries, files, uniqueSrcs, &dagChecker,
- config, debugSources);
+ if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+ std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+ AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
+ contextDependentObjects = processSources(this, linkObjectsEntries, files,
+ uniqueSrcs, debugSources);
+ }
if (!contextDependentDirectSources &&
!(contextDependentInterfaceSources && numFilesBefore < files.size()) &&
@@ -1280,8 +1443,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
this->LinkImplementationLanguageIsContextDependent = false;
}
- cmDeleteAll(linkInterfaceSourcesEntries);
- cmDeleteAll(linkObjectsEntries);
return files;
}
@@ -1362,7 +1523,7 @@ cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
// Lookup any existing link implementation for this configuration.
std::string const key = cmSystemTools::UpperCase(config);
- KindedSourcesMapType::iterator it = this->KindedSourcesMap.find(key);
+ auto it = this->KindedSourcesMap.find(key);
if (it != this->KindedSourcesMap.end()) {
if (!it->second.Initialized) {
std::ostringstream e;
@@ -1408,11 +1569,13 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
kind = SourceKindCustomCommand;
} else if (this->Target->GetType() == cmStateEnums::UTILITY) {
kind = SourceKindExtra;
+ } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
+ kind = SourceKindUnityBatched;
} else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) {
kind = SourceKindHeader;
} else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
kind = SourceKindExternalObject;
- } else if (!sf->GetLanguage().empty()) {
+ } else if (!sf->GetOrDetermineLanguage().empty()) {
kind = SourceKindObjectSource;
} else if (ext == "def") {
kind = SourceKindModuleDefinition;
@@ -1431,7 +1594,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& 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->GetFullPath();
+ std::string resx = sf->ResolveFullPath();
std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
files.ExpectedResxHeaders.insert(hFileName);
} else if (ext == "appxmanifest") {
@@ -1447,12 +1610,12 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& 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->GetFullPath();
+ 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->GetFullPath())) {
+ } else if (header_regex.find(sf->ResolveFullPath())) {
kind = SourceKindHeader;
} else {
kind = SourceKindExtra;
@@ -1494,8 +1657,7 @@ void cmGeneratorTarget::ComputeAllConfigSources() const
for (size_t ci = 0; ci < configs.size(); ++ci) {
KindedSources const& sources = this->GetKindedSources(configs[ci]);
for (SourceAndKind const& src : sources.Sources) {
- std::map<cmSourceFile const*, size_t>::iterator mi =
- index.find(src.Source.Value);
+ auto mi = index.find(src.Source.Value);
if (mi == index.end()) {
AllConfigSource acs;
acs.Source = src.Source.Value;
@@ -1521,8 +1683,7 @@ std::string cmGeneratorTarget::GetCompilePDBName(
// Check for a per-configuration output directory target property.
std::string configUpper = cmSystemTools::UpperCase(config);
- std::string configProp = "COMPILE_PDB_NAME_";
- configProp += configUpper;
+ 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";
@@ -1594,9 +1755,8 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall(
// Check for rpath support on this platform.
std::string ll = this->GetLinkerLanguage(config);
if (!ll.empty()) {
- std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- flagVar += ll;
- flagVar += "_FLAG";
+ std::string flagVar =
+ cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG");
if (!this->Makefile->IsSet(flagVar)) {
// There is no rpath support on this platform so nothing needs
// relinking.
@@ -1612,7 +1772,7 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall(
// will likely change between the build tree and install tree and
// this target must be relinked.
bool have_rpath =
- this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
+ this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(config);
bool is_ninja =
this->LocalGenerator->GetGlobalGenerator()->GetName() == "Ninja";
@@ -1674,9 +1834,8 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
// binaries.
std::string ll = this->GetLinkerLanguage(config);
if (!ll.empty()) {
- std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- sepVar += ll;
- sepVar += "_FLAG_SEP";
+ std::string sepVar =
+ cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP");
const char* sep = this->Makefile->GetDefinition(sepVar);
if (sep && *sep) {
// TODO: Add ELF check to ABI detection and get rid of
@@ -1793,7 +1952,7 @@ bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
const char* build_with_install_name =
this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR");
if (build_with_install_name) {
- return cmSystemTools::IsOn(build_with_install_name);
+ return cmIsOn(build_with_install_name);
}
cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
@@ -1858,23 +2017,23 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return this->GetLibraryNames(config).SharedObject;
}
-static bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
+namespace {
+bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
{
return level == cmGeneratorTarget::FullLevel;
}
-static bool shouldAddContentLevel(
- cmGeneratorTarget::BundleDirectoryLevel level)
+bool shouldAddContentLevel(cmGeneratorTarget::BundleDirectoryLevel level)
{
return level == cmGeneratorTarget::ContentLevel || shouldAddFullLevel(level);
}
+}
std::string cmGeneratorTarget::GetAppBundleDirectory(
const std::string& config, BundleDirectoryLevel level) const
{
- std::string fpath =
- this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact);
- fpath += ".";
+ std::string fpath = cmStrCat(
+ this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
const char* ext = this->GetProperty("BUNDLE_EXTENSION");
if (!ext) {
ext = "app";
@@ -1899,9 +2058,8 @@ bool cmGeneratorTarget::IsBundleOnApple() const
std::string cmGeneratorTarget::GetCFBundleDirectory(
const std::string& config, BundleDirectoryLevel level) const
{
- std::string fpath;
- fpath += this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact);
- fpath += ".";
+ std::string fpath = cmStrCat(
+ this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
const char* ext = this->GetProperty("BUNDLE_EXTENSION");
if (!ext) {
if (this->IsXCTestOnApple()) {
@@ -1924,9 +2082,8 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(
std::string cmGeneratorTarget::GetFrameworkDirectory(
const std::string& config, BundleDirectoryLevel level) const
{
- std::string fpath;
- fpath += this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact);
- fpath += ".";
+ std::string fpath = cmStrCat(
+ this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
const char* ext = this->GetProperty("BUNDLE_EXTENSION");
if (!ext) {
ext = "framework";
@@ -1983,8 +2140,7 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
if (install_name_dir && *install_name_dir) {
- dir = install_name_dir;
- dir += "/";
+ dir = cmStrCat(install_name_dir, '/');
}
}
if (!install_name_dir) {
@@ -2025,8 +2181,7 @@ const std::string* cmGeneratorTarget::GetExportMacro() const
if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
this->ExportMacro = custom_export_name;
} else {
- std::string in = this->GetName();
- in += "_EXPORTS";
+ std::string in = cmStrCat(this->GetName(), "_EXPORTS");
this->ExportMacro = cmSystemTools::MakeCidentifier(in);
}
return &this->ExportMacro;
@@ -2113,7 +2268,7 @@ cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
const std::string& config) const
{
std::string key(cmSystemTools::UpperCase(config));
- LinkClosureMapType::iterator i = this->LinkClosureMap.find(key);
+ auto i = this->LinkClosureMap.find(key);
if (i == this->LinkClosureMap.end()) {
LinkClosure lc;
this->ComputeLinkClosure(config, lc);
@@ -2247,8 +2402,7 @@ std::string cmGeneratorTarget::GetMacContentDirectory(
const std::string& config, cmStateEnums::ArtifactType artifact) const
{
// Start with the output directory for the target.
- std::string fpath = this->GetDirectory(config, artifact);
- fpath += "/";
+ std::string fpath = cmStrCat(this->GetDirectory(config, artifact), '/');
BundleDirectoryLevel level = ContentLevel;
if (this->IsFrameworkOnApple()) {
// additional files with a framework go into the version specific
@@ -2284,10 +2438,9 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
}
if (this->GetType() > cmStateEnums::OBJECT_LIBRARY) {
- std::string msg = "cmTarget::GetCompileInfo called for ";
- msg += this->GetName();
- msg += " which has type ";
- msg += cmState::GetTargetTypeName(this->GetType());
+ std::string msg = cmStrCat("cmTarget::GetCompileInfo called for ",
+ this->GetName(), " which has type ",
+ cmState::GetTargetTypeName(this->GetType()));
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
return nullptr;
}
@@ -2297,8 +2450,7 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
if (!config.empty()) {
config_upper = cmSystemTools::UpperCase(config);
}
- CompileInfoMapType::const_iterator i =
- this->CompileInfoMap.find(config_upper);
+ auto i = this->CompileInfoMap.find(config_upper);
if (i == this->CompileInfoMap.end()) {
CompileInfo info;
this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
@@ -2323,8 +2475,7 @@ cmGeneratorTarget::GetModuleDefinitionInfo(std::string const& config) const
if (!config.empty()) {
config_upper = cmSystemTools::UpperCase(config);
}
- ModuleDefinitionInfoMapType::const_iterator i =
- this->ModuleDefinitionInfoMap.find(config_upper);
+ auto i = this->ModuleDefinitionInfoMap.find(config_upper);
if (i == this->ModuleDefinitionInfoMap.end()) {
ModuleDefinitionInfo info;
this->ComputeModuleDefinitionInfo(config, info);
@@ -2341,7 +2492,7 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
info.DefFileGenerated =
info.WindowsExportAllSymbols || info.Sources.size() > 1;
#else
@@ -2357,7 +2508,7 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
bool cmGeneratorTarget::IsDLLPlatform() const
{
- return this->DLLPlatform;
+ return this->Target->IsDLLPlatform();
}
void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
@@ -2368,14 +2519,12 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
if (!prop) {
return;
}
- cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
nullptr);
- cmSystemTools::ExpandListArgument(
- ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this,
- &dagChecker),
- result);
+ cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator,
+ config, this, &dagChecker),
+ result);
}
void processILibs(const std::string& config,
@@ -2426,11 +2575,11 @@ private:
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator const* GlobalGenerator;
- typedef cmGeneratorTarget::SourceEntry SourceEntry;
+ using SourceEntry = cmGeneratorTarget::SourceEntry;
SourceEntry* CurrentEntry;
std::queue<cmSourceFile*> SourceQueue;
std::set<cmSourceFile*> SourcesQueued;
- typedef std::map<std::string, cmSourceFile*> NameMapType;
+ using NameMapType = std::map<std::string, cmSourcesWithOutput>;
NameMapType NameMap;
std::vector<std::string> NewSources;
@@ -2456,21 +2605,18 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
// Queue all the source files already specified for the target.
if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- std::vector<std::string> configs;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
std::set<cmSourceFile*> emitted;
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs();
for (std::string const& c : configs) {
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, c);
for (cmSourceFile* sf : sources) {
const std::set<cmGeneratorTarget const*> tgts =
this->GlobalGenerator->GetFilenameTargetDepends(sf);
- if (tgts.find(this->GeneratorTarget) != tgts.end()) {
+ if (cmContains(tgts, this->GeneratorTarget)) {
std::ostringstream e;
- e << "Evaluation output file\n \"" << sf->GetFullPath()
+ e << "Evaluation output file\n \"" << sf->ResolveFullPath()
<< "\"\ndepends on the sources of a target it is used in. This "
"is a dependency loop and is not allowed.";
this->GeneratorTarget->LocalGenerator->IssueMessage(
@@ -2502,8 +2648,7 @@ void cmTargetTraceDependencies::Trace()
// Queue dependencies added explicitly by the user.
if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps;
- cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
+ std::vector<std::string> objDeps = cmExpandedList(additionalDeps);
for (std::string& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
@@ -2513,7 +2658,7 @@ void cmTargetTraceDependencies::Trace()
}
// Queue the source needed to generate this file, if any.
- this->FollowName(sf->GetFullPath());
+ this->FollowName(sf->ResolveFullPath());
// Queue dependencies added programmatically by commands.
this->FollowNames(sf->GetDepends());
@@ -2534,25 +2679,36 @@ void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
this->SourceQueue.push(sf);
// Make sure this file is in the target at the end.
- this->NewSources.push_back(sf->GetFullPath());
+ this->NewSources.push_back(sf->ResolveFullPath());
}
}
void cmTargetTraceDependencies::FollowName(std::string const& name)
{
- NameMapType::iterator i = this->NameMap.find(name);
- if (i == this->NameMap.end()) {
+ // Use lower bound with key comparison to not repeat the search for the
+ // insert position if the name could not be found (which is the common case).
+ auto i = this->NameMap.lower_bound(name);
+ if (i == this->NameMap.end() || i->first != name) {
// Check if we know how to generate this file.
- cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
- NameMapType::value_type entry(name, sf);
- i = this->NameMap.insert(entry).first;
- }
- if (cmSourceFile* sf = i->second) {
- // Record the dependency we just followed.
- if (this->CurrentEntry) {
- this->CurrentEntry->Depends.push_back(sf);
+ cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+ i = this->NameMap.emplace_hint(i, name, sources);
+ }
+ if (cmTarget* t = i->second.Target) {
+ // The name is a byproduct of a utility target or a PRE_BUILD, PRE_LINK, or
+ // POST_BUILD command.
+ this->GeneratorTarget->Target->AddUtility(t->GetName());
+ }
+ if (cmSourceFile* sf = i->second.Source) {
+ // For now only follow the dependency if the source file is not a
+ // byproduct. Semantics of byproducts in a non-Ninja context will have to
+ // be defined first.
+ if (!i->second.SourceIsByproduct) {
+ // Record the dependency we just followed.
+ if (this->CurrentEntry) {
+ this->CurrentEntry->Depends.push_back(sf);
+ }
+ this->QueueSource(sf);
}
- this->QueueSource(sf);
}
}
@@ -2637,7 +2793,8 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
// Check for target references in generator expressions.
for (std::string const& cl : cCmdLine) {
const std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cl);
- cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "", true);
+ cge->SetQuiet(true);
+ cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "");
std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
targets.insert(geTargets.begin(), geTargets.end());
}
@@ -2648,12 +2805,9 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
}
// Queue the custom command dependencies.
- std::vector<std::string> configs;
std::set<std::string> emitted;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs();
for (std::string const& conf : configs) {
this->FollowCommandDepends(cc, conf, emitted);
}
@@ -2716,15 +2870,15 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
{
const char* archs = nullptr;
if (!config.empty()) {
- std::string defVarName = "OSX_ARCHITECTURES_";
- defVarName += cmSystemTools::UpperCase(config);
+ std::string defVarName =
+ cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config));
archs = this->GetProperty(defVarName);
}
if (!archs) {
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if (archs) {
- cmSystemTools::ExpandListArgument(std::string(archs), archVec);
+ cmExpandList(std::string(archs), archVec);
}
}
@@ -2757,33 +2911,35 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
case cmStateEnums::MODULE_LIBRARY:
return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
case cmStateEnums::EXECUTABLE:
+ if (this->IsExecutableWithExports()) {
+ std::string linkExeWithExports =
+ "CMAKE_" + lang + "_LINK_EXECUTABLE_WITH_EXPORTS";
+ if (this->Makefile->IsDefinitionSet(linkExeWithExports)) {
+ return linkExeWithExports;
+ }
+ }
return "CMAKE_" + lang + "_LINK_EXECUTABLE";
default:
break;
}
return "";
}
-static void processIncludeDirectories(
+
+namespace {
+void processIncludeDirectories(
cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
std::vector<BT<std::string>>& includes,
- std::unordered_set<std::string>& uniqueIncludes,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugIncludes, const std::string& language)
+ std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
bool const fromImported = item.Target && item.Target->IsImported();
bool const checkCMP0027 = item.FromGenex;
- std::vector<std::string> entryIncludes;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryIncludes);
std::string usedIncludes;
- for (std::string& entryInclude : entryIncludes) {
+ for (std::string& entryInclude : entry.Values) {
if (fromImported && !cmSystemTools::FileExists(entryInclude)) {
std::ostringstream e;
MessageType messageType = MessageType::FATAL_ERROR;
@@ -2852,15 +3008,14 @@ static void processIncludeDirectories(
}
}
- if (!cmSystemTools::IsOff(entryInclude)) {
+ if (!cmIsOff(entryInclude)) {
cmSystemTools::ConvertToUnixSlashes(entryInclude);
}
- std::string inc = entryInclude;
- if (uniqueIncludes.insert(inc).second) {
- includes.emplace_back(inc, entry->GetBacktrace());
+ if (uniqueIncludes.insert(entryInclude).second) {
+ includes.emplace_back(entryInclude, entry.Backtrace);
if (debugIncludes) {
- usedIncludes += " * " + inc + "\n";
+ usedIncludes += " * " + entryInclude + "\n";
}
}
}
@@ -2869,10 +3024,11 @@ static void processIncludeDirectories(
MessageType::LOG,
std::string("Used includes for target ") + tgt->GetName() + ":\n" +
usedIncludes,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
+}
std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
const std::string& config, const std::string& lang) const
@@ -2887,25 +3043,22 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
bool debugIncludes = !this->DebugIncludesDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "INCLUDE_DIRECTORIES") != debugProperties.end();
+ cmContains(debugProperties, "INCLUDE_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugIncludesDone = true;
}
- processIncludeDirectories(this, this->IncludeDirectoriesEntries, includes,
- uniqueIncludes, &dagChecker, config, debugIncludes,
- lang);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
+ this->IncludeDirectoriesEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceIncludeDirectoriesEntries;
- AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES",
- linkInterfaceIncludeDirectoriesEntries);
+ AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
+ &dagChecker, entries);
if (this->Makefile->IsOn("APPLE")) {
cmLinkImplementationLibraries const* impl =
@@ -2921,16 +3074,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
libDir = frameworkCheck.match(1);
- linkInterfaceIncludeDirectoriesEntries.push_back(
- CreateTargetPropertyEntry(libDir));
+ EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+ ee.Values.emplace_back(std::move(libDir));
+ entries.emplace_back(std::move(ee));
}
}
- processIncludeDirectories(this, linkInterfaceIncludeDirectoriesEntries,
- includes, uniqueIncludes, &dagChecker, config,
- debugIncludes, lang);
-
- cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+ processIncludeDirectories(this, entries, includes, uniqueIncludes,
+ debugIncludes);
return includes;
}
@@ -2941,33 +3092,26 @@ enum class OptionsParse
Shell
};
-static void processOptionsInternal(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, const char* logName, std::string const& language,
- OptionsParse parse)
-{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- std::vector<std::string> entryOptions;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryOptions);
+namespace {
+void processOptions(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry> const& entries,
+ std::vector<BT<std::string>>& options,
+ std::unordered_set<std::string>& uniqueOptions,
+ bool debugOptions, const char* logName, OptionsParse parse)
+{
+ for (EvaluatedTargetPropertyEntry const& entry : entries) {
std::string usedOptions;
- for (std::string const& opt : entryOptions) {
+ for (std::string const& opt : entry.Values) {
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->GetBacktrace());
+ options.emplace_back(std::move(o), entry.Backtrace);
}
} else {
- options.emplace_back(opt, entry->GetBacktrace());
+ options.emplace_back(opt, entry.Backtrace);
}
if (debugOptions) {
usedOptions += " * " + opt + "\n";
@@ -2979,22 +3123,10 @@ static void processOptionsInternal(
MessageType::LOG,
std::string("Used ") + logName + std::string(" for target ") +
tgt->GetName() + ":\n" + usedOptions,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
-
-static void processCompileOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile options", language,
- OptionsParse::Shell);
}
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3021,48 +3153,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
bool debugOptions = !this->DebugCompileOptionsDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "COMPILE_OPTIONS") != debugProperties.end();
+ cmContains(debugProperties, "COMPILE_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileOptionsDone = true;
}
- processCompileOptions(this, this->CompileOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->CompileOptionsEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileOptionsEntries;
+ AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
+ &dagChecker, entries);
- AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS",
- linkInterfaceCompileOptionsEntries);
+ processOptions(this, entries, result, uniqueOptions, debugOptions,
+ "compile options", OptionsParse::Shell);
- processCompileOptions(this, linkInterfaceCompileOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
-
- cmDeleteAll(linkInterfaceCompileOptionsEntries);
return result;
}
-static void processCompileFeatures(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile features",
- std::string(), OptionsParse::None);
-}
-
void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
const std::string& config) const
{
@@ -3086,45 +3199,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
bool debugFeatures = !this->DebugCompileFeaturesDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "COMPILE_FEATURES") != debugProperties.end();
+ cmContains(debugProperties, "COMPILE_FEATURES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileFeaturesDone = true;
}
- processCompileFeatures(this, this->CompileFeaturesEntries, result,
- uniqueFeatures, &dagChecker, config, debugFeatures);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
+ this->CompileFeaturesEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileFeaturesEntries;
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
- linkInterfaceCompileFeaturesEntries);
+ std::string(), &dagChecker, entries);
- processCompileFeatures(this, linkInterfaceCompileFeaturesEntries, result,
- uniqueFeatures, &dagChecker, config, debugFeatures);
+ processOptions(this, entries, result, uniqueFeatures, debugFeatures,
+ "compile features", OptionsParse::None);
- cmDeleteAll(linkInterfaceCompileFeaturesEntries);
return result;
}
-static void processCompileDefinitions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "compile definitions", language,
- OptionsParse::None);
-}
-
void cmGeneratorTarget::GetCompileDefinitions(
std::vector<std::string>& result, const std::string& config,
const std::string& language) const
@@ -3150,25 +3247,23 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
bool debugDefines = !this->DebugCompileDefinitionsDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "COMPILE_DEFINITIONS") != debugProperties.end();
+ cmContains(debugProperties, "COMPILE_DEFINITIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileDefinitionsDone = true;
}
- processCompileDefinitions(this, this->CompileDefinitionsEntries, list,
- uniqueOptions, &dagChecker, config, debugDefines,
- language);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->CompileDefinitionsEntries);
+
+ AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
+ &dagChecker, entries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceCompileDefinitionsEntries;
- AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS",
- linkInterfaceCompileDefinitionsEntries);
if (!config.empty()) {
std::string configPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
@@ -3176,15 +3271,16 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
if (configProp) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
case cmPolicies::WARN: {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
- this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING,
- e.str());
+ this->LocalGenerator->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0043));
CM_FALLTHROUGH;
}
case cmPolicies::OLD: {
- linkInterfaceCompileDefinitionsEntries.push_back(
+ std::unique_ptr<TargetPropertyEntry> entry(
CreateTargetPropertyEntry(configProp));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
} break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
@@ -3194,27 +3290,322 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
}
- processCompileDefinitions(this, linkInterfaceCompileDefinitionsEntries, list,
- uniqueOptions, &dagChecker, config, debugDefines,
- language);
+ processOptions(this, entries, list, uniqueOptions, debugDefines,
+ "compile definitions", OptionsParse::None);
- cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
return list;
}
-namespace {
-void processLinkOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugOptions, std::string const& language)
+std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
+ const std::string& config, const std::string& language) const
{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, debugOptions, "link options", language,
- OptionsParse::Shell);
+ std::unordered_set<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
+ nullptr, nullptr);
+
+ std::vector<std::string> debugProperties;
+ const char* debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp) {
+ cmExpandList(debugProp, debugProperties);
+ }
+
+ bool debugDefines = !this->DebugPrecompileHeadersDone &&
+ std::find(debugProperties.begin(), debugProperties.end(),
+ "PRECOMPILE_HEADERS") != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
+ this->DebugPrecompileHeadersDone = true;
+ }
+
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->PrecompileHeadersEntries);
+
+ AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
+ &dagChecker, entries);
+
+ std::vector<BT<std::string>> list;
+ processOptions(this, entries, list, uniqueOptions, debugDefines,
+ "precompile headers", OptionsParse::None);
+
+ return list;
+}
+
+std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
+ const std::string& language) const
+{
+ if (language != "C" && language != "CXX" && language != "OBJC" &&
+ language != "OBJCXX") {
+ return std::string();
+ }
+
+ if (this->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
+ return std::string();
+ }
+ const cmGeneratorTarget* generatorTarget = this;
+ const char* pchReuseFrom =
+ generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
+ const auto inserted =
+ this->PchHeaders.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::vector<BT<std::string>> headers =
+ this->GetPrecompileHeaders(config, language);
+ if (headers.empty() && !pchReuseFrom) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+
+ if (pchReuseFrom) {
+ generatorTarget =
+ this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ }
+
+ filename = cmStrCat(
+ generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(), "/");
+
+ const std::map<std::string, std::string> languageToExtension = {
+ { "C", ".h" },
+ { "CXX", ".hxx" },
+ { "OBJC", ".objc.h" },
+ { "OBJCXX", ".objcxx.hxx" }
+ };
+
+ filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(),
+ ".dir/cmake_pch", languageToExtension.at(language));
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ if (!pchReuseFrom) {
+ auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
+ auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE");
+
+ {
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ this->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+ if (pchPrologue) {
+ file << pchPrologue << "\n";
+ }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (language == "CXX") {
+ file << "#ifdef __cplusplus\n";
+ }
+ for (auto const& header_bt : headers) {
+ if (header_bt.Value.empty()) {
+ continue;
+ }
+ if (header_bt.Value[0] == '<' || header_bt.Value[0] == '\"') {
+ file << "#include " << header_bt.Value << "\n";
+ } else {
+ file << "#include \"" << header_bt.Value << "\"\n";
+ }
+ }
+ if (language == "CXX") {
+ file << "#endif // __cplusplus\n";
+ }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n";
+ }
+ if (pchEpilogue) {
+ file << pchEpilogue << "\n";
+ }
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ }
+ }
+ return inserted.first->second;
}
+
+std::string cmGeneratorTarget::GetPchSource(const std::string& config,
+ const std::string& language) const
+{
+ if (language != "C" && language != "CXX" && language != "OBJC" &&
+ language != "OBJCXX") {
+ return std::string();
+ }
+ const auto inserted =
+ this->PchSources.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::string pchHeader = this->GetPchHeader(config, language);
+ if (pchHeader.empty()) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+
+ const cmGeneratorTarget* generatorTarget = this;
+ const char* pchReuseFrom =
+ generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ if (pchReuseFrom) {
+ generatorTarget =
+ this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ }
+
+ filename =
+ cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch");
+
+ // For GCC the source extension will be tranformed into .h[xx].gch
+ if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ const std::map<std::string, std::string> languageToExtension = {
+ { "C", ".h.c" },
+ { "CXX", ".hxx.cxx" },
+ { "OBJC", ".objc.h.m" },
+ { "OBJCXX", ".objcxx.hxx.mm" }
+ };
+
+ filename += languageToExtension.at(language);
+ } else {
+ const std::map<std::string, std::string> languageToExtension = {
+ { "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
+ };
+
+ filename += languageToExtension.at(language);
+ }
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ if (!pchReuseFrom) {
+ {
+ cmGeneratedFileStream file(filename_tmp);
+ file << "/* generated by CMake */\n";
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ }
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
+ const std::string& language)
+{
+ if (language != "C" && language != "CXX" && language != "OBJC" &&
+ language != "OBJCXX") {
+ return std::string();
+ }
+ const auto inserted =
+ this->PchObjectFiles.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ const std::string pchSource = this->GetPchSource(config, language);
+ if (pchSource.empty()) {
+ return std::string();
+ }
+ std::string& filename = inserted.first->second;
+
+ this->AddSource(pchSource, true);
+
+ auto pchSf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
+
+ filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf));
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchFile(const std::string& config,
+ const std::string& language)
+{
+ const auto inserted =
+ this->PchFiles.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ std::string& pchFile = inserted.first->second;
+
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ auto replaceExtension = [](const std::string& str,
+ const std::string& ext) -> std::string {
+ auto dot_pos = str.rfind('.');
+ std::string result;
+ if (dot_pos != std::string::npos) {
+ result = str.substr(0, dot_pos);
+ }
+ result += ext;
+ return result;
+ };
+
+ cmGeneratorTarget* generatorTarget = this;
+ const char* pchReuseFrom =
+ generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ if (pchReuseFrom) {
+ generatorTarget =
+ this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ }
+
+ const std::string pchFileObject =
+ generatorTarget->GetPchFileObject(config, language);
+ if (!pchExtension.empty()) {
+ pchFile = replaceExtension(pchFileObject, pchExtension);
+ }
+ } else {
+ pchFile = this->GetPchHeader(config, language);
+ pchFile += pchExtension;
+ }
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchCreateCompileOptions(
+ const std::string& config, const std::string& language)
+{
+ const auto inserted = this->PchCreateCompileOptions.insert(
+ std::make_pair(language + config, ""));
+ if (inserted.second) {
+ std::string& createOptionList = inserted.first->second;
+
+ 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);
+
+ cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
+ cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
+ }
+ return inserted.first->second;
+}
+
+std::string cmGeneratorTarget::GetPchUseCompileOptions(
+ const std::string& config, const std::string& language)
+{
+ const auto inserted =
+ this->PchUseCompileOptions.insert(std::make_pair(language + config, ""));
+ if (inserted.second) {
+ std::string& useOptionList = inserted.first->second;
+
+ const std::string useOptVar =
+ cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
+ useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+
+ const std::string pchHeader = this->GetPchHeader(config, language);
+ const std::string pchFile = this->GetPchFile(config, language);
+
+ cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
+ cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
+ }
+ return inserted.first->second;
+}
+
+void cmGeneratorTarget::AddSourceFileToUnityBatch(
+ const std::string& sourceFilename)
+{
+ this->UnityBatchedSourceFiles.insert(sourceFilename);
+}
+
+bool cmGeneratorTarget::IsSourceFilePartOfUnityBatch(
+ const std::string& sourceFilename) const
+{
+ if (!this->GetPropertyAsBool("UNITY_BUILD")) {
+ return false;
+ }
+
+ return this->UnityBatchedSourceFiles.find(sourceFilename) !=
+ this->UnityBatchedSourceFiles.end();
}
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
@@ -3241,38 +3632,31 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
- bool debugOptions = !this->DebugLinkOptionsDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "LINK_OPTIONS") != debugProperties.end();
+ bool debugOptions =
+ !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkOptionsDone = true;
}
- processLinkOptions(this, this->LinkOptionsEntries, result, uniqueOptions,
- &dagChecker, config, debugOptions, language);
-
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceLinkOptionsEntries;
-
- AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS",
- linkInterfaceLinkOptionsEntries);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->LinkOptionsEntries);
- processLinkOptions(this, linkInterfaceLinkOptionsEntries, result,
- uniqueOptions, &dagChecker, config, debugOptions,
- language);
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
+ &dagChecker, entries);
- cmDeleteAll(linkInterfaceLinkOptionsEntries);
+ processOptions(this, entries, result, uniqueOptions, debugOptions,
+ "link options", OptionsParse::Shell);
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
- std::vector<std::string> wrapperFlag;
- cmSystemTools::ExpandListArgument(wrapper, wrapperFlag);
+ std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
bool concatFlagAndArgs = true;
@@ -3300,8 +3684,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmSystemTools::ParseUnixCommandLine(
value.c_str() + LINKER_SHELL.length(), linkerOptions);
} else {
- linkerOptions =
- cmSystemTools::tokenize(value.substr(LINKER.length()), ",");
+ linkerOptions = cmTokenize(value.substr(LINKER.length()), ",");
}
if (linkerOptions.empty() ||
@@ -3371,21 +3754,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
return result;
}
-namespace {
-void processStaticLibraryLinkOptions(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, false, "static library link options",
- language, OptionsParse::Shell);
-}
-}
-
void cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<std::string>& result, const std::string& config,
const std::string& language) const
@@ -3402,47 +3770,40 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::string const& config, std::string const& language) const
{
std::vector<BT<std::string>> result;
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
std::unordered_set<std::string> uniqueOptions;
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;
- cmSystemTools::ExpandListArgument(linkOptions, options);
+ std::vector<std::string> options = cmExpandedList(linkOptions);
for (const auto& option : options) {
- entries.push_back(CreateTargetPropertyEntry(option));
+ std::unique_ptr<TargetPropertyEntry> entry(
+ CreateTargetPropertyEntry(option));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
}
}
- processStaticLibraryLinkOptions(this, entries, result, uniqueOptions,
- &dagChecker, config, language);
+ processOptions(this, entries, result, uniqueOptions, false,
+ "static library link options", OptionsParse::Shell);
- cmDeleteAll(entries);
return result;
}
namespace {
-void processLinkDirectories(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& directories,
- std::unordered_set<std::string>& uniqueDirectories,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- bool debugDirectories, std::string const& language)
-{
- for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
- cmLinkImplItem const& item = entry->LinkImplItem;
+void processLinkDirectories(cmGeneratorTarget const* tgt,
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
+ std::vector<BT<std::string>>& directories,
+ std::unordered_set<std::string>& uniqueDirectories,
+ bool debugDirectories)
+{
+ for (EvaluatedTargetPropertyEntry& entry : entries) {
+ cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
- std::vector<std::string> entryDirectories;
- cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
- config, false, tgt,
- dagChecker, language),
- entryDirectories);
-
std::string usedDirectories;
- for (std::string& entryDirectory : entryDirectories) {
+ for (std::string& entryDirectory : entry.Values) {
if (!cmSystemTools::FileIsFullPath(entryDirectory)) {
std::ostringstream e;
bool noMessage = false;
@@ -3484,7 +3845,7 @@ void processLinkDirectories(
// in case projects set the LINK_DIRECTORIES property directly.
cmSystemTools::ConvertToUnixSlashes(entryDirectory);
if (uniqueDirectories.insert(entryDirectory).second) {
- directories.emplace_back(entryDirectory);
+ directories.emplace_back(entryDirectory, entry.Backtrace);
if (debugDirectories) {
usedDirectories += " * " + entryDirectory + "\n";
}
@@ -3495,7 +3856,7 @@ void processLinkDirectories(
MessageType::LOG,
std::string("Used link directories for target ") + tgt->GetName() +
":\n" + usedDirectories,
- entry->GetBacktrace());
+ entry.Backtrace);
}
}
}
@@ -3526,50 +3887,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
const char* debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
- std::find(debugProperties.begin(), debugProperties.end(),
- "LINK_DIRECTORIES") != debugProperties.end();
+ cmContains(debugProperties, "LINK_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkDirectoriesDone = true;
}
- processLinkDirectories(this, this->LinkDirectoriesEntries, result,
- uniqueDirectories, &dagChecker, config,
- debugDirectories, language);
+ std::vector<EvaluatedTargetPropertyEntry> entries =
+ EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+ this->LinkDirectoriesEntries);
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>
- linkInterfaceLinkDirectoriesEntries;
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
+ &dagChecker, entries);
- AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES",
- linkInterfaceLinkDirectoriesEntries);
+ processLinkDirectories(this, entries, result, uniqueDirectories,
+ debugDirectories);
- processLinkDirectories(this, linkInterfaceLinkDirectoriesEntries, result,
- uniqueDirectories, &dagChecker, config,
- debugDirectories, language);
-
- cmDeleteAll(linkInterfaceLinkDirectoriesEntries);
return result;
}
-namespace {
-void processLinkDepends(
- cmGeneratorTarget const* tgt,
- const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
- std::vector<BT<std::string>>& options,
- std::unordered_set<std::string>& uniqueOptions,
- cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
- std::string const& language)
-{
- processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
- config, false, "link depends", language,
- OptionsParse::None);
-}
-}
-
void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
@@ -3585,24 +3925,26 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
std::string const& config, std::string const& language) const
{
std::vector<BT<std::string>> result;
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
nullptr);
+ std::vector<EvaluatedTargetPropertyEntry> entries;
if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends;
- cmSystemTools::ExpandListArgument(linkDepends, depends);
+ std::vector<std::string> depends = cmExpandedList(linkDepends);
for (const auto& depend : depends) {
- linkDependsEntries.push_back(CreateTargetPropertyEntry(depend));
+ std::unique_ptr<TargetPropertyEntry> entry(
+ CreateTargetPropertyEntry(depend));
+ entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, entry.get()));
}
}
- AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS",
- linkDependsEntries);
- processLinkDepends(this, linkDependsEntries, result, uniqueOptions,
- &dagChecker, config, language);
+ AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
+ &dagChecker, entries);
+
+ processOptions(this, entries, result, uniqueOptions, false, "link depends",
+ OptionsParse::None);
- cmDeleteAll(linkDependsEntries);
return result;
}
@@ -3632,33 +3974,25 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
// Add each name.
std::string f;
if (!targetNames.Output.empty()) {
- f = dir;
- f += "/";
- f += targetNames.Output;
+ f = cmStrCat(dir, '/', targetNames.Output);
gg->AddToManifest(f);
}
if (!targetNames.SharedObject.empty()) {
- f = dir;
- f += "/";
- f += targetNames.SharedObject;
+ f = cmStrCat(dir, '/', targetNames.SharedObject);
gg->AddToManifest(f);
}
if (!targetNames.Real.empty()) {
- f = dir;
- f += "/";
- f += targetNames.Real;
+ f = cmStrCat(dir, '/', targetNames.Real);
gg->AddToManifest(f);
}
if (!targetNames.PDB.empty()) {
- f = dir;
- f += "/";
- f += targetNames.PDB;
+ f = cmStrCat(dir, '/', targetNames.PDB);
gg->AddToManifest(f);
}
if (!targetNames.ImportLibrary.empty()) {
- f = this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
- f += "/";
- f += targetNames.ImportLibrary;
+ f =
+ cmStrCat(this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact),
+ '/', targetNames.ImportLibrary);
gg->AddToManifest(f);
}
}
@@ -3698,11 +4032,10 @@ std::string cmGeneratorTarget::NormalGetFullPath(
const std::string& config, cmStateEnums::ArtifactType artifact,
bool realname) const
{
- std::string fpath = this->GetDirectory(config, artifact);
- fpath += "/";
+ std::string fpath = cmStrCat(this->GetDirectory(config, artifact), '/');
if (this->IsAppBundleOnApple()) {
- fpath = this->BuildBundleDirectory(fpath, config, FullLevel);
- fpath += "/";
+ fpath =
+ cmStrCat(this->BuildBundleDirectory(fpath, config, FullLevel), '/');
}
// Add the full name of the target.
@@ -3729,8 +4062,8 @@ std::string cmGeneratorTarget::NormalGetRealName(
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
if (this->IsImported()) {
- std::string msg = "NormalGetRealName called on imported target: ";
- msg += this->GetName();
+ std::string msg = cmStrCat("NormalGetRealName called on imported target: ",
+ this->GetName());
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
}
@@ -3751,8 +4084,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
if (this->IsImported()) {
- std::string msg = "GetLibraryNames called on imported target: ";
- msg += this->GetName();
+ std::string msg =
+ cmStrCat("GetLibraryNames called on imported target: ", this->GetName());
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
}
@@ -3828,8 +4161,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
if (this->IsImported()) {
- std::string msg = "GetExecutableNames called on imported target: ";
- msg += this->GetName();
+ std::string msg = cmStrCat(
+ "GetExecutableNames called on imported target: ", this->GetName());
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
}
@@ -3924,8 +4257,7 @@ void cmGeneratorTarget::GetFullNameInternal(
// Return an empty name for the import library if this platform
// does not support import libraries.
- if (isImportedLibraryArtifact &&
- !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+ if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
outPrefix.clear();
outBase.clear();
outSuffix.clear();
@@ -3934,8 +4266,8 @@ void cmGeneratorTarget::GetFullNameInternal(
// retrieve prefix and suffix
std::string ll = this->GetLinkerLanguage(config);
- const char* targetPrefix = this->GetFilePrefixInternal(artifact, ll);
- const char* targetSuffix = this->GetFileSuffixInternal(artifact, ll);
+ const char* targetPrefix = this->GetFilePrefixInternal(config, artifact, ll);
+ const char* targetSuffix = this->GetFileSuffixInternal(config, artifact, ll);
// The implib option is only allowed for shared libraries, module
// libraries, and executables.
@@ -3951,15 +4283,14 @@ void cmGeneratorTarget::GetFullNameInternal(
// frameworks have directory prefix but no suffix
std::string fw_prefix;
if (this->IsFrameworkOnApple()) {
- fw_prefix = this->GetFrameworkDirectory(config, ContentLevel);
- fw_prefix += "/";
+ fw_prefix =
+ cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/');
targetPrefix = fw_prefix.c_str();
targetSuffix = nullptr;
}
if (this->IsCFBundleOnApple()) {
- fw_prefix = this->GetCFBundleDirectory(config, FullLevel);
- fw_prefix += "/";
+ fw_prefix = cmStrCat(this->GetCFBundleDirectory(config, FullLevel), '/');
targetPrefix = fw_prefix.c_str();
targetSuffix = nullptr;
}
@@ -4080,8 +4411,7 @@ void cmGeneratorTarget::GetTargetObjectNames(
for (cmSourceFile const* src : objectSources) {
// Find the object file name corresponding to this source file.
- std::map<cmSourceFile const*, std::string>::const_iterator map_it =
- mapping.find(src);
+ auto map_it = mapping.find(src);
// It must exist because we populated the mapping just above.
assert(!map_it->second.empty());
objects.push_back(map_it->second);
@@ -4105,8 +4435,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
{
struct SourceFileFlags flags;
this->ConstructSourceFileFlags();
- std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
- this->SourceFlagsMap.find(sf);
+ auto si = this->SourceFlagsMap.find(sf);
if (si != this->SourceFlagsMap.end()) {
flags = si->second;
} else {
@@ -4121,7 +4450,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
if (stripResources) {
flags.MacFolder = "";
}
- } else if (cmSystemTools::StringStartsWith(location, "Resources/")) {
+ } else if (cmHasLiteralPrefix(location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
flags.MacFolder += strlen("Resources/");
@@ -4143,8 +4472,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process public headers to mark the source files.
if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ 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];
@@ -4157,8 +4485,7 @@ 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;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ 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];
@@ -4170,8 +4497,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Mark sources listed as resources.
if (const char* files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ 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];
@@ -4200,7 +4526,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
std::vector<std::string> props; \
- cmSystemTools::ExpandListArgument(prop, props); \
+ cmExpandList(prop, props); \
compat.Props##x.insert(props.begin(), props.end()); \
}
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -4313,10 +4639,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
return;
}
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
- std::string pdir = cmSystemTools::GetCMakeRoot();
- pdir += "/Help/prop_tgt/";
+ std::vector<std::string> props = cmExpandedList(prop);
+ std::string pdir =
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
for (std::string const& p : props) {
std::string pname = cmSystemTools::HelpFileName(p);
@@ -4343,8 +4668,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
}
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2)
+namespace {
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2)
{
std::set<std::string> intersect;
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
@@ -4355,9 +4681,9 @@ static std::string intersect(const std::set<std::string>& s1,
return "";
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2,
- const std::set<std::string>& s3)
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2,
+ const std::set<std::string>& s3)
{
std::string result;
result = intersect(s1, s2);
@@ -4371,10 +4697,10 @@ static std::string intersect(const std::set<std::string>& s1,
return intersect(s2, s3);
}
-static std::string intersect(const std::set<std::string>& s1,
- const std::set<std::string>& s2,
- const std::set<std::string>& s3,
- const std::set<std::string>& s4)
+std::string intersect(const std::set<std::string>& s1,
+ const std::set<std::string>& s2,
+ const std::set<std::string>& s3,
+ const std::set<std::string>& s4)
{
std::string result;
result = intersect(s1, s2);
@@ -4391,6 +4717,7 @@ static std::string intersect(const std::set<std::string>& s1,
}
return intersect(s2, s3, s4);
}
+}
void cmGeneratorTarget::CheckPropertyCompatibility(
cmComputeLinkInformation* info, const std::string& config) const
@@ -4442,7 +4769,7 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
if (!prop.empty()) {
// Use a sorted std::vector to keep the error message sorted.
std::vector<std::string> props;
- std::set<std::string>::const_iterator i = emittedBools.find(prop);
+ auto i = emittedBools.find(prop);
if (i != emittedBools.end()) {
props.push_back(strBool);
}
@@ -4460,8 +4787,8 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
}
std::sort(props.begin(), props.end());
- std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
- propsString += " and the " + props.back();
+ std::string propsString = cmStrCat(
+ cmJoin(cmMakeRange(props).retreat(1), ", "), " and the ", props.back());
std::ostringstream e;
e << "Property \"" << prop << "\" appears in both the " << propsString
@@ -4542,7 +4869,7 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
}
const char* value = tgt->GetProperty(prop);
- return cmSystemTools::IsOn(genexInterpreter->Evaluate(value, prop));
+ return cmIsOn(genexInterpreter->Evaluate(value, prop));
}
template <>
@@ -4600,21 +4927,21 @@ template <>
std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
CompatibleType /*unused*/)
{
- return std::make_pair(lhs == rhs, lhs);
+ return { lhs == rhs, lhs };
}
std::pair<bool, const char*> consistentStringProperty(const char* lhs,
const char* rhs)
{
const bool b = strcmp(lhs, rhs) == 0;
- return std::make_pair(b, b ? lhs : nullptr);
+ return { b, b ? lhs : nullptr };
}
std::pair<bool, std::string> consistentStringProperty(const std::string& lhs,
const std::string& rhs)
{
const bool b = lhs == rhs;
- return std::make_pair(b, b ? lhs : valueAsString(nullptr));
+ return { b, b ? lhs : valueAsString(nullptr) };
}
std::pair<bool, const char*> consistentNumberProperty(const char* lhs,
@@ -4623,22 +4950,21 @@ std::pair<bool, const char*> consistentNumberProperty(const char* lhs,
{
char* pEnd;
- const char* const null_ptr = nullptr;
-
long lnum = strtol(lhs, &pEnd, 0);
if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) {
- return std::pair<bool, const char*>(false, null_ptr);
+ return { false, nullptr };
}
long rnum = strtol(rhs, &pEnd, 0);
if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) {
- return std::pair<bool, const char*>(false, null_ptr);
+ return { false, nullptr };
}
if (t == NumberMaxType) {
- return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
+ return { true, std::max(lnum, rnum) == lnum ? lhs : rhs };
}
- return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
+
+ return { true, std::min(lnum, rnum) == lnum ? lhs : rhs };
}
template <>
@@ -4647,21 +4973,19 @@ std::pair<bool, const char*> consistentProperty(const char* lhs,
CompatibleType t)
{
if (!lhs && !rhs) {
- return std::make_pair(true, lhs);
+ return { true, lhs };
}
if (!lhs) {
- return std::make_pair(true, rhs);
+ return { true, rhs };
}
if (!rhs) {
- return std::make_pair(true, lhs);
+ return { true, lhs };
}
- const char* const null_ptr = nullptr;
-
switch (t) {
case BoolType: {
- bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs);
- return std::make_pair(same, same ? lhs : nullptr);
+ bool same = cmIsOn(lhs) == cmIsOn(rhs);
+ return { same, same ? lhs : nullptr };
}
case StringType:
return consistentStringProperty(lhs, rhs);
@@ -4670,7 +4994,7 @@ std::pair<bool, const char*> consistentProperty(const char* lhs,
return consistentNumberProperty(lhs, rhs, t);
}
assert(false && "Unreachable!");
- return std::pair<bool, const char*>(false, null_ptr);
+ return { false, nullptr };
}
std::pair<bool, std::string> consistentProperty(const std::string& lhs,
@@ -4680,31 +5004,31 @@ std::pair<bool, std::string> consistentProperty(const std::string& lhs,
const std::string null_ptr = valueAsString(nullptr);
if (lhs == null_ptr && rhs == null_ptr) {
- return std::make_pair(true, lhs);
+ return { true, lhs };
}
if (lhs == null_ptr) {
- return std::make_pair(true, rhs);
+ return { true, rhs };
}
if (rhs == null_ptr) {
- return std::make_pair(true, lhs);
+ return { true, lhs };
}
switch (t) {
case BoolType: {
- bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs);
- return std::make_pair(same, same ? lhs : null_ptr);
+ bool same = cmIsOn(lhs) == cmIsOn(rhs);
+ return { same, same ? lhs : null_ptr };
}
case StringType:
return consistentStringProperty(lhs, rhs);
case NumberMinType:
case NumberMaxType: {
auto value = consistentNumberProperty(lhs.c_str(), rhs.c_str(), t);
- return std::make_pair(
- value.first, value.first ? std::string(value.second) : null_ptr);
+ return { value.first,
+ value.first ? std::string(value.second) : null_ptr };
}
}
assert(false && "Unreachable!");
- return std::pair<bool, std::string>(false, null_ptr);
+ return { false, null_ptr };
}
template <typename PropertyType>
@@ -4718,9 +5042,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
- const bool explicitlySet =
- std::find(headPropKeys.begin(), headPropKeys.end(), p) !=
- headPropKeys.end();
+ const bool explicitlySet = cmContains(headPropKeys, p);
const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
@@ -4733,8 +5055,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
}
bool propInitialized = explicitlySet;
- std::string report = " * Target \"";
- report += tgt->GetName();
+ std::string report = cmStrCat(" * Target \"", tgt->GetName());
if (explicitlySet) {
report += "\" has property content \"";
report += valueAsString<PropertyType>(propContent);
@@ -4760,8 +5081,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
- const bool ifaceIsSet = std::find(propKeys.begin(), propKeys.end(),
- interfaceProperty) != propKeys.end();
+ const bool ifaceIsSet = cmContains(propKeys, interfaceProperty);
PropertyType ifacePropContent = getTypedProperty<PropertyType>(
theTarget, interfaceProperty, genexInterpreter.get());
@@ -4894,7 +5214,7 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation(
{
// Lookup any existing information for this configuration.
std::string key(cmSystemTools::UpperCase(config));
- cmTargetLinkInformationMap::iterator i = this->LinkInformation.find(key);
+ auto i = this->LinkInformation.find(key);
if (i == this->LinkInformation.end()) {
// Compute information for this configuration.
cmComputeLinkInformation* info =
@@ -4991,9 +5311,8 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
mod_dir = target_mod_dir;
} else {
// Interpret relative to the current output directory.
- mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory();
- mod_dir += "/";
- mod_dir += target_mod_dir;
+ mod_dir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+ '/', target_mod_dir);
}
// Make sure the module output directory exists.
@@ -5032,13 +5351,7 @@ void cmGeneratorTarget::ComputeVersionedName(std::string& vName,
std::vector<std::string> cmGeneratorTarget::GetPropertyKeys() const
{
- cmPropertyMap const& propsObject = this->Target->GetProperties();
- std::vector<std::string> props;
- props.reserve(propsObject.size());
- for (auto const& it : propsObject) {
- props.push_back(it.first);
- }
- return props;
+ return this->Target->GetProperties().GetKeys();
}
void cmGeneratorTarget::ReportPropertyOrigin(
@@ -5049,12 +5362,11 @@ void cmGeneratorTarget::ReportPropertyOrigin(
const char* debugProp = this->Target->GetMakefile()->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp) {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ cmExpandList(debugProp, debugProperties);
}
- bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
- std::find(debugProperties.begin(), debugProperties.end(), p) !=
- debugProperties.end();
+ bool debugOrigin =
+ !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p);
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompatiblePropertiesDone[p] = true;
@@ -5063,12 +5375,9 @@ void cmGeneratorTarget::ReportPropertyOrigin(
return;
}
- std::string areport = compatibilityType;
- areport += std::string(" of property \"") + p + "\" for target \"";
- areport += std::string(this->GetName());
- areport += "\" (result: \"";
- areport += result;
- areport += "\"):\n" + report;
+ std::string areport =
+ cmStrCat(compatibilityType, " of property \"", p, "\" for target \"",
+ this->GetName(), "\" (result: \"", result, "\"):\n", report);
this->LocalGenerator->GetCMakeInstance()->IssueMessage(MessageType::LOG,
areport);
@@ -5101,10 +5410,9 @@ void cmGeneratorTarget::ExpandLinkItems(
}
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- cmSystemTools::ExpandListArgument(cge->Evaluate(this->LocalGenerator, config,
- false, headTarget, this,
- &dagChecker),
- libs);
+ cmExpandList(
+ cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this),
+ libs);
this->LookupLinkItems(libs, cge->GetBacktrace(), items);
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
}
@@ -5152,7 +5460,7 @@ void cmGeneratorTarget::ComputeLinkInterface(
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget) const
{
- if (iface.ExplicitLibraries) {
+ if (iface.Explicit) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -5209,8 +5517,7 @@ void cmGeneratorTarget::ComputeLinkInterface(
// How many repetitions are needed if this library has cyclic
// dependencies?
- std::string propName = "LINK_INTERFACE_MULTIPLICITY";
- propName += suffix;
+ 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 =
@@ -5296,10 +5603,9 @@ cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
// Only libraries and executables have well-defined output files.
if (!this->HaveWellDefinedOutputFiles()) {
- std::string msg = "cmGeneratorTarget::GetOutputInfo called for ";
- msg += this->GetName();
- msg += " which has type ";
- msg += cmState::GetTargetTypeName(this->GetType());
+ std::string msg = cmStrCat("cmGeneratorTarget::GetOutputInfo called for ",
+ this->GetName(), " which has type ",
+ cmState::GetTargetTypeName(this->GetType()));
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
return nullptr;
}
@@ -5309,7 +5615,7 @@ cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
if (!config.empty()) {
config_upper = cmSystemTools::UpperCase(config);
}
- OutputInfoMapType::iterator i = this->OutputInfoMap.find(config_upper);
+ auto i = this->OutputInfoMap.find(config_upper);
if (i == this->OutputInfoMap.end()) {
// Add empty info in map to detect potential recursion.
OutputInfo info;
@@ -5369,18 +5675,15 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
// Select an output directory.
if (const char* config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(config_outdir);
- out = cge->Evaluate(this->LocalGenerator, config);
+ out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ config);
// Skip per-configuration subdirectory.
conf.clear();
} else if (const char* outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outdir);
- out = cge->Evaluate(this->LocalGenerator, config);
+ out =
+ cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
@@ -5448,18 +5751,15 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
// Select an output directory.
if (const char* config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(config_outdir);
- out = cge->Evaluate(this->LocalGenerator, config);
+ out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ config);
// Skip per-configuration subdirectory.
conf.clear();
} else if (const char* outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outdir);
- out = cge->Evaluate(this->LocalGenerator, config);
+ out =
+ cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
@@ -5485,13 +5785,40 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
return true;
}
-bool cmGeneratorTarget::HaveInstallTreeRPATH() const
+bool cmGeneratorTarget::HaveInstallTreeRPATH(const std::string& config) const
{
- const char* install_rpath = this->GetProperty("INSTALL_RPATH");
- return (install_rpath && *install_rpath) &&
+ std::string install_rpath;
+ this->GetInstallRPATH(config, install_rpath);
+ return !install_rpath.empty() &&
!this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
}
+bool cmGeneratorTarget::GetBuildRPATH(const std::string& config,
+ std::string& rpath) const
+{
+ return this->GetRPATH(config, "BUILD_RPATH", rpath);
+}
+
+bool cmGeneratorTarget::GetInstallRPATH(const std::string& config,
+ std::string& rpath) const
+{
+ return this->GetRPATH(config, "INSTALL_RPATH", rpath);
+}
+
+bool cmGeneratorTarget::GetRPATH(const std::string& config,
+ const std::string& prop,
+ std::string& rpath) const
+{
+ const char* value = this->GetProperty(prop);
+ if (!value) {
+ return false;
+ }
+
+ rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config);
+
+ return true;
+}
+
void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget, bool usage_requirements_only) const
@@ -5508,8 +5835,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// libraries and executables that export symbols.
const char* explicitLibraries = nullptr;
std::string linkIfaceProp;
- if (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
- this->GetPolicyStatusCMP0022() != cmPolicies::WARN) {
+ bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+ this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
+ if (cmp0022NEW) {
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp);
@@ -5519,8 +5847,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// shared lib or executable.
// Lookup the per-configuration property.
- linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- linkIfaceProp += suffix;
+ linkIfaceProp = cmStrCat("LINK_INTERFACE_LIBRARIES", suffix);
explicitLibraries = this->GetProperty(linkIfaceProp);
// If not set, try the generic property.
@@ -5564,15 +5891,14 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
return;
}
iface.Exists = true;
- iface.ExplicitLibraries = explicitLibraries;
+ iface.Explicit = cmp0022NEW || explicitLibraries != nullptr;
if (explicitLibraries) {
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
usage_requirements_only, iface.Libraries,
iface.HadHeadSensitiveCondition);
- } else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN ||
- this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ } 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
// cleared the property explicitly and we should not fall back
@@ -5653,12 +5979,11 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
if (!iface.AllDone) {
iface.AllDone = true;
iface.Multiplicity = info->Multiplicity;
- cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+ cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
iface.HadHeadSensitiveCondition);
- std::vector<std::string> deps;
- cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+ std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -5682,7 +6007,7 @@ cmGeneratorTarget::ImportInfo const* cmGeneratorTarget::GetImportInfo(
config_upper = "NOCONFIG";
}
- ImportInfoMapType::const_iterator i = this->ImportInfoMap.find(config_upper);
+ auto i = this->ImportInfoMap.find(config_upper);
if (i == this->ImportInfoMap.end()) {
ImportInfo info;
this->ComputeImportInfo(config_upper, info);
@@ -5727,8 +6052,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (!propertyLibs) {
- linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
- linkProp += suffix;
+ linkProp = cmStrCat("IMPORTED_LINK_INTERFACE_LIBRARIES", suffix);
propertyLibs = this->GetProperty(linkProp);
}
@@ -5756,8 +6080,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (loc) {
info.Location = loc;
} else {
- std::string impProp = "IMPORTED_LOCATION";
- impProp += suffix;
+ 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")) {
@@ -5767,8 +6090,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the soname.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
- std::string soProp = "IMPORTED_SONAME";
- soProp += suffix;
+ 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")) {
@@ -5778,13 +6100,12 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the "no-soname" mark.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
- std::string soProp = "IMPORTED_NO_SONAME";
- soProp += suffix;
+ std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix);
if (const char* config_no_soname = this->GetProperty(soProp)) {
- info.NoSOName = cmSystemTools::IsOn(config_no_soname);
+ info.NoSOName = cmIsOn(config_no_soname);
} else if (const char* no_soname =
this->GetProperty("IMPORTED_NO_SONAME")) {
- info.NoSOName = cmSystemTools::IsOn(no_soname);
+ info.NoSOName = cmIsOn(no_soname);
}
}
@@ -5793,8 +6114,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
info.ImportLibrary = imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
- std::string impProp = "IMPORTED_IMPLIB";
- impProp += suffix;
+ 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")) {
@@ -5804,8 +6124,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the link dependencies.
{
- std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
- linkProp += suffix;
+ 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 =
@@ -5816,8 +6136,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the link languages.
if (this->LinkLanguagePropagatesToDependents()) {
- std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
- linkProp += suffix;
+ 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 =
@@ -5838,8 +6158,8 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the cyclic repetition count.
if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
- std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
- linkProp += suffix;
+ 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 =
@@ -5888,13 +6208,10 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
bool cmGeneratorTarget::GetConfigCommonSourceFiles(
std::vector<cmSourceFile*>& files) const
{
- std::vector<std::string> configs;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs();
- std::vector<std::string>::const_iterator it = configs.begin();
+ auto it = configs.begin();
const std::string& firstConfig = *it;
this->GetSourceFilesWithoutObjectLibraries(files, firstConfig);
@@ -5906,7 +6223,7 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
const char* sep = "";
for (cmSourceFile* f : files) {
firstConfigFiles += sep;
- firstConfigFiles += f->GetFullPath();
+ firstConfigFiles += f->ResolveFullPath();
sep = "\n ";
}
@@ -5914,7 +6231,7 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
sep = "";
for (cmSourceFile* f : configFiles) {
thisConfigFiles += sep;
- thisConfigFiles += f->GetFullPath();
+ thisConfigFiles += f->ResolveFullPath();
sep = "\n ";
}
std::ostringstream e;
@@ -5946,8 +6263,7 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026(
// behavior of CMP0024 and CMP0026 only.
cmStringRange rng = this->Target->GetSourceEntries();
for (std::string const& entry : rng) {
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
for (std::string const& li : files) {
if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') {
std::string objLibName = li.substr(17, li.size() - 18);
@@ -6020,7 +6336,7 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
std::vector<cmSourceFile*> sourceFiles;
this->GetSourceFiles(sourceFiles, config);
for (cmSourceFile* src : sourceFiles) {
- const std::string& lang = src->GetLanguage();
+ const std::string& lang = src->GetOrDetermineLanguage();
if (!lang.empty()) {
languages.insert(lang);
}
@@ -6091,7 +6407,8 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) {
return false;
}
- if (this->GetProperty("BUILD_RPATH")) {
+ std::string build_rpath;
+ if (this->GetBuildRPATH(config, build_rpath)) {
return true;
}
if (cmLinkImplementationLibraries const* impl =
@@ -6138,8 +6455,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
const std::string& p) const
{
- return this->LinkImplicitNullProperties.find(p) !=
- this->LinkImplicitNullProperties.end();
+ return cmContains(this->LinkImplicitNullProperties, p);
}
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
@@ -6159,8 +6475,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
std::string const& evaluated =
- cge->Evaluate(this->LocalGenerator, config, false, head, &dagChecker);
- cmSystemTools::ExpandListArgument(evaluated, llibs);
+ cge->Evaluate(this->LocalGenerator, config, head, &dagChecker);
+ cmExpandList(evaluated, llibs);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
@@ -6317,8 +6633,8 @@ bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config,
{
if (this->HasImplibGNUtoMS(config) && gnuName.size() > 6 &&
gnuName.substr(gnuName.size() - 6) == ".dll.a") {
- out = gnuName.substr(0, gnuName.size() - 6);
- out += newExt ? newExt : ".lib";
+ out = cmStrCat(cm::string_view(gnuName).substr(0, gnuName.size() - 6),
+ newExt ? newExt : ".lib");
return true;
}
return false;
@@ -6337,15 +6653,24 @@ bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const
this->IsExecutableWithExports()) &&
// Assemblies which have only managed code do not have
// import libraries.
- this->GetManagedType(config) != ManagedType::Managed);
+ this->GetManagedType(config) != ManagedType::Managed) ||
+ (this->Target->IsAIX() && this->IsExecutableWithExports());
+}
+
+bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
+{
+ return this->HasImportLibrary(config) ||
+ // On DLL platforms we always generate the import library name
+ // just in case the sources have export markup.
+ (this->IsDLLPlatform() &&
+ (this->GetType() == cmStateEnums::EXECUTABLE ||
+ this->GetType() == cmStateEnums::MODULE_LIBRARY));
}
std::string cmGeneratorTarget::GetSupportDirectory() const
{
- std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/CMakeFiles";
- dir += "/";
- dir += this->GetName();
+ std::string dir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", this->GetName());
#if defined(__VMS)
dir += "_dir";
#else
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 0e0ee6a6f..493eafcf0 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -5,18 +5,20 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmLinkItem.h"
-#include "cmListFileCache.h"
-#include "cmPolicies.h"
-#include "cmStateTypes.h"
-
+#include <cstddef>
#include <map>
#include <set>
-#include <stddef.h>
#include <string>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
+#include "cmLinkItem.h"
+#include "cmListFileCache.h"
+#include "cmPolicies.h"
+#include "cmStateTypes.h"
+
class cmComputeLinkInformation;
class cmCustomCommand;
class cmGlobalGenerator;
@@ -25,6 +27,9 @@ class cmMakefile;
class cmSourceFile;
class cmTarget;
+struct cmGeneratorExpressionContext;
+struct cmGeneratorExpressionDAGChecker;
+
class cmGeneratorTarget
{
public:
@@ -94,7 +99,8 @@ public:
SourceKindModuleDefinition,
SourceKindObjectSource,
SourceKindResx,
- SourceKindXaml
+ SourceKindXaml,
+ SourceKindUnityBatched
};
/** A source file paired with a kind (classification). */
@@ -451,6 +457,25 @@ public:
std::vector<BT<std::string>> GetLinkDepends(
std::string const& config, std::string const& language) const;
+ std::vector<BT<std::string>> GetPrecompileHeaders(
+ const std::string& config, const std::string& language) const;
+
+ std::string GetPchHeader(const std::string& config,
+ const std::string& language) const;
+ std::string GetPchSource(const std::string& config,
+ const std::string& language) const;
+ std::string GetPchFileObject(const std::string& config,
+ const std::string& language);
+ std::string GetPchFile(const std::string& config,
+ const std::string& language);
+ std::string GetPchCreateCompileOptions(const std::string& config,
+ const std::string& language);
+ std::string GetPchUseCompileOptions(const std::string& config,
+ const std::string& language);
+
+ void AddSourceFileToUnityBatch(const std::string& sourceFilename);
+ bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
+
bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config,
const std::string& language) const;
@@ -519,7 +544,7 @@ public:
CompileInfo const* GetCompileInfo(const std::string& config) const;
- typedef std::map<std::string, CompileInfo> CompileInfoMapType;
+ using CompileInfoMapType = std::map<std::string, CompileInfo>;
mutable CompileInfoMapType CompileInfoMap;
bool IsNullImpliedByLinkLibraries(const std::string& p) const;
@@ -674,7 +699,14 @@ public:
class TargetPropertyEntry;
- bool HaveInstallTreeRPATH() const;
+ std::string EvaluateInterfaceProperty(
+ std::string const& prop, cmGeneratorExpressionContext* context,
+ cmGeneratorExpressionDAGChecker* dagCheckerParent) const;
+
+ bool HaveInstallTreeRPATH(const std::string& config) const;
+
+ bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
+ bool GetInstallRPATH(const std::string& config, std::string& rpath) const;
/** Whether this library has \@rpath and platform supports it. */
bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
@@ -726,7 +758,7 @@ private:
{
std::vector<cmSourceFile*> Depends;
};
- typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
+ using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
SourceEntriesType SourceDepends;
mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName;
@@ -740,9 +772,13 @@ private:
mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
- const char* GetFilePrefixInternal(cmStateEnums::ArtifactType artifact,
+ bool NeedImportLibraryName(std::string const& config) const;
+
+ const char* GetFilePrefixInternal(std::string const& config,
+ cmStateEnums::ArtifactType artifact,
const std::string& language = "") const;
- const char* GetFileSuffixInternal(cmStateEnums::ArtifactType artifact,
+ const char* GetFileSuffixInternal(std::string const& config,
+ cmStateEnums::ArtifactType artifact,
const std::string& language = "") const;
std::string GetFullNameInternal(const std::string& config,
@@ -752,7 +788,7 @@ private:
std::string& outPrefix, std::string& outBase,
std::string& outSuffix) const;
- typedef std::map<std::string, LinkClosure> LinkClosureMapType;
+ using LinkClosureMapType = std::map<std::string, LinkClosure>;
mutable LinkClosureMapType LinkClosureMap;
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
@@ -779,8 +815,8 @@ private:
};
mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
- typedef std::map<std::string, cmComputeLinkInformation*>
- cmTargetLinkInformationMap;
+ using cmTargetLinkInformationMap =
+ std::map<std::string, cmComputeLinkInformation*>;
mutable cmTargetLinkInformationMap LinkInformation;
void CheckPropertyCompatibility(cmComputeLinkInformation* info,
@@ -792,7 +828,7 @@ private:
};
mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
- typedef std::map<std::string, cmHeadToLinkInterfaceMap> LinkInterfaceMapType;
+ using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>;
mutable LinkInterfaceMapType LinkInterfaceMap;
mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
@@ -820,7 +856,7 @@ private:
std::string SharedDeps;
};
- typedef std::map<std::string, ImportInfo> ImportInfoMapType;
+ using ImportInfoMapType = std::map<std::string, ImportInfo>;
mutable ImportInfoMapType ImportInfoMap;
void ComputeImportInfo(std::string const& desired_config,
ImportInfo& info) const;
@@ -834,7 +870,7 @@ private:
const std::string& config, const cmGeneratorTarget* head,
bool usage_requirements_only) const;
- typedef std::map<std::string, KindedSources> KindedSourcesMapType;
+ using KindedSourcesMapType = std::map<std::string, KindedSources>;
mutable KindedSourcesMapType KindedSourcesMap;
void ComputeKindedSources(KindedSources& files,
std::string const& config) const;
@@ -842,14 +878,27 @@ private:
mutable std::vector<AllConfigSource> AllConfigSources;
void ComputeAllConfigSources() const;
+ mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
+ bool MaybeHaveInterfaceProperty(std::string const& prop,
+ cmGeneratorExpressionContext* context) const;
+
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
std::vector<TargetPropertyEntry*> LinkOptionsEntries;
std::vector<TargetPropertyEntry*> LinkDirectoriesEntries;
+ std::vector<TargetPropertyEntry*> PrecompileHeadersEntries;
std::vector<TargetPropertyEntry*> SourceEntries;
mutable std::set<std::string> LinkImplicitNullProperties;
+ mutable std::map<std::string, std::string> PchHeaders;
+ mutable std::map<std::string, std::string> PchSources;
+ mutable std::map<std::string, std::string> PchObjectFiles;
+ mutable std::map<std::string, std::string> PchFiles;
+ mutable std::map<std::string, std::string> PchCreateCompileOptions;
+ mutable std::map<std::string, std::string> PchUseCompileOptions;
+
+ std::unordered_set<std::string> UnityBatchedSourceFiles;
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config,
@@ -872,7 +921,7 @@ private:
: public std::map<cmGeneratorTarget const*, cmOptionalLinkImplementation>
{
};
- typedef std::map<std::string, HeadToLinkImplementationMap> LinkImplMapType;
+ using LinkImplMapType = std::map<std::string, HeadToLinkImplementationMap>;
mutable LinkImplMapType LinkImplMap;
cmLinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(
@@ -881,17 +930,17 @@ private:
cmStateEnums::ArtifactType artifact,
std::string& out) const;
- typedef std::map<std::string, OutputInfo> OutputInfoMapType;
+ using OutputInfoMapType = std::map<std::string, OutputInfo>;
mutable OutputInfoMapType OutputInfoMap;
- typedef std::map<std::string, ModuleDefinitionInfo>
- ModuleDefinitionInfoMapType;
+ using ModuleDefinitionInfoMapType =
+ std::map<std::string, ModuleDefinitionInfo>;
mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap;
void ComputeModuleDefinitionInfo(std::string const& config,
ModuleDefinitionInfo& info) const;
- typedef std::pair<std::string, cmStateEnums::ArtifactType> OutputNameKey;
- typedef std::map<OutputNameKey, std::string> OutputNameMapType;
+ using OutputNameKey = std::pair<std::string, cmStateEnums::ArtifactType>;
+ using OutputNameMapType = std::map<OutputNameKey, std::string>;
mutable OutputNameMapType OutputNameMap;
mutable std::set<cmLinkItem> UtilityItems;
cmPolicies::PolicyMap PolicyMap;
@@ -903,16 +952,19 @@ private:
mutable bool DebugCompileDefinitionsDone;
mutable bool DebugLinkOptionsDone;
mutable bool DebugLinkDirectoriesDone;
+ mutable bool DebugPrecompileHeadersDone;
mutable bool DebugSourcesDone;
mutable bool LinkImplementationLanguageIsContextDependent;
mutable bool UtilityItemsDone;
- bool DLLPlatform;
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
std::string& out) const;
ManagedType CheckManagedType(std::string const& propval) const;
+ bool GetRPATH(const std::string& config, const std::string& prop,
+ std::string& rpath) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
const std::string& config) const;
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index fc82feef5..ff4e312f3 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -4,19 +4,18 @@
#include <set>
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
-
-class cmExecutionStatus;
+#include "cmStringAlgorithms.h"
// cmGetCMakePropertyCommand
-bool cmGetCMakePropertyCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -24,29 +23,29 @@ bool cmGetCMakePropertyCommand::InitialPass(
std::string output = "NOTFOUND";
if (args[1] == "VARIABLES") {
- if (const char* varsProp = this->Makefile->GetProperty("VARIABLES")) {
+ if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
output = varsProp;
}
} else if (args[1] == "MACROS") {
output.clear();
- if (const char* macrosProp = this->Makefile->GetProperty("MACROS")) {
+ if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) {
output = macrosProp;
}
} else if (args[1] == "COMPONENTS") {
const std::set<std::string>* components =
- this->Makefile->GetGlobalGenerator()->GetInstallComponents();
+ status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
output = cmJoin(*components, ";");
} else {
const char* prop = nullptr;
if (!args[1].empty()) {
- prop = this->Makefile->GetState()->GetGlobalProperty(args[1]);
+ prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]);
}
if (prop) {
output = prop;
}
}
- this->Makefile->AddDefinition(variable, output.c_str());
+ status.GetMakefile().AddDefinition(variable, output);
return true;
}
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index 1f29c78dc..7a6728cfe 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetCMakePropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmGetCMakePropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index a92eb7186..64438d50a 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -2,51 +2,54 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetDirectoryPropertyCommand.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+namespace {
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+ const char* prop);
+}
// cmGetDirectoryPropertyCommand
-bool cmGetDirectoryPropertyCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
std::string const& variable = *i;
++i;
// get the directory argument if there is one
- cmMakefile* dir = this->Makefile;
+ cmMakefile* dir = &status.GetMakefile();
if (*i == "DIRECTORY") {
++i;
if (i == args.end()) {
- this->SetError(
+ status.SetError(
"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 = this->Makefile->GetCurrentSourceDirectory();
- sd += "/";
- sd += *i;
+ sd = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
}
// The local generators are associated with collapsed paths.
sd = cmSystemTools::CollapseFullPath(sd);
// lookup the makefile from the directory name
- dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd);
+ dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd);
if (!dir) {
- this->SetError(
+ status.SetError(
"DIRECTORY argument provided but requested directory not found. "
"This could be because the directory argument was invalid or, "
"it is valid but has not been processed yet.");
@@ -61,26 +64,27 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
if (*i == "DEFINITION") {
++i;
if (i == args.end()) {
- this->SetError("A request for a variable definition was made without "
- "providing the name of the variable to get.");
+ status.SetError("A request for a variable definition was made without "
+ "providing the name of the variable to get.");
return false;
}
std::string const& output = dir->GetSafeDefinition(*i);
- this->Makefile->AddDefinition(variable, output.c_str());
+ status.GetMakefile().AddDefinition(variable, output);
return true;
}
const char* prop = nullptr;
if (!i->empty()) {
if (*i == "DEFINITIONS") {
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0059)) {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) {
case cmPolicies::WARN:
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
CM_FALLTHROUGH;
case cmPolicies::OLD:
- this->StoreResult(variable, this->Makefile->GetDefineFlagsCMP0059());
+ StoreResult(status.GetMakefile(), variable,
+ status.GetMakefile().GetDefineFlagsCMP0059());
return true;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
@@ -90,16 +94,14 @@ bool cmGetDirectoryPropertyCommand::InitialPass(
}
prop = dir->GetProperty(*i);
}
- this->StoreResult(variable, prop);
+ StoreResult(status.GetMakefile(), variable, prop);
return true;
}
-void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
- const char* prop)
+namespace {
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+ const char* prop)
{
- if (prop) {
- this->Makefile->AddDefinition(variable, prop);
- return;
- }
- this->Makefile->AddDefinition(variable, "");
+ makefile.AddDefinition(variable, prop ? prop : "");
+}
}
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index 02ea0566f..f356ea5b4 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -8,24 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetDirectoryPropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmGetDirectoryPropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void StoreResult(const std::string& variable, const char* prop);
-};
+bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 163b4c8ab..7d91a7570 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -2,26 +2,26 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetFilenameComponentCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmGetFilenameComponentCommand
-bool cmGetFilenameComponentCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// Check and see if the value has been stored in the cache
// already, if so use that value
if (args.size() >= 4 && args.back() == "CACHE") {
- const char* cacheValue = this->Makefile->GetDefinition(args.front());
- if (cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) {
+ const char* cacheValue = status.GetMakefile().GetDefinition(args.front());
+ if (cacheValue && !cmIsNOTFOUND(cacheValue)) {
return true;
}
}
@@ -32,7 +32,7 @@ bool cmGetFilenameComponentCommand::InitialPass(
// Check the registry as the target application would view it.
cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
- if (this->Makefile->PlatformIs64Bit()) {
+ if (status.GetMakefile().PlatformIs64Bit()) {
view = cmSystemTools::KeyWOW64_64;
other_view = cmSystemTools::KeyWOW64_32;
}
@@ -64,7 +64,7 @@ bool cmGetFilenameComponentCommand::InitialPass(
// First assume the path to the program was specified with no
// arguments and with no quoting or escaping for spaces.
// Only bother doing this if there is non-whitespace.
- if (!cmSystemTools::TrimWhitespace(filename).empty()) {
+ if (!cmTrimWhitespace(filename).empty()) {
result = cmSystemTools::FindProgram(filename);
}
@@ -96,7 +96,7 @@ bool cmGetFilenameComponentCommand::InitialPass(
// If the path given is relative, evaluate it relative to the
// current source directory unless the user passes a different
// base directory.
- std::string baseDir = this->Makefile->GetCurrentSourceDirectory();
+ std::string baseDir = status.GetMakefile().GetCurrentSourceDirectory();
for (unsigned int i = 3; i < args.size(); ++i) {
if (args[i] == "BASE_DIR") {
++i;
@@ -113,24 +113,24 @@ bool cmGetFilenameComponentCommand::InitialPass(
}
} else {
std::string err = "unknown component " + args[2];
- this->SetError(err);
+ status.SetError(err);
return false;
}
if (args.size() >= 4 && args.back() == "CACHE") {
if (!programArgs.empty() && !storeArgs.empty()) {
- this->Makefile->AddCacheDefinition(
+ status.GetMakefile().AddCacheDefinition(
storeArgs, programArgs.c_str(), "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
}
- this->Makefile->AddCacheDefinition(
+ status.GetMakefile().AddCacheDefinition(
args.front(), result.c_str(), "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
} else {
if (!programArgs.empty() && !storeArgs.empty()) {
- this->Makefile->AddDefinition(storeArgs, programArgs.c_str());
+ status.GetMakefile().AddDefinition(storeArgs, programArgs);
}
- this->Makefile->AddDefinition(args.front(), result.c_str());
+ status.GetMakefile().AddDefinition(args.front(), result);
}
return true;
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index 8c266552c..db5293b2a 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -8,30 +8,15 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmGetFilenameComponentCommand
+/**
* \brief Get a specific component of a filename.
*
* cmGetFilenameComponentCommand is a utility command used to get the path,
* name, extension or name without extension of a full filename.
*/
-class cmGetFilenameComponentCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmGetFilenameComponentCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetPipes.cxx b/Source/cmGetPipes.cxx
index ad323f7ee..4eda1c54a 100644
--- a/Source/cmGetPipes.cxx
+++ b/Source/cmGetPipes.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetPipes.h"
-#include "cm_uv.h"
-
#include <fcntl.h>
+#include "cm_uv.h"
+
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h>
@@ -28,7 +28,8 @@ int cmGetPipes(int* fds)
return 0;
}
#else
-# include <errno.h>
+# include <cerrno>
+
# include <unistd.h>
int cmGetPipes(int* fds)
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 039f43922..947d893db 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -2,8 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetPropertyCommand.h"
-#include <sstream>
-
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
@@ -14,30 +13,70 @@
#include "cmPropertyDefinition.h"
#include "cmSourceFile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetPropertyComputer.h"
#include "cmTest.h"
#include "cmake.h"
-class cmExecutionStatus;
class cmMessenger;
-cmGetPropertyCommand::cmGetPropertyCommand()
+namespace {
+enum OutType
{
- this->InfoType = OutValue;
+ OutValue,
+ OutDefined,
+ OutBriefDoc,
+ OutFullDoc,
+ OutSet
+};
+
+// Implementation of result storage.
+bool StoreResult(OutType infoType, cmMakefile& makefile,
+ const std::string& variable, const char* value);
+
+// Implementation of each property type.
+bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
+bool HandleInstallMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName);
}
-bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmGetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ OutType infoType = OutValue;
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// The cmake variable in which to store the result.
- this->Variable = args[0];
+ const std::string variable = args[0];
+
+ std::string name;
+ std::string propertyName;
// Get the scope from which to get the property.
cmProperty::ScopeType scope;
@@ -58,11 +97,11 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
} else if (args[1] == "INSTALL") {
scope = cmProperty::INSTALL;
} else {
- std::ostringstream e;
- e << "given invalid scope " << args[1] << ". "
- << "Valid scopes are "
- << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "given invalid scope ", args[1],
+ ". "
+ "Valid scopes are "
+ "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."));
return false;
}
@@ -80,86 +119,90 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
doing = DoingProperty;
} else if (args[i] == "BRIEF_DOCS") {
doing = DoingNone;
- this->InfoType = OutBriefDoc;
+ infoType = OutBriefDoc;
} else if (args[i] == "FULL_DOCS") {
doing = DoingNone;
- this->InfoType = OutFullDoc;
+ infoType = OutFullDoc;
} else if (args[i] == "SET") {
doing = DoingNone;
- this->InfoType = OutSet;
+ infoType = OutSet;
} else if (args[i] == "DEFINED") {
doing = DoingNone;
- this->InfoType = OutDefined;
+ infoType = OutDefined;
} else if (doing == DoingName) {
doing = DoingNone;
- this->Name = args[i];
+ name = args[i];
} else if (doing == DoingProperty) {
doing = DoingNone;
- this->PropertyName = args[i];
+ propertyName = args[i];
} else {
- std::ostringstream e;
- e << "given invalid argument \"" << args[i] << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given invalid argument \"", args[i], "\"."));
return false;
}
}
// Make sure a property name was found.
- if (this->PropertyName.empty()) {
- this->SetError("not given a PROPERTY <name> argument.");
+ if (propertyName.empty()) {
+ status.SetError("not given a PROPERTY <name> argument.");
return false;
}
// Compute requested output.
- if (this->InfoType == OutBriefDoc) {
+ if (infoType == OutBriefDoc) {
// Lookup brief documentation.
std::string output;
if (cmPropertyDefinition const* def =
- this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
- scope)) {
+ status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+ scope)) {
output = def->GetShortDescription();
} else {
output = "NOTFOUND";
}
- this->Makefile->AddDefinition(this->Variable, output.c_str());
- } else if (this->InfoType == OutFullDoc) {
+ status.GetMakefile().AddDefinition(variable, output);
+ } else if (infoType == OutFullDoc) {
// Lookup full documentation.
std::string output;
if (cmPropertyDefinition const* def =
- this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
- scope)) {
+ status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+ scope)) {
output = def->GetFullDescription();
} else {
output = "NOTFOUND";
}
- this->Makefile->AddDefinition(this->Variable, output.c_str());
- } else if (this->InfoType == OutDefined) {
+ status.GetMakefile().AddDefinition(variable, output);
+ } else if (infoType == OutDefined) {
// Lookup if the property is defined
- if (this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
- scope)) {
- this->Makefile->AddDefinition(this->Variable, "1");
+ if (status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
+ scope)) {
+ status.GetMakefile().AddDefinition(variable, "1");
} else {
- this->Makefile->AddDefinition(this->Variable, "0");
+ status.GetMakefile().AddDefinition(variable, "0");
}
} else {
// Dispatch property getting.
switch (scope) {
case cmProperty::GLOBAL:
- return this->HandleGlobalMode();
+ return HandleGlobalMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::DIRECTORY:
- return this->HandleDirectoryMode();
+ return HandleDirectoryMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::TARGET:
- return this->HandleTargetMode();
+ return HandleTargetMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::SOURCE_FILE:
- return this->HandleSourceMode();
+ return HandleSourceMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::TEST:
- return this->HandleTestMode();
+ return HandleTestMode(status, name, infoType, variable, propertyName);
case cmProperty::VARIABLE:
- return this->HandleVariableMode();
+ return HandleVariableMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::CACHE:
- return this->HandleCacheMode();
+ return HandleCacheMode(status, name, infoType, variable, propertyName);
case cmProperty::INSTALL:
- return this->HandleInstallMode();
+ return HandleInstallMode(status, name, infoType, variable,
+ propertyName);
case cmProperty::CACHED_VARIABLE:
break; // should never happen
@@ -169,58 +212,64 @@ bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
-bool cmGetPropertyCommand::StoreResult(const char* value)
+namespace {
+
+bool StoreResult(OutType infoType, cmMakefile& makefile,
+ const std::string& variable, const char* value)
{
- if (this->InfoType == OutSet) {
- this->Makefile->AddDefinition(this->Variable, value ? "1" : "0");
- } else // if(this->InfoType == OutValue)
+ if (infoType == OutSet) {
+ makefile.AddDefinition(variable, value ? "1" : "0");
+ } else // if(infoType == OutValue)
{
if (value) {
- this->Makefile->AddDefinition(this->Variable, value);
+ makefile.AddDefinition(variable, value);
} else {
- this->Makefile->RemoveDefinition(this->Variable);
+ makefile.RemoveDefinition(variable);
}
}
return true;
}
-bool cmGetPropertyCommand::HandleGlobalMode()
+bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (!this->Name.empty()) {
- this->SetError("given name for GLOBAL scope.");
+ if (!name.empty()) {
+ status.SetError("given name for GLOBAL scope.");
return false;
}
// Get the property.
- cmake* cm = this->Makefile->GetCMakeInstance();
- return this->StoreResult(
- cm->GetState()->GetGlobalProperty(this->PropertyName));
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ cm->GetState()->GetGlobalProperty(propertyName));
}
-bool cmGetPropertyCommand::HandleDirectoryMode()
+bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
// Default to the current directory.
- cmMakefile* mf = this->Makefile;
+ cmMakefile* mf = &status.GetMakefile();
// Lookup the directory if given.
- if (!this->Name.empty()) {
+ if (!name.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = this->Name;
+ std::string dir = name;
if (!cmSystemTools::FileIsFullPath(dir)) {
- dir = this->Makefile->GetCurrentSourceDirectory();
- dir += "/";
- dir += this->Name;
+ dir =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', name);
}
// The local generators are associated with collapsed paths.
dir = cmSystemTools::CollapseFullPath(dir);
// Lookup the generator.
- mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
if (!mf) {
// Could not find the directory.
- this->SetError(
+ status.SetError(
"DIRECTORY scope provided but requested directory was not found. "
"This could be because the directory argument was invalid or, "
"it is valid but has not been processed yet.");
@@ -228,14 +277,15 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
}
}
- if (this->PropertyName == "DEFINITIONS") {
+ if (propertyName == "DEFINITIONS") {
switch (mf->GetPolicyStatus(cmPolicies::CMP0059)) {
case cmPolicies::WARN:
mf->IssueMessage(MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
CM_FALLTHROUGH;
case cmPolicies::OLD:
- return this->StoreResult(mf->GetDefineFlagsCMP0059());
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ mf->GetDefineFlagsCMP0059());
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
@@ -244,124 +294,136 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
}
// Get the property.
- return this->StoreResult(mf->GetProperty(this->PropertyName));
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ mf->GetProperty(propertyName));
}
-bool cmGetPropertyCommand::HandleTargetMode()
+bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (this->Name.empty()) {
- this->SetError("not given name for TARGET scope.");
+ if (name.empty()) {
+ status.SetError("not given name for TARGET scope.");
return false;
}
- if (cmTarget* target = this->Makefile->FindTargetToUse(this->Name)) {
- if (this->PropertyName == "ALIASED_TARGET") {
- if (this->Makefile->IsAlias(this->Name)) {
- return this->StoreResult(target->GetName().c_str());
+ if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
+ if (propertyName == "ALIASED_TARGET") {
+ if (status.GetMakefile().IsAlias(name)) {
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ target->GetName().c_str());
}
- return this->StoreResult(nullptr);
+ return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
}
const char* prop_cstr = nullptr;
- cmListFileBacktrace bt = this->Makefile->GetBacktrace();
- cmMessenger* messenger = this->Makefile->GetMessenger();
+ cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
+ cmMessenger* messenger = status.GetMakefile().GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(
- target->GetType(), this->PropertyName, messenger, bt)) {
- prop_cstr =
- target->GetComputedProperty(this->PropertyName, messenger, bt);
+ target->GetType(), propertyName, messenger, bt)) {
+ prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
if (!prop_cstr) {
- prop_cstr = target->GetProperty(this->PropertyName);
+ prop_cstr = target->GetProperty(propertyName);
}
}
- return this->StoreResult(prop_cstr);
+ return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr);
}
- std::ostringstream e;
- e << "could not find TARGET " << this->Name
- << ". Perhaps it has not yet been created.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("could not find TARGET ", name,
+ ". Perhaps it has not yet been created."));
return false;
}
-bool cmGetPropertyCommand::HandleSourceMode()
+bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (this->Name.empty()) {
- this->SetError("not given name for SOURCE scope.");
+ if (name.empty()) {
+ status.SetError("not given name for SOURCE scope.");
return false;
}
// Get the source file.
- if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(this->Name)) {
- return this->StoreResult(sf->GetPropertyForUser(this->PropertyName));
+ if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ sf->GetPropertyForUser(propertyName));
}
- std::ostringstream e;
- e << "given SOURCE name that could not be found or created: " << this->Name;
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("given SOURCE name that could not be found or created: ", name));
return false;
}
-bool cmGetPropertyCommand::HandleTestMode()
+bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (this->Name.empty()) {
- this->SetError("not given name for TEST scope.");
+ if (name.empty()) {
+ status.SetError("not given name for TEST scope.");
return false;
}
// Loop over all tests looking for matching names.
- if (cmTest* test = this->Makefile->GetTest(this->Name)) {
- return this->StoreResult(test->GetProperty(this->PropertyName));
+ if (cmTest* test = status.GetMakefile().GetTest(name)) {
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ test->GetProperty(propertyName));
}
// If not found it is an error.
- std::ostringstream e;
- e << "given TEST name that does not exist: " << this->Name;
- this->SetError(e.str());
+ status.SetError(cmStrCat("given TEST name that does not exist: ", name));
return false;
}
-bool cmGetPropertyCommand::HandleVariableMode()
+bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (!this->Name.empty()) {
- this->SetError("given name for VARIABLE scope.");
+ if (!name.empty()) {
+ status.SetError("given name for VARIABLE scope.");
return false;
}
- return this->StoreResult(this->Makefile->GetDefinition(this->PropertyName));
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ status.GetMakefile().GetDefinition(propertyName));
}
-bool cmGetPropertyCommand::HandleCacheMode()
+bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (this->Name.empty()) {
- this->SetError("not given name for CACHE scope.");
+ if (name.empty()) {
+ status.SetError("not given name for CACHE scope.");
return false;
}
const char* value = nullptr;
- if (this->Makefile->GetState()->GetCacheEntryValue(this->Name)) {
- value = this->Makefile->GetState()->GetCacheEntryProperty(
- this->Name, this->PropertyName);
+ if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
+ value = status.GetMakefile().GetState()->GetCacheEntryProperty(
+ name, propertyName);
}
- this->StoreResult(value);
+ StoreResult(infoType, status.GetMakefile(), variable, value);
return true;
}
-bool cmGetPropertyCommand::HandleInstallMode()
+bool HandleInstallMode(cmExecutionStatus& status, const std::string& name,
+ OutType infoType, const std::string& variable,
+ const std::string& propertyName)
{
- if (this->Name.empty()) {
- this->SetError("not given name for INSTALL scope.");
+ if (name.empty()) {
+ status.SetError("not given name for INSTALL scope.");
return false;
}
// Get the installed file.
- cmake* cm = this->Makefile->GetCMakeInstance();
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
if (cmInstalledFile* file =
- cm->GetOrCreateInstalledFile(this->Makefile, this->Name)) {
+ cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
std::string value;
- bool isSet = file->GetProperty(this->PropertyName, value);
+ bool isSet = file->GetProperty(propertyName, value);
- return this->StoreResult(isSet ? value.c_str() : nullptr);
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ isSet ? value.c_str() : nullptr);
}
- std::ostringstream e;
- e << "given INSTALL name that could not be found or created: " << this->Name;
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("given INSTALL name that could not be found or created: ", name));
return false;
}
+}
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index c3f653e2e..cc600f4ee 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -8,50 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetPropertyCommand : public cmCommand
-{
-public:
- cmGetPropertyCommand();
-
- cmCommand* Clone() override { return new cmGetPropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- enum OutType
- {
- OutValue,
- OutDefined,
- OutBriefDoc,
- OutFullDoc,
- OutSet
- };
- std::string Variable;
- std::string Name;
- std::string PropertyName;
- OutType InfoType;
-
- // Implementation of result storage.
- bool StoreResult(const char* value);
-
- // Implementation of each property type.
- bool HandleGlobalMode();
- bool HandleDirectoryMode();
- bool HandleTargetMode();
- bool HandleSourceMode();
- bool HandleTestMode();
- bool HandleVariableMode();
- bool HandleCacheMode();
- bool HandleInstallMode();
-};
+bool cmGetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 75879a553..eefdc6ccb 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -2,42 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetSourceFilePropertyCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-class cmExecutionStatus;
-
-// cmSetSourceFilePropertyCommand
-bool cmGetSourceFilePropertyCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& var = args[0];
std::string const& file = args[1];
- cmSourceFile* sf = this->Makefile->GetSource(file);
+ cmMakefile& mf = status.GetMakefile();
+ cmSourceFile* sf = mf.GetSource(file);
// for the location we must create a source file first
if (!sf && args[2] == "LOCATION") {
- sf = this->Makefile->CreateSource(file);
+ sf = mf.CreateSource(file);
}
if (sf) {
- if (args[2] == "LANGUAGE") {
- this->Makefile->AddDefinition(var, sf->GetLanguage().c_str());
- return true;
- }
const char* prop = nullptr;
if (!args[2].empty()) {
prop = sf->GetPropertyForUser(args[2]);
}
if (prop) {
- this->Makefile->AddDefinition(var, prop);
+ mf.AddDefinition(var, prop);
return true;
}
}
- this->Makefile->AddDefinition(var, "NOTFOUND");
+ mf.AddDefinition(var, "NOTFOUND");
return true;
}
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
index 43bc330a8..f0c319b0a 100644
--- a/Source/cmGetSourceFilePropertyCommand.h
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetSourceFilePropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmGetSourceFilePropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index fc0e9c693..7f5df9cfb 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -4,6 +4,7 @@
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -11,32 +12,31 @@
#include "cmTarget.h"
#include "cmTargetPropertyComputer.h"
-class cmExecutionStatus;
class cmMessenger;
-// cmSetTargetPropertyCommand
-bool cmGetTargetPropertyCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& var = args[0];
std::string const& targetName = args[1];
std::string prop;
bool prop_exists = false;
+ cmMakefile& mf = status.GetMakefile();
- if (cmTarget* tgt = this->Makefile->FindTargetToUse(targetName)) {
+ if (cmTarget* tgt = mf.FindTargetToUse(targetName)) {
if (args[2] == "ALIASED_TARGET") {
- if (this->Makefile->IsAlias(targetName)) {
+ if (mf.IsAlias(targetName)) {
prop = tgt->GetName();
prop_exists = true;
}
} else if (!args[2].empty()) {
const char* prop_cstr = nullptr;
- cmListFileBacktrace bt = this->Makefile->GetBacktrace();
- cmMessenger* messenger = this->Makefile->GetMessenger();
+ cmListFileBacktrace bt = mf.GetBacktrace();
+ cmMessenger* messenger = mf.GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
messenger, bt)) {
prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
@@ -53,7 +53,7 @@ bool cmGetTargetPropertyCommand::InitialPass(
bool issueMessage = false;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0045)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0045)) {
case cmPolicies::WARN:
issueMessage = true;
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0045) << "\n";
@@ -68,16 +68,16 @@ bool cmGetTargetPropertyCommand::InitialPass(
if (issueMessage) {
e << "get_target_property() called with non-existent target \""
<< targetName << "\".";
- this->Makefile->IssueMessage(messageType, e.str());
+ mf.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
}
}
if (prop_exists) {
- this->Makefile->AddDefinition(var, prop.c_str());
+ mf.AddDefinition(var, prop);
return true;
}
- this->Makefile->AddDefinition(var, (var + "-NOTFOUND").c_str());
+ mf.AddDefinition(var, var + "-NOTFOUND");
return true;
}
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
index 63ee5fd9b..c13078f8c 100644
--- a/Source/cmGetTargetPropertyCommand.h
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetTargetPropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmGetTargetPropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index 0b0d6eb3d..cf8c1d5fa 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -2,33 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetTestPropertyCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmTest.h"
-class cmExecutionStatus;
-
-// cmGetTestPropertyCommand
-bool cmGetTestPropertyCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& testName = args[0];
std::string const& var = args[2];
- cmTest* test = this->Makefile->GetTest(testName);
+ cmMakefile& mf = status.GetMakefile();
+ cmTest* test = mf.GetTest(testName);
if (test) {
const char* prop = nullptr;
if (!args[1].empty()) {
prop = test->GetProperty(args[1]);
}
if (prop) {
- this->Makefile->AddDefinition(var, prop);
+ mf.AddDefinition(var, prop);
return true;
}
}
- this->Makefile->AddDefinition(var, "NOTFOUND");
+ mf.AddDefinition(var, "NOTFOUND");
return true;
}
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
index 4a74f593f..30beb8f0f 100644
--- a/Source/cmGetTestPropertyCommand.h
+++ b/Source/cmGetTestPropertyCommand.h
@@ -8,21 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmGetTestPropertyCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmGetTestPropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h
index e588150f4..fbbef5d8f 100644
--- a/Source/cmGhsMultiGpj.h
+++ b/Source/cmGhsMultiGpj.h
@@ -4,6 +4,7 @@
#define cmGhsMultiGpj_h
#include "cmConfigure.h" // IWYU pragma: keep
+
#include <iosfwd>
class GhsMultiGpj
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index b80da7231..8e4352e29 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -2,6 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGhsMultiTargetGenerator.h"
+#include <algorithm>
+#include <memory>
+#include <ostream>
+#include <set>
+#include <utility>
+#include <vector>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -18,14 +25,10 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include <algorithm>
-#include <ostream>
-#include <set>
-#include <utility>
-
cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
: GeneratorTarget(target)
, LocalGenerator(
@@ -72,8 +75,8 @@ void cmGhsMultiTargetGenerator::Generate()
break;
}
case cmStateEnums::SHARED_LIBRARY: {
- std::string msg = "add_library(<name> SHARED ...) not supported: ";
- msg += this->Name;
+ std::string msg =
+ cmStrCat("add_library(<name> SHARED ...) not supported: ", this->Name);
cmSystemTools::Message(msg);
return;
}
@@ -84,8 +87,8 @@ void cmGhsMultiTargetGenerator::Generate()
break;
}
case cmStateEnums::MODULE_LIBRARY: {
- std::string msg = "add_library(<name> MODULE ...) not supported: ";
- msg += this->Name;
+ std::string msg =
+ cmStrCat("add_library(<name> MODULE ...) not supported: ", this->Name);
cmSystemTools::Message(msg);
return;
}
@@ -120,10 +123,9 @@ void cmGhsMultiTargetGenerator::Generate()
void cmGhsMultiTargetGenerator::GenerateTarget()
{
// Open the target file in copy-if-different mode.
- std::string fproj = this->LocalGenerator->GetCurrentBinaryDirectory();
- fproj += "/";
- fproj += this->Name;
- fproj += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+ std::string fproj =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->Name, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
cmGeneratedFileStream fout(fproj);
fout.SetCopyIfDifferent(true);
@@ -175,8 +177,7 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
const std::string& language)
{
- std::map<std::string, std::string>::iterator i =
- this->FlagsByLanguage.find(language);
+ auto i = this->FlagsByLanguage.find(language);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
const char* lang = language.c_str();
@@ -207,8 +208,7 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
std::string const& config)
{
- std::map<std::string, std::string>::iterator i =
- this->DefinesByLanguage.find(language);
+ auto i = this->DefinesByLanguage.find(language);
if (i == this->DefinesByLanguage.end()) {
std::set<std::string> defines;
const char* lang = language.c_str();
@@ -230,8 +230,7 @@ void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
std::string const&,
const std::string& language)
{
- std::map<std::string, std::string>::iterator flagsByLangI =
- this->FlagsByLanguage.find(language);
+ auto flagsByLangI = this->FlagsByLanguage.find(language);
if (flagsByLangI != this->FlagsByLanguage.end()) {
if (!flagsByLangI->second.empty()) {
std::vector<std::string> ghsCompFlags =
@@ -344,12 +343,11 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
for (cmCustomCommand const& cc : ccv) {
cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator);
// Open the filestream for this custom command
- std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
- fname +=
- "/" + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- fname += "/" + this->Name + "_" + name;
- fname += std::to_string(cmdcount++);
- fname += this->CmdWindowsShell ? ".bat" : ".sh";
+ std::string fname =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ '/', this->Name, '_', name, cmdcount++,
+ this->CmdWindowsShell ? ".bat" : ".sh");
cmGeneratedFileStream f(fname);
f.SetCopyIfDifferent(true);
this->WriteCustomCommandsHelper(f, ccg);
@@ -392,8 +390,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// Echo the custom command's comment text.
const char* comment = ccg.GetComment();
if (comment && *comment) {
- std::string echocmd = "echo ";
- echocmd += comment;
+ std::string echocmd = cmStrCat("echo ", comment);
cmdLines.push_back(std::move(echocmd));
}
@@ -440,12 +437,12 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// This command was specified as a path to a file in the
// current directory. Add a leading "./" so it can run
// without the current directory being in the search path.
- cmd = "./" + cmd;
+ cmd = cmStrCat("./", cmd);
}
cmd = this->LocalGenerator->ConvertToOutputFormat(
cmd, cmOutputConverter::SHELL);
if (useCall) {
- cmd = "call " + cmd;
+ cmd = cmStrCat("call ", cmd);
}
ccg.AppendArguments(c, cmd);
cmdLines.push_back(std::move(cmd));
@@ -465,8 +462,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
{
const char* prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(prop, list);
+ std::vector<std::string> list = cmExpandedList(prop);
for (auto& p : list) {
fout << " " << propFlag << p << std::endl;
}
@@ -489,7 +485,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
std::set<std::string> groupNames;
for (auto& sf : sources) {
cmSourceGroup* sourceGroup =
- this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
+ this->Makefile->FindSourceGroup(sf->ResolveFullPath(), sourceGroups);
std::string gn = sourceGroup->GetFullName();
groupFiles[gn].push_back(sf);
groupNames.insert(std::move(gn));
@@ -544,7 +540,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
for (auto& n : groupFilesList) {
std::sort(groupFiles[n].begin(), groupFiles[n].end(),
[](cmSourceFile* l, cmSourceFile* r) {
- return l->GetFullPath() < r->GetFullPath();
+ return l->ResolveFullPath() < r->ResolveFullPath();
});
}
@@ -558,24 +554,19 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
for (auto& sg : groupFilesList) {
std::ostream* fout;
bool useProjectFile =
- cmSystemTools::IsOn(
- this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
- cmSystemTools::IsOn(
- this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
+ 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;
} else {
// Open the filestream in copy-if-different mode.
std::string gname = sg;
cmsys::SystemTools::ReplaceString(gname, "\\", "_");
- std::string lpath =
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- lpath += "/";
- lpath += gname;
- lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
- std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
- fpath += "/";
- fpath += lpath;
+ std::string lpath = cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
+ gname, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
+ std::string fpath = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/', lpath);
cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath);
f->SetCopyIfDifferent(true);
gfiles.push_back(f);
@@ -667,14 +658,12 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
this->LocalGenerator);
// Open the filestream for this custom command
- std::string fname =
- this->LocalGenerator->GetCurrentBinaryDirectory();
- fname += "/" +
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- fname += "/" + this->Name + "_cc";
- fname += std::to_string(cmdcount++) + "_";
- fname += (sf->GetLocation()).GetName();
- fname += this->CmdWindowsShell ? ".bat" : ".sh";
+ std::string fname = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ '/', this->Name, "_cc", cmdcount++, '_',
+ (sf->GetLocation()).GetName(),
+ this->CmdWindowsShell ? ".bat" : ".sh");
cmGeneratedFileStream f(fname);
f.SetCopyIfDifferent(true);
this->WriteCustomCommandsHelper(f, ccg);
@@ -737,8 +726,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
{
const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
if (p) {
- return cmSystemTools::IsOn(
- this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+ return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app"));
}
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index a131567c8..f03ca44a2 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -3,14 +3,14 @@
#ifndef cmGhsMultiTargetGenerator_h
#define cmGhsMultiTargetGenerator_h
-#include "cmGhsMultiGpj.h"
-
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmGhsMultiGpj.h"
+
class cmCustomCommand;
class cmCustomCommandGenerator;
class cmGeneratorTarget;
diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx
index 9fb417098..481777345 100644
--- a/Source/cmGlobVerificationManager.cxx
+++ b/Source/cmGlobVerificationManager.cxx
@@ -2,11 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobVerificationManager.h"
-#include "cmsys/FStream.hxx"
#include <sstream>
+#include "cmsys/FStream.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
@@ -16,8 +18,7 @@ bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
return true;
}
- std::string scriptFile = path;
- scriptFile += "/CMakeFiles";
+ std::string scriptFile = cmStrCat(path, "/CMakeFiles");
std::string stampFile = scriptFile;
cmSystemTools::MakeDirectory(scriptFile);
scriptFile += "/VerifyGlobs.cmake";
diff --git a/Source/cmGlobVerificationManager.h b/Source/cmGlobVerificationManager.h
index 48606d3f3..2e7e1ca70 100644
--- a/Source/cmGlobVerificationManager.h
+++ b/Source/cmGlobVerificationManager.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmListFileCache.h"
-
#include <iosfwd>
#include <map>
#include <string>
#include <utility>
#include <vector>
+#include "cmListFileCache.h"
+
/** \class cmGlobVerificationManager
* \brief Class for expressing build-time dependencies on glob expressions.
*
@@ -72,7 +72,7 @@ private:
std::vector<std::pair<std::string, cmListFileBacktrace>> Backtraces;
};
- typedef std::map<CacheEntryKey, CacheEntryValue> CacheEntryMap;
+ using CacheEntryMap = std::map<CacheEntryKey, CacheEntryValue>;
CacheEntryMap Cache;
std::string VerifyScript;
std::string VerifyStamp;
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index ee7de70f6..da04743ac 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -3,10 +3,10 @@
#ifndef cmGlobalBorlandMakefileGenerator_h
#define cmGlobalBorlandMakefileGenerator_h
-#include "cmGlobalNMakeMakefileGenerator.h"
-
#include <iosfwd>
+#include "cmGlobalNMakeMakefileGenerator.h"
+
/** \class cmGlobalBorlandMakefileGenerator
* \brief Write a Borland makefiles.
*
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index bf992b48b..9fa4467b2 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -2,6 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalCommonGenerator.h"
+#include <utility>
+
+#include "cmGeneratorTarget.h"
+#include "cmLocalGenerator.h"
+#include "cmStateDirectory.h"
+#include "cmStateSnapshot.h"
+#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+
class cmake;
cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
@@ -10,3 +19,60 @@ cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
}
cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default;
+
+std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
+cmGlobalCommonGenerator::ComputeDirectoryTargets() const
+{
+ std::map<std::string, DirectoryTarget> dirTargets;
+ for (cmLocalGenerator* lg : this->LocalGenerators) {
+ std::string const& currentBinaryDir(
+ lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
+ DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
+ dirTarget.LG = lg;
+
+ // The directory-level rule should depend on the target-level rules
+ // for all targets in the directory.
+ for (auto gt : lg->GetGeneratorTargets()) {
+ cmStateEnums::TargetType const type = gt->GetType();
+ if (type != cmStateEnums::EXECUTABLE &&
+ type != cmStateEnums::STATIC_LIBRARY &&
+ type != cmStateEnums::SHARED_LIBRARY &&
+ type != cmStateEnums::MODULE_LIBRARY &&
+ type != cmStateEnums::OBJECT_LIBRARY &&
+ type != cmStateEnums::UTILITY) {
+ continue;
+ }
+ DirectoryTarget::Target t;
+ t.GT = gt;
+ if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
+ if (cmIsOn(exclude)) {
+ // This target has been explicitly excluded.
+ t.ExcludeFromAll = true;
+ } else {
+ // This target has been explicitly un-excluded. The directory-level
+ // rule for every directory between this and the root should depend
+ // on the target-level rule for this target.
+ for (cmStateSnapshot dir =
+ lg->GetStateSnapshot().GetBuildsystemDirectoryParent();
+ dir.IsValid(); dir = dir.GetBuildsystemDirectoryParent()) {
+ std::string const& d = dir.GetDirectory().GetCurrentBinary();
+ dirTargets[d].Targets.emplace_back(t);
+ }
+ }
+ }
+ dirTarget.Targets.emplace_back(t);
+ }
+
+ // The directory-level rule should depend on the directory-level
+ // rules of the subdirectories.
+ for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
+ DirectoryTarget::Dir d;
+ d.Path = state.GetDirectory().GetCurrentBinary();
+ d.ExcludeFromAll =
+ state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL");
+ dirTarget.Children.emplace_back(std::move(d));
+ }
+ }
+
+ return dirTargets;
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index e19118b50..7d16daca2 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -5,9 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
+#include <string>
+#include <vector>
+
#include "cmGlobalGenerator.h"
class cmake;
+class cmGeneratorTarget;
+class cmLocalGenerator;
/** \class cmGlobalCommonGenerator
* \brief Common infrastructure for Makefile and Ninja global generators.
@@ -17,6 +23,24 @@ class cmGlobalCommonGenerator : public cmGlobalGenerator
public:
cmGlobalCommonGenerator(cmake* cm);
~cmGlobalCommonGenerator() override;
+
+ struct DirectoryTarget
+ {
+ cmLocalGenerator* LG = nullptr;
+ struct Target
+ {
+ cmGeneratorTarget const* GT = nullptr;
+ bool ExcludeFromAll = false;
+ };
+ std::vector<Target> Targets;
+ struct Dir
+ {
+ std::string Path;
+ bool ExcludeFromAll = false;
+ };
+ std::vector<Dir> Children;
+ };
+ std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
};
#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ea898e175..96656a599 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2,16 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalGenerator.h"
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
#include <cstring>
#include <initializer_list>
#include <iterator>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <windows.h>
@@ -44,11 +45,12 @@
#include "cmWorkingDirectory.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include "cmCryptoHash.h"
-# include "cmQtAutoGenGlobalInitializer.h"
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_jsoncpp_value.h"
# include "cm_jsoncpp_writer.h"
+
+# include "cmCryptoHash.h"
+# include "cmQtAutoGenGlobalInitializer.h"
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1800
@@ -92,7 +94,6 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
// how long to let try compiles run
this->TryCompileTimeout = cmDuration::zero();
- this->ExtraGenerator = nullptr;
this->CurrentConfigureMakefile = nullptr;
this->TryCompileOuterMakefile = nullptr;
@@ -113,10 +114,9 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
cmGlobalGenerator::~cmGlobalGenerator()
{
this->ClearGeneratorMembers();
- delete this->ExtraGenerator;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmGlobalGenerator::GetJson() const
{
Json::Value generator = Json::objectValue;
@@ -188,15 +188,15 @@ std::string cmGlobalGenerator::SelectMakeProgram(
const std::string& inMakeProgram, const std::string& makeDefault) const
{
std::string makeProgram = inMakeProgram;
- if (cmSystemTools::IsOff(makeProgram)) {
+ if (cmIsOff(makeProgram)) {
const char* makeProgramCSTR =
this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
- if (cmSystemTools::IsOff(makeProgramCSTR)) {
+ if (cmIsOff(makeProgramCSTR)) {
makeProgram = makeDefault;
} else {
makeProgram = makeProgramCSTR;
}
- if (cmSystemTools::IsOff(makeProgram) && !makeProgram.empty()) {
+ if (cmIsOff(makeProgram) && !makeProgram.empty()) {
makeProgram = "CMAKE_MAKE_PROGRAM-NOTFOUND";
}
}
@@ -207,9 +207,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
cmMakefile* mf,
bool optional) const
{
- std::string langComp = "CMAKE_";
- langComp += lang;
- langComp += "_COMPILER";
+ std::string langComp = cmStrCat("CMAKE_", lang, "_COMPILER");
if (!mf->GetDefinition(langComp)) {
if (!optional) {
@@ -302,7 +300,7 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::TargetType::UTILITY ||
- cmSystemTools::IsOn(target->GetProperty("ghs_integrity_app"))) {
+ cmIsOn(target->GetProperty("ghs_integrity_app"))) {
continue;
}
@@ -341,12 +339,8 @@ bool cmGlobalGenerator::CheckTargetsForType() const
for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::EXECUTABLE &&
target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
- std::vector<std::string> configs;
- target->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
-
+ std::vector<std::string> const& configs =
+ target->Makefile->GetGeneratorConfigs();
for (std::string const& config : configs) {
if (target->GetLinkerLanguage(config) == "Swift") {
this->GetCMakeInstance()->IssueMessage(
@@ -363,6 +357,42 @@ bool cmGlobalGenerator::CheckTargetsForType() const
return failed;
}
+bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
+{
+ if (!this->GetLanguageEnabled("C") && !this->GetLanguageEnabled("CXX")) {
+ return false;
+ }
+ bool failed = false;
+ for (cmLocalGenerator* generator : this->LocalGenerators) {
+ for (cmGeneratorTarget* 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"))) {
+ continue;
+ }
+
+ const std::string reuseFrom =
+ target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ const std::string compilePdb =
+ target->GetSafeProperty("COMPILE_PDB_NAME");
+
+ if (!reuseFrom.empty() && reuseFrom != compilePdb) {
+ const std::string e = cmStrCat(
+ "PRECOMPILE_HEADERS_REUSE_FROM property is set on target (\"",
+ target->GetName(),
+ "\"). Reusable precompile headers requires the COMPILE_PDB_NAME"
+ " property to have the value \"",
+ reuseFrom, "\"\n");
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ target->GetBacktrace());
+ failed = true;
+ }
+ }
+ }
+ return failed;
+}
+
bool cmGlobalGenerator::IsExportedTargetsFile(
const std::string& filename) const
{
@@ -370,8 +400,7 @@ bool cmGlobalGenerator::IsExportedTargetsFile(
if (it == this->BuildExportSets.end()) {
return false;
}
- return this->BuildExportExportSets.find(filename) ==
- this->BuildExportExportSets.end();
+ return !cmContains(this->BuildExportExportSets, filename);
}
// Find the make program for the generator, required for try compiles
@@ -384,14 +413,14 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
return false;
}
if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
- cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+ cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile);
if (!setMakeProgram.empty()) {
mf->ReadListFile(setMakeProgram);
}
}
if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
- cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+ cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
std::ostringstream err;
err << "CMake was unable to find a build program corresponding to \""
<< this->GetName() << "\". CMAKE_MAKE_PROGRAM is not set. You "
@@ -411,9 +440,7 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
std::string saveFile = file;
cmSystemTools::GetShortPath(makeProgram, makeProgram);
cmSystemTools::SplitProgramPath(makeProgram, dir, file);
- makeProgram = dir;
- makeProgram += "/";
- makeProgram += saveFile;
+ makeProgram = cmStrCat(dir, '/', saveFile);
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
"make program", cmStateEnums::FILEPATH);
}
@@ -499,7 +526,7 @@ void cmGlobalGenerator::EnableLanguage(
if (lang == "NONE") {
this->SetLanguageEnabled("NONE", mf);
} else {
- if (this->LanguagesReady.find(lang) == this->LanguagesReady.end()) {
+ if (!cmContains(this->LanguagesReady, lang)) {
std::ostringstream e;
e << "The test project needs language " << lang
<< " which is not enabled.";
@@ -514,9 +541,9 @@ void cmGlobalGenerator::EnableLanguage(
bool fatalError = false;
- mf->AddDefinition("RUN_CONFIGURE", true);
- std::string rootBin = this->CMakeInstance->GetHomeOutputDirectory();
- rootBin += "/CMakeFiles";
+ mf->AddDefinitionBool("RUN_CONFIGURE", true);
+ std::string rootBin =
+ cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), "/CMakeFiles");
// If the configuration files path has been set,
// then we are in a try compile and need to copy the enable language
@@ -524,11 +551,11 @@ void cmGlobalGenerator::EnableLanguage(
if (!this->ConfiguredFilesPath.empty()) {
rootBin = this->ConfiguredFilesPath;
}
- rootBin += "/";
+ rootBin += '/';
rootBin += cmVersion::GetCMakeVersion();
// set the dir for parent files so they can be used by modules
- mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin.c_str());
+ mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin);
if (!this->CMakeInstance->GetIsInTryCompile()) {
// Keep a mark in the cache to indicate that we've initialized the
@@ -588,16 +615,14 @@ void cmGlobalGenerator::EnableLanguage(
windowsVersionString << osviex.dwMajorVersion << "."
<< osviex.dwMinorVersion << "."
<< osviex.dwBuildNumber;
- mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
- windowsVersionString.str().c_str());
+ mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str());
#endif
// Read the DetermineSystem file
std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
mf->ReadListFile(systemFile);
// load the CMakeSystem.cmake from the binary directory
// this file is configured by the CMakeDetermineSystem.cmake file
- fpath = rootBin;
- fpath += "/CMakeSystem.cmake";
+ fpath = cmStrCat(rootBin, "/CMakeSystem.cmake");
mf->ReadListFile(fpath);
}
@@ -663,14 +688,9 @@ void cmGlobalGenerator::EnableLanguage(
this->SetLanguageEnabled("NONE", mf);
continue;
}
- std::string loadedLang = "CMAKE_";
- loadedLang += lang;
- loadedLang += "_COMPILER_LOADED";
+ std::string loadedLang = cmStrCat("CMAKE_", lang, "_COMPILER_LOADED");
if (!mf->GetDefinition(loadedLang)) {
- fpath = rootBin;
- fpath += "/CMake";
- fpath += lang;
- fpath += "Compiler.cmake";
+ fpath = cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake");
// If the existing build tree was already configured with this
// version of CMake then try to load the configured file first
@@ -697,9 +717,8 @@ void cmGlobalGenerator::EnableLanguage(
}
// if the CMake(LANG)Compiler.cmake file was not found then
// load CMakeDetermine(LANG)Compiler.cmake
- std::string determineCompiler = "CMakeDetermine";
- determineCompiler += lang;
- determineCompiler += "Compiler.cmake";
+ std::string determineCompiler =
+ cmStrCat("CMakeDetermine", lang, "Compiler.cmake");
std::string determineFile = mf->GetModulesFile(determineCompiler);
if (!mf->ReadListFile(determineFile)) {
cmSystemTools::Error("Could not find cmake module file: " +
@@ -715,27 +734,19 @@ void cmGlobalGenerator::EnableLanguage(
// put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
// into the environment, in case user scripts want to run
// configure, or sub cmakes
- std::string compilerName = "CMAKE_";
- compilerName += lang;
- compilerName += "_COMPILER";
- std::string compilerEnv = "CMAKE_";
- compilerEnv += lang;
- compilerEnv += "_COMPILER_ENV_VAR";
+ std::string compilerName = cmStrCat("CMAKE_", lang, "_COMPILER");
+ std::string compilerEnv =
+ cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR");
const std::string& envVar = mf->GetRequiredDefinition(compilerEnv);
const std::string& envVarValue =
mf->GetRequiredDefinition(compilerName);
- std::string env = envVar;
- env += "=";
- env += envVarValue;
+ std::string env = cmStrCat(envVar, '=', envVarValue);
cmSystemTools::PutEnv(env);
}
// if determineLanguage was called then load the file it
// configures CMake(LANG)Compiler.cmake
- fpath = rootBin;
- fpath += "/CMake";
- fpath += lang;
- fpath += "Compiler.cmake";
+ fpath = cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake");
if (!mf->ReadListFile(fpath)) {
cmSystemTools::Error("Could not find cmake module file: " + fpath);
}
@@ -766,16 +777,11 @@ void cmGlobalGenerator::EnableLanguage(
}
// Check that the compiler was found.
- std::string compilerName = "CMAKE_";
- compilerName += lang;
- compilerName += "_COMPILER";
- std::string compilerEnv = "CMAKE_";
- compilerEnv += lang;
- compilerEnv += "_COMPILER_ENV_VAR";
+ std::string compilerName = cmStrCat("CMAKE_", lang, "_COMPILER");
+ std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR");
std::ostringstream noCompiler;
const char* compilerFile = mf->GetDefinition(compilerName);
- if (!compilerFile || !*compilerFile ||
- cmSystemTools::IsNOTFOUND(compilerFile)) {
+ if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) {
/* clang-format off */
noCompiler <<
"No " << compilerName << " could be found.\n"
@@ -806,10 +812,8 @@ void cmGlobalGenerator::EnableLanguage(
if (!optional) {
// The compiler was not found and it is not optional. Remove
// CMake(LANG)Compiler.cmake so we try again next time CMake runs.
- std::string compilerLangFile = rootBin;
- compilerLangFile += "/CMake";
- compilerLangFile += lang;
- compilerLangFile += "Compiler.cmake";
+ std::string compilerLangFile =
+ cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake");
cmSystemTools::RemoveFile(compilerLangFile);
if (!this->CMakeInstance->GetIsInTryCompile()) {
this->PrintCompilerAdvice(noCompiler, lang,
@@ -820,13 +824,10 @@ void cmGlobalGenerator::EnableLanguage(
}
}
- std::string langLoadedVar = "CMAKE_";
- langLoadedVar += lang;
- langLoadedVar += "_INFORMATION_LOADED";
+ std::string langLoadedVar =
+ cmStrCat("CMAKE_", lang, "_INFORMATION_LOADED");
if (!mf->GetDefinition(langLoadedVar)) {
- fpath = "CMake";
- fpath += lang;
- fpath += "Information.cmake";
+ fpath = cmStrCat("CMake", lang, "Information.cmake");
std::string informationFile = mf->GetModulesFile(fpath);
if (informationFile.empty()) {
cmSystemTools::Error("Could not find cmake module file: " + fpath);
@@ -847,33 +848,27 @@ void cmGlobalGenerator::EnableLanguage(
// If the language is untested then test it now with a try compile.
if (needTestLanguage[lang]) {
if (!this->CMakeInstance->GetIsInTryCompile()) {
- std::string testLang = "CMakeTest";
- testLang += lang;
- testLang += "Compiler.cmake";
+ std::string testLang = cmStrCat("CMakeTest", lang, "Compiler.cmake");
std::string ifpath = mf->GetModulesFile(testLang);
if (!mf->ReadListFile(ifpath)) {
cmSystemTools::Error("Could not find cmake module file: " +
testLang);
}
- std::string compilerWorks = "CMAKE_";
- compilerWorks += lang;
- compilerWorks += "_COMPILER_WORKS";
+ std::string compilerWorks =
+ cmStrCat("CMAKE_", lang, "_COMPILER_WORKS");
// if the compiler did not work, then remove the
// CMake(LANG)Compiler.cmake file so that it will get tested the
// next time cmake is run
if (!mf->IsOn(compilerWorks)) {
- std::string compilerLangFile = rootBin;
- compilerLangFile += "/CMake";
- compilerLangFile += lang;
- compilerLangFile += "Compiler.cmake";
+ std::string compilerLangFile =
+ cmStrCat(rootBin, "/CMake", lang, "Compiler.cmake");
cmSystemTools::RemoveFile(compilerLangFile);
}
} // end if in try compile
} // end need test language
// Store the shared library flags so that we can satisfy CMP0018
- std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_";
- sharedLibFlagsVar += lang;
- sharedLibFlagsVar += "_FLAGS";
+ std::string sharedLibFlagsVar =
+ cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS");
this->LanguageToOriginalSharedLibFlags[lang] =
mf->GetSafeDefinition(sharedLibFlagsVar);
@@ -884,10 +879,9 @@ void cmGlobalGenerator::EnableLanguage(
// Now load files that can override any settings on the platform or for
// the project First load the project compatibility file if it is in
// cmake
- std::string projectCompatibility = cmSystemTools::GetCMakeRoot();
- projectCompatibility += "/Modules/";
- projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME");
- projectCompatibility += "Compatibility.cmake";
+ std::string projectCompatibility =
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/",
+ mf->GetSafeDefinition("PROJECT_NAME"), "Compatibility.cmake");
if (cmSystemTools::FileExists(projectCompatibility)) {
mf->ReadListFile(projectCompatibility);
}
@@ -1097,8 +1091,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
{
// use LanguageToLinkerPreference to detect whether this functions has
// run before
- if (this->LanguageToLinkerPreference.find(l) !=
- this->LanguageToLinkerPreference.end()) {
+ if (cmContains(this->LanguageToLinkerPreference, l)) {
return;
}
@@ -1121,8 +1114,8 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
}
if (preference < 0) {
- std::string msg = linkerPrefVar;
- msg += " is negative, adjusting it to 0";
+ std::string msg =
+ cmStrCat(linkerPrefVar, " is negative, adjusting it to 0");
cmSystemTools::Message(msg, "Warning");
preference = 0;
}
@@ -1148,8 +1141,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
std::string ignoreExtensionsVar =
std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
- std::vector<std::string> extensionList;
- cmSystemTools::ExpandListArgument(ignoreExts, extensionList);
+ std::vector<std::string> extensionList = cmExpandedList(ignoreExts);
for (std::string const& i : extensionList) {
this->IgnoreExtensions[i] = true;
}
@@ -1161,8 +1153,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
std::string extensionsVar = std::string("CMAKE_") + std::string(l) +
std::string("_SOURCE_FILE_EXTENSIONS");
const std::string& exts = mf->GetSafeDefinition(extensionsVar);
- std::vector<std::string> extensionList;
- cmSystemTools::ExpandListArgument(exts, extensionList);
+ std::vector<std::string> extensionList = cmExpandedList(exts);
for (std::string const& i : extensionList) {
this->ExtensionToLanguage[i] = l;
}
@@ -1277,10 +1268,8 @@ void cmGlobalGenerator::Configure()
msg << "Configuring incomplete, errors occurred!";
const char* logs[] = { "CMakeOutput.log", "CMakeError.log", nullptr };
for (const char** log = logs; *log; ++log) {
- std::string f = this->CMakeInstance->GetHomeOutputDirectory();
- f += "/CMakeFiles";
- f += "/";
- f += *log;
+ std::string f = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(),
+ "/CMakeFiles/", *log);
if (cmSystemTools::FileExists(f)) {
msg << "\nSee also \"" << f << "\".";
}
@@ -1392,6 +1381,11 @@ bool cmGlobalGenerator::Compute()
return false;
}
+ // Add automatically generated sources (e.g. unity build).
+ if (!this->AddAutomaticSources()) {
+ return false;
+ }
+
// Add generator specific helper commands
for (cmLocalGenerator* localGen : this->LocalGenerators) {
localGen->AddHelperCommands();
@@ -1447,6 +1441,10 @@ bool cmGlobalGenerator::Compute()
return false;
}
+ if (this->CheckTargetsForPchCompilePdb()) {
+ return false;
+ }
+
for (cmLocalGenerator* localGen : this->LocalGenerators) {
localGen->ComputeHomeRelativeOutputPath();
}
@@ -1497,7 +1495,7 @@ void cmGlobalGenerator::Generate()
this->WriteSummary();
- if (this->ExtraGenerator != nullptr) {
+ if (this->ExtraGenerator) {
this->ExtraGenerator->Generate();
}
@@ -1547,7 +1545,7 @@ bool cmGlobalGenerator::ComputeTargetDepends()
bool cmGlobalGenerator::QtAutoGen()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmQtAutoGenGlobalInitializer initializer(this->LocalGenerators);
return initializer.generate();
#else
@@ -1555,6 +1553,21 @@ bool cmGlobalGenerator::QtAutoGen()
#endif
}
+bool cmGlobalGenerator::AddAutomaticSources()
+{
+ for (cmLocalGenerator* lg : this->LocalGenerators) {
+ lg->CreateEvaluationFileOutputs();
+ for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ continue;
+ }
+ lg->AddUnityBuild(gt);
+ lg->AddPchDependencies(gt);
+ }
+ }
+ return true;
+}
+
cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) const
{
@@ -1606,8 +1619,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
mf->GetConfigurations(configs);
for (std::string const& c : configs) {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(c);
+ std::string defPropName =
+ cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
t->AppendProperty(defPropName, mf->GetProperty(defPropName));
}
}
@@ -1621,9 +1634,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
"CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES";
std::string const& standardIncludesStr =
mf->GetSafeDefinition(standardIncludesVar);
- std::vector<std::string> standardIncludesVec;
- cmSystemTools::ExpandListArgument(standardIncludesStr,
- standardIncludesVec);
+ std::vector<std::string> standardIncludesVec =
+ cmExpandedList(standardIncludesStr);
standardIncludesSet.insert(standardIncludesVec.begin(),
standardIncludesVec.end());
}
@@ -1710,17 +1722,15 @@ void cmGlobalGenerator::CheckTargetProperties()
continue;
}
for (auto const& lib : target.second.GetOriginalLinkLibraries()) {
- if (lib.first.size() > 9 &&
- cmSystemTools::IsNOTFOUND(lib.first.c_str())) {
+ if (lib.first.size() > 9 && cmIsNOTFOUND(lib.first)) {
std::string varName = lib.first.substr(0, lib.first.size() - 9);
if (state->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) {
varName += " (ADVANCED)";
}
- std::string text = notFoundMap[varName];
- text += "\n linked by target \"";
- text += target.second.GetName();
- text += "\" in directory ";
- text += this->Makefiles[i]->GetCurrentSourceDirectory();
+ std::string text =
+ cmStrCat(notFoundMap[varName], "\n linked by target \"",
+ target.second.GetName(), "\" in directory ",
+ this->Makefiles[i]->GetCurrentSourceDirectory());
notFoundMap[varName] = text;
}
}
@@ -1734,17 +1744,18 @@ void cmGlobalGenerator::CheckTargetProperties()
std::string incDirs = cmGeneratorExpression::Preprocess(
incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- cmSystemTools::ExpandListArgument(incDirs, incs);
+ cmExpandList(incDirs, incs);
for (std::string const& incDir : incs) {
- if (incDir.size() > 9 && cmSystemTools::IsNOTFOUND(incDir.c_str())) {
+ if (incDir.size() > 9 && cmIsNOTFOUND(incDir)) {
std::string varName = incDir.substr(0, incDir.size() - 9);
if (state->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) {
varName += " (ADVANCED)";
}
- std::string text = notFoundMap[varName];
- text += "\n used as include directory in directory ";
- text += this->Makefiles[i]->GetCurrentSourceDirectory();
+ std::string text =
+ cmStrCat(notFoundMap[varName],
+ "\n used as include directory in directory ",
+ this->Makefiles[i]->GetCurrentSourceDirectory());
notFoundMap[varName] = text;
}
}
@@ -1843,8 +1854,8 @@ int cmGlobalGenerator::Build(
output += "\n";
if (workdir.Failed()) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
- std::string err = "Failed to change directory: ";
- err += std::strerror(workdir.GetLastResult());
+ std::string err = cmStrCat("Failed to change directory: ",
+ std::strerror(workdir.GetLastResult()));
cmSystemTools::Error(err);
output += err;
output += "\n";
@@ -1949,8 +1960,8 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
const std::string& native, bool ignoreErrors)
{
std::string makeCommand = cmSystemTools::GetCMakeCommand();
- makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand);
- makeCommand += " --build .";
+ makeCommand =
+ cmStrCat(cmSystemTools::ConvertToOutputPath(makeCommand), " --build .");
if (!config.empty()) {
makeCommand += " --config \"";
makeCommand += config;
@@ -2053,8 +2064,8 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
if (!gen->ConfiguredFilesPath.empty()) {
this->ConfiguredFilesPath = gen->ConfiguredFilesPath;
} else {
- this->ConfiguredFilesPath = gen->CMakeInstance->GetHomeOutputDirectory();
- this->ConfiguredFilesPath += "/CMakeFiles";
+ this->ConfiguredFilesPath =
+ cmStrCat(gen->CMakeInstance->GetHomeOutputDirectory(), "/CMakeFiles");
}
}
@@ -2095,7 +2106,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
return true;
}
if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
- return cmSystemTools::IsOn(exclude);
+ return cmIsOn(exclude);
}
// This target is included in its directory. Check whether the
// directory is excluded.
@@ -2162,7 +2173,7 @@ void cmGlobalGenerator::AddAlias(const std::string& name,
bool cmGlobalGenerator::IsAlias(const std::string& name) const
{
- return this->AliasTargets.find(name) != this->AliasTargets.end();
+ return cmContains(this->AliasTargets, name);
}
void cmGlobalGenerator::IndexTarget(cmTarget* t)
@@ -2278,14 +2289,6 @@ bool cmGlobalGenerator::NameResolvesToFramework(
return false;
}
-inline std::string removeQuotes(const std::string& s)
-{
- if (s.front() == '\"' && s.back() == '\"') {
- return s.substr(1, s.size() - 2);
- }
- return s;
-}
-
bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName,
std::string const& reason) const
{
@@ -2340,8 +2343,8 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
std::vector<GlobalTargetInfo>& targets)
{
cmMakefile* mf = this->Makefiles[0];
- std::string configFile = mf->GetCurrentBinaryDirectory();
- configFile += "/CPackConfig.cmake";
+ std::string configFile =
+ cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
return;
}
@@ -2373,7 +2376,7 @@ void cmGlobalGenerator::AddGlobalTarget_Package(
} else {
const char* noPackageAll =
mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
- if (!noPackageAll || cmSystemTools::IsOff(noPackageAll)) {
+ if (!noPackageAll || cmIsOff(noPackageAll)) {
gti.Depends.emplace_back(this->GetAllTargetName());
}
}
@@ -2389,8 +2392,8 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource(
}
cmMakefile* mf = this->Makefiles[0];
- std::string configFile = mf->GetCurrentBinaryDirectory();
- configFile += "/CPackSourceConfig.cmake";
+ std::string configFile =
+ cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackSourceConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
return;
}
@@ -2542,7 +2545,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
} else {
const char* noall =
mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
- if (!noall || cmSystemTools::IsOff(noall)) {
+ if (!noall || cmIsOff(noall)) {
gti.Depends.emplace_back(this->GetAllTargetName());
}
}
@@ -2625,7 +2628,7 @@ bool cmGlobalGenerator::UseFolderProperty() const
// If this property is defined, let the setter turn this on or off...
//
if (prop) {
- return cmSystemTools::IsOn(prop);
+ return cmIsOn(prop);
}
// By default, this feature is OFF, since it is not supported in the
@@ -2649,7 +2652,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
cmCustomCommand cc(nullptr, no_outputs, no_byproducts, no_depends,
gti.CommandLines, nullptr, gti.WorkingDir.c_str());
cc.SetUsesTerminal(gti.UsesTerminal);
- target.AddPostBuildCommand(cc);
+ target.AddPostBuildCommand(std::move(cc));
if (!gti.Message.empty()) {
target.SetProperty("EchoString", gti.Message.c_str());
}
@@ -2669,8 +2672,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
std::string cmGlobalGenerator::GenerateRuleFile(
std::string const& output) const
{
- std::string ruleFile = output;
- ruleFile += ".rule";
+ std::string ruleFile = cmStrCat(output, ".rule");
const char* dir = this->GetCMakeCFGIntDir();
if (dir && dir[0] == '$') {
cmSystemTools::ReplaceString(ruleFile, dir, "/CMakeFiles");
@@ -2720,15 +2722,14 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
"clean", "edit_cache", "rebuild_cache",
"ZERO_CHECK" };
- return std::find(cm::cbegin(reservedTargets), cm::cend(reservedTargets),
- name) != cm::cend(reservedTargets);
+ return cmContains(reservedTargets, name);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator* extraGenerator)
{
- this->ExtraGenerator = extraGenerator;
- if (this->ExtraGenerator != nullptr) {
+ this->ExtraGenerator.reset(extraGenerator);
+ if (this->ExtraGenerator) {
this->ExtraGenerator->SetGlobalGenerator(this);
}
}
@@ -2837,7 +2838,7 @@ std::set<std::string> const& cmGlobalGenerator::GetDirectoryContent(
void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
std::string const& content)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Ignore if there are no outputs.
if (outputs.empty()) {
return;
@@ -2867,11 +2868,9 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
void cmGlobalGenerator::CheckRuleHashes()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory();
- std::string pfile = home;
- pfile += "/CMakeFiles";
- pfile += "/CMakeRuleHashes.txt";
+ std::string pfile = cmStrCat(home, "/CMakeFiles/CMakeRuleHashes.txt");
this->CheckRuleHashes(pfile, home);
this->WriteRuleHashes(pfile);
#endif
@@ -2947,9 +2946,8 @@ void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile)
void cmGlobalGenerator::WriteSummary()
{
// Record all target directories in a central location.
- std::string fname = this->CMakeInstance->GetHomeOutputDirectory();
- fname += "/CMakeFiles";
- fname += "/TargetDirectories.txt";
+ std::string fname = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(),
+ "/CMakeFiles/TargetDirectories.txt");
cmGeneratedFileStream fout(fname);
for (cmLocalGenerator* lg : this->LocalGenerators) {
@@ -2967,11 +2965,10 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
{
// Place the labels file in a per-target support directory.
std::string dir = target->GetSupportDirectory();
- std::string file = dir;
- file += "/Labels.txt";
+ std::string file = cmStrCat(dir, "/Labels.txt");
std::string json_file = dir + "/Labels.json";
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Check whether labels are enabled for this target.
const char* targetLabels = target->GetProperty("LABELS");
const char* directoryLabels =
@@ -2993,7 +2990,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
// List the target-wide labels. All sources in the target get
// these labels.
if (targetLabels) {
- cmSystemTools::ExpandListArgument(targetLabels, labels);
+ cmExpandList(targetLabels, labels);
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
@@ -3008,12 +3005,11 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::vector<std::string> cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmSystemTools::ExpandListArgument(directoryLabels, directoryLabelsList);
+ cmExpandList(directoryLabels, directoryLabelsList);
}
if (cmakeDirectoryLabels) {
- cmSystemTools::ExpandListArgument(cmakeDirectoryLabels,
- cmakeDirectoryLabelsList);
+ cmExpandList(cmakeDirectoryLabels, cmakeDirectoryLabelsList);
}
if (!directoryLabelsList.empty() || !cmakeDirectoryLabelsList.empty()) {
@@ -3033,24 +3029,21 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
// List the source files with any per-source labels.
fout << "# Source files and their labels\n";
std::vector<cmSourceFile*> sources;
- std::vector<std::string> configs;
- target->Target->GetMakefile()->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ std::vector<std::string> const& configs =
+ target->Target->GetMakefile()->GetGeneratorConfigs();
for (std::string const& c : configs) {
target->GetSourceFiles(sources, c);
}
auto const sourcesEnd = cmRemoveDuplicates(sources);
for (cmSourceFile* sf : cmMakeRange(sources.cbegin(), sourcesEnd)) {
Json::Value& lj_source = lj_sources.append(Json::objectValue);
- std::string const& sfp = sf->GetFullPath();
+ std::string const& sfp = sf->ResolveFullPath();
fout << sfp << "\n";
lj_source["file"] = sfp;
if (const char* svalue = sf->GetProperty("LABELS")) {
labels.clear();
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
- cmSystemTools::ExpandListArgument(svalue, labels);
+ cmExpandList(svalue, labels);
for (std::string const& label : labels) {
fout << " " << label << "\n";
lj_source_labels.append(label);
@@ -3104,14 +3097,6 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const
return this->FilenameTargetDepends[sf];
}
-void cmGlobalGenerator::CreateEvaluationSourceFiles(
- std::string const& config) const
-{
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- localGen->CreateEvaluationFileOutputs(config);
- }
-}
-
void cmGlobalGenerator::ProcessEvaluationFiles()
{
std::vector<std::string> generatedFiles;
@@ -3137,8 +3122,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
std::vector<std::string> configs;
std::string config = mf->GetConfigurations(configs, false);
- std::string path = this->CMakeInstance->GetHomeOutputDirectory();
- path += "/CPackProperties.cmake";
+ std::string path = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(),
+ "/CPackProperties.cmake");
if (!cmSystemTools::FileExists(path) && installedFiles.empty()) {
return true;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 500853444..f25ff7b77 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -7,25 +7,29 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
+#include "cm_codecvt.hxx"
+
#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
-#include "cmExportSetMap.h"
+#include "cmExportSet.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
-#include "cm_codecvt.hxx"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include "cmFileLockPool.h"
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_jsoncpp_value.h"
+
+# include "cmFileLockPool.h"
#endif
#define CMAKE_DIRECTORY_ID_SEP "::@"
@@ -107,7 +111,7 @@ public:
return codecvt::None;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
/** Get a JSON object describing the generator. */
virtual Json::Value GetJson() const;
#endif
@@ -374,7 +378,7 @@ public:
virtual std::string GetEditCacheCommand() const { return ""; }
// Class to track a set of dependencies.
- typedef cmTargetDependSet TargetDependSet;
+ using TargetDependSet = cmTargetDependSet;
// what targets does the specified target depend on directly
// via a target_link_libraries or add_dependencies
@@ -453,14 +457,12 @@ public:
bool GenerateCPackPropertiesFile();
- void CreateEvaluationSourceFiles(std::string const& config) const;
-
void SetFilenameTargetDepends(
cmSourceFile* sf, std::set<cmGeneratorTarget const*> const& tgts);
const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends(
cmSourceFile* sf) const;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmFileLockPool& GetFileLockPool() { return FileLockPool; }
#endif
@@ -474,7 +476,7 @@ public:
int RecursionDepth;
protected:
- typedef std::vector<cmLocalGenerator*> GeneratorVector;
+ using GeneratorVector = std::vector<cmLocalGenerator*>;
// for a project collect all its targets by following depend
// information, and also collect all the targets
void GetTargetSets(TargetDependSet& projectTargets,
@@ -499,6 +501,8 @@ protected:
/// @return true on success
bool QtAutoGen();
+ bool AddAutomaticSources();
+
std::string SelectMakeProgram(const std::string& makeProgram,
const std::string& makeDefault = "") const;
@@ -553,17 +557,15 @@ protected:
cmTarget* FindTargetImpl(std::string const& name) const;
cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
- cmGeneratorTarget* FindImportedGeneratorTargetImpl(
- std::string const& name) const;
const char* GetPredefinedTargetsFolder();
private:
- typedef std::unordered_map<std::string, cmTarget*> TargetMap;
- typedef std::unordered_map<std::string, cmGeneratorTarget*>
- GeneratorTargetMap;
- typedef std::unordered_map<std::string, cmMakefile*> MakefileMap;
- typedef std::unordered_map<std::string, cmLocalGenerator*> LocalGeneratorMap;
+ using TargetMap = std::unordered_map<std::string, cmTarget*>;
+ using GeneratorTargetMap =
+ std::unordered_map<std::string, cmGeneratorTarget*>;
+ using MakefileMap = std::unordered_map<std::string, cmMakefile*>;
+ using LocalGeneratorMap = std::unordered_map<std::string, cmLocalGenerator*>;
// Map efficiently from target name to cmTarget instance.
// Do not use this structure for looping over all targets.
// It contains both normal and globally visible imported targets.
@@ -610,6 +612,7 @@ private:
bool CheckTargetsForMissingSources() const;
bool CheckTargetsForType() const;
+ bool CheckTargetsForPchCompilePdb() const;
void CreateLocalGenerators();
@@ -618,13 +621,13 @@ private:
void ComputeBuildFileGenerators();
- cmExternalMakefileProjectGenerator* ExtraGenerator;
+ std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator;
// track files replaced during a Generate
std::vector<std::string> FilesReplacedDuringGenerate;
// Store computed inter-target dependencies.
- typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap;
+ using TargetDependMap = std::map<cmGeneratorTarget const*, TargetDependSet>;
TargetDependMap TargetDependencies;
friend class cmake;
@@ -663,7 +666,7 @@ private:
mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
FilenameTargetDepends;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
cmFileLockPool FileLockPool;
#endif
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index b69dea038..5a708abbc 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -2,6 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalGhsMultiGenerator.h"
+#include <algorithm>
+#include <cstring>
+#include <map>
+#include <ostream>
+#include <utility>
+
+#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -11,16 +18,11 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmake.h"
-#include <algorithm>
-#include <map>
-#include <ostream>
-#include <string.h>
-#include <utility>
-
const char* cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
#ifdef __linux__
const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild";
@@ -55,11 +57,9 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
- std::string dir;
- dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/";
- dir += gt->LocalGenerator->GetTargetDirectory(gt);
- dir += "/";
+ std::string dir =
+ cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ gt->LocalGenerator->GetTargetDirectory(gt), '/');
gt->ObjectDirectory = dir;
}
@@ -76,10 +76,9 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
}
if (ts.empty()) {
std::string message;
- message =
- "Green Hills MULTI: -T <toolset> not specified; defaulting to \"";
- message += tsp;
- message += "\"";
+ message = cmStrCat(
+ "Green Hills MULTI: -T <toolset> not specified; defaulting to \"", tsp,
+ '"');
cmSystemTools::Message(message);
/* store the full toolset for later use
@@ -97,12 +96,11 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
/* check if the toolset changed from last generate */
if (prevTool != nullptr && (gbuild != prevTool)) {
- std::string message = "toolset build tool: ";
- message += gbuild;
- message += "\nDoes not match the previously used build tool: ";
- message += prevTool;
- message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
- "directory or choose a different binary directory.";
+ std::string message =
+ cmStrCat("toolset build tool: ", gbuild,
+ "\nDoes not match the previously used build tool: ", prevTool,
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.");
cmSystemTools::Error(message);
return false;
}
@@ -111,7 +109,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
"build program to use", cmStateEnums::INTERNAL, true);
- mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str());
+ mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
return true;
}
@@ -138,24 +136,20 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
/* check if OS location has been updated by platform scripts */
std::string platform = mf->GetSafeDefinition("GHS_TARGET_PLATFORM");
std::string osdir = mf->GetSafeDefinition("GHS_OS_DIR");
- if (cmSystemTools::IsOff(osdir.c_str()) &&
- platform.find("integrity") != std::string::npos) {
+ if (cmIsOff(osdir) && platform.find("integrity") != std::string::npos) {
if (!this->CMakeInstance->GetIsInTryCompile()) {
/* required OS location is not found */
- std::string m =
- "Green Hills MULTI: GHS_OS_DIR not specified; No OS found in \"";
- m += mf->GetSafeDefinition("GHS_OS_ROOT");
- m += "\"";
+ std::string m = cmStrCat(
+ "Green Hills MULTI: GHS_OS_DIR not specified; No OS found in \"",
+ mf->GetSafeDefinition("GHS_OS_ROOT"), '"');
cmSystemTools::Message(m);
}
osdir = "GHS_OS_DIR-NOT-SPECIFIED";
} else if (!this->CMakeInstance->GetIsInTryCompile() &&
- cmSystemTools::IsOff(this->OsDir) &&
- !cmSystemTools::IsOff(osdir)) {
+ cmIsOff(this->OsDir) && !cmIsOff(osdir)) {
/* OS location was updated by auto-selection */
- std::string m = "Green Hills MULTI: GHS_OS_DIR not specified; found \"";
- m += osdir;
- m += "\"";
+ std::string m = cmStrCat(
+ "Green Hills MULTI: GHS_OS_DIR not specified; found \"", osdir, '"');
cmSystemTools::Message(m);
}
this->OsDir = osdir;
@@ -163,17 +157,15 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
// Determine GHS_BSP_NAME
std::string bspName = mf->GetSafeDefinition("GHS_BSP_NAME");
- if (cmSystemTools::IsOff(bspName.c_str()) &&
- platform.find("integrity") != std::string::npos) {
+ 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(),
"Name of GHS target platform.",
cmStateEnums::STRING, true);
- std::string m =
- "Green Hills MULTI: GHS_BSP_NAME not specified; defaulting to \"";
- m += bspName;
- m += "\"";
+ std::string m = cmStrCat(
+ "Green Hills MULTI: GHS_BSP_NAME not specified; defaulting to \"",
+ bspName, '"');
cmSystemTools::Message(m);
}
@@ -334,18 +326,18 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
// Specify BSP option if supplied by user
const char* bspName =
this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
- if (!cmSystemTools::IsOff(bspName)) {
+ if (!cmIsOff(bspName)) {
fout << " -bsp " << bspName << std::endl;
}
// Specify OS DIR if supplied by user
// -- not all platforms require this entry in the project file
- if (!cmSystemTools::IsOff(this->OsDir.c_str())) {
+ if (!cmIsOff(this->OsDir)) {
const char* osDirOption =
this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR_OPTION");
std::replace(this->OsDir.begin(), this->OsDir.end(), '\\', '/');
fout << " ";
- if (cmSystemTools::IsOff(osDirOption)) {
+ if (cmIsOff(osDirOption)) {
fout << "";
} else {
fout << osDirOption;
@@ -404,8 +396,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
{
- std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
- rootBinaryDir += "/CMakeFiles";
+ std::string rootBinaryDir =
+ cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles");
// All known targets
for (cmGeneratorTarget const* target : this->ProjectTargets) {
@@ -418,17 +410,17 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
}
// create target build file
- std::string name = target->GetName() + ".tgt" + FILE_EXTENSION;
- std::string fname = rootBinaryDir + "/" + name;
+ std::string name = cmStrCat(target->GetName(), ".tgt", FILE_EXTENSION);
+ std::string fname = cmStrCat(rootBinaryDir, "/", name);
cmGeneratedFileStream fbld(fname);
fbld.SetCopyIfDifferent(true);
this->WriteFileHeader(fbld);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
std::vector<cmGeneratorTarget const*> build;
if (ComputeTargetBuildOrder(target, build)) {
- std::string message = "The inter-target dependency graph for target [" +
- target->GetName() + "] had a cycle.\n";
- cmSystemTools::Error(message);
+ cmSystemTools::Error(
+ cmStrCat("The inter-target dependency graph for target [",
+ target->GetName(), "] had a cycle.\n"));
} else {
for (auto& tgt : build) {
WriteProjectLine(fbld, tgt, root, rootBinaryDir);
@@ -469,7 +461,7 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- if (!cmSystemTools::IsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+ if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
defaultTargets.push_back(t);
}
}
@@ -480,8 +472,8 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
cmSystemTools::Error(message);
} else {
// determine the targets for ALL target
- std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
- rootBinaryDir += "/CMakeFiles";
+ std::string rootBinaryDir =
+ cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles");
for (cmGeneratorTarget const* target : build) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::MODULE_LIBRARY ||
@@ -539,11 +531,8 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
* with target projects. This avoid the issue where the project has
* the same name as the executable target.
*/
- fname = root->GetCurrentBinaryDirectory();
- fname += "/";
- fname += root->GetProjectName();
- fname += ".top";
- fname += FILE_EXTENSION;
+ fname = cmStrCat(root->GetCurrentBinaryDirectory(), '/',
+ root->GetProjectName(), ".top", FILE_EXTENSION);
cmGeneratedFileStream top(fname);
top.SetCopyIfDifferent(true);
@@ -588,16 +577,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
/* if multiple top-projects are found in build directory
* then prefer projectName top-project.
*/
- auto p = std::find(files.begin(), files.end(), proj);
- if (p == files.end()) {
+ if (!cmContains(files, proj)) {
proj = files.at(0);
}
}
makeCommand.Add("-top", proj);
if (!targetNames.empty()) {
- if (std::find(targetNames.begin(), targetNames.end(), "clean") !=
- targetNames.end()) {
+ if (cmContains(targetNames, "clean")) {
makeCommand.Add("-clean");
} else {
for (const auto& tname : targetNames) {
@@ -623,8 +610,8 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
if (nullptr != ghsGpjMacros) {
- std::vector<std::string> expandedList;
- cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList);
+ std::vector<std::string> expandedList =
+ cmExpandedList(std::string(ghsGpjMacros));
for (std::string const& arg : expandedList) {
fout << "macro " << arg << std::endl;
}
@@ -646,10 +633,7 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
this->GetCMakeInstance()->GetCacheDefinition("CMAKE_GENERATOR_PLATFORM");
const char* p =
this->GetCMakeInstance()->GetCacheDefinition("GHS_TARGET_PLATFORM");
- tgt = (a ? a : "");
- tgt += "_";
- tgt += (p ? p : "");
- tgt += ".tgt";
+ tgt = cmStrCat((a ? a : ""), '_', (p ? p : ""), ".tgt");
}
fout << "primaryTarget=" << tgt << std::endl;
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 98358c74d..ccfe07382 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -3,17 +3,16 @@
#ifndef cmGhsMultiGenerator_h
#define cmGhsMultiGenerator_h
-#include "cmGlobalGenerator.h"
-
-#include "cmGlobalGeneratorFactory.h"
-#include "cmTargetDepend.h"
-
#include <iosfwd>
#include <set>
#include <string>
#include <utility>
#include <vector>
+#include "cmGlobalGenerator.h"
+#include "cmGlobalGeneratorFactory.h"
+#include "cmTargetDepend.h"
+
class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
@@ -148,12 +147,11 @@ class cmGlobalGhsMultiGenerator::OrderedTargetDependSet
: public std::multiset<cmTargetDepend,
cmGlobalGhsMultiGenerator::TargetCompare>
{
- typedef std::multiset<cmTargetDepend,
- cmGlobalGhsMultiGenerator::TargetCompare>
- derived;
+ using derived =
+ std::multiset<cmTargetDepend, cmGlobalGhsMultiGenerator::TargetCompare>;
public:
- typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
+ using TargetDependSet = cmGlobalGenerator::TargetDependSet;
OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
};
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index df3aec9b4..fc39ddf42 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -3,10 +3,10 @@
#ifndef cmGlobalJOMMakefileGenerator_h
#define cmGlobalJOMMakefileGenerator_h
-#include "cmGlobalUnixMakefileGenerator3.h"
-
#include <iosfwd>
+#include "cmGlobalUnixMakefileGenerator3.h"
+
/** \class cmGlobalJOMMakefileGenerator
* \brief Write a JOM makefiles.
*
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index 7b5838909..ae9d5a768 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -24,8 +24,7 @@ cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator(cmake* cm)
std::string cmGlobalMSYSMakefileGenerator::FindMinGW(
std::string const& makeloc)
{
- std::string fstab = makeloc;
- fstab += "/../etc/fstab";
+ std::string fstab = cmStrCat(makeloc, "/../etc/fstab");
cmsys::ifstream fin(fstab.c_str());
std::string path;
std::string mount;
@@ -34,8 +33,7 @@ std::string cmGlobalMSYSMakefileGenerator::FindMinGW(
fin >> path;
fin >> mount;
if (mount == "/mingw") {
- mingwBin = path;
- mingwBin += "/bin";
+ mingwBin = cmStrCat(path, "/bin");
}
}
return mingwBin;
@@ -69,9 +67,9 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage(
rc = trc;
}
mf->AddDefinition("MSYS", "1");
- mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+ mf->AddDefinition("CMAKE_GENERATOR_CC", gcc);
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx);
+ mf->AddDefinition("CMAKE_GENERATOR_RC", rc);
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
if (!mf->IsSet("CMAKE_AR") && !this->CMakeInstance->GetIsInTryCompile() &&
diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx
index e218b4b95..d9fc50530 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.cxx
+++ b/Source/cmGlobalMinGWMakefileGenerator.cxx
@@ -44,9 +44,9 @@ void cmGlobalMinGWMakefileGenerator::EnableLanguage(
if (!trc.empty()) {
rc = trc;
}
- mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+ mf->AddDefinition("CMAKE_GENERATOR_CC", gcc);
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx);
+ mf->AddDefinition("CMAKE_GENERATOR_RC", rc);
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 2fdf1ce5d..4586b77b1 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -3,10 +3,10 @@
#ifndef cmGlobalNMakeMakefileGenerator_h
#define cmGlobalNMakeMakefileGenerator_h
-#include "cmGlobalUnixMakefileGenerator3.h"
-
#include <iosfwd>
+#include "cmGlobalUnixMakefileGenerator3.h"
+
/** \class cmGlobalNMakeMakefileGenerator
* \brief Write a NMake makefiles.
*
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 2d52356bc..da21d6c2a 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2,16 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalNinjaGenerator.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#include "cmsys/FStream.hxx"
#include <algorithm>
-#include <ctype.h>
+#include <cctype>
+#include <cstdio>
#include <iterator>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
+
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
@@ -19,6 +22,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -31,6 +35,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
@@ -381,7 +386,7 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
}
// Do not add a variable if the value is empty.
- std::string val = cmSystemTools::TrimWhitespace(value);
+ std::string val = cmTrimWhitespace(value);
if (val.empty()) {
return;
}
@@ -413,14 +418,6 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
: cmGlobalCommonGenerator(cm)
- , UsingGCCOnWindows(false)
- , ComputingUnknownDependencies(false)
- , PolicyCMP0058(cmPolicies::WARN)
- , NinjaSupportsConsolePool(false)
- , NinjaSupportsImplicitOuts(false)
- , NinjaSupportsManifestRestat(false)
- , NinjaSupportsMultilineDepfile(false)
- , NinjaSupportsDyndeps(0)
{
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
@@ -534,7 +531,7 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
cmSystemTools::SetFatalErrorOccured();
return false;
}
- this->NinjaVersion = cmSystemTools::TrimWhitespace(version);
+ this->NinjaVersion = cmTrimWhitespace(version);
this->CheckNinjaFeatures();
}
return true;
@@ -554,14 +551,22 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsMultilineDepfile = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForMultilineDepfile().c_str());
- {
+ this->NinjaSupportsDyndeps = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForDyndeps().c_str());
+ if (!this->NinjaSupportsDyndeps) {
+ // The ninja version number is not new enough to have upstream support.
// Our ninja branch adds ".dyndep-#" to its version number,
// where '#' is a feature-specific version number. Extract it.
static std::string const k_DYNDEP_ = ".dyndep-";
std::string::size_type pos = this->NinjaVersion.find(k_DYNDEP_);
if (pos != std::string::npos) {
const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()];
- cmSystemTools::StringToULong(fv, &this->NinjaSupportsDyndeps);
+ unsigned long dyndep = 0;
+ cmStrToULong(fv, &dyndep);
+ if (dyndep == 1) {
+ this->NinjaSupportsDyndeps = true;
+ }
}
}
}
@@ -569,8 +574,7 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
bool cmGlobalNinjaGenerator::CheckLanguages(
std::vector<std::string> const& languages, cmMakefile* mf) const
{
- if (std::find(languages.begin(), languages.end(), "Fortran") !=
- languages.end()) {
+ if (cmContains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
return true;
@@ -578,37 +582,25 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
{
- if (this->NinjaSupportsDyndeps == 1) {
+ if (this->NinjaSupportsDyndeps) {
return true;
}
std::ostringstream e;
- if (this->NinjaSupportsDyndeps == 0) {
- /* clang-format off */
- e <<
- "The Ninja generator does not support Fortran using Ninja version\n"
- " " + this->NinjaVersion + "\n"
- "due to lack of required features. "
- "Kitware has implemented the required features but as of this version "
- "of CMake they have not been integrated to upstream ninja. "
- "Pending integration, Kitware maintains a branch at:\n"
- " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n"
- "with the required features. "
- "One may build ninja from that branch to get support for Fortran."
- ;
- /* clang-format on */
- } else {
- /* clang-format off */
- e <<
- "The Ninja generator in this version of CMake does not support Fortran "
- "using Ninja version\n"
- " " + this->NinjaVersion + "\n"
- "because its 'dyndep' feature version is " <<
- this->NinjaSupportsDyndeps << ". "
- "This version of CMake is aware only of 'dyndep' feature version 1."
- ;
- /* clang-format on */
- }
+ /* clang-format off */
+ e <<
+ "The Ninja generator does not support Fortran using Ninja version\n"
+ " " + this->NinjaVersion + "\n"
+ "due to lack of required features. "
+ "Kitware has implemented the required features and they have been "
+ "merged to upstream ninja for inclusion in Ninja 1.10 and higher. "
+ "As of this version of CMake, Ninja 1.10 has not been released. "
+ "Meanwhile, Kitware maintains a branch of Ninja at:\n"
+ " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n"
+ "with the required features. "
+ "One may build ninja from that branch to get support for Fortran."
+ ;
+ /* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
@@ -638,7 +630,9 @@ void cmGlobalNinjaGenerator::EnableLanguage(
(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") ||
(mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") ||
(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") ||
- (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang")))) {
+ (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") ||
+ (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "QCC") ||
+ (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "QCC")))) {
this->UsingGCCOnWindows = true;
}
#endif
@@ -713,11 +707,9 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
- std::string dir;
- dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/";
- dir += gt->LocalGenerator->GetTargetDirectory(gt);
- dir += "/";
+ std::string dir =
+ cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ gt->LocalGenerator->GetTargetDirectory(gt), '/');
gt->ObjectDirectory = dir;
}
@@ -727,9 +719,8 @@ bool cmGlobalNinjaGenerator::OpenBuildFileStream()
{
// Compute Ninja's build file path.
std::string buildFilePath =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- buildFilePath += "/";
- buildFilePath += cmGlobalNinjaGenerator::NINJA_BUILD_FILE;
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
+ cmGlobalNinjaGenerator::NINJA_BUILD_FILE);
// Get a stream where to generate things.
if (!this->BuildFileStream) {
@@ -766,9 +757,8 @@ bool cmGlobalNinjaGenerator::OpenRulesFileStream()
{
// Compute Ninja's build file path.
std::string rulesFilePath =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- rulesFilePath += "/";
- rulesFilePath += cmGlobalNinjaGenerator::NINJA_RULES_FILE;
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
+ cmGlobalNinjaGenerator::NINJA_RULES_FILE);
// Get a stream where to generate things.
if (!this->RulesFileStream) {
@@ -901,16 +891,6 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
<< cmVersion::GetMinorVersion() << "\n\n";
}
-void cmGlobalNinjaGenerator::AddDependencyToAll(cmGeneratorTarget* target)
-{
- this->AppendTargetOutputs(target, this->AllDependencies);
-}
-
-void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input)
-{
- this->AllDependencies.push_back(input);
-}
-
void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
{
for (auto const& asd : this->AssumedSourceDependencies) {
@@ -1109,59 +1089,32 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Folder targets.\n\n";
- std::string const& rootBinaryDir =
- this->LocalGenerators[0]->GetBinaryDirectory();
-
- std::map<std::string, cmNinjaDeps> targetsPerFolder;
- for (cmLocalGenerator const* lg : this->LocalGenerators) {
- std::string const& currentBinaryFolder(
- lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
-
- // Do not generate a rule for the root binary dir.
- if (currentBinaryFolder == rootBinaryDir) {
- continue;
- }
+ std::map<std::string, DirectoryTarget> dirTargets =
+ this->ComputeDirectoryTargets();
- // The directory-level rule should depend on the target-level rules
- // for all targets in the directory.
- cmNinjaDeps& folderTargets = targetsPerFolder[currentBinaryFolder];
- for (auto gt : lg->GetGeneratorTargets()) {
- cmStateEnums::TargetType const type = gt->GetType();
- if ((type == cmStateEnums::EXECUTABLE ||
- type == cmStateEnums::STATIC_LIBRARY ||
- type == cmStateEnums::SHARED_LIBRARY ||
- type == cmStateEnums::MODULE_LIBRARY ||
- type == cmStateEnums::OBJECT_LIBRARY ||
- type == cmStateEnums::UTILITY) &&
- !gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
- folderTargets.push_back(gt->GetName());
+ for (auto const& it : dirTargets) {
+ cmNinjaBuild build("phony");
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ std::string const& currentBinaryDir = it.first;
+ DirectoryTarget const& dt = it.second;
+
+ // Setup target
+ build.Comment = "Folder: " + currentBinaryDir;
+ build.Outputs.emplace_back(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"));
+ for (DirectoryTarget::Target const& t : dt.Targets) {
+ if (!t.ExcludeFromAll) {
+ this->AppendTargetOutputs(t.GT, build.ExplicitDeps);
}
}
-
- // The directory-level rule should depend on the directory-level
- // rules of the subdirectories.
- for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
- std::string const& currentBinaryDir =
- state.GetDirectory().GetCurrentBinary();
- folderTargets.push_back(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"));
- }
- }
-
- if (!targetsPerFolder.empty()) {
- cmNinjaBuild build("phony");
- build.Outputs.emplace_back("");
- for (auto& it : targetsPerFolder) {
- cmGlobalNinjaGenerator::WriteDivider(os);
- std::string const& currentBinaryDir = it.first;
-
- // Setup target
- build.Comment = "Folder: " + currentBinaryDir;
- build.Outputs[0] = this->ConvertToNinjaPath(currentBinaryDir + "/all");
- build.ExplicitDeps = std::move(it.second);
- // Write target
- this->WriteBuild(os, build);
+ for (DirectoryTarget::Dir const& d : dt.Children) {
+ if (!d.ExcludeFromAll) {
+ build.ExplicitDeps.emplace_back(
+ this->ConvertToNinjaPath(d.Path + "/all"));
+ }
}
+ // Write target
+ this->WriteBuild(os, build);
}
}
@@ -1294,22 +1247,18 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Built-in targets\n\n";
- this->WriteTargetAll(os);
+ this->WriteTargetDefault(os);
this->WriteTargetRebuildManifest(os);
this->WriteTargetClean(os);
this->WriteTargetHelp(os);
}
-void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
+void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os)
{
- cmNinjaBuild build("phony");
- build.Comment = "The main all target.";
- build.Outputs.push_back(this->TargetAll);
- build.ExplicitDeps = this->AllDependencies;
- this->WriteBuild(os, build);
-
if (!this->HasOutputPathPrefix()) {
- cmGlobalNinjaGenerator::WriteDefault(os, build.Outputs,
+ cmNinjaDeps all;
+ all.push_back(this->TargetAll);
+ cmGlobalNinjaGenerator::WriteDefault(os, all,
"Make the all target the default.");
}
}
@@ -1323,13 +1272,13 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
{
cmNinjaRule rule("RERUN_CMAKE");
- rule.Command = CMakeCmd();
- rule.Command += " -S";
- rule.Command += lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
- cmOutputConverter::SHELL);
- rule.Command += " -B";
- rule.Command += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
- cmOutputConverter::SHELL);
+ rule.Command =
+ cmStrCat(CMakeCmd(), " -S",
+ lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
+ cmOutputConverter::SHELL),
+ " -B",
+ lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
+ cmOutputConverter::SHELL));
rule.Description = "Re-running CMake...";
rule.Comment = "Rule for re-running cmake.";
rule.Generator = true;
@@ -1357,10 +1306,10 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) {
{
cmNinjaRule rule("VERIFY_GLOBS");
- rule.Command = CMakeCmd();
- rule.Command += " -P ";
- rule.Command += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
- cmOutputConverter::SHELL);
+ rule.Command =
+ cmStrCat(CMakeCmd(), " -P ",
+ lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL));
rule.Description = "Re-checking globbed directories...";
rule.Comment = "Rule for re-checking globbed directories.";
rule.Generator = true;
@@ -1466,9 +1415,8 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmLocalGenerator* lgr = this->LocalGenerators.at(0);
std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
- std::string cleanScriptAbs = lgr->GetBinaryDirectory();
- cleanScriptAbs += '/';
- cleanScriptAbs += cleanScriptRel;
+ std::string cleanScriptAbs =
+ cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
// Check if there are additional files to clean
if (this->AdditionalCleanFiles.empty()) {
@@ -1498,10 +1446,10 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
// Write rule
{
cmNinjaRule rule("CLEAN_ADDITIONAL");
- rule.Command = CMakeCmd();
- rule.Command += " -P ";
- rule.Command += lgr->ConvertToOutputFormat(
- this->NinjaOutputPath(cleanScriptRel), cmOutputConverter::SHELL);
+ rule.Command = cmStrCat(
+ CMakeCmd(), " -P ",
+ lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel),
+ cmOutputConverter::SHELL));
rule.Description = "Cleaning additional files...";
rule.Comment = "Rule for cleaning additional files.";
WriteRule(*this->RulesFileStream, rule);
@@ -1739,8 +1687,9 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
if (arg_lang == "Fortran") {
info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp);
} else {
- cmSystemTools::Error("-E cmake_ninja_depends does not understand the " +
- arg_lang + " language");
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends does not understand the ", arg_lang,
+ " language"));
return 1;
}
@@ -1794,8 +1743,9 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(tdif, tdio, false)) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to parse " +
- arg_tdi + reader.getFormattedErrorMessages());
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to parse ", arg_tdi,
+ reader.getFormattedErrorMessages()));
return nullptr;
}
}
@@ -1874,8 +1824,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
cmsys::ifstream ddif(arg_ddi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(ddif, ddio, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_ddi +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_ddi,
+ reader.getFormattedErrorMessages()));
return false;
}
@@ -1902,14 +1853,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// Populate the module map with those provided by linked targets first.
for (std::string const& linked_target_dir : linked_target_dirs) {
std::string const ltmn =
- linked_target_dir + "/" + arg_lang + "Modules.json";
+ cmStrCat(linked_target_dir, "/", arg_lang, "Modules.json");
Json::Value ltm;
cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (ltmf && !reader.parse(ltmf, ltm, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " +
- linked_target_dir +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ linked_target_dir,
+ reader.getFormattedErrorMessages()));
return false;
}
if (ltm.isObject()) {
@@ -2013,8 +1964,9 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(tdif, tdio, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_tdi +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_tdi,
+ reader.getFormattedErrorMessages()));
return 1;
}
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 04d8e37ae..244e9fd38 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -7,7 +7,7 @@
#include <iosfwd>
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
@@ -15,13 +15,13 @@
#include <utility>
#include <vector>
+#include "cm_codecvt.hxx"
+
#include "cmGeneratedFileStream.h"
#include "cmGlobalCommonGenerator.h"
-#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmNinjaTypes.h"
#include "cmPolicies.h"
-#include "cm_codecvt.hxx"
class cmCustomCommand;
class cmGeneratorTarget;
@@ -228,7 +228,7 @@ public:
return this->GG->ConvertToNinjaPath(path);
}
};
- MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); }
+ MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
// -- Additional clean files
void AddAdditionalCleanFile(std::string fileName);
@@ -294,19 +294,12 @@ public:
cmNinjaDeps& outputs);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
cmNinjaOuts& outputs, bool omit_self);
- void AddDependencyToAll(cmGeneratorTarget* target);
- void AddDependencyToAll(const std::string& input);
const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
{
return LocalGenerators;
}
- bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target)
- {
- return cmGlobalGenerator::IsExcluded(root, target);
- }
-
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
@@ -322,6 +315,7 @@ public:
{
return "1.9";
}
+ static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -372,7 +366,7 @@ private:
void WriteUnknownExplicitDependencies(std::ostream& os);
void WriteBuiltinTargets(std::ostream& os);
- void WriteTargetAll(std::ostream& os);
+ void WriteTargetDefault(std::ostream& os);
void WriteTargetRebuildManifest(std::ostream& os);
bool WriteTargetCleanAdditional(std::ostream& os);
void WriteTargetClean(std::ostream& os);
@@ -399,10 +393,7 @@ private:
/// Length of rule command, used by rsp file evaluation
std::unordered_map<std::string, int> RuleCmdLength;
- /// The set of dependencies to add to the "all" target.
- cmNinjaDeps AllDependencies;
-
- bool UsingGCCOnWindows;
+ bool UsingGCCOnWindows = false;
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
@@ -412,8 +403,8 @@ private:
/// Whether we are collecting known build outputs and needed
/// dependencies to determine unknown dependencies.
- bool ComputingUnknownDependencies;
- cmPolicies::PolicyStatus PolicyCMP0058;
+ bool ComputingUnknownDependencies = false;
+ cmPolicies::PolicyStatus PolicyCMP0058 = cmPolicies::WARN;
/// The combined explicit dependencies of custom build commands
std::set<std::string> CombinedCustomCommandExplicitDependencies;
@@ -425,7 +416,7 @@ private:
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
- typedef std::map<std::string, cmGeneratorTarget*> TargetAliasMap;
+ using TargetAliasMap = std::map<std::string, cmGeneratorTarget*>;
TargetAliasMap TargetAliases;
std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
@@ -435,11 +426,11 @@ private:
std::string NinjaCommand;
std::string NinjaVersion;
- bool NinjaSupportsConsolePool;
- bool NinjaSupportsImplicitOuts;
- bool NinjaSupportsManifestRestat;
- bool NinjaSupportsMultilineDepfile;
- unsigned long NinjaSupportsDyndeps;
+ bool NinjaSupportsConsolePool = false;
+ bool NinjaSupportsImplicitOuts = false;
+ bool NinjaSupportsManifestRestat = false;
+ bool NinjaSupportsMultilineDepfile = false;
+ bool NinjaSupportsDyndeps = false;
private:
void InitOutputPathPrefix();
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4eb2252e9..4c2d69f09 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
@@ -20,6 +22,7 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTargetDepend.h"
#include "cmake.h"
@@ -105,11 +108,9 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
- std::string dir;
- dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/";
- dir += gt->LocalGenerator->GetTargetDirectory(gt);
- dir += "/";
+ std::string dir =
+ cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ gt->LocalGenerator->GetTargetDirectory(gt), '/');
gt->ObjectDirectory = dir;
}
@@ -144,10 +145,8 @@ void cmGlobalUnixMakefileGenerator3::Generate()
pmi.second.WriteProgressVariables(total, current);
}
for (cmLocalGenerator* lg : this->LocalGenerators) {
- std::string markFileName = lg->GetCurrentBinaryDirectory();
- markFileName += "/";
- markFileName += "/CMakeFiles";
- markFileName += "/progress.marks";
+ std::string markFileName =
+ cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks");
cmGeneratedFileStream markFile(markFileName);
markFile << this->CountProgressMarksInAll(lg) << "\n";
}
@@ -195,9 +194,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
// because the check-build-system step compares the makefile time to
// see if the build system must be regenerated.
std::string makefileName =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- makefileName += "/CMakeFiles";
- makefileName += "/Makefile2";
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles/Makefile2");
cmGeneratedFileStream makefileStream(makefileName, false,
this->GetMakefileEncoding());
if (!makefileStream) {
@@ -232,17 +230,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
depends.push_back(this->EmptyRuleHackDepends);
}
- // Write and empty all:
- lg->WriteMakeRule(makefileStream, "The main recursive all target", "all",
- depends, no_commands, true);
-
- // Write an empty preinstall:
- lg->WriteMakeRule(makefileStream, "The main recursive preinstall target",
- "preinstall", depends, no_commands, true);
-
// Write out the "special" stuff
lg->WriteSpecialTargetsTop(makefileStream);
+ // Write the directory level rules.
+ for (auto const& it : this->ComputeDirectoryTargets()) {
+ this->WriteDirectoryRules2(makefileStream, it.second);
+ }
+
// Write the target convenience rules
for (cmLocalGenerator* localGen : this->LocalGenerators) {
this->WriteConvenienceRules2(
@@ -263,17 +258,15 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// because the check-build-system step compares the makefile time to
// see if the build system must be regenerated.
std::string cmakefileName =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- cmakefileName += "/CMakeFiles";
- cmakefileName += "/Makefile.cmake";
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles/Makefile.cmake");
cmGeneratedFileStream cmakefileStream(cmakefileName);
if (!cmakefileStream) {
return;
}
std::string makefileName =
- this->GetCMakeInstance()->GetHomeOutputDirectory();
- makefileName += "/Makefile";
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), "/Makefile");
// get a local generator for some useful methods
cmLocalUnixMakefileGenerator3* lg =
@@ -303,8 +296,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Sort the list and remove duplicates.
std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
#if !defined(__VMS) // The Compaq STL on VMS crashes, so accept duplicates.
- std::vector<std::string>::iterator new_end =
- std::unique(lfiles.begin(), lfiles.end());
+ auto new_end = std::unique(lfiles.begin(), lfiles.end());
lfiles.erase(new_end, lfiles.end());
#endif
@@ -325,9 +317,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
cmakefileStream << " )\n\n";
// Build the path to the cache check file.
- std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
- check += "/CMakeFiles";
- check += "/cmake.check_cache";
+ std::string check =
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles/cmake.check_cache");
// Set the corresponding makefile in the cmake file.
cmakefileStream << "# The corresponding makefile is:\n"
@@ -357,9 +349,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
std::string tmpStr;
for (cmLocalGenerator* localGen : this->LocalGenerators) {
lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
- tmpStr = lg->GetCurrentBinaryDirectory();
- tmpStr += "/CMakeFiles";
- tmpStr += "/CMakeDirectoryInformation.cmake";
+ tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeDirectoryInformation.cmake");
cmakefileStream << " \""
<< lg->MaybeConvertToRelativePath(binDir, tmpStr)
<< "\"\n";
@@ -391,8 +382,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
(tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
(tgt->GetType() == cmStateEnums::UTILITY)) {
cmGeneratorTarget* gt = tgt;
- std::string tname = lg->GetRelativeTargetDirectory(gt);
- tname += "/DependInfo.cmake";
+ std::string tname =
+ cmStrCat(lg->GetRelativeTargetDirectory(gt), "/DependInfo.cmake");
cmSystemTools::ConvertToUnixSlashes(tname);
cmakefileStream << " \"" << tname << "\"\n";
}
@@ -402,44 +393,37 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
}
void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
- std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg,
- const char* pass, bool check_all, bool check_relink,
- std::vector<std::string> const& commands)
+ std::ostream& ruleFileStream, DirectoryTarget const& dt, const char* pass,
+ bool check_all, bool check_relink, std::vector<std::string> const& commands)
{
- // Get the relative path to the subdirectory from the top.
- std::string makeTarget = lg->GetCurrentBinaryDirectory();
- makeTarget += '/';
- makeTarget += pass;
+ auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG);
+ std::string makeTarget =
+ cmStrCat(lg->GetCurrentBinaryDirectory(), '/', pass);
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
std::vector<std::string> depends;
- for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
- int type = gtarget->GetType();
- if ((type == cmStateEnums::EXECUTABLE) ||
- (type == cmStateEnums::STATIC_LIBRARY) ||
- (type == cmStateEnums::SHARED_LIBRARY) ||
- (type == cmStateEnums::MODULE_LIBRARY) ||
- (type == cmStateEnums::OBJECT_LIBRARY) ||
- (type == cmStateEnums::UTILITY)) {
- // Add this to the list of depends rules in this directory.
- if ((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
- (!check_relink ||
- gtarget->NeedRelinkBeforeInstall(lg->GetConfigName()))) {
- std::string tname = lg->GetRelativeTargetDirectory(gtarget);
- tname += "/";
- tname += pass;
- depends.push_back(std::move(tname));
- }
+ for (DirectoryTarget::Target const& t : dt.Targets) {
+ // Add this to the list of depends rules in this directory.
+ if ((!check_all || !t.ExcludeFromAll) &&
+ (!check_relink ||
+ t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) {
+ // The target may be from a different directory; use its local gen.
+ auto const* tlg = static_cast<cmLocalUnixMakefileGenerator3 const*>(
+ t.GT->GetLocalGenerator());
+ std::string tname =
+ cmStrCat(tlg->GetRelativeTargetDirectory(t.GT), '/', pass);
+ depends.push_back(std::move(tname));
}
}
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
- for (cmStateSnapshot const& c : lg->GetStateSnapshot().GetChildren()) {
- std::string subdir = c.GetDirectory().GetCurrentBinary();
- subdir += '/';
- subdir += pass;
+ for (DirectoryTarget::Dir const& d : dt.Children) {
+ if (check_all && d.ExcludeFromAll) {
+ continue;
+ }
+ std::string subdir = cmStrCat(d.Path, '/', pass);
depends.push_back(std::move(subdir));
}
@@ -452,21 +436,18 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
// Write the rule.
std::string doc;
if (lg->IsRootMakefile()) {
- doc = "The main recursive \"";
- doc += pass;
- doc += "\" target.";
+ doc = cmStrCat("The main recursive \"", pass, "\" target.");
} else {
- doc = "Recursive \"";
- doc += pass;
- doc += "\" directory target.";
+ doc = cmStrCat("Recursive \"", pass, "\" directory target.");
}
lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, commands,
true);
}
void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
- std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg)
+ std::ostream& ruleFileStream, DirectoryTarget const& dt)
{
+ auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG);
// Begin the directory-level rules section.
{
std::string dir =
@@ -481,19 +462,17 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
ruleFileStream << "\n\n";
}
- if (!lg->IsRootMakefile()) {
- // Write directory-level rules for "all".
- this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
+ // Write directory-level rules for "all".
+ this->WriteDirectoryRule2(ruleFileStream, dt, "all", true, false);
- // Write directory-level rules for "preinstall".
- this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
- }
+ // Write directory-level rules for "preinstall".
+ this->WriteDirectoryRule2(ruleFileStream, dt, "preinstall", true, true);
// Write directory-level rules for "clean".
{
std::vector<std::string> cmds;
lg->AppendDirectoryCleanCommand(cmds);
- this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false, cmds);
+ this->WriteDirectoryRule2(ruleFileStream, dt, "clean", false, false, cmds);
}
}
@@ -591,8 +570,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
// Write the rule.
commands.clear();
- std::string tmp = "CMakeFiles/";
- tmp += "Makefile2";
+ std::string tmp = "CMakeFiles/Makefile2";
commands.push_back(lg->GetRecursiveMakeCall(tmp, name));
depends.clear();
if (regenerate) {
@@ -604,14 +582,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
// Add a fast rule to build the target
std::string localName = lg->GetRelativeTargetDirectory(gtarget);
std::string makefileName;
- makefileName = localName;
- makefileName += "/build.make";
+ makefileName = cmStrCat(localName, "/build.make");
depends.clear();
commands.clear();
- std::string makeTargetName = localName;
- makeTargetName += "/build";
- localName = name;
- localName += "/fast";
+ std::string makeTargetName = cmStrCat(localName, "/build");
+ localName = cmStrCat(name, "/fast");
commands.push_back(
lg->GetRecursiveMakeCall(makefileName, makeTargetName));
lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
@@ -620,10 +595,9 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
// Add a local name for the rule to relink the target before
// installation.
if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- makeTargetName = lg->GetRelativeTargetDirectory(gtarget);
- makeTargetName += "/preinstall";
- localName = name;
- localName += "/preinstall";
+ makeTargetName =
+ cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ localName = cmStrCat(name, "/preinstall");
depends.clear();
commands.clear();
commands.push_back(
@@ -645,9 +619,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
std::string localName;
std::string makeTargetName;
- // write the directory level rules for this local gen
- this->WriteDirectoryRules2(ruleFileStream, lg);
-
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
@@ -667,20 +638,17 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
std::string makefileName;
// Add a rule to build the target by name.
localName = lg->GetRelativeTargetDirectory(gtarget);
- makefileName = localName;
- makefileName += "/build.make";
+ makefileName = cmStrCat(localName, "/build.make");
lg->WriteDivider(ruleFileStream);
ruleFileStream << "# Target rules for target " << localName << "\n\n";
commands.clear();
- makeTargetName = localName;
- makeTargetName += "/depend";
+ makeTargetName = cmStrCat(localName, "/depend");
commands.push_back(
lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- makeTargetName = localName;
- makeTargetName += "/build";
+ makeTargetName = cmStrCat(localName, "/build");
commands.push_back(
lg->GetRecursiveMakeCall(makefileName, makeTargetName));
@@ -689,8 +657,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
depends.clear();
cmLocalUnixMakefileGenerator3::EchoProgress progress;
- progress.Dir = lg->GetBinaryDirectory();
- progress.Dir += "/CMakeFiles";
+ progress.Dir = cmStrCat(lg->GetBinaryDirectory(), "/CMakeFiles");
{
std::ostringstream progressArg;
const char* sep = "";
@@ -705,7 +672,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
if (const char* tgtMsg =
this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"TARGET_MESSAGES")) {
- targetMessages = cmSystemTools::IsOn(tgtMsg);
+ targetMessages = cmIsOn(tgtMsg);
}
if (targetMessages) {
@@ -717,15 +684,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName, depends, commands, true);
- // add the all/all dependency
- if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) {
- depends.clear();
- depends.push_back(localName);
- commands.clear();
- lg->WriteMakeRule(ruleFileStream, "Include target in all.", "all",
- depends, commands, true);
- }
-
// Write the rule.
commands.clear();
@@ -742,8 +700,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
progCmd << " " << this->CountProgressMarksInTarget(gtarget, emitted);
commands.push_back(progCmd.str());
}
- std::string tmp = "CMakeFiles/";
- tmp += "Makefile2";
+ std::string tmp = "CMakeFiles/Makefile2";
commands.push_back(lg->GetRecursiveMakeCall(tmp, localName));
{
std::ostringstream progCmd;
@@ -758,8 +715,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- localName = lg->GetRelativeTargetDirectory(gtarget);
- localName += "/rule";
+ localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/rule");
lg->WriteMakeRule(ruleFileStream,
"Build rule for subdir invocation for target.",
localName, depends, commands, true);
@@ -773,28 +729,19 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
// Add rules to prepare the target for installation.
if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- localName = lg->GetRelativeTargetDirectory(gtarget);
- localName += "/preinstall";
+ localName =
+ cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall(makefileName, localName));
lg->WriteMakeRule(ruleFileStream,
"Pre-install relink rule for target.", localName,
depends, commands, true);
-
- if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) {
- depends.clear();
- depends.push_back(localName);
- commands.clear();
- lg->WriteMakeRule(ruleFileStream, "Prepare target for install.",
- "preinstall", depends, commands, true);
- }
}
// add the clean rule
localName = lg->GetRelativeTargetDirectory(gtarget);
- makeTargetName = localName;
- makeTargetName += "/clean";
+ makeTargetName = cmStrCat(localName, "/clean");
depends.clear();
commands.clear();
commands.push_back(
@@ -913,9 +860,9 @@ void cmGlobalUnixMakefileGenerator3::AppendGlobalTargetDepends(
}
cmLocalUnixMakefileGenerator3* lg3 =
static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator());
- std::string tgtName =
- lg3->GetRelativeTargetDirectory(const_cast<cmGeneratorTarget*>(dep));
- tgtName += "/all";
+ std::string tgtName = cmStrCat(
+ lg3->GetRelativeTargetDirectory(const_cast<cmGeneratorTarget*>(dep)),
+ "/all");
depends.push_back(tgtName);
}
}
@@ -958,8 +905,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
(type == cmStateEnums::UTILITY)) {
std::string const& name = target->GetName();
if (emittedTargets.insert(name).second) {
- path = "... ";
- path += name;
+ path = cmStrCat("... ", name);
lg->AppendEcho(commands, path);
}
}
@@ -967,8 +913,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
}
}
for (std::string const& o : lg->GetLocalHelp()) {
- path = "... ";
- path += o;
+ path = cmStrCat("... ", o);
lg->AppendEcho(commands, path);
}
lg->WriteMakeRule(ruleFileStream, "Help Target", "help", no_depends,
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 287472c81..79db30ebd 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <iosfwd>
#include <map>
#include <set>
-#include <stddef.h>
#include <string>
#include <vector>
@@ -164,11 +164,11 @@ protected:
cmLocalUnixMakefileGenerator3*);
void WriteDirectoryRule2(std::ostream& ruleFileStream,
- cmLocalUnixMakefileGenerator3* lg, const char* pass,
+ DirectoryTarget const& dt, const char* pass,
bool check_all, bool check_relink,
std::vector<std::string> const& commands = {});
void WriteDirectoryRules2(std::ostream& ruleFileStream,
- cmLocalUnixMakefileGenerator3* lg);
+ DirectoryTarget const& dt);
void AppendGlobalTargetDepends(std::vector<std::string>& depends,
cmGeneratorTarget* target);
@@ -220,9 +220,8 @@ protected:
std::vector<unsigned long> Marks;
void WriteProgressVariables(unsigned long total, unsigned long& current);
};
- typedef std::map<cmGeneratorTarget const*, TargetProgress,
- cmGeneratorTarget::StrictTargetComparison>
- ProgressMapType;
+ using ProgressMapType = std::map<cmGeneratorTarget const*, TargetProgress,
+ cmGeneratorTarget::StrictTargetComparison>;
ProgressMapType ProgressMap;
size_t CountProgressMarksInTarget(
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 55374a48e..09a49e1e9 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -2,6 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio10Generator.h"
+#include <algorithm>
+
+#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"
@@ -13,15 +21,8 @@
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
#include "cmXMLWriter.h"
-#include "cm_jsoncpp_reader.h"
#include "cmake.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-
-#include <algorithm>
-
static const char vs10generatorName[] = "Visual Studio 10 2010";
static std::map<std::string, std::vector<cmIDEFlagTable>> loadedFlagJsonFiles;
@@ -232,7 +233,15 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (this->GeneratorToolsetCuda.empty()) {
// Find the highest available version of the CUDA tools.
std::vector<std::string> cudaTools;
- std::string const bcDir = this->VCTargetsPath + "/BuildCustomizations";
+ std::string bcDir;
+ if (this->GeneratorToolsetCudaCustomDir.empty()) {
+ bcDir = this->VCTargetsPath + "/BuildCustomizations";
+ } else {
+ bcDir = this->GetPlatformToolsetCudaCustomDirString() +
+ "CUDAVisualStudioIntegration\\extras\\"
+ "visual_studio_integration\\MSBuildExtensions";
+ cmSystemTools::ConvertToUnixSlashes(bcDir);
+ }
cmsys::Glob gl;
gl.SetRelative(bcDir.c_str());
if (gl.FindFiles(bcDir + "/CUDA *.props")) {
@@ -243,6 +252,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
std::sort(cudaTools.begin(), cudaTools.end(),
cmSystemTools::VersionCompareGreater);
this->GeneratorToolsetCuda = cudaTools.at(0);
+ } else if (!this->GeneratorToolsetCudaCustomDir.empty()) {
+ // Generate an error if Visual Studio integration files are not found
+ // inside of custom cuda toolset.
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "given toolset\n"
+ " cuda=" << this->GeneratorToolsetCudaCustomDir << "\n"
+ "cannot detect Visual Studio integration files in path\n"
+ " " << bcDir;
+
+ /* clang-format on */
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+
+ // Clear the configured tool-set
+ this->GeneratorToolsetCuda.clear();
}
}
@@ -319,13 +346,16 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (const char* cuda = this->GetPlatformToolsetCuda()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA", cuda);
}
+ if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir);
+ }
return true;
}
bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
- std::vector<std::string> const fields = cmSystemTools::tokenize(ts, ",");
+ std::vector<std::string> const fields = cmTokenize(ts, ",");
std::vector<std::string>::const_iterator fi = fields.begin();
if (fi == fields.end()) {
return true;
@@ -395,7 +425,17 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
std::string const& key, std::string const& value)
{
if (key == "cuda") {
- this->GeneratorToolsetCuda = value;
+ /* test if cuda toolset is path to custom dir or cuda version */
+ auto pos = value.find_first_not_of("0123456789.");
+ if (pos != std::string::npos) {
+ this->GeneratorToolsetCudaCustomDir = value;
+ /* ensure trailing backslash for easy path joining */
+ if (this->GeneratorToolsetCudaCustomDir.back() != '\\') {
+ this->GeneratorToolsetCudaCustomDir.push_back('\\');
+ }
+ } else {
+ this->GeneratorToolsetCuda = value;
+ }
return true;
}
if (key == "version") {
@@ -445,7 +485,7 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
this->DefaultPlatformName = "Tegra-Android";
this->DefaultPlatformToolset = "Default";
this->NsightTegraVersion = v;
- mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v.c_str());
+ mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
}
return true;
@@ -643,6 +683,21 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaString() const
return this->GeneratorToolsetCuda;
}
+const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDir()
+ const
+{
+ if (!this->GeneratorToolsetCudaCustomDir.empty()) {
+ return this->GeneratorToolsetCudaCustomDir.c_str();
+ }
+ return nullptr;
+}
+
+std::string const&
+cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDirString() const
+{
+ return this->GeneratorToolsetCudaCustomDir;
+}
+
bool cmGlobalVisualStudio10Generator::IsDefaultToolset(
const std::string&) const
{
@@ -659,8 +714,7 @@ bool cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf)
if (!this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf)) {
return false;
}
- mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND",
- this->GetMSBuildCommand().c_str());
+ mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND", this->GetMSBuildCommand());
return true;
}
@@ -679,9 +733,9 @@ std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand()
std::string mskey;
// Search in standard location.
- mskey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\";
- mskey += this->GetToolsVersion();
- mskey += ";MSBuildToolsPath";
+ mskey = cmStrCat(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\",
+ this->GetToolsVersion(), ";MSBuildToolsPath");
if (cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(msbuild);
@@ -721,8 +775,8 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
// In a try-compile we are given the outer CMakeFiles directory.
wd = this->ConfiguredFilesPath;
} else {
- wd = this->GetCMakeInstance()->GetHomeOutputDirectory();
- wd += "/CMakeFiles";
+ wd = cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles");
}
wd += "/";
wd += cmVersion::GetCMakeVersion();
@@ -906,8 +960,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
{
std::string slnFile;
if (!projectDir.empty()) {
- slnFile = projectDir;
- slnFile += "/";
+ slnFile = cmStrCat(projectDir, '/');
}
slnFile += projectName;
slnFile += ".sln";
@@ -954,8 +1007,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
makeCommand.Add(std::string(projectName) + ".sln");
makeCommand.Add("/t:Clean");
} else {
- std::string targetProject(tname);
- targetProject += ".vcxproj";
+ std::string targetProject = cmStrCat(tname, ".vcxproj");
if (targetProject.find('/') == std::string::npos) {
// it might be in a subdir
if (cmSlnProjectEntry const* proj = slnData.GetProjectByName(tname)) {
@@ -1038,14 +1090,12 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile(
{
// The VS 10 generator needs to create the .rule files on disk.
// Hide them away under the CMakeFiles directory.
- std::string ruleDir = this->GetCMakeInstance()->GetHomeOutputDirectory();
- ruleDir += "/CMakeFiles";
- ruleDir += "/";
- ruleDir += cmSystemTools::ComputeStringMD5(
- cmSystemTools::GetFilenamePath(output).c_str());
- std::string ruleFile = ruleDir + "/";
- ruleFile += cmSystemTools::GetFilenameName(output);
- ruleFile += ".rule";
+ std::string ruleDir = cmStrCat(
+ this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/",
+ cmSystemTools::ComputeStringMD5(
+ cmSystemTools::GetFilenamePath(output).c_str()));
+ std::string ruleFile =
+ cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule");
return ruleFile;
}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 1d30cd6b3..9adcf08ae 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -61,6 +61,10 @@ public:
const char* GetPlatformToolsetCuda() const;
std::string const& GetPlatformToolsetCudaString() const;
+ /** The custom cuda install directory */
+ const char* GetPlatformToolsetCudaCustomDir() const;
+ std::string const& GetPlatformToolsetCudaCustomDirString() const;
+
/** Return whether we need to use No/Debug instead of false/true
for GenerateDebugInformation. */
bool GetPlatformToolsetNeedsDebugEnum() const
@@ -152,6 +156,7 @@ protected:
std::string GeneratorToolsetVersion;
std::string GeneratorToolsetHostArchitecture;
std::string GeneratorToolsetCuda;
+ std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
std::string DefaultPlatformToolsetHostArchitecture;
std::string WindowsTargetPlatformVersion;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 6509b5616..cd4847427 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -182,7 +182,7 @@ void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion(
mf->DisplayStatus(e.str(), -1);
}
mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
- this->WindowsTargetPlatformVersion.c_str());
+ this->WindowsTargetPlatformVersion);
}
bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 8e67fad89..e8e9eced9 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -145,10 +145,8 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends(
for (std::string const& name : depends) {
std::string guid = this->GetGUID(name);
if (guid.empty()) {
- std::string m = "Target: ";
- m += target->GetName();
- m += " depends on unknown target: ";
- m += name;
+ std::string m = cmStrCat("Target: ", target->GetName(),
+ " depends on unknown target: ", name);
cmSystemTools::Error(m);
}
fout << "\t\t{" << guid << "} = {" << guid << "}\n";
@@ -201,7 +199,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmSystemTools::ExpandListArgument(m, mapConfig);
+ cmExpandList(m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 8764ee439..40b214c03 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -2,19 +2,26 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio7Generator.h"
+#include <vector>
+
+#include <cm/string_view>
+
+#include <windows.h>
+
+#include <assert.h>
+
+#include "cmsys/Encoding.hxx"
+
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmUuid.h"
#include "cmake.h"
-#include "cmsys/Encoding.hxx"
-
-#include <assert.h>
-#include <vector>
-#include <windows.h>
static cmVS7FlagTable cmVS7ExtraFlagTable[] = {
// Precompiled header and related options. Note that the
@@ -41,6 +48,14 @@ static cmVS7FlagTable cmVS7ExtraFlagTable[] = {
{ "", "", "", "", 0 }
};
+namespace {
+std::string GetSLNFile(cmLocalGenerator* root)
+{
+ return cmStrCat(root->GetCurrentBinaryDirectory(), '/',
+ root->GetProjectName(), ".sln");
+}
+}
+
cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
cmake* cm, std::string const& platformInGeneratorName)
: cmGlobalVisualStudioGenerator(cm, platformInGeneratorName)
@@ -64,8 +79,9 @@ const std::string& cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
// Compute the version of the Intel plugin to the VS IDE.
// If the key does not exist then use a default guess.
std::string intelVersion;
- std::string vskey = this->GetRegistryBase();
- vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
+ std::string vskey =
+ cmStrCat(this->GetRegistryBase(),
+ "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion");
cmSystemTools::ReadRegistryValue(vskey, intelVersion,
cmSystemTools::KeyWOW64_32);
unsigned int intelVersionNumber = ~0u;
@@ -121,8 +137,7 @@ bool cmGlobalVisualStudio7Generator::FindMakeProgram(cmMakefile* mf)
if (!this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf)) {
return false;
}
- mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND",
- this->GetDevEnvCommand().c_str());
+ mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND", this->GetDevEnvCommand());
return true;
}
@@ -152,8 +167,9 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
}
// Search where VS15Preview places it.
- vskey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;";
- vskey += this->GetIDEVersion();
+ vskey = cmStrCat(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;",
+ this->GetIDEVersion());
if (cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vscmd);
@@ -255,7 +271,7 @@ cmLocalGenerator* cmGlobalVisualStudio7Generator::CreateLocalGenerator(
return lg;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmGlobalVisualStudio7Generator::GetJson() const
{
Json::Value generator = this->cmGlobalVisualStudioGenerator::GetJson();
@@ -268,7 +284,7 @@ bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s,
cmMakefile* mf)
{
mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
- this->GetIntelProjectVersion().c_str());
+ this->GetIntelProjectVersion());
return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
}
@@ -281,8 +297,10 @@ void cmGlobalVisualStudio7Generator::Generate()
this->OutputSLNFile();
// If any solution or project files changed during the generation,
// tell Visual Studio to reload them...
- if (!cmSystemTools::GetErrorOccuredFlag()) {
- this->CallVisualStudioMacro(MacroReload);
+ if (!cmSystemTools::GetErrorOccuredFlag() &&
+ !this->LocalGenerators.empty()) {
+ this->CallVisualStudioMacro(MacroReload,
+ GetSLNFile(this->LocalGenerators[0]));
}
}
@@ -293,10 +311,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile(
return;
}
this->CurrentProject = root->GetProjectName();
- std::string fname = root->GetCurrentBinaryDirectory();
- fname += "/";
- fname += root->GetProjectName();
- fname += ".sln";
+ std::string fname = GetSLNFile(root);
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
if (!fout) {
@@ -433,16 +448,15 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
{
- const char* prefix = "CMAKE_FOLDER_GUID_";
- const std::string::size_type skip_prefix = strlen(prefix);
+ cm::string_view const prefix = "CMAKE_FOLDER_GUID_";
std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
for (auto const& iter : VisualStudioFolders) {
std::string fullName = iter.first;
std::string guid = this->GetGUID(fullName);
std::replace(fullName.begin(), fullName.end(), '/', '\\');
- if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix)) {
- fullName = fullName.substr(skip_prefix);
+ if (cmHasPrefix(fullName, prefix)) {
+ fullName = fullName.substr(prefix.size());
}
std::string nameOnly = cmSystemTools::GetFilenameName(fullName);
@@ -511,16 +525,15 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
extensibilityAddInsOverridden = true;
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
- std::vector<std::string> keyValuePairs;
- cmSystemTools::ExpandListArgument(root->GetMakefile()->GetProperty(it),
- keyValuePairs);
+ std::vector<std::string> keyValuePairs =
+ cmExpandedList(root->GetMakefile()->GetProperty(it));
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
const std::string key =
- cmSystemTools::TrimWhitespace(itPair.substr(0, posEqual));
+ cmTrimWhitespace(itPair.substr(0, posEqual));
const std::string value =
- cmSystemTools::TrimWhitespace(itPair.substr(posEqual + 1));
+ cmTrimWhitespace(itPair.substr(posEqual + 1));
fout << "\t\t" << key << " = " << value << "\n";
if (key == "SolutionGuid") {
addGuid = false;
@@ -555,12 +568,10 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
{
std::vector<std::string> configs;
target->Target->GetMakefile()->GetConfigurations(configs);
- std::string pname = target->GetName();
- pname += "_UTILITY";
- std::string fname = target->GetLocalGenerator()->GetCurrentBinaryDirectory();
- fname += "/";
- fname += pname;
- fname += ".vcproj";
+ std::string pname = cmStrCat(target->GetName(), "_UTILITY");
+ std::string fname =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+ pname, ".vcproj");
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
std::string guid = this->GetGUID(pname.c_str());
@@ -617,9 +628,8 @@ std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
return std::string(storedGUID);
}
// Compute a GUID that is deterministic but unique to the build tree.
- std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
- input += "|";
- input += name;
+ std::string input =
+ cmStrCat(this->CMakeInstance->GetState()->GetBinaryDirectory(), '|', name);
cmUuid uuidGenerator;
@@ -665,11 +675,8 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
for (std::string const& i : configs) {
const char* propertyValue =
target->Target->GetMakefile()->GetDefinition(propertyName);
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(propertyValue);
- if (cmSystemTools::IsOn(
- cge->Evaluate(target->GetLocalGenerator(), i))) {
+ if (cmIsOn(cmGeneratorExpression::Evaluate(
+ propertyValue, target->GetLocalGenerator(), i))) {
activeConfigs.insert(i);
}
}
@@ -685,7 +692,7 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
for (std::string const& i : configs) {
const char* propertyValue =
target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i);
- if (cmSystemTools::IsOff(propertyValue)) {
+ if (cmIsOff(propertyValue)) {
activeConfigs.insert(i);
}
}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index f004afb9c..7a9fcefa2 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -3,9 +3,8 @@
#ifndef cmGlobalVisualStudio7Generator_h
#define cmGlobalVisualStudio7Generator_h
-#include "cmGlobalVisualStudioGenerator.h"
-
#include "cmGlobalGeneratorFactory.h"
+#include "cmGlobalVisualStudioGenerator.h"
class cmTarget;
struct cmIDEFlagTable;
@@ -23,7 +22,7 @@ public:
//! Create a local generator appropriate to this Global Generator
cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value GetJson() const override;
#endif
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 85ddc85b5..8e6125b8a 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio8Generator.h"
+#include "cmCustomCommand.h"
+#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -26,9 +29,9 @@ std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand()
{
// First look for VCExpress.
std::string vsxcmd;
- std::string vsxkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\";
- vsxkey += this->GetIDEVersion();
- vsxkey += ";InstallDir";
+ std::string vsxkey =
+ cmStrCat("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\",
+ this->GetIDEVersion(), ";InstallDir");
if (cmSystemTools::ReadRegistryValue(vsxkey.c_str(), vsxcmd,
cmSystemTools::KeyWOW64_32)) {
cmSystemTools::ConvertToUnixSlashes(vsxcmd);
@@ -54,8 +57,7 @@ void cmGlobalVisualStudio8Generator::EnableLanguage(
void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
{
if (this->TargetsWindowsCE()) {
- mf->AddDefinition("CMAKE_VS_WINCE_VERSION",
- this->WindowsCEVersion.c_str());
+ mf->AddDefinition("CMAKE_VS_WINCE_VERSION", this->WindowsCEVersion);
}
}
@@ -94,17 +96,18 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
return false;
}
- const char* no_working_directory = nullptr;
- std::vector<std::string> no_depends;
std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
cmLocalVisualStudio7Generator* lg =
static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
cmMakefile* mf = lg->GetMakefile();
- cmCustomCommandLines noCommandLines;
+ const char* no_working_directory = nullptr;
+ std::vector<std::string> no_byproducts;
+ std::vector<std::string> no_depends;
+ cmCustomCommandLines no_commands;
cmTarget* tgt = mf->AddUtilityCommand(
- CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator,
- false, no_working_directory, no_depends, noCommandLines);
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, false,
+ no_working_directory, no_byproducts, no_depends, no_commands);
cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
lg->AddGeneratorTarget(gt);
@@ -117,20 +120,17 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Create a list of all stamp files for this project.
std::vector<std::string> stamps;
- std::string stampList = "CMakeFiles/";
- stampList += cmGlobalVisualStudio8Generator::GetGenerateStampList();
+ std::string stampList = cmStrCat(
+ "CMakeFiles/", cmGlobalVisualStudio8Generator::GetGenerateStampList());
{
std::string stampListFile =
- generators[0]->GetMakefile()->GetCurrentBinaryDirectory();
- stampListFile += "/";
- stampListFile += stampList;
+ cmStrCat(generators[0]->GetMakefile()->GetCurrentBinaryDirectory(), '/',
+ stampList);
std::string stampFile;
cmGeneratedFileStream fout(stampListFile.c_str());
for (cmLocalGenerator const* gi : generators) {
- stampFile = gi->GetMakefile()->GetCurrentBinaryDirectory();
- stampFile += "/";
- stampFile += "CMakeFiles/";
- stampFile += "generate.stamp";
+ stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/generate.stamp");
fout << stampFile << "\n";
stamps.push_back(stampFile);
}
@@ -148,19 +148,15 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Add a custom prebuild target to run the VerifyGlobs script.
cmake* cm = this->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
- cmCustomCommandLine verifyCommandLine;
- verifyCommandLine.push_back(cmSystemTools::GetCMakeCommand());
- verifyCommandLine.push_back("-P");
- verifyCommandLine.push_back(cm->GetGlobVerifyScript());
- cmCustomCommandLines verifyCommandLines;
- verifyCommandLines.push_back(verifyCommandLine);
+ cmCustomCommandLines verifyCommandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-P", cm->GetGlobVerifyScript() });
std::vector<std::string> byproducts;
byproducts.push_back(cm->GetGlobVerifyStamp());
- mf->AddCustomCommandToTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts,
- no_depends, verifyCommandLines,
- cmTarget::PRE_BUILD, "Checking File Globs",
- no_working_directory, false);
+ mf->AddCustomCommandToTarget(
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
+ verifyCommandLines, cmCustomCommandType::PRE_BUILD,
+ "Checking File Globs", no_working_directory, false);
// Ensure ZERO_CHECK always runs in Visual Studio using MSBuild,
// otherwise the prebuild command will not be run.
@@ -175,33 +171,25 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.erase(new_end, listFiles.end());
// Create a rule to re-run CMake.
- cmCustomCommandLine commandLine;
- commandLine.push_back(cmSystemTools::GetCMakeCommand());
- std::string argS = "-S";
- argS += lg->GetSourceDirectory();
- commandLine.push_back(argS);
- std::string argB = "-B";
- argB += lg->GetBinaryDirectory();
- commandLine.push_back(argB);
- commandLine.push_back("--check-stamp-list");
- commandLine.push_back(stampList.c_str());
- commandLine.push_back("--vs-solution-file");
+ std::string argS = cmStrCat("-S", lg->GetSourceDirectory());
+ std::string argB = cmStrCat("-B", lg->GetBinaryDirectory());
std::string const sln =
lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln";
- commandLine.push_back(sln);
- cmCustomCommandLines commandLines;
- commandLines.push_back(commandLine);
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
+ stampList, "--vs-solution-file", sln });
// Add the rule. Note that we cannot use the CMakeLists.txt
// file as the main dependency because it would get
// overwritten by the CreateVCProjBuildRule.
// (this could be avoided with per-target source files)
std::string no_main_dependency;
- std::vector<std::string> no_byproducts;
+ cmImplicitDependsList no_implicit_depends;
if (cmSourceFile* file = mf->AddCustomCommandToOutput(
- stamps, no_byproducts, listFiles, no_main_dependency, commandLines,
- "Checking Build System", no_working_directory, true, false)) {
- gt->AddSource(file->GetFullPath());
+ stamps, no_byproducts, listFiles, no_main_dependency,
+ no_implicit_depends, commandLines, "Checking Build System",
+ no_working_directory, true, false)) {
+ gt->AddSource(file->ResolveFullPath());
} else {
cmSystemTools::Error("Error adding rule for " + stamps[0]);
}
@@ -251,7 +239,7 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmSystemTools::ExpandListArgument(m, mapConfig);
+ cmExpandList(m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
@@ -296,11 +284,9 @@ bool cmGlobalVisualStudio8Generator::DeployInhibited(
cmGeneratorTarget const& target, const char* config) const
{
bool rVal = false;
- if (const char* propStr = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propStr);
- std::string prop = cge->Evaluate(target.LocalGenerator, config);
- rVal = cmSystemTools::IsOn(prop);
+ if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
+ rVal = cmIsOn(
+ cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
}
return rVal;
}
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index cc97cef09..ed0cba7dd 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -3,16 +3,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudioGenerator.h"
-#include "cmsys/Encoding.hxx"
#include <future>
#include <iostream>
+
+#include <cm/iterator>
+
+#include <windows.h>
+
#include <objbase.h>
#include <shellapi.h>
-#include <windows.h>
-#include "cmAlgorithms.h"
+#include "cmsys/Encoding.hxx"
+
#include "cmCallVisualStudioMacro.h"
#include "cmCustomCommand.h"
+#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudioGenerator.h"
@@ -57,7 +62,7 @@ void cmGlobalVisualStudioGenerator::EnableLanguage(
std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
{
mf->AddDefinition("CMAKE_VS_PLATFORM_NAME_DEFAULT",
- this->DefaultPlatformName.c_str());
+ this->DefaultPlatformName);
this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
}
@@ -69,7 +74,7 @@ bool cmGlobalVisualStudioGenerator::SetGeneratorPlatform(std::string const& p,
} else if (this->GetPlatformName() == "Itanium") {
mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
}
- mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
+ mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
return this->cmGlobalGenerator::SetGeneratorPlatform(p, mf);
}
@@ -104,6 +109,9 @@ const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
{
+ char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) };
+ fout.write(utf8bom, 3);
+
switch (this->Version) {
case cmGlobalVisualStudioGenerator::VS9:
fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
@@ -178,7 +186,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
{
// Add a special target that depends on ALL projects for easy build
// of one configuration only.
- const char* no_working_dir = 0;
+ const char* no_working_dir = nullptr;
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
cmCustomCommandLines no_commands;
for (auto const& it : this->ProjectMap) {
@@ -188,8 +197,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
// Use no actual command lines so that the target itself is not
// considered always out of date.
cmTarget* allBuild = gen[0]->GetMakefile()->AddUtilityCommand(
- "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, no_working_dir,
- no_depends, no_commands, false, "Build all projects");
+ "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_dir,
+ no_byproducts, no_depends, no_commands, false, "Build all projects");
cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
gen[0]->AddGeneratorTarget(gt);
@@ -224,8 +233,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
- std::string dir = gt->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/";
+ std::string dir =
+ cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/');
std::string tgtDir = gt->LocalGenerator->GetTargetDirectory(gt);
if (!tgtDir.empty()) {
dir += tgtDir;
@@ -258,8 +267,8 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
std::string dir = this->GetUserMacrosDirectory();
if (!dir.empty()) {
- std::string src = cmSystemTools::GetCMakeRoot();
- src += "/Templates/" CMAKE_VSMACROS_FILENAME;
+ std::string src = cmStrCat(cmSystemTools::GetCMakeRoot(),
+ "/Templates/" CMAKE_VSMACROS_FILENAME);
std::string dst = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
@@ -283,11 +292,10 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
}
void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
- MacroName m, const char* vsSolutionFile)
+ MacroName m, const std::string& vsSolutionFile)
{
// If any solution or project files changed during the generation,
// tell Visual Studio to reload them...
- cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
std::string dir = this->GetUserMacrosDirectory();
// Only really try to call the macro if:
@@ -302,28 +310,18 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
if (cmSystemTools::FileExists(macrosFile.c_str()) &&
IsVisualStudioMacrosFileRegistered(
macrosFile, this->GetUserMacrosRegKeyBase(), nextSubkeyName)) {
- std::string topLevelSlnName;
- if (vsSolutionFile) {
- topLevelSlnName = vsSolutionFile;
- } else {
- topLevelSlnName = mf->GetCurrentBinaryDirectory();
- topLevelSlnName += "/";
- topLevelSlnName += this->LocalGenerators[0]->GetProjectName();
- topLevelSlnName += ".sln";
- }
-
if (m == MacroReload) {
std::vector<std::string> filenames;
this->GetFilesReplacedDuringGenerate(filenames);
if (!filenames.empty()) {
std::string projects = cmJoin(filenames, ";");
cmCallVisualStudioMacro::CallMacro(
- topLevelSlnName, CMAKE_VSMACROS_RELOAD_MACRONAME, projects,
+ vsSolutionFile, CMAKE_VSMACROS_RELOAD_MACRONAME, projects,
this->GetCMakeInstance()->GetDebugOutput());
}
} else if (m == MacroStop) {
cmCallVisualStudioMacro::CallMacro(
- topLevelSlnName, CMAKE_VSMACROS_STOP_MACRONAME, "",
+ vsSolutionFile, CMAKE_VSMACROS_STOP_MACRONAME, "",
this->GetCMakeInstance()->GetDebugOutput());
}
}
@@ -487,8 +485,8 @@ bool cmGlobalVisualStudioGenerator::FindMakeProgram(cmMakefile* mf)
// Visual Studio generators know how to lookup their build tool
// directly instead of needing a helper module to do it, so we
// do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
- if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
- mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram().c_str());
+ if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+ mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram());
}
return true;
}
@@ -553,9 +551,9 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
// Iterate the subkeys and look for the values of interest in each subkey:
wchar_t subkeyname[256];
- DWORD cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]);
+ DWORD cch_subkeyname = cm::size(subkeyname);
wchar_t keyclass[256];
- DWORD cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]);
+ DWORD cch_keyclass = cm::size(keyclass);
FILETIME lastWriteTime;
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
@@ -569,8 +567,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
DWORD valueType = REG_SZ;
wchar_t data1[256];
- DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]);
- RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)&data1[0],
+ DWORD cch_data1 = sizeof(data1);
+ RegQueryValueExW(hsubkey, L"Path", 0, &valueType, (LPBYTE)data1,
&cch_data1);
DWORD data2 = 0;
@@ -618,8 +616,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
}
++index;
- cch_subkeyname = sizeof(subkeyname) * sizeof(subkeyname[0]);
- cch_keyclass = sizeof(keyclass) * sizeof(keyclass[0]);
+ cch_subkeyname = cm::size(subkeyname);
+ cch_keyclass = cm::size(keyclass);
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
}
@@ -634,9 +632,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
// follow the expected naming scheme. Expected naming scheme is that
// the subkeys of OtherProjects7 is 0 to n-1, so it's ok to use "n"
// as the name of the next subkey.
- std::ostringstream ossNext;
- ossNext << index;
- nextAvailableSubKeyName = ossNext.str();
+ nextAvailableSubKeyName = std::to_string(index);
keyname = regKeyBase + "\\RecordingProject7";
hkey = NULL;
@@ -646,9 +642,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
if (ERROR_SUCCESS == result) {
DWORD valueType = REG_SZ;
wchar_t data1[256];
- DWORD cch_data1 = sizeof(data1) * sizeof(data1[0]);
- RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)&data1[0],
- &cch_data1);
+ DWORD cch_data1 = sizeof(data1);
+ RegQueryValueExW(hkey, L"Path", 0, &valueType, (LPBYTE)data1, &cch_data1);
DWORD data2 = 0;
DWORD cch_data2 = sizeof(data2);
@@ -900,18 +895,11 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
std::string obj_dir = gt->ObjectDirectory;
std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
- cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
- cmCustomCommandLine cmdl;
- cmdl.push_back(cmakeCommand);
- cmdl.push_back("-E");
- cmdl.push_back("__create_def");
- cmdl.push_back(mdi->DefFile);
std::string obj_dir_expanded = obj_dir;
cmSystemTools::ReplaceString(obj_dir_expanded, this->GetCMakeCFGIntDir(),
configName.c_str());
cmSystemTools::MakeDirectory(obj_dir_expanded);
std::string const objs_file = obj_dir_expanded + "/objects.txt";
- cmdl.push_back(objs_file);
cmGeneratedFileStream fout(objs_file.c_str());
if (!fout) {
cmSystemTools::Error("could not open " + objs_file);
@@ -949,8 +937,8 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
fout << i->GetFullPath() << "\n";
}
- cmCustomCommandLines commandLines;
- commandLines.push_back(cmdl);
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file });
cmCustomCommand command(gt->Target->GetMakefile(), outputs, empty, empty,
commandLines, "Auto build dll exports", ".");
commands.push_back(command);
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index cbab3294d..4f2007f75 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -90,7 +90,7 @@ public:
* Call the ReloadProjects macro if necessary based on
* GetFilesReplacedDuringGenerate results.
*/
- void CallVisualStudioMacro(MacroName m, const char* vsSolutionFile = 0);
+ void CallVisualStudioMacro(MacroName m, const std::string& vsSolutionFile);
// return true if target is fortran only
bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
@@ -110,6 +110,13 @@ public:
bool IsIncludeExternalMSProjectSupported() const override { return true; }
+ /** Get encoding used by generator for generated source files
+ */
+ codecvt::Encoding GetMakefileEncoding() const override
+ {
+ return codecvt::ANSI;
+ }
+
class TargetSet : public std::set<cmGeneratorTarget const*>
{
};
@@ -173,7 +180,7 @@ protected:
const std::string&);
virtual std::string WriteUtilityDepend(cmGeneratorTarget const*) = 0;
std::string GetUtilityDepend(const cmGeneratorTarget* target);
- typedef std::map<cmGeneratorTarget const*, std::string> UtilityDependsMap;
+ using UtilityDependsMap = std::map<cmGeneratorTarget const*, std::string>;
UtilityDependsMap UtilityDepends;
protected:
@@ -206,13 +213,12 @@ class cmGlobalVisualStudioGenerator::OrderedTargetDependSet
: public std::multiset<cmTargetDepend,
cmGlobalVisualStudioGenerator::TargetCompare>
{
- typedef std::multiset<cmTargetDepend,
- cmGlobalVisualStudioGenerator::TargetCompare>
- derived;
+ using derived = std::multiset<cmTargetDepend,
+ cmGlobalVisualStudioGenerator::TargetCompare>;
public:
- typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
- typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet;
+ using TargetDependSet = cmGlobalGenerator::TargetDependSet;
+ using TargetSet = cmGlobalVisualStudioGenerator::TargetSet;
OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
OrderedTargetDependSet(TargetSet const&, std::string const& first);
};
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 66a57eb10..1eca1f600 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -388,17 +388,15 @@ std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
if (version) {
std::string instancePath;
GetVSInstance(instancePath);
- std::string toolsetDir = instancePath + "/VC/Auxiliary/Build";
- char sep = '/';
- if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
- std::string toolsetDot = toolsetDir + "." + version +
- "/Microsoft.VCToolsVersion." + version + ".props";
- if (cmSystemTools::PathExists(toolsetDot)) {
- sep = '.';
- }
- }
- std::string toolsetPath = toolsetDir + sep + version +
- "/Microsoft.VCToolsVersion." + version + ".props";
+ std::stringstream path;
+ path << instancePath;
+ path << "/VC/Auxiliary/Build";
+ path << (cmSystemTools::VersionCompareGreaterEq(version, "14.20") ? '.'
+ : '/');
+ path << version;
+ path << "/Microsoft.VCToolsVersion." << version << ".props";
+
+ std::string toolsetPath = path.str();
cmSystemTools::ConvertToUnixSlashes(toolsetPath);
return toolsetPath;
}
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index 8a2738431..308ddda73 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -2,14 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalWatcomWMakeGenerator.h"
+#include <ostream>
+
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmake.h"
-#include <ostream>
-
cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
: cmGlobalUnixMakefileGenerator3(cm)
{
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 3ca5e7d86..64ace1359 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGlobalGeneratorFactory.h"
-#include "cmGlobalUnixMakefileGenerator3.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmGlobalGeneratorFactory.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+
class cmMakefile;
class cmake;
struct cmDocumentationEntry;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 9d725282b..3002b2a68 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2,18 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalXCodeGenerator.h"
-#include "cmsys/RegularExpression.hxx"
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
+#include <cstring>
#include <iomanip>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
-#include <string.h>
+
+#include <cm/memory>
+
+#include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
@@ -37,12 +40,12 @@
struct cmLinkImplementation;
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(__APPLE__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(__APPLE__)
# define HAVE_APPLICATION_SERVICES
# include <ApplicationServices/ApplicationServices.h>
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmXMLParser.h"
// parse the xml file storing the installed version of Xcode on
@@ -187,7 +190,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
if (name != GetActualName()) {
return nullptr;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmXcodeVersionParser parser;
std::string versionFile;
{
@@ -239,9 +242,8 @@ bool cmGlobalXCodeGenerator::FindMakeProgram(cmMakefile* mf)
// The Xcode generator knows how to lookup its build tool
// directly instead of needing a helper module to do it, so we
// do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
- if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
- mf->AddDefinition("CMAKE_MAKE_PROGRAM",
- this->GetXcodeBuildCommand().c_str());
+ if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+ mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetXcodeBuildCommand());
}
return true;
}
@@ -282,8 +284,7 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
}
this->GeneratorToolset = ts;
if (!this->GeneratorToolset.empty()) {
- mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
- this->GeneratorToolset.c_str());
+ mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset);
}
return true;
}
@@ -292,7 +293,7 @@ void cmGlobalXCodeGenerator::EnableLanguage(
std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
{
mf->AddDefinition("XCODE", "1");
- mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str());
+ mf->AddDefinition("XCODE_VERSION", this->VersionString);
if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
mf->AddCacheDefinition(
"CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo",
@@ -350,13 +351,10 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
if (!projectName.empty()) {
makeCommand.Add("-project");
- std::string projectArg = projectName;
- projectArg += ".xcode";
- projectArg += "proj";
+ std::string projectArg = cmStrCat(projectName, ".xcodeproj");
makeCommand.Add(projectArg);
}
- if (std::find(targetNames.begin(), targetNames.end(), "clean") !=
- targetNames.end()) {
+ if (cmContains(targetNames, "clean")) {
makeCommand.Add("clean");
makeCommand.Add("-target", "ALL_BUILD");
} else {
@@ -477,8 +475,8 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
this->CurrentLocalGenerator->GetCurrentBinaryDirectory(),
this->ProjectOutputDirectoryComponents);
- this->CurrentXCodeHackMakefile = root->GetCurrentBinaryDirectory();
- this->CurrentXCodeHackMakefile += "/CMakeScripts";
+ this->CurrentXCodeHackMakefile =
+ cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeScripts");
cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile);
this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
}
@@ -488,8 +486,7 @@ std::string cmGlobalXCodeGenerator::PostBuildMakeTarget(
{
std::string target = tName;
std::replace(target.begin(), target.end(), ' ', '_');
- std::string out = "PostBuild." + target;
- out += "." + configName;
+ std::string out = cmStrCat("PostBuild.", target, '.', configName);
return out;
}
@@ -501,26 +498,24 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
{
cmMakefile* mf = root->GetMakefile();
- // Add ALL_BUILD
const char* no_working_directory = nullptr;
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
+
+ // Add ALL_BUILD
cmTarget* allbuild = mf->AddUtilityCommand(
- "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, no_depends,
- no_working_directory, "echo", "Build all projects");
+ "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_directory,
+ no_byproducts, no_depends,
+ cmMakeSingleCommandLine({ "echo", "Build all projects" }));
cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
root->AddGeneratorTarget(allBuildGt);
// Add XCODE depend helper
std::string dir = root->GetCurrentBinaryDirectory();
- cmCustomCommandLine makeHelper;
- makeHelper.push_back("make");
- makeHelper.push_back("-C");
- makeHelper.push_back(dir);
- makeHelper.push_back("-f");
- makeHelper.push_back(this->CurrentXCodeHackMakefile);
- makeHelper.push_back("OBJDIR=$(OBJDIR)");
- makeHelper.push_back(""); // placeholder, see below
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { "make", "-C", dir, "-f", this->CurrentXCodeHackMakefile,
+ "OBJDIR=$(OBJDIR)", /* placeholder, see below */ "" });
// Add ZERO_CHECK
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
@@ -534,8 +529,9 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile);
cmSystemTools::ReplaceString(file, "\\ ", " ");
cmTarget* check = mf->AddUtilityCommand(
- CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator,
- true, no_depends, no_working_directory, "make", "-f", file.c_str());
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, true,
+ no_working_directory, no_byproducts, no_depends,
+ cmMakeSingleCommandLine({ "make", "-f", file }));
cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
root->AddGeneratorTarget(checkGt);
@@ -549,9 +545,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
continue;
}
- std::string targetName = target->GetName();
-
- if (regenerate && (targetName != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) {
+ if (regenerate &&
+ (target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) {
target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
}
@@ -560,15 +555,13 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
// this will make sure that when the next target is built
// things are up-to-date
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- makeHelper.back() = // fill placeholder
+ commandLines.front().back() = // fill placeholder
this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)");
- cmCustomCommandLines commandLines;
- commandLines.push_back(makeHelper);
- std::vector<std::string> no_byproducts;
gen->GetMakefile()->AddCustomCommandToTarget(
target->GetName(), no_byproducts, no_depends, commandLines,
- cmTarget::POST_BUILD, "Depend check for xcode", dir.c_str(), true,
- false, "", "", false, cmMakefile::AcceptObjectLibraryCommands);
+ cmCustomCommandType::POST_BUILD, "Depend check for xcode",
+ dir.c_str(), true, false, "", "", false,
+ cmObjectLibraryCommands::Accept);
}
if (!this->IsExcluded(gens[0], target)) {
@@ -587,18 +580,16 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
}
// sort the array
- std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
- std::vector<std::string>::iterator new_end =
- std::unique(lfiles.begin(), lfiles.end());
- lfiles.erase(new_end, lfiles.end());
+ std::sort(lfiles.begin(), lfiles.end());
+ lfiles.erase(std::unique(lfiles.begin(), lfiles.end()), lfiles.end());
cmake* cm = this->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
lfiles.emplace_back(cm->GetGlobVerifyStamp());
}
- this->CurrentReRunCMakeMakefile = root->GetCurrentBinaryDirectory();
- this->CurrentReRunCMakeMakefile += "/CMakeScripts";
+ this->CurrentReRunCMakeMakefile =
+ cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeScripts");
cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile);
this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
cmGeneratedFileStream makefileStream(this->CurrentReRunCMakeMakefile);
@@ -616,10 +607,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
}
makefileStream << "\n";
- std::string checkCache = root->GetBinaryDirectory();
- checkCache += "/";
- checkCache += "CMakeFiles/";
- checkCache += "cmake.check_cache";
+ std::string checkCache =
+ cmStrCat(root->GetBinaryDirectory(), "/CMakeFiles/cmake.check_cache");
if (cm->DoWriteGlobVerifyTarget()) {
makefileStream << ".NOTPARALLEL:\n\n";
@@ -787,7 +776,7 @@ public:
"Xcode does not support per-config per-source " << property << ":\n"
" " << expression << "\n"
"specified for source:\n"
- " " << this->SourceFile->GetFullPath() << "\n";
+ " " << this->SourceFile->ResolveFullPath() << "\n";
/* clang-format on */
this->LocalGenerator->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
@@ -838,6 +827,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS).c_str(),
true);
}
+
+ if (sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
+ this->AppendDefines(flagsBuild, "CMAKE_SKIP_PRECOMPILE_HEADERS", true);
+ }
+
if (!flagsBuild.IsEmpty()) {
if (!flags.empty()) {
flags += ' ';
@@ -856,7 +850,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
cmXCodeObject* buildFile =
- this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), gtgt, lang, sf);
+ this->CreateXCodeSourceFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf);
cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
settings->AddAttributeIfNotEmpty("COMPILER_FLAGS",
@@ -882,8 +876,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes;
- cmSystemTools::ExpandListArgument(extraFileAttributes, attributes);
+ std::vector<std::string> attributes = cmExpandedList(extraFileAttributes);
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -901,11 +894,11 @@ void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const
{
std::string listfile =
- target->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(listfile);
- if (std::find(sources.begin(), sources.end(), srcCMakeLists) ==
- sources.end()) {
+ cmStrCat(target->GetLocalGenerator()->GetCurrentSourceDirectory(),
+ "/CMakeLists.txt");
+ cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(
+ listfile, false, cmSourceFileLocationKind::Known);
+ if (!cmContains(sources, srcCMakeLists)) {
sources.push_back(srcCMakeLists);
}
}
@@ -949,6 +942,10 @@ std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
sourcecode += ".cpp.cpp";
} else if (lang == "C") {
sourcecode += ".c.c";
+ } else if (lang == "OBJCXX") {
+ sourcecode += ".cpp.objcpp";
+ } else if (lang == "OBJC") {
+ sourcecode += ".c.objc";
} else if (lang == "Fortran") {
sourcecode += ".fortran.f90";
} else if (lang == "ASM") {
@@ -1037,7 +1034,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReference(
{
std::string lang = this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
- return this->CreateXCodeFileReferenceFromPath(sf->GetFullPath(), target,
+ return this->CreateXCodeFileReferenceFromPath(sf->ResolveFullPath(), target,
lang, sf);
}
@@ -1072,7 +1069,7 @@ struct cmSourceFilePathCompare
{
bool operator()(cmSourceFile* l, cmSourceFile* r)
{
- return l->GetFullPath() < r->GetFullPath();
+ return l->ResolveFullPath() < r->ResolveFullPath();
}
};
@@ -1147,7 +1144,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
// Add the Info.plist we are about to generate for an App Bundle.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
std::string plist = this->ComputeInfoPListLocation(gtgt);
- cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(plist, true);
+ cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
+ plist, true, cmSourceFileLocationKind::Known);
classes.push_back(sf);
}
@@ -1180,7 +1178,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
headerFiles.push_back(xsf);
} else if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource) {
resourceFiles.push_back(xsf);
- } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY")) {
+ } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY") &&
+ !gtgt->IsSourceFilePartOfUnityBatch(
+ sourceFile->ResolveFullPath())) {
// Include this file in the build if it has a known language
// and has not been listed as an ignored extension for this
// generator.
@@ -1253,8 +1253,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
// framework or bundle targets
std::vector<cmXCodeObject*> contentBuildPhases;
if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) {
- typedef std::map<std::string, std::vector<cmSourceFile*>>
- mapOfVectorOfSourceFiles;
+ using mapOfVectorOfSourceFiles =
+ std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
for (auto sourceFile : classes) {
cmGeneratorTarget::SourceFileFlags tsFlags =
@@ -1263,7 +1263,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
bundleFiles[tsFlags.MacFolder].push_back(sourceFile);
}
}
- for (auto keySources : bundleFiles) {
+ for (auto const& keySources : bundleFiles) {
cmXCodeObject* copyFilesBuildPhase =
this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
copyFilesBuildPhase->SetComment("Copy files");
@@ -1301,8 +1301,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
// create vector of "resource content file" build phases - only for
// framework or bundle targets
if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) {
- typedef std::map<std::string, std::vector<cmSourceFile*>>
- mapOfVectorOfSourceFiles;
+ using mapOfVectorOfSourceFiles =
+ std::map<std::string, std::vector<cmSourceFile*>>;
mapOfVectorOfSourceFiles bundleFiles;
for (auto sourceFile : classes) {
cmGeneratorTarget::SourceFileFlags tsFlags =
@@ -1311,7 +1311,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
bundleFiles[tsFlags.MacFolder].push_back(sourceFile);
}
}
- for (auto keySources : bundleFiles) {
+ for (auto const& keySources : bundleFiles) {
cmXCodeObject* copyFilesBuildPhase =
this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
copyFilesBuildPhase->SetComment("Copy files");
@@ -1399,13 +1399,9 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
// linker language. This should convince Xcode to choose the proper
// language.
cmMakefile* mf = gtgt->Target->GetMakefile();
- std::string fname = gtgt->GetLocalGenerator()->GetCurrentBinaryDirectory();
- fname += "/CMakeFiles";
- fname += "/";
- fname += gtgt->GetName();
- fname += "-CMakeForceLinker";
- fname += ".";
- fname += cmSystemTools::LowerCase(llang);
+ std::string fname = cmStrCat(
+ gtgt->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ gtgt->GetName(), "-CMakeForceLinker.", cmSystemTools::LowerCase(llang));
{
cmGeneratedFileStream fout(fname);
fout << "\n";
@@ -1418,10 +1414,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
- const std::vector<std::string>& hdrExts =
- this->CMakeInstance->GetHeaderExtensions();
- return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) !=
- hdrExts.end());
+ return cmContains(this->CMakeInstance->GetHeaderExtensions(),
+ sf->GetExtension());
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
@@ -1448,7 +1442,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
void cmGlobalXCodeGenerator::CreateCustomCommands(
cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase,
cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase,
- std::vector<cmXCodeObject*> contentBuildPhases,
+ std::vector<cmXCodeObject*> const& contentBuildPhases,
cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt)
{
std::vector<cmCustomCommand> const& prebuild = gtgt->GetPreBuildCommands();
@@ -1457,23 +1451,14 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
if (gtgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
!gtgt->IsFrameworkOnApple()) {
- cmCustomCommandLines cmd;
- cmd.resize(1);
- cmd[0].push_back(cmSystemTools::GetCMakeCommand());
- cmd[0].push_back("-E");
- cmd[0].push_back("cmake_symlink_library");
- std::string str_file = "$<TARGET_FILE:";
- str_file += gtgt->GetName();
- str_file += ">";
- std::string str_so_file = "$<TARGET_SONAME_FILE:";
- str_so_file += gtgt->GetName();
- str_so_file += ">";
- std::string str_link_file = "$<TARGET_LINKER_FILE:";
- str_link_file += gtgt->GetName();
- str_link_file += ">";
- cmd[0].push_back(str_file);
- cmd[0].push_back(str_so_file);
- cmd[0].push_back(str_link_file);
+ std::string str_file = cmStrCat("$<TARGET_FILE:", gtgt->GetName(), '>');
+ std::string str_so_file =
+ cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
+ std::string str_link_file =
+ cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
+ cmCustomCommandLines cmd = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
+ str_file, str_so_file, str_link_file });
cmCustomCommand command(this->CurrentMakefile, std::vector<std::string>(),
std::vector<std::string>(),
@@ -1637,15 +1622,11 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase(
cmXCodeObject* buildphase, cmGeneratorTarget* target,
std::vector<cmCustomCommand> const& commands, const char* name)
{
- std::string dir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
- dir += "/CMakeScripts";
+ std::string dir = cmStrCat(
+ this->CurrentLocalGenerator->GetCurrentBinaryDirectory(), "/CMakeScripts");
cmSystemTools::MakeDirectory(dir);
- std::string makefile = dir;
- makefile += "/";
- makefile += target->GetName();
- makefile += "_";
- makefile += name;
- makefile += ".make";
+ std::string makefile =
+ cmStrCat(dir, '/', target->GetName(), '_', name, ".make");
for (const auto& currentConfig : this->CurrentConfigurationTypes) {
this->CreateCustomRulesMakefile(makefile.c_str(), target, commands,
@@ -1654,12 +1635,10 @@ void cmGlobalXCodeGenerator::AddCommandsToBuildPhase(
std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
cdir = this->ConvertToRelativeForMake(cdir);
- std::string makecmd = "make -C ";
- makecmd += cdir;
- makecmd += " -f ";
- makecmd += this->ConvertToRelativeForMake((makefile + "$CONFIGURATION"));
- makecmd += " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\")";
- makecmd += " all";
+ std::string makecmd =
+ cmStrCat("make -C ", cdir, " -f ",
+ this->ConvertToRelativeForMake((makefile + "$CONFIGURATION")),
+ " OBJDIR=$(basename \"$OBJECT_FILE_DIR_normal\") all");
buildphase->AddAttribute("shellScript", this->CreateString(makecmd));
buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0"));
}
@@ -1668,8 +1647,7 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
const char* makefileBasename, cmGeneratorTarget* target,
std::vector<cmCustomCommand> const& commands, const std::string& configName)
{
- std::string makefileName = makefileBasename;
- makefileName += configName;
+ std::string makefileName = cmStrCat(makefileBasename, configName);
cmGeneratedFileStream makefileStream(makefileName);
if (!makefileStream) {
return;
@@ -1732,9 +1710,10 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
makefileStream << "\n";
if (const char* comment = ccg.GetComment()) {
- std::string echo_cmd = "echo ";
- echo_cmd += (this->CurrentLocalGenerator->EscapeForShell(
- comment, ccg.GetCC().GetEscapeAllowMakeVars()));
+ std::string echo_cmd =
+ cmStrCat("echo ",
+ (this->CurrentLocalGenerator->EscapeForShell(
+ comment, ccg.GetCC().GetEscapeAllowMakeVars())));
makefileStream << "\t" << echo_cmd << "\n";
}
@@ -1775,8 +1754,7 @@ void cmGlobalXCodeGenerator::AddPositionIndependentLinkAttribute(
}
buildSettings->AddAttribute(
- "LD_NO_PIE",
- this->CreateString(cmSystemTools::IsOn(PICValue) ? "NO" : "YES"));
+ "LD_NO_PIE", this->CreateString(cmIsOn(PICValue) ? "NO" : "YES"));
}
void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
@@ -1883,8 +1861,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
targetLinkFlags);
}
if (!configName.empty()) {
- std::string linkFlagsVar = "LINK_FLAGS_";
- linkFlagsVar += cmSystemTools::UpperCase(configName);
+ std::string linkFlagsVar =
+ cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName));
if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) {
this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
}
@@ -2136,8 +2114,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
for (auto& include : includes) {
if (this->NameResolvesToFramework(include)) {
- std::string frameworkDir = include;
- frameworkDir += "/../";
+ std::string frameworkDir = cmStrCat(include, "/../");
frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
if (emitted.insert(frameworkDir).second) {
std::string incpath = this->XCodeEscapePath(frameworkDir);
@@ -2249,7 +2226,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// extract C++ stdlib
for (auto const& language : languages) {
- if (language != "CXX") {
+ if (language != "CXX" && language != "OBJCXX") {
continue;
}
std::string& flags = cflags[language];
@@ -2258,8 +2235,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->ExtractFlagRegex("(^| )(-stdlib=[^ ]+)( |$)", 2, flags);
if (stdlib.size() > 8) {
const auto cxxLibrary = stdlib.substr(8);
- buildSettings->AddAttribute("CLANG_CXX_LIBRARY",
- this->CreateString(cxxLibrary));
+ if (language == "CXX" ||
+ !buildSettings->GetObject("CLANG_CXX_LIBRARY")) {
+ buildSettings->AddAttribute("CLANG_CXX_LIBRARY",
+ this->CreateString(cxxLibrary));
+ }
}
}
@@ -2273,16 +2253,22 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CreateString("NO"));
buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
this->CreateString("NO"));
+
for (auto const& language : languages) {
std::string flags = cflags[language] + " " + defFlags;
- if (language == "CXX") {
- buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
- this->CreateString(flags));
+ if (language == "CXX" || language == "OBJCXX") {
+ if (language == "CXX" ||
+ !buildSettings->GetObject("OTHER_CPLUSPLUSFLAGS")) {
+ buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
+ this->CreateString(flags));
+ }
} else if (language == "Fortran") {
buildSettings->AddAttribute("IFORT_OTHER_FLAGS",
this->CreateString(flags));
- } else if (language == "C") {
- buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags));
+ } else if (language == "C" || language == "OBJC") {
+ if (language == "C" || !buildSettings->GetObject("OTHER_CFLAGS")) {
+ buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags));
+ }
} else if (language == "Swift") {
buildSettings->AddAttribute("OTHER_SWIFT_FLAGS",
this->CreateString(flags));
@@ -2401,6 +2387,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
this->CreateString(vso.str()));
}
+
+ // Precompile Headers
+ std::string pchHeader = gtgt->GetPchHeader(configName, llang);
+ if (!pchHeader.empty()) {
+ buildSettings->AddAttribute("GCC_PREFIX_HEADER",
+ this->CreateString(pchHeader));
+ buildSettings->AddAttribute("GCC_PRECOMPILE_PREFIX_HEADER",
+ this->CreateString("YES"));
+ }
+
// put this last so it can override existing settings
// Convert "XCODE_ATTRIBUTE_*" properties directly.
{
@@ -2409,10 +2405,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string attribute = prop.substr(16);
this->FilterConfigurationAttribute(configName, attribute);
if (!attribute.empty()) {
- cmGeneratorExpression ge;
- std::string processed =
- ge.Parse(gtgt->GetProperty(prop))
- ->Evaluate(this->CurrentLocalGenerator, configName);
+ std::string processed = cmGeneratorExpression::Evaluate(
+ gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName);
buildSettings->AddAttribute(attribute,
this->CreateString(processed));
}
@@ -2483,20 +2477,16 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
cmGeneratorTarget* gtgt)
{
- std::vector<std::string> const configVector =
- cmSystemTools::ExpandedListArgument(
- this->CurrentMakefile->GetRequiredDefinition(
- "CMAKE_CONFIGURATION_TYPES"));
+ std::vector<std::string> const configVector = cmExpandedList(
+ this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES"));
cmXCodeObject* configlist =
this->CreateObject(cmXCodeObject::XCConfigurationList);
cmXCodeObject* buildConfigurations =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
configlist->AddAttribute("buildConfigurations", buildConfigurations);
- std::string comment = "Build configuration list for ";
- comment += cmXCodeObject::PBXTypeNames[target->GetIsA()];
- comment += " \"";
- comment += gtgt->GetName();
- comment += "\"";
+ std::string comment = cmStrCat("Build configuration list for ",
+ cmXCodeObject::PBXTypeNames[target->GetIsA()],
+ " \"", gtgt->GetName(), '"');
configlist->SetComment(comment);
target->AddAttribute("buildConfigurationList",
this->CreateObjectReference(configlist));
@@ -2624,9 +2614,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
}
std::string fullName;
if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- fullName = "lib";
- fullName += gtgt->GetName();
- fullName += ".a";
+ fullName = cmStrCat("lib", gtgt->GetName(), ".a");
} else {
fullName = gtgt->GetFullName(defConfig);
}
@@ -2652,8 +2640,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(
return nullptr;
}
- std::map<cmGeneratorTarget const*, cmXCodeObject*>::const_iterator const i =
- this->XCodeObjectMap.find(t);
+ auto const i = this->XCodeObjectMap.find(t);
if (i == this->XCodeObjectMap.end()) {
return nullptr;
}
@@ -2663,8 +2650,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(
std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name,
const std::string& id)
{
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
+ std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
const char* storedGUID =
this->CMakeInstance->GetCacheDefinition(guidStoreName);
@@ -2719,9 +2705,7 @@ void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
if (!attr) {
settings->AddAttribute(attribute, this->CreateString(value));
} else {
- std::string oldValue = attr->GetString();
- oldValue += " ";
- oldValue += value;
+ std::string oldValue = cmStrCat(attr->GetString(), ' ', value);
attr->SetString(oldValue);
}
}
@@ -2886,17 +2870,19 @@ bool cmGlobalXCodeGenerator::CreateGroups(
// Add CMakeLists.txt file for user convenience.
{
std::string listfile =
- gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(listfile);
- addSourceToGroup(sf->GetFullPath());
+ cmStrCat(gtgt->GetLocalGenerator()->GetCurrentSourceDirectory(),
+ "/CMakeLists.txt");
+ cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
+ listfile, false, cmSourceFileLocationKind::Known);
+ addSourceToGroup(sf->ResolveFullPath());
}
// Add the Info.plist we are about to generate for an App Bundle.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
std::string plist = this->ComputeInfoPListLocation(gtgt);
- cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(plist, true);
- addSourceToGroup(sf->GetFullPath());
+ cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
+ plist, true, cmSourceFileLocationKind::Known);
+ addSourceToGroup(sf->ResolveFullPath());
}
}
}
@@ -2929,14 +2915,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
std::string target;
const std::string targetFolder = gtgt->GetEffectiveFolderName();
if (!targetFolder.empty()) {
- target = targetFolder;
- target += "/";
+ target = cmStrCat(targetFolder, '/');
}
target += gtgt->GetName();
- s = target + "/";
- s += sg->GetFullName();
- std::map<std::string, cmXCodeObject*>::iterator it =
- this->GroupNameMap.find(s);
+ s = cmStrCat(target, '/', sg->GetFullName());
+ auto it = this->GroupNameMap.find(s);
if (it != this->GroupNameMap.end()) {
return it->second;
}
@@ -2946,8 +2929,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
if (it != this->TargetGroup.end()) {
tgroup = it->second;
} else {
- std::vector<std::string> tgt_folders =
- cmSystemTools::tokenize(target, "/");
+ std::vector<std::string> tgt_folders = cmTokenize(target, "/");
std::string curr_tgt_folder;
for (std::vector<std::string>::size_type i = 0; i < tgt_folders.size();
i++) {
@@ -2979,13 +2961,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
// It's a recursive folder structure, let's find the real parent group
if (sg->GetFullName() != sg->GetName()) {
- std::string curr_folder = target;
- curr_folder += "/";
- for (auto const& folder :
- cmSystemTools::tokenize(sg->GetFullName(), "\\")) {
+ std::string curr_folder = cmStrCat(target, '/');
+ for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) {
curr_folder += folder;
- std::map<std::string, cmXCodeObject*>::iterator i_folder =
- this->GroupNameMap.find(curr_folder);
+ auto const i_folder = this->GroupNameMap.find(curr_folder);
// Create new folder
if (i_folder == this->GroupNameMap.end()) {
cmXCodeObject* group = this->CreatePBXGroup(tgroup, folder);
@@ -2994,7 +2973,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
} else {
tgroup = i_folder->second;
}
- curr_folder = curr_folder + "\\";
+ curr_folder += "\\";
}
return tgroup;
}
@@ -3046,8 +3025,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
this->RootObject->SetComment("Project object");
- std::string project_id = "PROJECT_";
- project_id += root->GetProjectName();
+ std::string project_id = cmStrCat("PROJECT_", root->GetProjectName());
this->RootObject->SetId(
this->GetOrCreateId(project_id, this->RootObject->GetId()));
@@ -3078,7 +3056,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->CreateObject(cmXCodeObject::XCConfigurationList);
cmXCodeObject* buildConfigurations =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
- typedef std::vector<std::pair<std::string, cmXCodeObject*>> Configs;
+ using Configs = std::vector<std::pair<std::string, cmXCodeObject*>>;
Configs configs;
std::string defaultConfigName;
for (const auto& name : this->CurrentConfigurationTypes) {
@@ -3098,10 +3076,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
}
configlist->AddAttribute("buildConfigurations", buildConfigurations);
- std::string comment = "Build configuration list for PBXProject";
- comment += " \"";
- comment += this->CurrentProject;
- comment += "\"";
+ std::string comment = cmStrCat("Build configuration list for PBXProject \"",
+ this->CurrentProject, '"');
configlist->SetComment(comment);
configlist->AddAttribute("defaultConfigurationIsVisible",
this->CreateString("0"));
@@ -3150,8 +3126,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
this->CreateString(swiftVersion));
}
- std::string symroot = root->GetCurrentBinaryDirectory();
- symroot += "/build";
+ std::string symroot = cmStrCat(root->GetCurrentBinaryDirectory(), "/build");
buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot));
for (auto& config : configs) {
@@ -3164,10 +3139,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
std::string attribute = var.substr(22);
this->FilterConfigurationAttribute(config.first, attribute);
if (!attribute.empty()) {
- cmGeneratorExpression ge;
- std::string processed =
- ge.Parse(this->CurrentMakefile->GetDefinition(var))
- ->Evaluate(this->CurrentLocalGenerator, config.first);
+ std::string processed = cmGeneratorExpression::Evaluate(
+ this->CurrentMakefile->GetDefinition(var),
+ this->CurrentLocalGenerator, config.first);
buildSettingsForCfg->AddAttribute(attribute,
this->CreateString(processed));
}
@@ -3208,15 +3182,9 @@ std::string cmGlobalXCodeGenerator::GetObjectsDirectory(
const std::string& projName, const std::string& configName,
const cmGeneratorTarget* t, const std::string& variant) const
{
- std::string dir = t->GetLocalGenerator()->GetCurrentBinaryDirectory();
- dir += "/";
- dir += projName;
- dir += ".build/";
- dir += configName;
- dir += "/";
- dir += t->GetName();
- dir += ".build/";
- dir += variant;
+ std::string dir = cmStrCat(
+ t->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/', projName,
+ ".build/", configName, '/', t->GetName(), ".build/", variant);
return dir;
}
@@ -3226,8 +3194,7 @@ void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf)
const char* osxArch = mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
const char* sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT");
if (osxArch && sysroot) {
- cmSystemTools::ExpandListArgument(std::string(osxArch),
- this->Architectures);
+ cmExpandList(std::string(osxArch), this->Architectures);
}
if (this->Architectures.empty()) {
@@ -3308,8 +3275,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::string trel = this->ConvertToRelativeForMake(tfull);
// Add this target to the post-build phases of its dependencies.
- std::map<std::string, cmXCodeObject::StringVec>::const_iterator y =
- target->GetDependTargets().find(configName);
+ auto const y = target->GetDependTargets().find(configName);
if (y != target->GetDependTargets().end()) {
for (auto const& deptgt : y->second) {
makefileStream << this->PostBuildMakeTarget(deptgt, configName)
@@ -3329,8 +3295,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
makefileStream << trel << ":";
// List dependencies if any exist.
- std::map<std::string, cmXCodeObject::StringVec>::const_iterator x =
- target->GetDependLibraries().find(configName);
+ auto const x = target->GetDependLibraries().find(configName);
if (x != target->GetDependLibraries().end()) {
for (auto const& deplib : x->second) {
std::string file = this->ConvertToRelativeForMake(deplib);
@@ -3342,12 +3307,10 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
for (auto objLib : objlibs) {
const std::string objLibName = objLib->GetName();
- std::string d =
+ std::string d = cmStrCat(
this->GetObjectsDirectory(this->CurrentProject, configName, objLib,
- OBJECT_LIBRARY_ARTIFACT_DIR);
- d += "lib";
- d += objLibName;
- d += ".a";
+ OBJECT_LIBRARY_ARTIFACT_DIR),
+ "lib", objLibName, ".a");
std::string dependency = this->ConvertToRelativeForMake(d);
makefileStream << "\\\n\t" << dependency;
@@ -3364,10 +3327,8 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::string universal = this->GetObjectsDirectory(
this->CurrentProject, configName, gt, "$(OBJDIR)/");
for (const auto& architecture : this->Architectures) {
- std::string universalFile = universal;
- universalFile += architecture;
- universalFile += "/";
- universalFile += gt->GetFullName(configName);
+ std::string universalFile = cmStrCat(universal, architecture, '/',
+ gt->GetFullName(configName));
makefileStream << "\t/bin/rm -f "
<< this->ConvertToRelativeForMake(universalFile)
<< "\n";
@@ -3395,10 +3356,8 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
if (!this->CreateXCodeObjects(root, generators)) {
return;
}
- std::string xcodeDir = root->GetCurrentBinaryDirectory();
- xcodeDir += "/";
- xcodeDir += root->GetProjectName();
- xcodeDir += ".xcodeproj";
+ std::string xcodeDir = cmStrCat(root->GetCurrentBinaryDirectory(), '/',
+ root->GetProjectName(), ".xcodeproj");
cmSystemTools::MakeDirectory(xcodeDir);
std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
cmGeneratedFileStream fout(xcodeProjFile);
@@ -3472,12 +3431,12 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
void cmGlobalXCodeGenerator::OutputXCodeWorkspaceSettings(
const std::string& xcProjDir, bool hasGeneratedSchemes)
{
- std::string xcodeSharedDataDir = xcProjDir;
- xcodeSharedDataDir += "/project.xcworkspace/xcshareddata";
+ std::string xcodeSharedDataDir =
+ cmStrCat(xcProjDir, "/project.xcworkspace/xcshareddata");
cmSystemTools::MakeDirectory(xcodeSharedDataDir);
- std::string workspaceSettingsFile = xcodeSharedDataDir;
- workspaceSettingsFile += "/WorkspaceSettings.xcsettings";
+ std::string workspaceSettingsFile =
+ cmStrCat(xcodeSharedDataDir, "/WorkspaceSettings.xcsettings");
cmGeneratedFileStream fout(workspaceSettingsFile);
fout.SetCopyIfDifferent(true);
@@ -3583,9 +3542,7 @@ std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p)
{
if (p.find(' ') != std::string::npos) {
- std::string t = "\"";
- t += p;
- t += "\"";
+ std::string t = cmStrCat('"', p, '"');
return t;
}
return p;
@@ -3607,9 +3564,7 @@ std::string cmGlobalXCodeGenerator::LookupFlags(
const std::string& varNameSuffix, const std::string& default_flags)
{
if (!varNameLang.empty()) {
- std::string varName = varNamePrefix;
- varName += varNameLang;
- varName += varNameSuffix;
+ std::string varName = cmStrCat(varNamePrefix, varNameLang, varNameSuffix);
if (const char* varValue = this->CurrentMakefile->GetDefinition(varName)) {
if (*varValue) {
return varValue;
@@ -3629,8 +3584,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
}
// Expand the list of definitions.
- std::vector<std::string> defines;
- cmSystemTools::ExpandListArgument(defines_list, defines);
+ std::vector<std::string> defines = cmExpandedList(defines_list);
// Store the definitions in the string.
this->AppendDefines(defs, defines, dflag);
@@ -3644,8 +3598,7 @@ void cmGlobalXCodeGenerator::AppendDefines(
std::string def;
for (auto const& define : defines) {
// Start with -D if requested.
- def = dflag ? "-D" : "";
- def += define;
+ def = cmStrCat(dflag ? "-D" : "", define);
// Append the flag with needed escapes.
std::string tmp;
@@ -3706,11 +3659,9 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
std::string cmGlobalXCodeGenerator::ComputeInfoPListLocation(
cmGeneratorTarget* target)
{
- std::string plist = target->GetLocalGenerator()->GetCurrentBinaryDirectory();
- plist += "/CMakeFiles";
- plist += "/";
- plist += target->GetName();
- plist += ".dir/Info.plist";
+ std::string plist =
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", target->GetName(), ".dir/Info.plist");
return plist;
}
@@ -3744,7 +3695,7 @@ bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
return mf->PlatformIsAppleEmbedded();
}
- return cmSystemTools::IsOn(epnValue);
+ return cmIsOn(epnValue);
}
bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
@@ -3757,10 +3708,10 @@ void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
std::string configName = this->GetCMakeCFGIntDir();
- std::string dir = this->GetObjectsDirectory(
- "$(PROJECT_NAME)", configName, gt, "$(OBJECT_FILE_DIR_normal:base)/");
- dir += this->ObjectDirArch;
- dir += "/";
+ std::string dir =
+ cmStrCat(this->GetObjectsDirectory("$(PROJECT_NAME)", configName, gt,
+ "$(OBJECT_FILE_DIR_normal:base)/"),
+ this->ObjectDirArch, '/');
gt->ObjectDirectory = dir;
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 71446f997..af905d00c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -122,13 +122,11 @@ private:
std::string RelativeToSource(const std::string& p);
std::string RelativeToBinary(const std::string& p);
std::string ConvertToRelativeForMake(std::string const& p);
- void CreateCustomCommands(cmXCodeObject* buildPhases,
- cmXCodeObject* sourceBuildPhase,
- cmXCodeObject* headerBuildPhase,
- cmXCodeObject* resourceBuildPhase,
- std::vector<cmXCodeObject*> contentBuildPhases,
- cmXCodeObject* frameworkBuildPhase,
- cmGeneratorTarget* gtgt);
+ void CreateCustomCommands(
+ cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase,
+ cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase,
+ std::vector<cmXCodeObject*> const& contentBuildPhases,
+ cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt);
std::string ComputeInfoPListLocation(cmGeneratorTarget* target);
diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h
index 5ca9269ed..5ed6af461 100644
--- a/Source/cmGraphAdjacencyList.h
+++ b/Source/cmGraphAdjacencyList.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmListFileCache.h"
-
#include <utility>
#include <vector>
+#include "cmListFileCache.h"
+
/**
* Graph edge representation. Most use cases just need the
* destination vertex, so we support conversion to/from an int. We
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index a75d8a97a..e0d545d86 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -4,7 +4,7 @@
#include <cstddef>
#include <iostream>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
#include <utility>
@@ -15,6 +15,7 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -73,7 +74,8 @@ std::map<std::string, LinkLibraryScopeType> getScopedLinkLibrariesFromTarget(
{
char sep = ';';
std::map<std::string, LinkLibraryScopeType> tokens;
- size_t start = 0, end = 0;
+ size_t start = 0;
+ size_t end = 0;
const char* pInterfaceLinkLibraries =
Target->GetProperty("INTERFACE_LINK_LIBRARIES");
@@ -233,9 +235,8 @@ void cmGraphVizWriter::ReadSettings(
this->TargetsToIgnoreRegex.clear();
if (!ignoreTargetsRegexes.empty()) {
- std::vector<std::string> ignoreTargetsRegExVector;
- cmSystemTools::ExpandListArgument(ignoreTargetsRegexes,
- ignoreTargetsRegExVector);
+ std::vector<std::string> ignoreTargetsRegExVector =
+ cmExpandedList(ignoreTargetsRegexes);
for (std::string const& currentRegexString : ignoreTargetsRegExVector) {
cmsys::RegularExpression currentRegex;
if (!currentRegex.compile(currentRegexString)) {
@@ -266,10 +267,8 @@ void cmGraphVizWriter::WriteTargetDependersFiles(const std::string& fileName)
continue;
}
- std::string currentFilename = fileName;
- currentFilename += ".";
- currentFilename += ptr.first;
- currentFilename += ".dependers";
+ std::string currentFilename =
+ cmStrCat(fileName, '.', ptr.first, ".dependers");
cmGeneratedFileStream str(currentFilename);
if (!str) {
@@ -311,9 +310,7 @@ void cmGraphVizWriter::WritePerTargetFiles(const std::string& fileName)
std::set<std::string> insertedConnections;
std::set<std::string> insertedNodes;
- std::string currentFilename = fileName;
- currentFilename += ".";
- currentFilename += ptr.first;
+ std::string currentFilename = cmStrCat(fileName, '.', ptr.first);
cmGeneratedFileStream str(currentFilename);
if (!str) {
return;
@@ -371,8 +368,7 @@ void cmGraphVizWriter::WriteConnections(
const std::string& targetName, std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
{
- std::map<std::string, const cmGeneratorTarget*>::const_iterator targetPtrIt =
- this->TargetPtrs.find(targetName);
+ auto targetPtrIt = this->TargetPtrs.find(targetName);
if (targetPtrIt == this->TargetPtrs.end()) // not found at all
{
@@ -393,17 +389,14 @@ void cmGraphVizWriter::WriteConnections(
for (auto const& llit : ll) {
const std::string& libName = llit.first;
- std::map<std::string, std::string>::const_iterator libNameIt =
- this->TargetNamesNodes.find(libName);
+ auto libNameIt = this->TargetNamesNodes.find(libName);
// can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
if (libNameIt == this->TargetNamesNodes.end()) {
continue;
}
- std::string connectionName = myNodeName;
- connectionName += "-";
- connectionName += libNameIt->second;
+ std::string connectionName = cmStrCat(myNodeName, '-', libNameIt->second);
if (insertedConnections.find(connectionName) ==
insertedConnections.end()) {
insertedConnections.insert(connectionName);
@@ -424,8 +417,7 @@ void cmGraphVizWriter::WriteDependerConnections(
const std::string& targetName, std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
{
- std::map<std::string, const cmGeneratorTarget*>::const_iterator targetPtrIt =
- this->TargetPtrs.find(targetName);
+ auto targetPtrIt = this->TargetPtrs.find(targetName);
if (targetPtrIt == this->TargetPtrs.end()) // not found at all
{
@@ -459,13 +451,11 @@ void cmGraphVizWriter::WriteDependerConnections(
for (auto const& llit : ll) {
if (llit.first == targetName) {
// So this target links against targetName.
- std::map<std::string, std::string>::const_iterator dependerNodeNameIt =
- this->TargetNamesNodes.find(tptr.first);
+ auto dependerNodeNameIt = this->TargetNamesNodes.find(tptr.first);
if (dependerNodeNameIt != this->TargetNamesNodes.end()) {
- std::string connectionName = dependerNodeNameIt->second;
- connectionName += "-";
- connectionName += myNodeName;
+ std::string connectionName =
+ cmStrCat(dependerNodeNameIt->second, '-', myNodeName);
if (insertedConnections.find(connectionName) ==
insertedConnections.end()) {
@@ -493,8 +483,7 @@ void cmGraphVizWriter::WriteNode(const std::string& targetName,
{
if (insertedNodes.find(targetName) == insertedNodes.end()) {
insertedNodes.insert(targetName);
- std::map<std::string, std::string>::const_iterator nameIt =
- this->TargetNamesNodes.find(targetName);
+ auto nameIt = this->TargetNamesNodes.find(targetName);
str << " \"" << nameIt->second << "\" [ label=\"" << targetName
<< "\" shape=\"" << getShapeForTarget(target) << "\"];" << std::endl;
@@ -562,8 +551,7 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
}
}
- std::map<std::string, const cmGeneratorTarget*>::const_iterator tarIt =
- this->TargetPtrs.find(libName);
+ auto tarIt = this->TargetPtrs.find(libName);
if (tarIt == this->TargetPtrs.end()) {
std::ostringstream ostr;
ostr << this->GraphNodePrefix << cnt++;
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 768683a3b..9c3051f2c 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -5,14 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmStateTypes.h"
-
-#include "cmsys/RegularExpression.hxx"
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmStateTypes.h"
+
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLocalGenerator;
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
index 190f2e305..2fa4b5505 100644
--- a/Source/cmHexFileConverter.cxx
+++ b/Source/cmHexFileConverter.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmHexFileConverter.h"
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
#include "cmSystemTools.h"
diff --git a/Source/cmHexFileConverter.h b/Source/cmHexFileConverter.h
index cb5de8f34..26f9ea8ba 100644
--- a/Source/cmHexFileConverter.h
+++ b/Source/cmHexFileConverter.h
@@ -4,6 +4,7 @@
#define cmHexFileConverter_h
#include "cmConfigure.h" // IWYU pragma: keep
+
#include <string>
/** \class cmHexFileConverter
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 7b992d743..71326d23a 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -2,13 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIDEOptions.h"
-#include "cmsys/String.h"
#include <iterator>
+
#include <string.h>
+#include "cmsys/String.h"
+
#include "cmAlgorithms.h"
#include "cmIDEFlagTable.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
cmIDEOptions::cmIDEOptions()
{
@@ -166,7 +168,7 @@ void cmIDEOptions::AddDefines(std::string const& defines)
{
if (!defines.empty()) {
// Expand the list of definitions.
- cmSystemTools::ExpandListArgument(defines, this->Defines);
+ cmExpandList(defines, this->Defines);
}
}
void cmIDEOptions::AddDefines(const std::vector<std::string>& defines)
@@ -188,7 +190,7 @@ void cmIDEOptions::AddIncludes(std::string const& includes)
{
if (!includes.empty()) {
// Expand the list of includes.
- cmSystemTools::ExpandListArgument(includes, this->Includes);
+ cmExpandList(includes, this->Includes);
}
}
void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes)
diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h
index 4a430732f..f949ae3dd 100644
--- a/Source/cmIDEOptions.h
+++ b/Source/cmIDEOptions.h
@@ -51,7 +51,7 @@ protected:
// and overwrite or add new values to this map
class FlagValue : public std::vector<std::string>
{
- typedef std::vector<std::string> derived;
+ using derived = std::vector<std::string>;
public:
FlagValue& operator=(std::string const& r)
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index d1f8f58e2..290e064b4 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -2,17 +2,26 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIfCommand.h"
+#include <string>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <memory> // IWYU pragma: keep
-
static std::string cmIfCommandError(
std::vector<cmExpandedCommandArgument> const& args)
{
@@ -25,192 +34,178 @@ static std::string cmIfCommandError(
return err;
}
-//=========================================================================
-bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+class cmIfFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cm::string_view StartCommandName() const override { return "if"_s; }
+ cm::string_view EndCommandName() const override { return "endif"_s; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+ std::vector<cmListFileArgument> Args;
+ bool IsBlocking;
+ bool HasRun = false;
+ bool ElseSeen = false;
+};
+
+bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const
{
- // we start by recording all the functions
- if (lff.Name.Lower == "if") {
- this->ScopeDepth++;
- } else if (lff.Name.Lower == "endif") {
- this->ScopeDepth--;
- // if this is the endif for this if statement, then start executing
- if (!this->ScopeDepth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
+ return lff.Arguments.empty() || lff.Arguments == this->Args;
+}
+
+bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus)
+{
+ cmMakefile& mf = inStatus.GetMakefile();
+ // execute the functions for the true parts of the if statement
+ int scopeDepth = 0;
+ for (cmListFileFunction const& func : functions) {
+ // keep track of scope depth
+ if (func.Name.Lower == "if") {
+ scopeDepth++;
+ }
+ if (func.Name.Lower == "endif") {
+ scopeDepth--;
+ }
+ // watch for our state change
+ if (scopeDepth == 0 && func.Name.Lower == "else") {
+
+ if (this->ElseSeen) {
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "A duplicate ELSE command was found inside an IF block.", bt);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
}
- // execute the functions for the true parts of the if statement
- cmExecutionStatus status;
- int scopeDepth = 0;
- for (cmListFileFunction const& func : this->Functions) {
- // keep track of scope depth
- if (func.Name.Lower == "if") {
- scopeDepth++;
- }
- if (func.Name.Lower == "endif") {
- scopeDepth--;
+ this->IsBlocking = this->HasRun;
+ this->HasRun = true;
+ this->ElseSeen = true;
+
+ // if trace is enabled, print a (trivially) evaluated "else"
+ // statement
+ if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
+ mf.PrintCommandTrace(func);
+ }
+ } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
+ if (this->ElseSeen) {
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "An ELSEIF command was found after an ELSE command.", bt);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ if (this->HasRun) {
+ this->IsBlocking = true;
+ } else {
+ // if trace is enabled, print the evaluated "elseif" statement
+ if (mf.GetCMakeInstance()->GetTrace()) {
+ mf.PrintCommandTrace(func);
}
- // watch for our state change
- if (scopeDepth == 0 && func.Name.Lower == "else") {
-
- if (this->ElseSeen) {
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- "A duplicate ELSE command was found inside an IF block.", bt);
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- this->IsBlocking = this->HasRun;
- this->HasRun = true;
- this->ElseSeen = true;
+ std::string errorString;
- // if trace is enabled, print a (trivially) evaluated "else"
- // statement
- if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
- }
- } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
- if (this->ElseSeen) {
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- "An ELSEIF command was found after an ELSE command.", bt);
+ std::vector<cmExpandedCommandArgument> expandedArguments;
+ mf.ExpandArguments(func.Arguments, expandedArguments);
+
+ MessageType messType;
+
+ cmListFileContext conditionContext =
+ cmListFileContext::FromCommandContext(
+ func, this->GetStartingContext().FilePath);
+
+ cmConditionEvaluator conditionEvaluator(mf, conditionContext,
+ mf.GetBacktrace(func));
+
+ bool isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messType);
+
+ if (!errorString.empty()) {
+ std::string err =
+ cmStrCat(cmIfCommandError(expandedArguments), errorString);
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
+ if (messType == MessageType::FATAL_ERROR) {
cmSystemTools::SetFatalErrorOccured();
return true;
}
-
- if (this->HasRun) {
- this->IsBlocking = true;
- } else {
- // if trace is enabled, print the evaluated "elseif" statement
- if (mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
- }
-
- std::string errorString;
-
- std::vector<cmExpandedCommandArgument> expandedArguments;
- mf.ExpandArguments(func.Arguments, expandedArguments);
-
- MessageType messType;
-
- cmListFileContext conditionContext =
- cmListFileContext::FromCommandContext(
- func, this->GetStartingContext().FilePath);
-
- cmConditionEvaluator conditionEvaluator(mf, conditionContext,
- mf.GetBacktrace(func));
-
- bool isTrue = conditionEvaluator.IsTrue(expandedArguments,
- errorString, messType);
-
- if (!errorString.empty()) {
- std::string err = cmIfCommandError(expandedArguments);
- err += errorString;
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
- if (messType == MessageType::FATAL_ERROR) {
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- }
-
- if (isTrue) {
- this->IsBlocking = false;
- this->HasRun = true;
- }
- }
}
- // should we execute?
- else if (!this->IsBlocking) {
- status.Clear();
- mf.ExecuteCommand(func, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- return true;
- }
- if (status.GetBreakInvoked()) {
- inStatus.SetBreakInvoked();
- return true;
- }
- if (status.GetContinueInvoked()) {
- inStatus.SetContinueInvoked();
- return true;
- }
+ if (isTrue) {
+ this->IsBlocking = false;
+ this->HasRun = true;
}
}
- return true;
}
- }
- // record the command
- this->Functions.push_back(lff);
-
- // always return true
- return true;
-}
-
-//=========================================================================
-bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile&)
-{
- if (lff.Name.Lower == "endif") {
- // if the endif has arguments, then make sure
- // they match the arguments of the matching if
- if (lff.Arguments.empty() || lff.Arguments == this->Args) {
- return true;
+ // should we execute?
+ else if (!this->IsBlocking) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(func, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ inStatus.SetBreakInvoked();
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ inStatus.SetContinueInvoked();
+ return true;
+ }
}
}
-
- return false;
+ return true;
}
//=========================================================================
-bool cmIfCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus)
{
+ cmMakefile& makefile = inStatus.GetMakefile();
std::string errorString;
std::vector<cmExpandedCommandArgument> expandedArguments;
- this->Makefile->ExpandArguments(args, expandedArguments);
+ makefile.ExpandArguments(args, expandedArguments);
MessageType status;
cmConditionEvaluator conditionEvaluator(
- *(this->Makefile), this->Makefile->GetExecutionContext(),
- this->Makefile->GetBacktrace());
+ makefile, makefile.GetExecutionContext(), makefile.GetBacktrace());
bool isTrue =
conditionEvaluator.IsTrue(expandedArguments, errorString, status);
if (!errorString.empty()) {
- std::string err = "if " + cmIfCommandError(expandedArguments);
- err += errorString;
+ std::string err =
+ cmStrCat("if ", cmIfCommandError(expandedArguments), errorString);
if (status == MessageType::FATAL_ERROR) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err);
+ makefile.IssueMessage(MessageType::FATAL_ERROR, err);
cmSystemTools::SetFatalErrorOccured();
return true;
}
- this->Makefile->IssueMessage(status, err);
+ makefile.IssueMessage(status, err);
}
- cmIfFunctionBlocker* f = new cmIfFunctionBlocker();
- // if is isn't true block the commands
- f->ScopeDepth = 1;
- f->IsBlocking = !isTrue;
- if (isTrue) {
- f->HasRun = true;
+ {
+ auto fb = cm::make_unique<cmIfFunctionBlocker>();
+ // if is isn't true block the commands
+ fb->IsBlocking = !isTrue;
+ if (isTrue) {
+ fb->HasRun = true;
+ }
+ fb->Args = args;
+ makefile.AddFunctionBlocker(std::move(fb));
}
- f->Args = args;
- this->Makefile->AddFunctionBlocker(f);
return true;
}
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index d34ed02c8..820ffa4c6 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -5,61 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmExpandedCommandArgument;
-class cmMakefile;
-
-class cmIfFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<cmListFileArgument> Args;
- std::vector<cmListFileFunction> Functions;
- bool IsBlocking;
- bool HasRun = false;
- bool ElseSeen = false;
- unsigned int ScopeDepth = 0;
-};
+struct cmListFileArgument;
/// Starts an if block
-class cmIfCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIfCommand; }
-
- /**
- * This overrides the default InvokeInitialPass implementation.
- * It records the arguments before expansion.
- */
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
-
- // Filter the given variable definition based on policy CMP0054.
- static const char* GetDefinitionIfUnquoted(
- const cmMakefile* mf, cmExpandedCommandArgument const& argument);
-};
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 0d608bb9d..14264f487 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -4,21 +4,21 @@
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmIncludeCommand
-bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmIncludeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty() || args.size() > 4) {
- this->SetError("called with wrong number of arguments. "
- "include() only takes one file.");
+ status.SetError("called with wrong number of arguments. "
+ "include() only takes one file.");
return false;
}
bool optional = false;
@@ -29,20 +29,20 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
for (unsigned int i = 1; i < args.size(); i++) {
if (args[i] == "OPTIONAL") {
if (optional) {
- this->SetError("called with invalid arguments: OPTIONAL used twice");
+ status.SetError("called with invalid arguments: OPTIONAL used twice");
return false;
}
optional = true;
} else if (args[i] == "RESULT_VARIABLE") {
if (!resultVarName.empty()) {
- this->SetError("called with invalid arguments: "
- "only one result variable allowed");
+ status.SetError("called with invalid arguments: "
+ "only one result variable allowed");
return false;
}
if (++i < args.size()) {
resultVarName = args[i];
} else {
- this->SetError("called with no value for RESULT_VARIABLE.");
+ status.SetError("called with no value for RESULT_VARIABLE.");
return false;
}
} else if (args[i] == "NO_POLICY_SCOPE") {
@@ -50,39 +50,39 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
} else if (i > 1) // compat.: in previous cmake versions the second
// parameter was ignored if it wasn't "OPTIONAL"
{
- std::string errorText = "called with invalid argument: ";
- errorText += args[i];
- this->SetError(errorText);
+ std::string errorText =
+ cmStrCat("called with invalid argument: ", args[i]);
+ status.SetError(errorText);
return false;
}
}
if (fname.empty()) {
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- "include() given empty file name (ignored).");
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "include() given empty file name (ignored).");
return true;
}
if (!cmSystemTools::FileIsFullPath(fname)) {
// Not a path. Maybe module.
- std::string module = fname;
- module += ".cmake";
- std::string mfile = this->Makefile->GetModulesFile(module);
+ std::string module = cmStrCat(fname, ".cmake");
+ std::string mfile = status.GetMakefile().GetModulesFile(module);
if (!mfile.empty()) {
fname = mfile;
}
}
std::string fname_abs = cmSystemTools::CollapseFullPath(
- fname, this->Makefile->GetCurrentSourceDirectory());
+ fname, status.GetMakefile().GetCurrentSourceDirectory());
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
if (gg->IsExportedTargetsFile(fname_abs)) {
const char* modal = nullptr;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0024)) {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0024)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n";
modal = "should";
@@ -102,7 +102,7 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
<< " not be used as the argument to the "
"include() command. Use ALIAS targets instead to refer to targets "
"by alternative names.\n";
- this->Makefile->IssueMessage(messageType, e.str());
+ status.GetMakefile().IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
@@ -112,27 +112,28 @@ bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
}
std::string listFile = cmSystemTools::CollapseFullPath(
- fname, this->Makefile->GetCurrentSourceDirectory());
+ fname, status.GetMakefile().GetCurrentSourceDirectory());
if (optional && !cmSystemTools::FileExists(listFile)) {
if (!resultVarName.empty()) {
- this->Makefile->AddDefinition(resultVarName, "NOTFOUND");
+ status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND");
}
return true;
}
- bool readit = this->Makefile->ReadDependentFile(listFile, noPolicyScope);
+ bool readit =
+ status.GetMakefile().ReadDependentFile(listFile, noPolicyScope);
// add the location of the included file if a result variable was given
if (!resultVarName.empty()) {
- this->Makefile->AddDefinition(resultVarName,
- readit ? fname_abs.c_str() : "NOTFOUND");
+ status.GetMakefile().AddDefinition(
+ resultVarName, readit ? fname_abs.c_str() : "NOTFOUND");
}
if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) {
- std::string m = "could not find load file:\n"
- " ";
- m += fname;
- this->SetError(m);
+ std::string m = cmStrCat("could not find load file:\n"
+ " ",
+ fname);
+ status.SetError(m);
return false;
}
return true;
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index 3b843b206..b0dd77956 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -8,30 +8,15 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmIncludeCommand
+/**
* \brief cmIncludeCommand defines a list of distant
* files that can be "included" in the current list file.
* In almost every sense, this is identical to a C/C++
* #include command. Arguments are first expended as usual.
*/
-class cmIncludeCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIncludeCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmIncludeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 62e2abdcd..170aea125 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -7,23 +7,28 @@
#include <utility>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+static void GetIncludes(cmMakefile& mf, const std::string& arg,
+ std::vector<std::string>& incs);
+static void NormalizeInclude(cmMakefile& mf, std::string& inc);
-// cmIncludeDirectoryCommand
-bool cmIncludeDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmIncludeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
}
- std::vector<std::string>::const_iterator i = args.begin();
+ cmMakefile& mf = status.GetMakefile();
- bool before = this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE");
+ auto i = args.begin();
+
+ bool before = mf.IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE");
bool system = false;
if ((*i) == "BEFORE") {
@@ -44,13 +49,13 @@ bool cmIncludeDirectoryCommand::InitialPass(
continue;
}
if (i->empty()) {
- this->SetError("given empty-string as include directory.");
+ status.SetError("given empty-string as include directory.");
return false;
}
std::vector<std::string> includes;
- this->GetIncludes(*i, includes);
+ GetIncludes(mf, *i, includes);
if (before) {
cmAppend(beforeIncludes, includes);
@@ -63,9 +68,9 @@ bool cmIncludeDirectoryCommand::InitialPass(
}
std::reverse(beforeIncludes.begin(), beforeIncludes.end());
- this->Makefile->AddIncludeDirectories(afterIncludes);
- this->Makefile->AddIncludeDirectories(beforeIncludes, before);
- this->Makefile->AddSystemIncludeDirectories(systemIncludes);
+ mf.AddIncludeDirectories(afterIncludes);
+ mf.AddIncludeDirectories(beforeIncludes, before);
+ mf.AddSystemIncludeDirectories(systemIncludes);
return true;
}
@@ -82,8 +87,8 @@ bool cmIncludeDirectoryCommand::InitialPass(
// output from a program and passing it into a command the cleanup doesn't
// always happen
//
-void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg,
- std::vector<std::string>& incs)
+static void GetIncludes(cmMakefile& mf, const std::string& arg,
+ std::vector<std::string>& incs)
{
// break apart any line feed arguments
std::string::size_type pos = 0;
@@ -91,7 +96,7 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg,
while ((pos = arg.find('\n', lastPos)) != std::string::npos) {
if (pos) {
std::string inc = arg.substr(lastPos, pos);
- this->NormalizeInclude(inc);
+ NormalizeInclude(mf, inc);
if (!inc.empty()) {
incs.push_back(std::move(inc));
}
@@ -99,13 +104,13 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg,
lastPos = pos + 1;
}
std::string inc = arg.substr(lastPos);
- this->NormalizeInclude(inc);
+ NormalizeInclude(mf, inc);
if (!inc.empty()) {
incs.push_back(std::move(inc));
}
}
-void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc)
+static void NormalizeInclude(cmMakefile& mf, std::string& inc)
{
std::string::size_type b = inc.find_first_not_of(" \r");
std::string::size_type e = inc.find_last_not_of(" \r");
@@ -116,16 +121,11 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc)
return;
}
- if (!cmSystemTools::IsOff(inc)) {
+ if (!cmIsOff(inc)) {
cmSystemTools::ConvertToUnixSlashes(inc);
-
- if (!cmSystemTools::FileIsFullPath(inc)) {
- if (!cmGeneratorExpression::StartsWithGeneratorExpression(inc)) {
- std::string tmp = this->Makefile->GetCurrentSourceDirectory();
- tmp += "/";
- tmp += inc;
- inc = tmp;
- }
+ if (!cmSystemTools::FileIsFullPath(inc) &&
+ !cmGeneratorExpression::StartsWithGeneratorExpression(inc)) {
+ inc = cmStrCat(mf.GetCurrentSourceDirectory(), '/', inc);
}
}
}
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index 01d98dbc0..66caff721 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -8,35 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmIncludeDirectoryCommand
- * \brief Add include directories to the build.
- *
- * cmIncludeDirectoryCommand is used to specify directory locations
- * to search for included files.
- */
-class cmIncludeDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIncludeDirectoryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- // used internally
- void GetIncludes(const std::string& arg, std::vector<std::string>& incs);
- void NormalizeInclude(std::string& inc);
-};
+bool cmIncludeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
index 93134adb6..fa1e8bcf9 100644
--- a/Source/cmIncludeExternalMSProjectCommand.cxx
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIncludeExternalMSProjectCommand.h"
+#include "cmExecutionStatus.h"
+
#ifdef _WIN32
# include "cmGlobalGenerator.h"
# include "cmMakefile.h"
@@ -11,22 +13,20 @@
# include "cmake.h"
#endif
-class cmExecutionStatus;
-
-// cmIncludeExternalMSProjectCommand
-bool cmIncludeExternalMSProjectCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect "
- "number of arguments");
+ status.SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect "
+ "number of arguments");
return false;
}
+
// only compile this for win32 to avoid coverage errors
#ifdef _WIN32
- if (this->Makefile->GetDefinition("WIN32") ||
- this->Makefile->GetGlobalGenerator()
- ->IsIncludeExternalMSProjectSupported()) {
+ cmMakefile& mf = status.GetMakefile();
+ if (mf.GetDefinition("WIN32") ||
+ mf.GetGlobalGenerator()->IsIncludeExternalMSProjectSupported()) {
enum Doing
{
DoingNone,
@@ -77,15 +77,15 @@ bool cmIncludeExternalMSProjectCommand::InitialPass(
if (!customGuid.empty()) {
std::string guidVariable = utility_name + "_GUID_CMAKE";
- this->Makefile->GetCMakeInstance()->AddCacheEntry(
- guidVariable.c_str(), customGuid.c_str(), "Stored GUID",
- cmStateEnums::INTERNAL);
+ mf.GetCMakeInstance()->AddCacheEntry(guidVariable.c_str(),
+ customGuid.c_str(), "Stored GUID",
+ cmStateEnums::INTERNAL);
}
// Create a target instance for this utility.
- cmTarget* target = this->Makefile->AddNewTarget(cmStateEnums::UTILITY,
- utility_name.c_str());
- if (this->Makefile->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
+ cmTarget* target =
+ mf.AddNewTarget(cmStateEnums::UTILITY, utility_name.c_str());
+ if (mf.GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
index 945acdc13..1013c4435 100644
--- a/Source/cmIncludeExternalMSProjectCommand.h
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmIncludeExternalMSProjectCommand
- * \brief Specify an external MS project file for inclusion in the workspace.
- *
- * cmIncludeExternalMSProjectCommand is used to specify an externally
- * generated Microsoft project file for inclusion in the default workspace
- * generated by CMake.
- */
-class cmIncludeExternalMSProjectCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIncludeExternalMSProjectCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index 505b07cad..ccb4496e6 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -21,7 +21,7 @@ enum IncludeGuardScope
std::string GetIncludeGuardVariableName(std::string const& filePath)
{
std::string result = "__INCGUARD_";
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
result += cmSystemTools::ComputeStringMD5(filePath);
#else
result += cmSystemTools::MakeCidentifier(filePath);
@@ -50,11 +50,11 @@ bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar)
} // anonymous namespace
// cmIncludeGuardCommand
-bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+bool cmIncludeGuardCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() > 1) {
- this->SetError(
+ status.SetError(
"given an invalid number of arguments. The command takes at "
"most 1 argument.");
return false;
@@ -69,15 +69,15 @@ bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
} else if (arg == "GLOBAL") {
scope = GLOBAL;
} else {
- this->SetError("given an invalid scope: " + arg);
+ status.SetError("given an invalid scope: " + arg);
return false;
}
}
std::string includeGuardVar = GetIncludeGuardVariableName(
- this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
+ status.GetMakefile().GetDefinition("CMAKE_CURRENT_LIST_FILE"));
- cmMakefile* const mf = this->Makefile;
+ cmMakefile* const mf = &status.GetMakefile();
switch (scope) {
case VARIABLE:
@@ -85,7 +85,7 @@ bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
status.SetReturnInvoked();
return true;
}
- mf->AddDefinition(includeGuardVar, true);
+ mf->AddDefinitionBool(includeGuardVar, true);
break;
case DIRECTORY:
if (CheckIncludeGuardIsSet(mf, includeGuardVar)) {
diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h
index eaad9b89a..b86b76015 100644
--- a/Source/cmIncludeGuardCommand.h
+++ b/Source/cmIncludeGuardCommand.h
@@ -8,30 +8,15 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmIncludeGuardCommand
+/**
* \brief cmIncludeGuardCommand identical to C++ #pragma_once command
* Can work in 3 modes: GLOBAL (works on global properties),
* DIRECTORY(use directory property), VARIABLE(unnamed overload without
* arguments) define an ordinary variable to be used as include guard checker
*/
-class cmIncludeGuardCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIncludeGuardCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmIncludeGuardCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx
index 073c95f7d..655ebd6e4 100644
--- a/Source/cmIncludeRegularExpressionCommand.cxx
+++ b/Source/cmIncludeRegularExpressionCommand.cxx
@@ -2,22 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIncludeRegularExpressionCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmIncludeRegularExpressionCommand
-bool cmIncludeRegularExpressionCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if ((args.empty()) || (args.size() > 2)) {
- this->SetError("called with incorrect number of arguments");
+ if (args.empty() || args.size() > 2) {
+ status.SetError("called with incorrect number of arguments");
return false;
}
- this->Makefile->SetIncludeRegularExpression(args[0].c_str());
+
+ cmMakefile& mf = status.GetMakefile();
+ mf.SetIncludeRegularExpression(args[0].c_str());
if (args.size() > 1) {
- this->Makefile->SetComplainRegularExpression(args[1]);
+ mf.SetComplainRegularExpression(args[1]);
}
return true;
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
index 8da991d08..ca152b046 100644
--- a/Source/cmIncludeRegularExpressionCommand.h
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmIncludeRegularExpressionCommand
- * \brief Set the regular expression for following #includes.
- *
- * cmIncludeRegularExpressionCommand is used to specify the regular expression
- * that determines whether to follow a #include file in dependency checking.
- */
-class cmIncludeRegularExpressionCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmIncludeRegularExpressionCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index c9e692333..0c52cc5b7 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -2,17 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallCommand.h"
-#include "cm_static_string_view.hxx"
-#include "cmsys/Glob.hxx"
+#include <cstddef>
#include <set>
#include <sstream>
-#include <stddef.h>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+
+#include "cmsys/Glob.hxx"
+
+#include "cm_static_string_view.hxx"
+
#include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
#include "cmExportSet.h"
-#include "cmExportSetMap.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallCommandArguments.h"
@@ -27,13 +30,62 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
-class cmExecutionStatus;
+namespace {
+
+class Helper
+{
+public:
+ Helper(cmExecutionStatus& status)
+ : Status(status)
+ , Makefile(&status.GetMakefile())
+ {
+ this->DefaultComponentName = this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ if (this->DefaultComponentName.empty()) {
+ this->DefaultComponentName = "Unspecified";
+ }
+ }
+
+ void SetError(std::string const& err) { this->Status.SetError(err); }
+
+ bool MakeFilesFullPath(const char* modeName,
+ const std::vector<std::string>& relFiles,
+ std::vector<std::string>& absFiles);
+ bool CheckCMP0006(bool& failure);
+
+ std::string GetDestination(const cmInstallCommandArguments* args,
+ const std::string& varName,
+ const std::string& guess);
+ std::string GetRuntimeDestination(const cmInstallCommandArguments* args);
+ std::string GetSbinDestination(const cmInstallCommandArguments* args);
+ std::string GetArchiveDestination(const cmInstallCommandArguments* args);
+ std::string GetLibraryDestination(const cmInstallCommandArguments* args);
+ std::string GetIncludeDestination(const cmInstallCommandArguments* args);
+ std::string GetSysconfDestination(const cmInstallCommandArguments* args);
+ std::string GetSharedStateDestination(const cmInstallCommandArguments* args);
+ std::string GetLocalStateDestination(const cmInstallCommandArguments* args);
+ std::string GetRunStateDestination(const cmInstallCommandArguments* args);
+ std::string GetDataRootDestination(const cmInstallCommandArguments* args);
+ std::string GetDataDestination(const cmInstallCommandArguments* args);
+ std::string GetInfoDestination(const cmInstallCommandArguments* args);
+ std::string GetLocaleDestination(const cmInstallCommandArguments* args);
+ std::string GetManDestination(const cmInstallCommandArguments* args);
+ std::string GetDocDestination(const cmInstallCommandArguments* args);
+ std::string GetDestinationForType(const cmInstallCommandArguments* args,
+ const std::string& type);
+
+ cmExecutionStatus& Status;
+ cmMakefile* Makefile;
+ std::string DefaultComponentName;
+};
-static cmInstallTargetGenerator* CreateInstallTargetGenerator(
+cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, const std::string& destination,
bool forceOpt = false, bool namelink = false)
@@ -52,7 +104,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(
return g;
}
-static cmInstallTargetGenerator* CreateInstallTargetGenerator(
+cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, bool forceOpt = false,
bool namelink = false)
@@ -62,7 +114,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(
namelink);
}
-static cmInstallFilesGenerator* CreateInstallFilesGenerator(
+cmInstallFilesGenerator* CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs,
const std::string& destination)
@@ -75,7 +127,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional());
}
-static cmInstallFilesGenerator* CreateInstallFilesGenerator(
+cmInstallFilesGenerator* CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs)
{
@@ -83,69 +135,18 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
args.GetDestination());
}
-static const std::set<std::string> allowedTypes{
+std::set<std::string> const allowedTypes{
"BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF",
"SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO",
"LOCALE", "MAN", "DOC",
};
-// cmInstallCommand
-bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool HandleScriptMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- // Allow calling with no arguments so that arguments may be built up
- // using a variable that may be left empty.
- if (args.empty()) {
- return true;
- }
-
- // Enable the install target.
- this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
-
- this->DefaultComponentName =
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
- if (this->DefaultComponentName.empty()) {
- this->DefaultComponentName = "Unspecified";
- }
-
- std::string const& mode = args[0];
-
- // Switch among the command modes.
- if (mode == "SCRIPT") {
- return this->HandleScriptMode(args);
- }
- if (mode == "CODE") {
- return this->HandleScriptMode(args);
- }
- if (mode == "TARGETS") {
- return this->HandleTargetsMode(args);
- }
- if (mode == "FILES") {
- return this->HandleFilesMode(args);
- }
- if (mode == "PROGRAMS") {
- return this->HandleFilesMode(args);
- }
- if (mode == "DIRECTORY") {
- return this->HandleDirectoryMode(args);
- }
- if (mode == "EXPORT") {
- return this->HandleExportMode(args);
- }
- if (mode == "EXPORT_ANDROID_MK") {
- return this->HandleExportAndroidMKMode(args);
- }
-
- // Unknown mode.
- std::string e = "called with unknown mode ";
- e += args[0];
- this->SetError(e);
- return false;
-}
+ Helper helper(status);
-bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
-{
- std::string component = this->DefaultComponentName;
+ std::string component = helper.DefaultComponentName;
int componentCount = 0;
bool doing_script = false;
bool doing_code = false;
@@ -165,9 +166,9 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
}
if (componentCount > 1) {
- this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
- "signature of the INSTALL command. "
- "Use multiple INSTALL commands with one COMPONENT each.");
+ status.SetError("given more than one COMPONENT for the SCRIPT or CODE "
+ "signature of the INSTALL command. "
+ "Use multiple INSTALL commands with one COMPONENT each.");
return false;
}
@@ -188,42 +189,44 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
doing_script = false;
std::string script = arg;
if (!cmSystemTools::FileIsFullPath(script)) {
- script = this->Makefile->GetCurrentSourceDirectory();
- script += "/";
- script += arg;
+ script =
+ cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', arg);
}
if (cmSystemTools::FileIsDirectory(script)) {
- this->SetError("given a directory as value of SCRIPT argument.");
+ status.SetError("given a directory as value of SCRIPT argument.");
return false;
}
- this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
+ helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
script.c_str(), false, component.c_str(), exclude_from_all));
} else if (doing_code) {
doing_code = false;
std::string const& code = arg;
- this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
+ helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
code.c_str(), true, component.c_str(), exclude_from_all));
}
}
if (doing_script) {
- this->SetError("given no value for SCRIPT argument.");
+ status.SetError("given no value for SCRIPT argument.");
return false;
}
if (doing_code) {
- this->SetError("given no value for CODE argument.");
+ status.SetError("given no value for CODE argument.");
return false;
}
// Tell the global generator about any installation component names
// specified.
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(component);
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component);
return true;
}
-bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
+bool HandleTargetsMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ Helper helper(status);
+
// This is the TARGETS mode.
std::vector<cmTarget*> targets;
@@ -263,21 +266,21 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
std::vector<std::string> targetList;
std::string exports;
std::vector<std::string> unknownArgs;
- cmInstallCommandArguments genericArgs(this->DefaultComponentName);
+ cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
genericArgs.Bind("TARGETS"_s, targetList);
genericArgs.Bind("EXPORT"_s, exports);
genericArgs.Parse(genericArgVector, &unknownArgs);
bool success = genericArgs.Finalize();
- cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
- cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
- cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
- cmInstallCommandArguments objectArgs(this->DefaultComponentName);
- cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
- cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
- cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
- cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
- cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
+ cmInstallCommandArguments archiveArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments libraryArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments objectArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments frameworkArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments bundleArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments privateHeaderArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments publicHeaderArgs(helper.DefaultComponentName);
+ cmInstallCommandArguments resourceArgs(helper.DefaultComponentName);
cmInstallCommandIncludesArgument includesArgs;
// now parse the args for specific parts of the target (e.g. LIBRARY,
@@ -295,9 +298,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (!unknownArgs.empty()) {
// Unknown argument.
- std::ostringstream e;
- e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given unknown argument \"", unknownArgs[0], "\"."));
return false;
}
@@ -332,7 +334,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
- this->SetError(
+ status.SetError(
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
"The NAMELINK_ONLY option may be specified only following LIBRARY.");
return false;
@@ -341,7 +343,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
- this->SetError(
+ status.SetError(
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
"The NAMELINK_SKIP option may be specified only following LIBRARY.");
return false;
@@ -354,15 +356,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
privateHeaderArgs.HasNamelinkComponent() ||
publicHeaderArgs.HasNamelinkComponent() ||
resourceArgs.HasNamelinkComponent()) {
- this->SetError(
+ status.SetError(
"TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. "
"The NAMELINK_COMPONENT option may be specified only following "
"LIBRARY.");
return false;
}
if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) {
- this->SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
- "At most one of these two options may be specified.");
+ status.SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
+ "At most one of these two options may be specified.");
return false;
}
if (!genericArgs.GetType().empty() || !archiveArgs.GetType().empty() ||
@@ -370,10 +372,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
!objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() ||
!bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() ||
!publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) {
- std::ostringstream e;
- e << "TARGETS given TYPE option. The TYPE option may only be specified in "
- " install(FILES) and install(DIRECTORIES).";
- this->SetError(e.str());
+ status.SetError(
+ "TARGETS given TYPE option. The TYPE option may only be specified in "
+ " install(FILES) and install(DIRECTORIES).");
return false;
}
@@ -391,24 +392,19 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
return true;
}
- // Check whether this is a DLL platform.
- bool dll_platform =
- !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
-
for (std::string const& tgt : targetList) {
- if (this->Makefile->IsAlias(tgt)) {
- std::ostringstream e;
- e << "TARGETS given target \"" << tgt << "\" which is an alias.";
- this->SetError(e.str());
+ if (helper.Makefile->IsAlias(tgt)) {
+ status.SetError(
+ cmStrCat("TARGETS given target \"", tgt, "\" which is an alias."));
return false;
}
// Lookup this target in the current directory.
- cmTarget* target = this->Makefile->FindLocalNonAliasTarget(tgt);
+ cmTarget* target = helper.Makefile->FindLocalNonAliasTarget(tgt);
if (!target) {
// If no local target has been found, find it in the global scope.
cmTarget* const global_target =
- this->Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
+ helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
if (global_target && !global_target->IsImported()) {
target = global_target;
}
@@ -421,19 +417,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
target->GetType() != cmStateEnums::MODULE_LIBRARY &&
target->GetType() != cmStateEnums::OBJECT_LIBRARY &&
target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- std::ostringstream e;
- e << "TARGETS given target \"" << tgt
- << "\" which is not an executable, library, or module.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given target \"", tgt,
+ "\" which is not an executable, library, or module."));
return false;
}
// Store the target in the list to be installed.
targets.push_back(target);
} else {
// Did not find the target.
- std::ostringstream e;
- e << "TARGETS given target \"" << tgt << "\" which does not exist.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given target \"", tgt, "\" which does not exist."));
return false;
}
}
@@ -474,7 +468,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Shared libraries are handled differently on DLL and non-DLL
// platforms. All windows platforms are DLL platforms including
// cygwin. Currently no other platform is a DLL platform.
- if (dll_platform) {
+ if (target.IsDLLPlatform()) {
// When in namelink only mode skip all libraries on Windows.
if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
continue;
@@ -484,20 +478,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (!archiveArgs.GetDestination().empty()) {
// The import library uses the ARCHIVE properties.
archiveGenerator = CreateInstallTargetGenerator(
- target, archiveArgs, true, this->Makefile->GetBacktrace());
+ target, archiveArgs, true, helper.Makefile->GetBacktrace());
}
if (!runtimeArgs.GetDestination().empty()) {
// The DLL uses the RUNTIME properties.
runtimeGenerator = CreateInstallTargetGenerator(
- target, runtimeArgs, false, this->Makefile->GetBacktrace());
+ target, runtimeArgs, false, helper.Makefile->GetBacktrace());
}
if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) {
archiveGenerator = CreateInstallTargetGenerator(
- target, archiveArgs, true, this->Makefile->GetBacktrace(),
- this->GetArchiveDestination(nullptr));
+ target, archiveArgs, true, helper.Makefile->GetBacktrace(),
+ helper.GetArchiveDestination(nullptr));
runtimeGenerator = CreateInstallTargetGenerator(
- target, runtimeArgs, false, this->Makefile->GetBacktrace(),
- this->GetRuntimeDestination(nullptr));
+ target, runtimeArgs, false, helper.Makefile->GetBacktrace(),
+ helper.GetRuntimeDestination(nullptr));
}
} else {
// This is a non-DLL platform.
@@ -512,28 +506,27 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Use the FRAMEWORK properties.
if (!frameworkArgs.GetDestination().empty()) {
frameworkGenerator = CreateInstallTargetGenerator(
- target, frameworkArgs, false, this->Makefile->GetBacktrace());
+ target, frameworkArgs, false, helper.Makefile->GetBacktrace());
} else {
- std::ostringstream e;
- e << "TARGETS given no FRAMEWORK DESTINATION for shared library "
- "FRAMEWORK target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given no FRAMEWORK DESTINATION for shared "
+ "library FRAMEWORK target \"",
+ target.GetName(), "\"."));
return false;
}
} else {
// The shared library uses the LIBRARY properties.
if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
libraryGenerator = CreateInstallTargetGenerator(
- target, libraryArgs, false, this->Makefile->GetBacktrace(),
- this->GetLibraryDestination(&libraryArgs));
+ target, libraryArgs, false, helper.Makefile->GetBacktrace(),
+ helper.GetLibraryDestination(&libraryArgs));
libraryGenerator->SetNamelinkMode(
cmInstallTargetGenerator::NamelinkModeSkip);
}
if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
namelinkGenerator = CreateInstallTargetGenerator(
- target, libraryArgs, false, this->Makefile->GetBacktrace(),
- this->GetLibraryDestination(&libraryArgs), false, true);
+ target, libraryArgs, false, helper.Makefile->GetBacktrace(),
+ helper.GetLibraryDestination(&libraryArgs), false, true);
namelinkGenerator->SetNamelinkMode(
cmInstallTargetGenerator::NamelinkModeOnly);
}
@@ -554,35 +547,34 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Use the FRAMEWORK properties.
if (!frameworkArgs.GetDestination().empty()) {
frameworkGenerator = CreateInstallTargetGenerator(
- target, frameworkArgs, false, this->Makefile->GetBacktrace());
+ target, frameworkArgs, false, helper.Makefile->GetBacktrace());
} else {
- std::ostringstream e;
- e << "TARGETS given no FRAMEWORK DESTINATION for static library "
- "FRAMEWORK target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given no FRAMEWORK DESTINATION for static "
+ "library FRAMEWORK target \"",
+ target.GetName(), "\"."));
return false;
}
} else {
// Static libraries use ARCHIVE properties.
archiveGenerator = CreateInstallTargetGenerator(
- target, archiveArgs, false, this->Makefile->GetBacktrace(),
- this->GetArchiveDestination(&archiveArgs));
+ target, archiveArgs, false, helper.Makefile->GetBacktrace(),
+ helper.GetArchiveDestination(&archiveArgs));
}
} break;
case cmStateEnums::MODULE_LIBRARY: {
// Modules use LIBRARY properties.
if (!libraryArgs.GetDestination().empty()) {
libraryGenerator = CreateInstallTargetGenerator(
- target, libraryArgs, false, this->Makefile->GetBacktrace());
+ target, libraryArgs, false, helper.Makefile->GetBacktrace());
libraryGenerator->SetNamelinkMode(namelinkMode);
namelinkOnly =
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
} else {
- std::ostringstream e;
- e << "TARGETS given no LIBRARY DESTINATION for module target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given no LIBRARY DESTINATION for module "
+ "target \"",
+ target.GetName(), "\"."));
return false;
}
} break;
@@ -591,17 +583,16 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (!objectArgs.GetDestination().empty()) {
// Verify that we know where the objects are to install them.
std::string reason;
- if (!this->Makefile->GetGlobalGenerator()
+ if (!helper.Makefile->GetGlobalGenerator()
->HasKnownObjectFileLocation(&reason)) {
- std::ostringstream e;
- e << "TARGETS given OBJECT library \"" << target.GetName()
- << "\" whose objects may not be installed" << reason << ".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat("TARGETS given OBJECT library \"", target.GetName(),
+ "\" whose objects may not be installed", reason, "."));
return false;
}
objectGenerator = CreateInstallTargetGenerator(
- target, objectArgs, false, this->Makefile->GetBacktrace());
+ target, objectArgs, false, helper.Makefile->GetBacktrace());
} else {
// Installing an OBJECT library without a destination transforms
// it to an INTERFACE library. It installs no files but can be
@@ -613,41 +604,40 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Application bundles use the BUNDLE properties.
if (!bundleArgs.GetDestination().empty()) {
bundleGenerator = CreateInstallTargetGenerator(
- target, bundleArgs, false, this->Makefile->GetBacktrace());
+ target, bundleArgs, false, helper.Makefile->GetBacktrace());
} else if (!runtimeArgs.GetDestination().empty()) {
bool failure = false;
- if (this->CheckCMP0006(failure)) {
+ if (helper.CheckCMP0006(failure)) {
// For CMake 2.4 compatibility fallback to the RUNTIME
// properties.
bundleGenerator = CreateInstallTargetGenerator(
- target, runtimeArgs, false, this->Makefile->GetBacktrace());
+ target, runtimeArgs, false, helper.Makefile->GetBacktrace());
} else if (failure) {
return false;
}
}
if (!bundleGenerator) {
- std::ostringstream e;
- e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
- "executable target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat("TARGETS given no BUNDLE DESTINATION for "
+ "MACOSX_BUNDLE executable target \"",
+ target.GetName(), "\"."));
return false;
}
} else {
// Executables use the RUNTIME properties.
runtimeGenerator = CreateInstallTargetGenerator(
- target, runtimeArgs, false, this->Makefile->GetBacktrace(),
- this->GetRuntimeDestination(&runtimeArgs));
+ target, runtimeArgs, false, helper.Makefile->GetBacktrace(),
+ helper.GetRuntimeDestination(&runtimeArgs));
}
// On DLL platforms an executable may also have an import
// library. Install it to the archive destination if it
// exists.
- if (dll_platform && !archiveArgs.GetDestination().empty() &&
+ if ((target.IsDLLPlatform() || target.IsAIX()) &&
+ !archiveArgs.GetDestination().empty() &&
target.IsExecutableWithExports()) {
// The import library uses the ARCHIVE properties.
archiveGenerator = CreateInstallTargetGenerator(
- target, archiveArgs, true, this->Makefile->GetBacktrace(), true);
+ target, archiveArgs, true, helper.Makefile->GetBacktrace(), true);
}
} break;
case cmStateEnums::INTERFACE_LIBRARY:
@@ -675,52 +665,49 @@ bool cmInstallCommand::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;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
- if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
+ if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
}
// Create the files install generator.
privateHeaderGenerator = CreateInstallFilesGenerator(
- this->Makefile, absFiles, privateHeaderArgs, false,
- this->GetIncludeDestination(&privateHeaderArgs));
+ helper.Makefile, absFiles, privateHeaderArgs, false,
+ helper.GetIncludeDestination(&privateHeaderArgs));
}
files = target.GetProperty("PUBLIC_HEADER");
if ((files) && (*files)) {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
- if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
+ if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
}
// Create the files install generator.
publicHeaderGenerator = CreateInstallFilesGenerator(
- this->Makefile, absFiles, publicHeaderArgs, false,
- this->GetIncludeDestination(&publicHeaderArgs));
+ helper.Makefile, absFiles, publicHeaderArgs, false,
+ helper.GetIncludeDestination(&publicHeaderArgs));
}
files = target.GetProperty("RESOURCE");
if ((files) && (*files)) {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> relFiles = cmExpandedList(files);
std::vector<std::string> absFiles;
- if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
+ if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
}
// Create the files install generator.
if (!resourceArgs.GetDestination().empty()) {
resourceGenerator = CreateInstallFilesGenerator(
- this->Makefile, absFiles, resourceArgs, false);
+ helper.Makefile, absFiles, resourceArgs, false);
} else {
- std::ostringstream e;
- e << "INSTALL TARGETS - target " << target.GetName() << " has "
- << "RESOURCE files but no RESOURCE DESTINATION.";
- cmSystemTools::Message(e.str(), "Warning");
+ cmSystemTools::Message(
+ cmStrCat("INSTALL TARGETS - target ", target.GetName(),
+ " has RESOURCE files but no RESOURCE DESTINATION."),
+ "Warning");
}
}
}
@@ -739,21 +726,21 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
installsPublicHeader || publicHeaderGenerator != nullptr;
installsResource = installsResource || resourceGenerator;
- this->Makefile->AddInstallGenerator(archiveGenerator);
- this->Makefile->AddInstallGenerator(libraryGenerator);
- this->Makefile->AddInstallGenerator(namelinkGenerator);
- this->Makefile->AddInstallGenerator(runtimeGenerator);
- this->Makefile->AddInstallGenerator(objectGenerator);
- this->Makefile->AddInstallGenerator(frameworkGenerator);
- this->Makefile->AddInstallGenerator(bundleGenerator);
- this->Makefile->AddInstallGenerator(privateHeaderGenerator);
- this->Makefile->AddInstallGenerator(publicHeaderGenerator);
- this->Makefile->AddInstallGenerator(resourceGenerator);
+ helper.Makefile->AddInstallGenerator(archiveGenerator);
+ helper.Makefile->AddInstallGenerator(libraryGenerator);
+ helper.Makefile->AddInstallGenerator(namelinkGenerator);
+ helper.Makefile->AddInstallGenerator(runtimeGenerator);
+ helper.Makefile->AddInstallGenerator(objectGenerator);
+ helper.Makefile->AddInstallGenerator(frameworkGenerator);
+ helper.Makefile->AddInstallGenerator(bundleGenerator);
+ helper.Makefile->AddInstallGenerator(privateHeaderGenerator);
+ helper.Makefile->AddInstallGenerator(publicHeaderGenerator);
+ helper.Makefile->AddInstallGenerator(resourceGenerator);
// Add this install rule to an export if one was specified and
// this is not a namelink-only rule.
if (!exports.empty() && !namelinkOnly) {
- cmTargetExport* te = new cmTargetExport;
+ auto te = cm::make_unique<cmTargetExport>();
te->TargetName = target.GetName();
te->ArchiveGenerator = archiveGenerator;
te->BundleGenerator = bundleGenerator;
@@ -762,66 +749,69 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
te->LibraryGenerator = libraryGenerator;
te->RuntimeGenerator = runtimeGenerator;
te->ObjectsGenerator = objectGenerator;
- this->Makefile->GetGlobalGenerator()
- ->GetExportSets()[exports]
- ->AddTargetExport(te);
-
te->InterfaceIncludeDirectories =
cmJoin(includesArgs.GetIncludeDirs(), ";");
+
+ helper.Makefile->GetGlobalGenerator()
+ ->GetExportSets()[exports]
+ .AddTargetExport(std::move(te));
}
}
// Tell the global generator about any installation component names
// specified
if (installsArchive) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
archiveArgs.GetComponent());
}
if (installsLibrary) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
libraryArgs.GetComponent());
}
if (installsNamelink) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
libraryArgs.GetNamelinkComponent());
}
if (installsRuntime) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
runtimeArgs.GetComponent());
}
if (installsObject) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
objectArgs.GetComponent());
}
if (installsFramework) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
frameworkArgs.GetComponent());
}
if (installsBundle) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
bundleArgs.GetComponent());
}
if (installsPrivateHeader) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
privateHeaderArgs.GetComponent());
}
if (installsPublicHeader) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
publicHeaderArgs.GetComponent());
}
if (installsResource) {
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
resourceArgs.GetComponent());
}
return true;
}
-bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
+bool HandleFilesMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ Helper helper(status);
+
// This is the FILES mode.
bool programs = (args[0] == "PROGRAMS");
- cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmInstallCommandArguments ica(helper.DefaultComponentName);
std::vector<std::string> files;
ica.Bind(programs ? "PROGRAMS"_s : "FILES"_s, files);
std::vector<std::string> unknownArgs;
@@ -829,17 +819,15 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
if (!unknownArgs.empty()) {
// Unknown argument.
- std::ostringstream e;
- e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\"."));
return false;
}
std::string type = ica.GetType();
if (!type.empty() && allowedTypes.count(type) == 0) {
- std::ostringstream e;
- e << args[0] << " given non-type \"" << type << "\" with TYPE argument.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given non-type \"", type, "\" with TYPE argument."));
return false;
}
@@ -852,28 +840,27 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
if (!ica.GetRename().empty() && filesVector.size() > 1) {
// The rename option works only with one file.
- std::ostringstream e;
- e << args[0] << " given RENAME option with more than one file.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given RENAME option with more than one file."));
return false;
}
std::vector<std::string> absFiles;
- if (!this->MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) {
+ if (!helper.MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) {
return false;
}
- cmPolicies::PolicyStatus status =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0062);
+ cmPolicies::PolicyStatus policyStatus =
+ helper.Makefile->GetPolicyStatus(cmPolicies::CMP0062);
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator* gg = helper.Makefile->GetGlobalGenerator();
for (std::string const& file : filesVector) {
if (gg->IsExportedTargetsFile(file)) {
const char* modal = nullptr;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (status) {
+ switch (policyStatus) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n";
modal = "should";
@@ -893,7 +880,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
<< " not be installed with the "
"install() command. Use the install(EXPORT) mechanism "
"instead. See the cmake-packages(7) manual for more.\n";
- this->Makefile->IssueMessage(messageType, e.str());
+ helper.Makefile->IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
@@ -906,38 +893,36 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
}
if (!type.empty() && !ica.GetDestination().empty()) {
- std::ostringstream e;
- e << args[0]
- << " given both TYPE and DESTINATION arguments. You may only specify "
- "one.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0],
+ " given both TYPE and DESTINATION arguments. "
+ "You may only specify one."));
return false;
}
- std::string destination = this->GetDestinationForType(&ica, type);
+ std::string destination = helper.GetDestinationForType(&ica, type);
if (destination.empty()) {
// A destination is required.
- std::ostringstream e;
- e << args[0] << " given no DESTINATION!";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given no DESTINATION!"));
return false;
}
// Create the files install generator.
- this->Makefile->AddInstallGenerator(CreateInstallFilesGenerator(
- this->Makefile, absFiles, ica, programs, destination));
+ helper.Makefile->AddInstallGenerator(CreateInstallFilesGenerator(
+ helper.Makefile, absFiles, ica, programs, destination));
// Tell the global generator about any installation component names
// specified.
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
ica.GetComponent());
return true;
}
-bool cmInstallCommand::HandleDirectoryMode(
- std::vector<std::string> const& args)
+bool HandleDirectoryMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ Helper helper(status);
+
enum Doing
{
DoingNone,
@@ -962,16 +947,14 @@ bool cmInstallCommand::HandleDirectoryMode(
std::string permissions_file;
std::string permissions_dir;
std::vector<std::string> configurations;
- std::string component = this->DefaultComponentName;
+ std::string component = helper.DefaultComponentName;
std::string literal_args;
std::string type;
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "DESTINATION") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -979,10 +962,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingDestination;
} else if (args[i] == "TYPE") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -990,10 +971,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingType;
} else if (args[i] == "OPTIONAL") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1002,10 +981,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingNone;
} else if (args[i] == "MESSAGE_NEVER") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1023,20 +1000,16 @@ bool cmInstallCommand::HandleDirectoryMode(
} else if (args[i] == "EXCLUDE") {
// Add this property to the current match rule.
if (!in_match_mode || doing == DoingPattern || doing == DoingRegex) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" before a PATTERN or REGEX is given.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" before a PATTERN or REGEX is given."));
return false;
}
literal_args += " EXCLUDE";
doing = DoingNone;
} else if (args[i] == "PERMISSIONS") {
if (!in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" before a PATTERN or REGEX is given.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" before a PATTERN or REGEX is given."));
return false;
}
@@ -1045,10 +1018,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingPermsMatch;
} else if (args[i] == "FILE_PERMISSIONS") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1056,10 +1027,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingPermsFile;
} else if (args[i] == "DIRECTORY_PERMISSIONS") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1067,10 +1036,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingPermsDir;
} else if (args[i] == "USE_SOURCE_PERMISSIONS") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1079,10 +1046,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingNone;
} else if (args[i] == "FILES_MATCHING") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1091,10 +1056,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingNone;
} else if (args[i] == "CONFIGURATIONS") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1102,10 +1065,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingConfigurations;
} else if (args[i] == "COMPONENT") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
@@ -1113,10 +1074,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingComponent;
} else if (args[i] == "EXCLUDE_FROM_ALL") {
if (in_match_mode) {
- std::ostringstream e;
- e << args[0] << " does not allow \"" << args[i]
- << "\" after PATTERN or REGEX.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " does not allow \"", args[i],
+ "\" after PATTERN or REGEX."));
return false;
}
exclude_from_all = true;
@@ -1126,18 +1085,15 @@ bool cmInstallCommand::HandleDirectoryMode(
std::string dir = args[i];
std::string::size_type gpos = cmGeneratorExpression::Find(dir);
if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) {
- dir = this->Makefile->GetCurrentSourceDirectory();
- dir += "/";
- dir += args[i];
+ dir =
+ cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', args[i]);
}
// Make sure the name is a directory.
if (cmSystemTools::FileExists(dir) &&
!cmSystemTools::FileIsDirectory(dir)) {
- std::ostringstream e;
- e << args[0] << " given non-directory \"" << args[i]
- << "\" to install.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given non-directory \"", args[i],
+ "\" to install."));
return false;
}
@@ -1150,10 +1106,8 @@ bool cmInstallCommand::HandleDirectoryMode(
doing = DoingNone;
} else if (doing == DoingType) {
if (allowedTypes.count(args[i]) == 0) {
- std::ostringstream e;
- e << args[0] << " given non-type \"" << args[i]
- << "\" with TYPE argument.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given non-type \"", args[i],
+ "\" with TYPE argument."));
return false;
}
@@ -1189,36 +1143,30 @@ bool cmInstallCommand::HandleDirectoryMode(
// Check the requested permission.
if (!cmInstallCommandArguments::CheckPermissions(args[i],
permissions_file)) {
- std::ostringstream e;
- e << args[0] << " given invalid file permission \"" << args[i]
- << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given invalid file permission \"",
+ args[i], "\"."));
return false;
}
} else if (doing == DoingPermsDir) {
// Check the requested permission.
if (!cmInstallCommandArguments::CheckPermissions(args[i],
permissions_dir)) {
- std::ostringstream e;
- e << args[0] << " given invalid directory permission \"" << args[i]
- << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ args[0], " given invalid directory permission \"", args[i], "\"."));
return false;
}
} else if (doing == DoingPermsMatch) {
// Check the requested permission.
if (!cmInstallCommandArguments::CheckPermissions(args[i],
literal_args)) {
- std::ostringstream e;
- e << args[0] << " given invalid permission \"" << args[i] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given invalid permission \"", args[i], "\"."));
return false;
}
} else {
// Unknown argument.
- std::ostringstream e;
- e << args[0] << " given unknown argument \"" << args[i] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given unknown argument \"", args[i], "\"."));
return false;
}
}
@@ -1236,44 +1184,42 @@ bool cmInstallCommand::HandleDirectoryMode(
if (!destination) {
if (type.empty()) {
// A destination is required.
- std::ostringstream e;
- e << args[0] << " given no DESTINATION!";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given no DESTINATION!"));
return false;
}
- destinationStr = this->GetDestinationForType(nullptr, type);
+ destinationStr = helper.GetDestinationForType(nullptr, type);
destination = destinationStr.c_str();
} else if (!type.empty()) {
- std::ostringstream e;
- e << args[0]
- << " given both TYPE and DESTINATION arguments. You may only specify "
- "one.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0],
+ " given both TYPE and DESTINATION "
+ "arguments. You may only specify one."));
return false;
}
cmInstallGenerator::MessageLevel message =
- cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never);
+ cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never);
// Create the directory install generator.
- this->Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator(
+ helper.Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator(
dirs, destination, permissions_file.c_str(), permissions_dir.c_str(),
configurations, component.c_str(), message, exclude_from_all,
literal_args.c_str(), optional));
// Tell the global generator about any installation component names
// specified.
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(component);
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component);
return true;
}
-bool cmInstallCommand::HandleExportAndroidMKMode(
- std::vector<std::string> const& args)
+bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
+ Helper helper(status);
+
// This is the EXPORT mode.
- cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmInstallCommandArguments ica(helper.DefaultComponentName);
std::string exp;
std::string name_space;
@@ -1290,9 +1236,8 @@ bool cmInstallCommand::HandleExportAndroidMKMode(
if (!unknownArgs.empty()) {
// Unknown argument.
- std::ostringstream e;
- e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\"."));
return false;
}
@@ -1303,39 +1248,35 @@ bool cmInstallCommand::HandleExportAndroidMKMode(
// Make sure there is a destination.
if (ica.GetDestination().empty()) {
// A destination is required.
- std::ostringstream e;
- e << args[0] << " given no DESTINATION!";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given no DESTINATION!"));
return false;
}
// Check the file name.
std::string fname = filename;
if (fname.find_first_of(":/\\") != std::string::npos) {
- std::ostringstream e;
- e << args[0] << " given invalid export file name \"" << fname << "\". "
- << "The FILE argument may not contain a path. "
- << "Specify the path in the DESTINATION argument.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given invalid export file name \"",
+ fname,
+ "\". The FILE argument may not contain a path. "
+ "Specify the path in the DESTINATION argument."));
return false;
}
// Check the file extension.
if (!fname.empty() &&
cmSystemTools::GetFilenameLastExtension(fname) != ".mk") {
- std::ostringstream e;
- e << args[0] << " given invalid export file name \"" << fname << "\". "
- << "The FILE argument must specify a name ending in \".mk\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ args[0], " given invalid export file name \"", fname,
+ R"(". The FILE argument must specify a name ending in ".mk".)"));
return false;
}
if (fname.find_first_of(":/\\") != std::string::npos) {
- std::ostringstream e;
- e << args[0] << " given export name \"" << exp << "\". "
- << "This name cannot be safely converted to a file name. "
- << "Specify a different export name or use the FILE option to set "
- << "a file name explicitly.";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given export name \"", exp,
+ "\". "
+ "This name cannot be safely converted to a file name. "
+ "Specify a different export name or use the FILE option to set "
+ "a file name explicitly."));
return false;
}
// Use the default name
@@ -1343,32 +1284,35 @@ bool cmInstallCommand::HandleExportAndroidMKMode(
fname = "Android.mk";
}
- cmExportSet* exportSet =
- this->Makefile->GetGlobalGenerator()->GetExportSets()[exp];
+ cmExportSet& exportSet =
+ helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp];
cmInstallGenerator::MessageLevel message =
- cmInstallGenerator::SelectMessageLevel(this->Makefile);
+ cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
+ &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
ica.GetConfigurations(), ica.GetComponent().c_str(), message,
ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
true);
- this->Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(exportGenerator);
return true;
#else
static_cast<void>(args);
- this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake");
+ status.SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake");
return false;
#endif
}
-bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
+bool HandleExportMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ Helper helper(status);
+
// This is the EXPORT mode.
- cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmInstallCommandArguments ica(helper.DefaultComponentName);
std::string exp;
std::string name_space;
@@ -1385,9 +1329,8 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
if (!unknownArgs.empty()) {
// Unknown argument.
- std::ostringstream e;
- e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\"."));
return false;
}
@@ -1398,103 +1341,96 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
// Make sure there is a destination.
if (ica.GetDestination().empty()) {
// A destination is required.
- std::ostringstream e;
- e << args[0] << " given no DESTINATION!";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given no DESTINATION!"));
return false;
}
// Check the file name.
std::string fname = filename;
if (fname.find_first_of(":/\\") != std::string::npos) {
- std::ostringstream e;
- e << args[0] << " given invalid export file name \"" << fname << "\". "
- << "The FILE argument may not contain a path. "
- << "Specify the path in the DESTINATION argument.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(args[0], " given invalid export file name \"",
+ fname,
+ "\". "
+ "The FILE argument may not contain a path. "
+ "Specify the path in the DESTINATION argument."));
return false;
}
// Check the file extension.
if (!fname.empty() &&
cmSystemTools::GetFilenameLastExtension(fname) != ".cmake") {
- std::ostringstream e;
- e << args[0] << " given invalid export file name \"" << fname << "\". "
- << "The FILE argument must specify a name ending in \".cmake\".";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " given invalid export file name \"", fname,
+ "\". "
+ "The FILE argument must specify a name ending in \".cmake\"."));
return false;
}
// Construct the file name.
if (fname.empty()) {
- fname = exp;
- fname += ".cmake";
+ fname = cmStrCat(exp, ".cmake");
if (fname.find_first_of(":/\\") != std::string::npos) {
- std::ostringstream e;
- e << args[0] << " given export name \"" << exp << "\". "
- << "This name cannot be safely converted to a file name. "
- << "Specify a different export name or use the FILE option to set "
- << "a file name explicitly.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ args[0], " given export name \"", exp,
+ "\". "
+ "This name cannot be safely converted to a file name. "
+ "Specify a different export name or use the FILE option to set "
+ "a file name explicitly."));
return false;
}
}
- cmExportSet* exportSet =
- this->Makefile->GetGlobalGenerator()->GetExportSets()[exp];
+ cmExportSet& exportSet =
+ helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp];
if (exportOld) {
- for (cmTargetExport* te : *exportSet->GetTargetExports()) {
+ for (auto const& te : exportSet.GetTargetExports()) {
cmTarget* tgt =
- this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName);
+ helper.Makefile->GetGlobalGenerator()->FindTarget(te->TargetName);
const bool newCMP0022Behavior =
(tgt && tgt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
tgt->GetPolicyStatusCMP0022() != cmPolicies::OLD);
if (!newCMP0022Behavior) {
- std::ostringstream e;
- e << "INSTALL(EXPORT) given keyword \""
- << "EXPORT_LINK_INTERFACE_LIBRARIES"
- << "\", but target \"" << te->TargetName
- << "\" does not have policy CMP0022 set to NEW.";
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "INSTALL(EXPORT) given keyword \""
+ "EXPORT_LINK_INTERFACE_LIBRARIES\", but target \"",
+ te->TargetName, "\" does not have policy CMP0022 set to NEW."));
return false;
}
}
}
cmInstallGenerator::MessageLevel message =
- cmInstallGenerator::SelectMessageLevel(this->Makefile);
+ cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
+ &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
ica.GetConfigurations(), ica.GetComponent().c_str(), message,
ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
false);
- this->Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(exportGenerator);
return true;
}
-bool cmInstallCommand::MakeFilesFullPath(
- const char* modeName, const std::vector<std::string>& relFiles,
- std::vector<std::string>& absFiles)
+bool Helper::MakeFilesFullPath(const char* modeName,
+ const std::vector<std::string>& relFiles,
+ std::vector<std::string>& absFiles)
{
for (std::string const& relFile : relFiles) {
std::string file = relFile;
std::string::size_type gpos = cmGeneratorExpression::Find(file);
if (gpos != 0 && !cmSystemTools::FileIsFullPath(file)) {
- file = this->Makefile->GetCurrentSourceDirectory();
- file += "/";
- file += relFile;
+ file =
+ cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', relFile);
}
// Make sure the file is not a directory.
if (gpos == std::string::npos && cmSystemTools::FileIsDirectory(file)) {
- std::ostringstream e;
- e << modeName << " given directory \"" << relFile << "\" to install.";
- this->SetError(e.str());
+ this->SetError(
+ cmStrCat(modeName, " given directory \"", relFile, "\" to install."));
return false;
}
// Store the file for installation.
@@ -1503,7 +1439,7 @@ bool cmInstallCommand::MakeFilesFullPath(
return true;
}
-bool cmInstallCommand::CheckCMP0006(bool& failure)
+bool Helper::CheckCMP0006(bool& failure)
{
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0006)) {
case cmPolicies::WARN:
@@ -1528,9 +1464,9 @@ bool cmInstallCommand::CheckCMP0006(bool& failure)
return false;
}
-std::string cmInstallCommand::GetDestination(
- const cmInstallCommandArguments* args, const std::string& varName,
- const std::string& guess)
+std::string Helper::GetDestination(const cmInstallCommandArguments* args,
+ const std::string& varName,
+ const std::string& guess)
{
if (args && !args->GetDestination().empty()) {
return args->GetDestination();
@@ -1542,55 +1478,54 @@ std::string cmInstallCommand::GetDestination(
return guess;
}
-std::string cmInstallCommand::GetRuntimeDestination(
+std::string Helper::GetRuntimeDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_BINDIR", "bin");
}
-std::string cmInstallCommand::GetSbinDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetSbinDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_SBINDIR", "sbin");
}
-std::string cmInstallCommand::GetArchiveDestination(
+std::string Helper::GetArchiveDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib");
}
-std::string cmInstallCommand::GetLibraryDestination(
+std::string Helper::GetLibraryDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib");
}
-std::string cmInstallCommand::GetIncludeDestination(
+std::string Helper::GetIncludeDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_INCLUDEDIR", "include");
}
-std::string cmInstallCommand::GetSysconfDestination(
+std::string Helper::GetSysconfDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_SYSCONFDIR", "etc");
}
-std::string cmInstallCommand::GetSharedStateDestination(
+std::string Helper::GetSharedStateDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_SHAREDSTATEDIR", "com");
}
-std::string cmInstallCommand::GetLocalStateDestination(
+std::string Helper::GetLocalStateDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_LOCALSTATEDIR", "var");
}
-std::string cmInstallCommand::GetRunStateDestination(
+std::string Helper::GetRunStateDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_RUNSTATEDIR",
@@ -1598,49 +1533,44 @@ std::string cmInstallCommand::GetRunStateDestination(
"/run");
}
-std::string cmInstallCommand::GetDataRootDestination(
+std::string Helper::GetDataRootDestination(
const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_DATAROOTDIR", "share");
}
-std::string cmInstallCommand::GetDataDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetDataDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_DATADIR",
this->GetDataRootDestination(nullptr));
}
-std::string cmInstallCommand::GetInfoDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetInfoDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_INFODIR",
this->GetDataRootDestination(nullptr) + "/info");
}
-std::string cmInstallCommand::GetLocaleDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetLocaleDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_LOCALEDIR",
this->GetDataRootDestination(nullptr) +
"/locale");
}
-std::string cmInstallCommand::GetManDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetManDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_MANDIR",
this->GetDataRootDestination(nullptr) + "/man");
}
-std::string cmInstallCommand::GetDocDestination(
- const cmInstallCommandArguments* args)
+std::string Helper::GetDocDestination(const cmInstallCommandArguments* args)
{
return this->GetDestination(args, "CMAKE_INSTALL_DOCDIR",
this->GetDataRootDestination(nullptr) + "/doc");
}
-std::string cmInstallCommand::GetDestinationForType(
+std::string Helper::GetDestinationForType(
const cmInstallCommandArguments* args, const std::string& type)
{
if (args && !args->GetDestination().empty()) {
@@ -1687,3 +1617,31 @@ std::string cmInstallCommand::GetDestinationForType(
}
return "";
}
+
+} // namespace
+
+bool cmInstallCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ // Allow calling with no arguments so that arguments may be built up
+ // using a variable that may be left empty.
+ if (args.empty()) {
+ return true;
+ }
+
+ // Enable the install target.
+ status.GetMakefile().GetGlobalGenerator()->EnableInstallTarget();
+
+ static cmSubcommandTable const subcommand{
+ { "SCRIPT"_s, HandleScriptMode },
+ { "CODE"_s, HandleScriptMode },
+ { "TARGETS"_s, HandleTargetsMode },
+ { "FILES"_s, HandleFilesMode },
+ { "PROGRAMS"_s, HandleFilesMode },
+ { "DIRECTORY"_s, HandleDirectoryMode },
+ { "EXPORT"_s, HandleExportMode },
+ { "EXPORT_ANDROID_MK"_s, HandleExportAndroidMKMode },
+ };
+
+ return subcommand(args[0], args, status);
+}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 202c43810..32f00ce49 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -8,66 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmInstallCommandArguments;
-
-/** \class cmInstallCommand
- * \brief Specifies where to install some files
- *
- * cmInstallCommand is a general-purpose interface command for
- * specifying install rules.
- */
-class cmInstallCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmInstallCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandleScriptMode(std::vector<std::string> const& args);
- bool HandleTargetsMode(std::vector<std::string> const& args);
- bool HandleFilesMode(std::vector<std::string> const& args);
- bool HandleDirectoryMode(std::vector<std::string> const& args);
- bool HandleExportMode(std::vector<std::string> const& args);
- bool HandleExportAndroidMKMode(std::vector<std::string> const& args);
- bool MakeFilesFullPath(const char* modeName,
- const std::vector<std::string>& relFiles,
- std::vector<std::string>& absFiles);
- bool CheckCMP0006(bool& failure);
-
- std::string GetDestination(const cmInstallCommandArguments* args,
- const std::string& varName,
- const std::string& guess);
- std::string GetRuntimeDestination(const cmInstallCommandArguments* args);
- std::string GetSbinDestination(const cmInstallCommandArguments* args);
- std::string GetArchiveDestination(const cmInstallCommandArguments* args);
- std::string GetLibraryDestination(const cmInstallCommandArguments* args);
- std::string GetIncludeDestination(const cmInstallCommandArguments* args);
- std::string GetSysconfDestination(const cmInstallCommandArguments* args);
- std::string GetSharedStateDestination(const cmInstallCommandArguments* args);
- std::string GetLocalStateDestination(const cmInstallCommandArguments* args);
- std::string GetRunStateDestination(const cmInstallCommandArguments* args);
- std::string GetDataRootDestination(const cmInstallCommandArguments* args);
- std::string GetDataDestination(const cmInstallCommandArguments* args);
- std::string GetInfoDestination(const cmInstallCommandArguments* args);
- std::string GetLocaleDestination(const cmInstallCommandArguments* args);
- std::string GetManDestination(const cmInstallCommandArguments* args);
- std::string GetDocDestination(const cmInstallCommandArguments* args);
- std::string GetDestinationForType(const cmInstallCommandArguments* args,
- const std::string& type);
- std::string DefaultComponentName;
-};
+bool cmInstallCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 8b33782ae..31ba63f2c 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -2,11 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallCommandArguments.h"
-#include "cmRange.h"
-#include "cmSystemTools.h"
+#include <utility>
+
#include "cm_static_string_view.hxx"
-#include <utility>
+#include "cmRange.h"
+#include "cmSystemTools.h"
// Table of valid permissions.
const char* cmInstallCommandArguments::PermissionsTable[] = {
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 14288f6d2..259c7f76d 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -6,10 +6,9 @@
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <memory> // IWYU pragma: keep
-
cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
std::vector<std::string> const& dirs, const char* dest,
const char* file_permissions, const char* dir_permissions,
@@ -63,18 +62,16 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig(
std::ostream& os, const std::string& config, Indent indent)
{
std::vector<std::string> dirs;
- cmGeneratorExpression ge;
for (std::string const& d : this->Directories) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(d);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(this->LocalGenerator, config), dirs);
+ cmExpandList(
+ cmGeneratorExpression::Evaluate(d, this->LocalGenerator, config), dirs);
}
// Make sure all dirs have absolute paths.
cmMakefile const& mf = *this->LocalGenerator->GetMakefile();
for (std::string& d : dirs) {
if (!cmSystemTools::FileIsFullPath(d)) {
- d = mf.GetCurrentSourceDirectory() + "/" + d;
+ d = cmStrCat(mf.GetCurrentSourceDirectory(), "/", d);
}
}
@@ -97,6 +94,6 @@ void cmInstallDirectoryGenerator::AddDirectoryInstallRule(
std::string cmInstallDirectoryGenerator::GetDestination(
std::string const& config) const
{
- cmGeneratorExpression ge;
- return ge.Parse(this->Destination)->Evaluate(this->LocalGenerator, config);
+ return cmGeneratorExpression::Evaluate(this->Destination,
+ this->LocalGenerator, config);
}
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index e30849f83..84c06948e 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -3,15 +3,15 @@
#ifndef cmInstallDirectoryGenerator_h
#define cmInstallDirectoryGenerator_h
-#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
-
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
+
class cmLocalGenerator;
/** \class cmInstallDirectoryGenerator
diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx
deleted file mode 100644
index 55d368507..000000000
--- a/Source/cmInstallExportAndroidMKGenerator.cxx
+++ /dev/null
@@ -1,137 +0,0 @@
-
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmInstallExportAndroidMKGenerator.h"
-
-#include <stdio.h>
-
-#include "cmExportInstallFileGenerator.h"
-#include "cmExportSet.h"
-#include "cmGeneratedFileStream.h"
-#include "cmGlobalGenerator.h"
-#include "cmInstallFilesGenerator.h"
-#include "cmInstallTargetGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
-#include "cmMessageType.h"
-
-cmInstallExportAndroidMKGenerator::cmInstallExportAndroidMKGenerator(
- cmExportSet* exportSet, const char* destination,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
- const char* filename, const char* name_space, bool exportOld)
- : cmInstallExportGenerator(exportSet, destination, file_permissions,
- configurations, component, message,
- exclude_from_all, filename, name_space, exportOld)
-{
-}
-
-cmInstallExportAndroidMKGenerator::~cmInstallExportAndroidMKGenerator()
-{
-}
-
-bool cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg)
-{
- this->LocalGenerator = lg;
- this->ExportSet->Compute(lg);
- return true;
-}
-
-void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os)
-{
- // Skip empty sets.
- if (ExportSet->GetTargetExports()->empty()) {
- std::ostringstream e;
- e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName()
- << "\"";
- cmSystemTools::Error(e.str());
- return;
- }
-
- // Create the temporary directory in which to store the files.
- this->ComputeTempDir();
- cmSystemTools::MakeDirectory(this->TempDir.c_str());
-
- // Construct a temporary location for the file.
- this->MainImportFile = this->TempDir;
- this->MainImportFile += "/";
- this->MainImportFile += this->FileName;
-
- // Generate the import file for this export set.
- this->EFGen->SetExportFile(this->MainImportFile.c_str());
- this->EFGen->SetNamespace(this->Namespace);
- this->EFGen->SetExportOld(this->ExportOld);
- if (this->ConfigurationTypes->empty()) {
- if (!this->ConfigurationName.empty()) {
- this->EFGen->AddConfiguration(this->ConfigurationName);
- } else {
- this->EFGen->AddConfiguration("");
- }
- } else {
- for (std::string const& config : this->ConfigurationTypes) {
- this->EFGen->AddConfiguration(config);
- }
- }
- this->EFGen->GenerateImportFile();
-
- // Perform the main install script generation.
- this->cmInstallGenerator::GenerateScript(os);
-}
-
-void cmInstallExportAndroidMKGenerator::GenerateScriptConfigs(
- std::ostream& os, Indent const& indent)
-{
- // Create the main install rules first.
- this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
-
- // Now create a configuration-specific install rule for the import
- // file of each configuration.
- std::vector<std::string> files;
- for (auto const& pair : this->EFGen->GetConfigImportFiles()) {
- files.push_back(pair.second);
- std::string config_test = this->CreateConfigTest(pair.first);
- os << indent << "if(" << config_test << ")\n";
- this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
- false, this->FilePermissions.c_str(), nullptr,
- nullptr, nullptr, indent.Next());
- os << indent << "endif()\n";
- files.clear();
- }
-}
-
-void cmInstallExportAndroidMKGenerator::GenerateScriptActions(
- std::ostream& os, Indent const& indent)
-{
- // Remove old per-configuration export files if the main changes.
- std::string installedDir = "$ENV{DESTDIR}";
- installedDir += this->ConvertToAbsoluteDestination(this->Destination);
- installedDir += "/";
- std::string installedFile = installedDir;
- installedFile += this->FileName;
- os << indent << "if(EXISTS \"" << installedFile << "\")\n";
- Indent indentN = indent.Next();
- Indent indentNN = indentN.Next();
- Indent indentNNN = indentNN.Next();
- /* clang-format off */
- os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
- << indentN << " \"" << installedFile << "\"\n"
- << indentN << " \"" << this->MainImportFile << "\")\n";
- os << indentN << "if(EXPORT_FILE_CHANGED)\n";
- os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir
- << this->EFGen->GetConfigImportFileGlob() << "\")\n";
- os << indentNN << "if(OLD_CONFIG_FILES)\n";
- os << indentNNN << "message(STATUS \"Old export file \\\"" << installedFile
- << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
- os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n";
- os << indentNN << "endif()\n";
- os << indentN << "endif()\n";
- os << indent << "endif()\n";
- /* clang-format on */
-
- // Install the main export file.
- std::vector<std::string> files;
- files.push_back(this->MainImportFile);
- this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
- false, this->FilePermissions.c_str(), nullptr, nullptr,
- nullptr, indent);
-}
diff --git a/Source/cmInstallExportAndroidMKGenerator.h b/Source/cmInstallExportAndroidMKGenerator.h
deleted file mode 100644
index a92ff27f1..000000000
--- a/Source/cmInstallExportAndroidMKGenerator.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmInstallExportAndroidMKGenerator_h
-#define cmInstallExportAndroidMKGenerator_h
-
-#include "cmInstallExportGenerator.h"
-
-class cmExportInstallFileGenerator;
-class cmInstallFilesGenerator;
-class cmInstallTargetGenerator;
-class cmExportSet;
-class cmMakefile;
-
-/** \class cmInstallExportAndroidMKGenerator
- * \brief Generate rules for creating an export files.
- */
-class cmInstallExportAndroidMKGenerator : public cmInstallExportGenerator
-{
-public:
- cmInstallExportAndroidMKGenerator(
- cmExportSet* exportSet, const char* dest, const char* file_permissions,
- const std::vector<std::string>& configurations, const char* component,
- MessageLevel message, bool exclude_from_all, const char* filename,
- const char* name_space, bool exportOld);
- ~cmInstallExportAndroidMKGenerator();
-
- bool Compute(cmLocalGenerator* lg) override;
-
-protected:
- virtual void GenerateScript(std::ostream& os);
- virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
- virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
- void GenerateImportFile(cmExportSet const* exportSet);
- void GenerateImportFile(const char* config, cmExportSet const* exportSet);
-};
-
-#endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index f5bedabc4..cba68bed4 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,13 +7,14 @@
#include <sstream>
#include <utility>
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
#include "cmExportInstallFileGenerator.h"
#include "cmExportSet.h"
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmInstallExportGenerator::cmInstallExportGenerator(
@@ -31,7 +32,7 @@ cmInstallExportGenerator::cmInstallExportGenerator(
, LocalGenerator(nullptr)
{
if (android) {
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->EFGen = new cmExportInstallAndroidMKGenerator(this);
#endif
} else {
@@ -56,9 +57,8 @@ void cmInstallExportGenerator::ComputeTempDir()
{
// Choose a temporary directory in which to generate the import
// files to be installed.
- this->TempDir = this->LocalGenerator->GetCurrentBinaryDirectory();
- this->TempDir += "/CMakeFiles";
- this->TempDir += "/Export";
+ this->TempDir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/Export");
if (this->Destination.empty()) {
return;
}
@@ -123,7 +123,7 @@ size_t cmInstallExportGenerator::GetMaxConfigLength() const
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
{
// Skip empty sets.
- if (ExportSet->GetTargetExports()->empty()) {
+ if (ExportSet->GetTargetExports().empty()) {
std::ostringstream e;
e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName()
<< "\"";
@@ -136,9 +136,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os)
cmSystemTools::MakeDirectory(this->TempDir);
// Construct a temporary location for the file.
- this->MainImportFile = this->TempDir;
- this->MainImportFile += "/";
- this->MainImportFile += this->FileName;
+ this->MainImportFile = cmStrCat(this->TempDir, '/', this->FileName);
// Generate the import file for this export set.
this->EFGen->SetExportFile(this->MainImportFile.c_str());
@@ -186,11 +184,10 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
Indent indent)
{
// Remove old per-configuration export files if the main changes.
- std::string installedDir = "$ENV{DESTDIR}";
- installedDir += this->ConvertToAbsoluteDestination(this->Destination);
- installedDir += "/";
- std::string installedFile = installedDir;
- installedFile += this->FileName;
+ std::string installedDir =
+ cmStrCat("$ENV{DESTDIR}",
+ this->ConvertToAbsoluteDestination(this->Destination), '/');
+ std::string installedFile = cmStrCat(installedDir, this->FileName);
os << indent << "if(EXISTS \"" << installedFile << "\")\n";
Indent indentN = indent.Next();
Indent indentNN = indentN.Next();
@@ -218,3 +215,8 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
false, this->FilePermissions.c_str(), nullptr, nullptr,
nullptr, indent);
}
+
+std::string cmInstallExportGenerator::GetDestinationFile() const
+{
+ return this->Destination + '/' + this->FileName;
+}
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index c4d252c47..f44127e3d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
-
+#include <cstddef>
#include <iosfwd>
-#include <stddef.h>
#include <string>
#include <vector>
+#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
+
class cmExportInstallFileGenerator;
class cmExportSet;
class cmLocalGenerator;
@@ -41,6 +41,7 @@ public:
const std::string& GetNamespace() const { return this->Namespace; }
std::string const& GetDestination() const { return this->Destination; }
+ std::string GetDestinationFile() const;
protected:
void GenerateScript(std::ostream& os) override;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index efbcb6713..d62394311 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -2,66 +2,72 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallFilesCommand.h"
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
#include "cmMakefile.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+static std::string FindInstallSource(cmMakefile& makefile, const char* name);
+static void CreateInstallGenerator(cmMakefile& makefile,
+ std::string const& dest,
+ std::vector<std::string> const& files);
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+ std::vector<std::string> const& args);
-// cmExecutableCommand
-bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmInstallFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Enable the install target.
- this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
+ mf.GetGlobalGenerator()->EnableInstallTarget();
- this->Destination = args[0];
+ std::string const& dest = args[0];
if ((args.size() > 1) && (args[1] == "FILES")) {
- this->IsFilesForm = true;
+ std::vector<std::string> files;
for (std::string const& arg : cmMakeRange(args).advance(2)) {
// Find the source location for each file listed.
- this->Files.push_back(this->FindInstallSource(arg.c_str()));
+ files.push_back(FindInstallSource(mf, arg.c_str()));
}
- this->CreateInstallGenerator();
+ CreateInstallGenerator(mf, dest, files);
} else {
- this->IsFilesForm = false;
- cmAppend(this->FinalArgs, args.begin() + 1, args.end());
+ std::vector<std::string> finalArgs(args.begin() + 1, args.end());
+ mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
+ FinalAction(makefile, dest, finalArgs);
+ });
}
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+ mf.GetGlobalGenerator()->AddInstallComponent(
+ mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
return true;
}
-void cmInstallFilesCommand::FinalPass()
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+ std::vector<std::string> const& args)
{
- // No final pass for "FILES" form of arguments.
- if (this->IsFilesForm) {
- return;
- }
-
std::string testf;
- std::string const& ext = this->FinalArgs[0];
+ std::string const& ext = args[0];
+ std::vector<std::string> installFiles;
// two different options
- if (this->FinalArgs.size() > 1) {
+ if (args.size() > 1) {
// now put the files into the list
- std::vector<std::string>::iterator s = this->FinalArgs.begin();
+ auto s = args.begin();
++s;
// for each argument, get the files
- for (; s != this->FinalArgs.end(); ++s) {
+ for (; s != args.end(); ++s) {
// replace any variables
std::string const& temps = *s;
if (!cmSystemTools::GetFilenamePath(temps).empty()) {
@@ -72,30 +78,31 @@ void cmInstallFilesCommand::FinalPass()
}
// add to the result
- this->Files.push_back(this->FindInstallSource(testf.c_str()));
+ installFiles.push_back(FindInstallSource(makefile, testf.c_str()));
}
} else // reg exp list
{
std::vector<std::string> files;
- std::string const& regex = this->FinalArgs[0];
- cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex,
- files);
+ std::string const& regex = args[0];
+ cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files);
- std::vector<std::string>::iterator s = files.begin();
+ auto s = files.begin();
// for each argument, get the files
for (; s != files.end(); ++s) {
- this->Files.push_back(this->FindInstallSource(s->c_str()));
+ installFiles.push_back(FindInstallSource(makefile, s->c_str()));
}
}
- this->CreateInstallGenerator();
+ CreateInstallGenerator(makefile, dest, installFiles);
}
-void cmInstallFilesCommand::CreateInstallGenerator() const
+static void CreateInstallGenerator(cmMakefile& makefile,
+ std::string const& dest,
+ std::vector<std::string> const& files)
{
// Construct the destination. This command always installs under
// the prefix. We skip the leading slash given by the user.
- std::string destination = this->Destination.substr(1);
+ std::string destination = dest.substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
if (destination.empty()) {
destination = ".";
@@ -106,12 +113,12 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
const char* no_rename = "";
bool no_exclude_from_all = false;
std::string no_component =
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
- cmInstallGenerator::SelectMessageLevel(this->Makefile);
- this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator(
- this->Files, destination.c_str(), false, no_permissions, no_configurations,
+ cmInstallGenerator::SelectMessageLevel(&makefile);
+ makefile.AddInstallGenerator(new cmInstallFilesGenerator(
+ files, destination.c_str(), false, no_permissions, no_configurations,
no_component.c_str(), message, no_exclude_from_all, no_rename));
}
@@ -121,7 +128,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
* present in the build tree. If a full path is given, it is just
* returned.
*/
-std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
+static std::string FindInstallSource(cmMakefile& makefile, const char* name)
{
if (cmSystemTools::FileIsFullPath(name) ||
cmGeneratorExpression::Find(name) == 0) {
@@ -130,12 +137,8 @@ std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
}
// This is a relative path.
- std::string tb = this->Makefile->GetCurrentBinaryDirectory();
- tb += "/";
- tb += name;
- std::string ts = this->Makefile->GetCurrentSourceDirectory();
- ts += "/";
- ts += name;
+ std::string tb = cmStrCat(makefile.GetCurrentBinaryDirectory(), '/', name);
+ std::string ts = cmStrCat(makefile.GetCurrentSourceDirectory(), '/', name);
if (cmSystemTools::FileExists(tb)) {
// The file exists in the binary tree. Use it.
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index a52f45e05..f4ebbdec9 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -8,49 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmInstallFilesCommand
- * \brief Specifies where to install some files
- *
- * cmInstallFilesCommand specifies the relative path where a list of
- * files should be installed.
- */
-class cmInstallFilesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmInstallFilesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * This is called at the end after all the information
- * specified by the command is accumulated. Most commands do
- * not implement this method. At this point, reading and
- * writing to the cache can be done.
- */
- void FinalPass() override;
- bool HasFinalPass() const override { return !this->IsFilesForm; }
-
-protected:
- void CreateInstallGenerator() const;
- std::string FindInstallSource(const char* name) const;
-
-private:
- std::vector<std::string> FinalArgs;
- bool IsFilesForm = false;
- std::string Destination;
- std::vector<std::string> Files;
-};
+bool cmInstallFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 2ed9f734d..f5b69a5d4 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -4,9 +4,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
-#include "cmSystemTools.h"
-
-#include <memory> // IWYU pragma: keep
+#include "cmStringAlgorithms.h"
class cmLocalGenerator;
@@ -51,8 +49,8 @@ bool cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
std::string cmInstallFilesGenerator::GetDestination(
std::string const& config) const
{
- cmGeneratorExpression ge;
- return ge.Parse(this->Destination)->Evaluate(this->LocalGenerator, config);
+ return cmGeneratorExpression::Evaluate(this->Destination,
+ this->LocalGenerator, config);
}
void cmInstallFilesGenerator::AddFilesInstallRule(
@@ -82,11 +80,9 @@ void cmInstallFilesGenerator::GenerateScriptForConfig(
std::ostream& os, const std::string& config, Indent indent)
{
std::vector<std::string> files;
- cmGeneratorExpression ge;
for (std::string const& f : this->Files) {
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(f);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(this->LocalGenerator, config), files);
+ cmExpandList(
+ cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config), files);
}
this->AddFilesInstallRule(os, config, indent, files);
}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index ac462d46f..a6800375b 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
+
class cmLocalGenerator;
/** \class cmInstallFilesGenerator
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 2ffca30f6..ec173619f 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallGenerator.h"
+#include <ostream>
+
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include <ostream>
-
cmInstallGenerator::cmInstallGenerator(
const char* destination, std::vector<std::string> const& configurations,
const char* component, MessageLevel message, bool exclude_from_all)
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index dbe707d1d..024027d4d 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -5,13 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallType.h"
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmInstallType.h"
+#include "cmScriptGenerator.h"
+
class cmLocalGenerator;
class cmMakefile;
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index a58f87578..6bb4409d5 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -2,73 +2,81 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallProgramsCommand.h"
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+ std::vector<std::string> const& args);
+static std::string FindInstallSource(cmMakefile& makefile, const char* name);
-// cmExecutableCommand
-bool cmInstallProgramsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmInstallProgramsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- // Enable the install target.
- this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
-
- this->Destination = args[0];
+ cmMakefile& mf = status.GetMakefile();
- cmAppend(this->FinalArgs, args.begin() + 1, args.end());
+ // Enable the install target.
+ mf.GetGlobalGenerator()->EnableInstallTarget();
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+ mf.GetGlobalGenerator()->AddInstallComponent(
+ mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+ std::string const& dest = args[0];
+ std::vector<std::string> const finalArgs(args.begin() + 1, args.end());
+ mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
+ FinalAction(makefile, dest, finalArgs);
+ });
return true;
}
-void cmInstallProgramsCommand::FinalPass()
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+ std::vector<std::string> const& args)
{
bool files_mode = false;
- if (!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES") {
+ if (!args.empty() && args[0] == "FILES") {
files_mode = true;
}
+ std::vector<std::string> files;
+
// two different options
- if (this->FinalArgs.size() > 1 || files_mode) {
+ if (args.size() > 1 || files_mode) {
// for each argument, get the programs
- std::vector<std::string>::iterator s = this->FinalArgs.begin();
+ auto s = args.begin();
if (files_mode) {
// Skip the FILES argument in files mode.
++s;
}
- for (; s != this->FinalArgs.end(); ++s) {
+ for (; s != args.end(); ++s) {
// add to the result
- this->Files.push_back(this->FindInstallSource(s->c_str()));
+ files.push_back(FindInstallSource(makefile, s->c_str()));
}
} else // reg exp list
{
std::vector<std::string> programs;
- cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(),
- this->FinalArgs[0], programs);
+ cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0],
+ programs);
- std::vector<std::string>::iterator s = programs.begin();
+ auto s = programs.begin();
// for each argument, get the programs
for (; s != programs.end(); ++s) {
- this->Files.push_back(this->FindInstallSource(s->c_str()));
+ files.push_back(FindInstallSource(makefile, s->c_str()));
}
}
// Construct the destination. This command always installs under
// the prefix. We skip the leading slash given by the user.
- std::string destination = this->Destination.substr(1);
+ std::string destination = dest.substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
if (destination.empty()) {
destination = ".";
@@ -79,12 +87,12 @@ void cmInstallProgramsCommand::FinalPass()
const char* no_rename = "";
bool no_exclude_from_all = false;
std::string no_component =
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
- cmInstallGenerator::SelectMessageLevel(this->Makefile);
- this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator(
- this->Files, destination.c_str(), true, no_permissions, no_configurations,
+ cmInstallGenerator::SelectMessageLevel(&makefile);
+ makefile.AddInstallGenerator(new cmInstallFilesGenerator(
+ files, destination.c_str(), true, no_permissions, no_configurations,
no_component.c_str(), message, no_exclude_from_all, no_rename));
}
@@ -94,7 +102,7 @@ void cmInstallProgramsCommand::FinalPass()
* present in the build tree. If a full path is given, it is just
* returned.
*/
-std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const
+static std::string FindInstallSource(cmMakefile& makefile, const char* name)
{
if (cmSystemTools::FileIsFullPath(name) ||
cmGeneratorExpression::Find(name) == 0) {
@@ -103,12 +111,8 @@ std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const
}
// This is a relative path.
- std::string tb = this->Makefile->GetCurrentBinaryDirectory();
- tb += "/";
- tb += name;
- std::string ts = this->Makefile->GetCurrentSourceDirectory();
- ts += "/";
- ts += name;
+ std::string tb = cmStrCat(makefile.GetCurrentBinaryDirectory(), '/', name);
+ std::string ts = cmStrCat(makefile.GetCurrentSourceDirectory(), '/', name);
if (cmSystemTools::FileExists(tb)) {
// The file exists in the binary tree. Use it.
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 5c705ebf6..c567f3bac 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -8,48 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmInstallProgramsCommand
- * \brief Specifies where to install some programs
- *
- * cmInstallProgramsCommand specifies the relative path where a list of
- * programs should be installed.
- */
-class cmInstallProgramsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmInstallProgramsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /**
- * This is called at the end after all the information
- * specified by the command is accumulated. Most commands do
- * not implement this method. At this point, reading and
- * writing to the cache can be done.
- */
- void FinalPass() override;
-
- bool HasFinalPass() const override { return true; }
-
-protected:
- std::string FindInstallSource(const char* name) const;
-
-private:
- std::vector<std::string> FinalArgs;
- std::string Destination;
- std::vector<std::string> Files;
-};
+bool cmInstallProgramsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index 5832d27e6..ea294556b 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -78,11 +78,9 @@ void cmInstallScriptGenerator::GenerateScriptForConfig(
std::ostream& os, const std::string& config, Indent indent)
{
if (this->AllowGenex) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(this->Script);
this->AddScriptInstallRule(os, indent,
- cge->Evaluate(this->LocalGenerator, config));
+ cmGeneratorExpression::Evaluate(
+ this->Script, this->LocalGenerator, config));
} else {
this->AddScriptInstallRule(os, indent, this->Script);
}
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 6af737113..7efa32169 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallGenerator.h"
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
+#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
+
class cmLocalGenerator;
/** \class cmInstallScriptGenerator
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index 1c0512ce5..8a0fefac2 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -2,15 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallSubdirectoryGenerator.h"
+#include <sstream>
+#include <vector>
+
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmScriptGenerator.h"
#include "cmSystemTools.h"
-#include <sstream>
-#include <vector>
-
cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator(
cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll)
: cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr,
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index 22759d948..b99bdd5ff 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallGenerator.h"
-
#include <iosfwd>
#include <string>
+#include "cmInstallGenerator.h"
+
class cmLocalGenerator;
class cmMakefile;
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 7c5a55bb6..aa92fa71a 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallTargetGenerator.h"
-#include <assert.h>
+#include <cassert>
#include <map>
#include <set>
#include <sstream>
@@ -16,7 +16,10 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmOutputConverter.h"
+#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -83,20 +86,18 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
std::string fromDirConfig;
if (this->Target->NeedRelinkBeforeInstall(config)) {
fromDirConfig =
- this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
- fromDirConfig += "/CMakeFiles";
- fromDirConfig += "/CMakeRelink.dir/";
+ cmStrCat(this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeRelink.dir/");
} else {
cmStateEnums::ArtifactType artifact = this->ImportLibrary
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
- fromDirConfig = this->Target->GetDirectory(config, artifact);
- fromDirConfig += "/";
+ fromDirConfig =
+ cmStrCat(this->Target->GetDirectory(config, artifact), '/');
}
- std::string toDir =
- this->ConvertToAbsoluteDestination(this->GetDestination(config));
- toDir += "/";
+ std::string toDir = cmStrCat(
+ this->ConvertToAbsoluteDestination(this->GetDestination(config)), '/');
// Compute the list of files to install for this target.
std::vector<std::string> filesFrom;
@@ -366,16 +367,15 @@ void cmInstallTargetGenerator::GetInstallObjectNames(
{
this->Target->GetTargetObjectNames(config, objects);
for (std::string& o : objects) {
- o = computeInstallObjectDir(this->Target, config) + "/" + o;
+ o = cmStrCat(computeInstallObjectDir(this->Target, config), "/", o);
}
}
std::string cmInstallTargetGenerator::GetDestination(
std::string const& config) const
{
- cmGeneratorExpression ge;
- return ge.Parse(this->Destination)
- ->Evaluate(this->Target->GetLocalGenerator(), config);
+ return cmGeneratorExpression::Evaluate(
+ this->Destination, this->Target->GetLocalGenerator(), config);
}
std::string cmInstallTargetGenerator::GetInstallFilename(
@@ -590,8 +590,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule(
// on the installed file.
if (for_build != for_install) {
// Prepare to refer to the install-tree install_name.
- new_id = for_install;
- new_id += this->GetInstallFilename(this->Target, config, NameSO);
+ new_id = cmStrCat(
+ for_install, this->GetInstallFilename(this->Target, config, NameSO));
}
}
@@ -632,17 +632,34 @@ void cmInstallTargetGenerator::AddRPathCheckRule(
return;
}
- // Get the install RPATH from the link information.
- std::string newRpath = cli->GetChrpathString();
-
// Write a rule to remove the installed file if its rpath is not the
// new rpath. This is needed for existing build/install trees when
// the installed rpath changes but the file is not rebuilt.
- /* clang-format off */
os << indent << "file(RPATH_CHECK\n"
- << indent << " FILE \"" << toDestDirPath << "\"\n"
- << indent << " RPATH \"" << newRpath << "\")\n";
- /* clang-format on */
+ << indent << " FILE \"" << toDestDirPath << "\"\n";
+
+ // CMP0095: ``RPATH`` entries are properly escaped in the intermediary
+ // CMake install script.
+ switch (this->Target->GetPolicyStatusCMP0095()) {
+ case cmPolicies::WARN:
+ // No author warning needed here, we warn later in
+ // cmInstallTargetGenerator::AddChrpathPatchRule().
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD: {
+ // Get the install RPATH from the link information.
+ std::string newRpath = cli->GetChrpathString();
+ os << indent << " RPATH \"" << newRpath << "\")\n";
+ break;
+ }
+ default: {
+ // Get the install RPATH from the link information and
+ // escape any CMake syntax in the install RPATH.
+ std::string escapedNewRpath =
+ cmOutputConverter::EscapeForCMake(cli->GetChrpathString());
+ os << indent << " RPATH " << escapedNewRpath << ")\n";
+ break;
+ }
+ }
}
void cmInstallTargetGenerator::AddChrpathPatchRule(
@@ -668,7 +685,8 @@ void cmInstallTargetGenerator::AddChrpathPatchRule(
std::string installNameTool =
mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
- std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
+ std::vector<std::string> oldRuntimeDirs;
+ std::vector<std::string> newRuntimeDirs;
cli->GetRPath(oldRuntimeDirs, false);
cli->GetRPath(newRuntimeDirs, true);
@@ -731,11 +749,34 @@ void cmInstallTargetGenerator::AddChrpathPatchRule(
return;
}
+ // Escape any CMake syntax in the RPATHs.
+ std::string escapedOldRpath = cmOutputConverter::EscapeForCMake(oldRpath);
+ std::string escapedNewRpath = cmOutputConverter::EscapeForCMake(newRpath);
+
// Write a rule to run chrpath to set the install-tree RPATH
os << indent << "file(RPATH_CHANGE\n"
<< indent << " FILE \"" << toDestDirPath << "\"\n"
- << indent << " OLD_RPATH \"" << oldRpath << "\"\n"
- << indent << " NEW_RPATH \"" << newRpath << "\")\n";
+ << indent << " OLD_RPATH " << escapedOldRpath << "\n";
+
+ // CMP0095: ``RPATH`` entries are properly escaped in the intermediary
+ // CMake install script.
+ switch (this->Target->GetPolicyStatusCMP0095()) {
+ case cmPolicies::WARN:
+ this->IssueCMP0095Warning(newRpath);
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ os << indent << " NEW_RPATH \"" << newRpath << "\"";
+ break;
+ default:
+ os << indent << " NEW_RPATH " << escapedNewRpath;
+ break;
+ }
+
+ if (this->Target->GetPropertyAsBool("INSTALL_REMOVE_ENVIRONMENT_RPATH")) {
+ os << "\n" << indent << " INSTALL_REMOVE_ENVIRONMENT_RPATH)\n";
+ } else {
+ os << ")\n";
+ }
}
}
@@ -838,3 +879,26 @@ void cmInstallTargetGenerator::AddUniversalInstallRule(
<< "\"" << this->Target->Target->GetName() << "\" "
<< "\"" << toDestDirPath << "\")\n";
}
+
+void cmInstallTargetGenerator::IssueCMP0095Warning(
+ const std::string& unescapedRpath)
+{
+ // Reduce warning noise to cases where used RPATHs may actually be affected
+ // by CMP0095. This filter is meant to skip warnings in cases when
+ // non-curly-braces syntax (e.g. $ORIGIN) or no keyword is used which has
+ // worked already before CMP0095. We intend to issue a warning in all cases
+ // with curly-braces syntax, even if the workaround of double-escaping is in
+ // place, since we deprecate the need for it with CMP0095.
+ const bool potentially_affected(unescapedRpath.find("${") !=
+ std::string::npos);
+
+ if (potentially_affected) {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0095) << "\n";
+ w << "RPATH entries for target '" << this->Target->GetName() << "' "
+ << "will not be escaped in the intermediary "
+ << "cmake_install.cmake script.";
+ this->Target->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING, w.str(), this->GetBacktrace());
+ }
+}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index ed3ab5246..8730454b1 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmInstallGenerator.h"
+#include "cmListFileCache.h"
+#include "cmScriptGenerator.h"
+
class cmGeneratorTarget;
class cmLocalGenerator;
@@ -74,9 +74,9 @@ protected:
void GenerateScriptForConfigObjectLibrary(std::ostream& os,
const std::string& config,
Indent indent);
- typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&, Indent,
- const std::string&,
- std::string const&);
+ using TweakMethod = void (cmInstallTargetGenerator::*)(std::ostream&, Indent,
+ const std::string&,
+ const std::string&);
void AddTweak(std::ostream& os, Indent indent, const std::string& config,
std::string const& file, TweakMethod tweak);
void AddTweak(std::ostream& os, Indent indent, const std::string& config,
@@ -104,6 +104,7 @@ protected:
const std::string& toDestDirPath);
void AddUniversalInstallRule(std::ostream& os, Indent indent,
const std::string& toDestDirPath);
+ void IssueCMP0095Warning(const std::string& unescapedRpath);
std::string TargetName;
cmGeneratorTarget* Target;
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
index ef07e2cf4..44f23a581 100644
--- a/Source/cmInstallTargetsCommand.cxx
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -5,54 +5,54 @@
#include <unordered_map>
#include <utility>
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmExecutableCommand
-bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmInstallTargetsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Enable the install target.
- this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
+ mf.GetGlobalGenerator()->EnableInstallTarget();
- cmMakefile::cmTargetMap& tgts = this->Makefile->GetTargets();
- std::vector<std::string>::const_iterator s = args.begin();
+ cmMakefile::cmTargetMap& tgts = mf.GetTargets();
+ auto s = args.begin();
++s;
std::string runtime_dir = "/bin";
for (; s != args.end(); ++s) {
if (*s == "RUNTIME_DIRECTORY") {
++s;
if (s == args.end()) {
- this->SetError("called with RUNTIME_DIRECTORY but no actual "
- "directory");
+ status.SetError("called with RUNTIME_DIRECTORY but no actual "
+ "directory");
return false;
}
runtime_dir = *s;
} else {
- cmMakefile::cmTargetMap::iterator ti = tgts.find(*s);
+ auto ti = tgts.find(*s);
if (ti != tgts.end()) {
ti->second.SetInstallPath(args[0]);
ti->second.SetRuntimeInstallPath(runtime_dir);
ti->second.SetHaveInstallRule(true);
} else {
std::string str = "Cannot find target: \"" + *s + "\" to install.";
- this->SetError(str);
+ status.SetError(str);
return false;
}
}
}
- this->Makefile->GetGlobalGenerator()->AddInstallComponent(
- this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+ mf.GetGlobalGenerator()->AddInstallComponent(
+ mf.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
return true;
}
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index 9950fb7db..0c5850c91 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmInstallTargetsCommand
- * \brief Specifies where to install some targets
- *
- * cmInstallTargetsCommand specifies the relative path where a list of
- * targets should be installed. The targets can be executables or
- * libraries.
- */
-class cmInstallTargetsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmInstallTargetsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmInstallTargetsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 537b4ecec..eabe5903b 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -2,12 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstalledFile.h"
+#include <utility>
+
#include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
-#include "cmSystemTools.h"
-
-#include <utility>
+#include "cmStringAlgorithms.h"
cmInstalledFile::cmInstalledFile() = default;
@@ -73,7 +74,7 @@ bool cmInstalledFile::HasProperty(const std::string& prop) const
bool cmInstalledFile::GetProperty(const std::string& prop,
std::string& value) const
{
- PropertyMapType::const_iterator i = this->Properties.find(prop);
+ auto i = this->Properties.find(prop);
if (i == this->Properties.end()) {
return false;
}
@@ -97,7 +98,7 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
{
std::string value;
bool isSet = this->GetProperty(prop, value);
- return isSet && cmSystemTools::IsOn(value);
+ return isSet && cmIsOn(value);
}
void cmInstalledFile::GetPropertyAsList(const std::string& prop,
@@ -107,5 +108,5 @@ void cmInstalledFile::GetPropertyAsList(const std::string& prop,
this->GetProperty(prop, value);
list.clear();
- cmSystemTools::ExpandListArgument(value, list);
+ cmExpandList(value, list);
}
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index b7d602ef4..ee809ee79 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -5,13 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGeneratorExpression.h"
-
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
+class cmCompiledGeneratorExpression;
class cmMakefile;
/** \class cmInstalledFile
@@ -22,10 +21,10 @@ class cmMakefile;
class cmInstalledFile
{
public:
- typedef std::unique_ptr<cmCompiledGeneratorExpression>
- CompiledGeneratorExpressionPtrType;
+ using CompiledGeneratorExpressionPtrType =
+ std::unique_ptr<cmCompiledGeneratorExpression>;
- typedef std::vector<cmCompiledGeneratorExpression*> ExpressionVectorType;
+ using ExpressionVectorType = std::vector<cmCompiledGeneratorExpression*>;
struct Property
{
@@ -38,7 +37,7 @@ public:
ExpressionVectorType ValueExpressions;
};
- typedef std::map<std::string, Property> PropertyMapType;
+ using PropertyMapType = std::map<std::string, Property>;
cmInstalledFile();
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index 636a8e1c2..b23ab43d8 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -2,6 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmJsonObjects.h" // IWYU pragma: keep
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <limits>
+#include <map>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -14,30 +26,18 @@
#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
-#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
#include "cmake.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <functional>
-#include <limits>
-#include <map>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
namespace {
std::vector<std::string> getConfigurations(const cmake* cm)
@@ -263,7 +263,7 @@ static Json::Value DumpSourceFilesList(
std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
for (cmSourceFile* file : files) {
LanguageData fileData;
- fileData.Language = file->GetLanguage();
+ fileData.Language = file->GetOrDetermineLanguage();
if (!fileData.Language.empty()) {
const LanguageData& ld = languageDataMap.at(fileData.Language);
cmLocalGenerator* lg = target->GetLocalGenerator();
@@ -326,7 +326,7 @@ static Json::Value DumpSourceFilesList(
fileData.IsGenerated = file->GetIsGenerated();
std::vector<std::string>& groupFileList = fileGroups[fileData];
- groupFileList.push_back(file->GetFullPath());
+ groupFileList.push_back(file->ResolveFullPath());
}
const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory();
@@ -356,21 +356,18 @@ static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo,
}
// Remove any config specific variables from the output.
- cmGeneratorExpression ge;
- auto cge = ge.Parse(command);
- const std::string& processed = cge->Evaluate(lg, config);
- result[kCTEST_COMMAND] = processed;
+ result[kCTEST_COMMAND] =
+ cmGeneratorExpression::Evaluate(command, lg, config);
// Build up the list of properties that may have been specified
Json::Value properties = Json::arrayValue;
- for (auto& prop : testInfo->GetProperties()) {
+ for (auto& prop : testInfo->GetProperties().GetList()) {
Json::Value entry = Json::objectValue;
entry[kKEY_KEY] = prop.first;
// Remove config variables from the value too.
- auto cge_value = ge.Parse(prop.second.GetValue());
- const std::string& processed_value = cge_value->Evaluate(lg, config);
- entry[kVALUE_KEY] = processed_value;
+ entry[kVALUE_KEY] =
+ cmGeneratorExpression::Evaluate(prop.second, lg, config);
properties.append(entry);
}
result[kPROPERTIES_KEY] = properties;
@@ -500,9 +497,9 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) {
installPath = dest;
} else {
- std::string installPrefix =
- target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
- installPath = installPrefix + '/' + dest;
+ installPath = cmStrCat(
+ target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/',
+ dest);
}
installPaths.append(installPath);
@@ -516,9 +513,11 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
Json::Value artifacts = Json::arrayValue;
artifacts.append(
target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact));
- if (target->IsDLLPlatform()) {
+ if (target->HasImportLibrary(config)) {
artifacts.append(
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+ }
+ if (target->IsDLLPlatform()) {
const cmGeneratorTarget::OutputInfo* output =
target->GetOutputInfo(config);
if (output && !output->PdbDir.empty()) {
@@ -539,19 +538,19 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
linkFlags, frameworkPath, linkPath, target);
- linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
- linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags);
- frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath);
- linkPath = cmSystemTools::TrimWhitespace(linkPath);
+ linkLibs = cmTrimWhitespace(linkLibs);
+ linkFlags = cmTrimWhitespace(linkFlags);
+ linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
+ frameworkPath = cmTrimWhitespace(frameworkPath);
+ linkPath = cmTrimWhitespace(linkPath);
- if (!cmSystemTools::TrimWhitespace(linkLibs).empty()) {
+ if (!cmTrimWhitespace(linkLibs).empty()) {
result[kLINK_LIBRARIES_KEY] = linkLibs;
}
- if (!cmSystemTools::TrimWhitespace(linkFlags).empty()) {
+ if (!cmTrimWhitespace(linkFlags).empty()) {
result[kLINK_FLAGS_KEY] = linkFlags;
}
- if (!cmSystemTools::TrimWhitespace(linkLanguageFlags).empty()) {
+ if (!cmTrimWhitespace(linkLanguageFlags).empty()) {
result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags;
}
if (!frameworkPath.empty()) {
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
index cd4da94f4..64291cc06 100644
--- a/Source/cmJsonObjects.h
+++ b/Source/cmJsonObjects.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
-
#include <string>
#include <vector>
+#include "cm_jsoncpp_value.h"
+
class cmake;
class cmGlobalGenerator;
diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx
new file mode 100644
index 000000000..cce6178da
--- /dev/null
+++ b/Source/cmLDConfigLDConfigTool.cxx
@@ -0,0 +1,71 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmLDConfigLDConfigTool.h"
+
+#include <istream>
+#include <string>
+#include <vector>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmMakefile.h"
+#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
+
+cmLDConfigLDConfigTool::cmLDConfigLDConfigTool(
+ cmRuntimeDependencyArchive* archive)
+ : cmLDConfigTool(archive)
+{
+}
+
+bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
+{
+ std::string ldConfigPath =
+ this->Archive->GetMakefile()->GetSafeDefinition("CMAKE_LDCONFIG_COMMAND");
+ if (ldConfigPath.empty()) {
+ ldConfigPath = cmSystemTools::FindProgram(
+ "ldconfig", { "/sbin", "/usr/sbin", "/usr/local/sbin" });
+ if (ldConfigPath.empty()) {
+ this->Archive->SetError("Could not find ldconfig");
+ return false;
+ }
+ }
+
+ std::vector<std::string> ldConfigCommand = cmExpandedList(ldConfigPath);
+ ldConfigCommand.emplace_back("-v");
+ ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache.
+ ldConfigCommand.emplace_back("-X"); // Don't update links.
+
+ cmUVProcessChainBuilder builder;
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .AddCommand(ldConfigCommand);
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ this->Archive->SetError("Failed to start ldconfig process");
+ return false;
+ }
+
+ std::string line;
+ static const cmsys::RegularExpression regex("^([^\t:]*):");
+ while (std::getline(*process.OutputStream(), line)) {
+ cmsys::RegularExpressionMatch match;
+ if (regex.find(line.c_str(), match)) {
+ paths.push_back(match.match(1));
+ }
+ }
+
+ if (!process.Wait()) {
+ this->Archive->SetError("Failed to wait on ldconfig process");
+ return false;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ this->Archive->SetError("Failed to run ldconfig");
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmLDConfigLDConfigTool.h b/Source/cmLDConfigLDConfigTool.h
new file mode 100644
index 000000000..34bf6c61f
--- /dev/null
+++ b/Source/cmLDConfigLDConfigTool.h
@@ -0,0 +1,22 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmLDConfigLDConfigTool_h
+#define cmLDConfigLDConfigTool_h
+
+#include <string>
+#include <vector>
+
+#include "cmLDConfigTool.h"
+
+class cmRuntimeDependencyArchive;
+
+class cmLDConfigLDConfigTool : public cmLDConfigTool
+{
+public:
+ cmLDConfigLDConfigTool(cmRuntimeDependencyArchive* archive);
+
+ bool GetLDConfigPaths(std::vector<std::string>& paths) override;
+};
+
+#endif
diff --git a/Source/cmLDConfigTool.cxx b/Source/cmLDConfigTool.cxx
new file mode 100644
index 000000000..8d5d5630b
--- /dev/null
+++ b/Source/cmLDConfigTool.cxx
@@ -0,0 +1,9 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmLDConfigTool.h"
+
+cmLDConfigTool::cmLDConfigTool(cmRuntimeDependencyArchive* archive)
+ : Archive(archive)
+{
+}
diff --git a/Source/cmLDConfigTool.h b/Source/cmLDConfigTool.h
new file mode 100644
index 000000000..c816562d4
--- /dev/null
+++ b/Source/cmLDConfigTool.h
@@ -0,0 +1,24 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmLDConfigTool_h
+#define cmLDConfigTool_h
+
+#include <string>
+#include <vector>
+
+class cmRuntimeDependencyArchive;
+
+class cmLDConfigTool
+{
+public:
+ cmLDConfigTool(cmRuntimeDependencyArchive* archive);
+ virtual ~cmLDConfigTool() = default;
+
+ virtual bool GetLDConfigPaths(std::vector<std::string>& paths) = 0;
+
+protected:
+ cmRuntimeDependencyArchive* Archive;
+};
+
+#endif
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 785097745..29140462a 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -4,24 +4,26 @@
#include <sstream>
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+static void AddLinkDir(cmMakefile& mf, std::string const& dir,
+ std::vector<std::string>& directories);
-// cmLinkDirectoriesCommand
-bool cmLinkDirectoriesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmLinkDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
}
- bool before = this->Makefile->IsOn("CMAKE_LINK_DIRECTORIES_BEFORE");
+ cmMakefile& mf = status.GetMakefile();
+ bool before = mf.IsOn("CMAKE_LINK_DIRECTORIES_BEFORE");
auto i = args.cbegin();
if ((*i) == "BEFORE") {
@@ -34,16 +36,16 @@ bool cmLinkDirectoriesCommand::InitialPass(
std::vector<std::string> directories;
for (; i != args.cend(); ++i) {
- this->AddLinkDir(*i, directories);
+ AddLinkDir(mf, *i, directories);
}
- this->Makefile->AddLinkDirectory(cmJoin(directories, ";"), before);
+ mf.AddLinkDirectory(cmJoin(directories, ";"), before);
return true;
}
-void cmLinkDirectoriesCommand::AddLinkDir(
- std::string const& dir, std::vector<std::string>& directories)
+static void AddLinkDir(cmMakefile& mf, std::string const& dir,
+ std::vector<std::string>& directories)
{
std::string unixPath = dir;
cmSystemTools::ConvertToUnixSlashes(unixPath);
@@ -56,10 +58,10 @@ void cmLinkDirectoriesCommand::AddLinkDir(
<< " " << unixPath << "\n"
<< "as a link directory.\n";
/* clang-format on */
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0015)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0015)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0015);
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
break;
case cmPolicies::OLD:
// OLD behavior does not convert
@@ -67,7 +69,7 @@ void cmLinkDirectoriesCommand::AddLinkDir(
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0015);
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
CM_FALLTHROUGH;
case cmPolicies::NEW:
// NEW behavior converts
@@ -75,10 +77,7 @@ void cmLinkDirectoriesCommand::AddLinkDir(
break;
}
if (convertToAbsolute) {
- std::string tmp = this->Makefile->GetCurrentSourceDirectory();
- tmp += "/";
- tmp += unixPath;
- unixPath = tmp;
+ unixPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', unixPath);
}
}
directories.push_back(unixPath);
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index ae4fb7f5f..a7caa5c63 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -8,36 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmLinkDirectoriesCommand
- * \brief Define a list of directories containing files to link.
- *
- * cmLinkDirectoriesCommand is used to specify a list
- * of directories containing files to link into executable(s).
- * Note that the command supports the use of CMake built-in variables
- * such as CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR.
- */
-class cmLinkDirectoriesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmLinkDirectoriesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void AddLinkDir(std::string const& dir,
- std::vector<std::string>& directories);
-};
+bool cmLinkDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx
index 9b03ad011..91eb18337 100644
--- a/Source/cmLinkItem.cxx
+++ b/Source/cmLinkItem.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLinkItem.h"
-#include "cmGeneratorTarget.h"
-
#include <utility> // IWYU pragma: keep
+#include "cmGeneratorTarget.h"
+
cmLinkItem::cmLinkItem() = default;
cmLinkItem::cmLinkItem(std::string n, cmListFileBacktrace bt)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 5b635b5b3..2d9378bd5 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <algorithm>
#include <map>
#include <ostream>
#include <string>
#include <vector>
+#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTargetLinkLibraryType.h"
@@ -58,6 +58,9 @@ struct cmLinkInterfaceLibraries
{
// Libraries listed in the interface.
std::vector<cmLinkItem> Libraries;
+
+ // Whether the list depends on a genex referencing the head target.
+ bool HadHeadSensitiveCondition = false;
};
struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -84,8 +87,7 @@ struct cmOptionalLinkInterface : public cmLinkInterface
bool LibrariesDone = false;
bool AllDone = false;
bool Exists = false;
- bool HadHeadSensitiveCondition = false;
- const char* ExplicitLibraries = nullptr;
+ bool Explicit = false;
};
struct cmHeadToLinkInterfaceMap
@@ -118,8 +120,7 @@ inline cmTargetLinkLibraryType CMP0003_ComputeLinkType(
// Check if any entry in the list matches this configuration.
std::string configUpper = cmSystemTools::UpperCase(config);
- if (std::find(debugConfigs.begin(), debugConfigs.end(), configUpper) !=
- debugConfigs.end()) {
+ if (cmContains(debugConfigs, configUpper)) {
return DEBUG_LibraryType;
}
// The current configuration is not a debug configuration.
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index 13f6baef3..cb63ceb03 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -2,39 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLinkLibrariesCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmLinkLibrariesCommand
-bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmLinkLibrariesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
}
+ cmMakefile& mf = status.GetMakefile();
// add libraries, note that there is an optional prefix
// of debug and optimized than can be used
- for (std::vector<std::string>::const_iterator i = args.begin();
- i != args.end(); ++i) {
+ for (auto i = args.begin(); i != args.end(); ++i) {
if (*i == "debug") {
++i;
if (i == args.end()) {
- this->SetError("The \"debug\" argument must be followed by "
- "a library");
+ status.SetError("The \"debug\" argument must be followed by "
+ "a library");
return false;
}
- this->Makefile->AppendProperty("LINK_LIBRARIES", "debug");
+ mf.AppendProperty("LINK_LIBRARIES", "debug");
} else if (*i == "optimized") {
++i;
if (i == args.end()) {
- this->SetError("The \"optimized\" argument must be followed by "
- "a library");
+ status.SetError("The \"optimized\" argument must be followed by "
+ "a library");
return false;
}
- this->Makefile->AppendProperty("LINK_LIBRARIES", "optimized");
+ mf.AppendProperty("LINK_LIBRARIES", "optimized");
}
- this->Makefile->AppendProperty("LINK_LIBRARIES", i->c_str());
+ mf.AppendProperty("LINK_LIBRARIES", i->c_str());
}
return true;
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index af25fba4a..34122513c 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmLinkLibrariesCommand
- * \brief Specify a list of libraries to link into executables.
- *
- * cmLinkLibrariesCommand is used to specify a list of libraries to link
- * into executable(s) or shared objects. The names of the libraries
- * should be those defined by the LIBRARY(library) command(s).
- */
-class cmLinkLibrariesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmLinkLibrariesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmLinkLibrariesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 469faca88..0dc6236a0 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -4,13 +4,17 @@
#include "cmLinkLineComputer.h"
#include <sstream>
+#include <utility>
#include <vector>
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
+#include "cmLinkItem.h"
+#include "cmListFileCache.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
@@ -55,22 +59,49 @@ std::string cmLinkLineComputer::ConvertToLinkReference(
std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli)
{
std::string linkLibs;
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ std::vector<BT<std::string>> linkLibsList;
+ this->ComputeLinkLibs(cli, linkLibsList);
+ cli.AppendValues(linkLibs, linkLibsList);
+ return linkLibs;
+}
+
+void cmLinkLineComputer::ComputeLinkLibs(
+ cmComputeLinkInformation& cli, std::vector<BT<std::string>>& linkLibraries)
+{
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
for (auto const& item : items) {
if (item.Target &&
item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
+
+ BT<std::string> linkLib;
if (item.IsPath) {
- linkLibs +=
+ linkLib.Value += cli.GetLibLinkFileFlag();
+ linkLib.Value +=
this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value));
} else {
- linkLibs += item.Value;
+ linkLib.Value += item.Value;
}
- linkLibs += " ";
+ linkLib.Value += " ";
+
+ const cmLinkImplementation* linkImpl =
+ cli.GetTarget()->GetLinkImplementation(cli.GetConfig());
+
+ for (const cmLinkImplItem& iter : linkImpl->Libraries) {
+ if (iter.Target != nullptr &&
+ iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ std::string libPath = iter.Target->GetLocation(cli.GetConfig());
+ if (item.Value == libPath) {
+ linkLib.Backtrace = iter.Backtrace;
+ break;
+ }
+ }
+ }
+
+ linkLibraries.emplace_back(linkLib);
}
- return linkLibs;
}
std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
@@ -99,8 +130,19 @@ std::string cmLinkLineComputer::ComputeLinkPath(
std::string const& libPathTerminator)
{
std::string linkPath;
+ std::vector<BT<std::string>> linkPathList;
+ this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList);
+ cli.AppendValues(linkPath, linkPathList);
+ return linkPath;
+}
+void cmLinkLineComputer::ComputeLinkPath(
+ cmComputeLinkInformation& cli, std::string const& libPathFlag,
+ std::string const& libPathTerminator, std::vector<BT<std::string>>& linkPath)
+{
if (cli.GetLinkLanguage() == "Swift") {
+ std::string linkPathNoBT;
+
for (const cmComputeLinkInformation::Item& item : cli.GetItems()) {
const cmGeneratorTarget* target = item.Target;
if (!target) {
@@ -110,24 +152,27 @@ std::string cmLinkLineComputer::ComputeLinkPath(
if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
target->GetType() == cmStateEnums::SHARED_LIBRARY) {
cmStateEnums::ArtifactType type = cmStateEnums::RuntimeBinaryArtifact;
- if (target->GetType() == cmStateEnums::SHARED_LIBRARY &&
- target->IsDLLPlatform()) {
+ if (target->HasImportLibrary(cli.GetConfig())) {
type = cmStateEnums::ImportLibraryArtifact;
}
- linkPath += " " + libPathFlag +
- item.Target->GetDirectory(cli.GetConfig(), type) +
- libPathTerminator + " ";
+ linkPathNoBT += cmStrCat(
+ " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type),
+ libPathTerminator, " ");
}
}
- }
- for (std::string const& libDir : cli.GetDirectories()) {
- linkPath += " " + libPathFlag + this->ConvertToOutputForExisting(libDir) +
- libPathTerminator + " ";
+ if (!linkPathNoBT.empty()) {
+ linkPath.emplace_back(std::move(linkPathNoBT));
+ }
}
- return linkPath;
+ for (BT<std::string> libDir : cli.GetDirectoriesWithBacktraces()) {
+ libDir.Value = cmStrCat(" ", libPathFlag,
+ this->ConvertToOutputForExisting(libDir.Value),
+ libPathTerminator, " ");
+ linkPath.emplace_back(libDir);
+ }
}
std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli)
@@ -177,13 +222,30 @@ std::string cmLinkLineComputer::ComputeFrameworkPath(
std::string cmLinkLineComputer::ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString)
{
- std::ostringstream fout;
- fout << this->ComputeRPath(cli);
+ std::string linkLibraries;
+ std::vector<BT<std::string>> linkLibrariesList;
+ this->ComputeLinkLibraries(cli, stdLibString, linkLibrariesList);
+ cli.AppendValues(linkLibraries, linkLibrariesList);
+ return linkLibraries;
+}
+
+void cmLinkLineComputer::ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString,
+ std::vector<BT<std::string>>& linkLibraries)
+{
+ std::ostringstream rpathOut;
+ rpathOut << this->ComputeRPath(cli);
+
+ std::string rpath = rpathOut.str();
+ if (!rpath.empty()) {
+ linkLibraries.emplace_back(std::move(rpath));
+ }
// Write the library flags to the build rule.
- fout << this->ComputeLinkLibs(cli);
+ this->ComputeLinkLibs(cli, linkLibraries);
// Add the linker runtime search path if any.
+ std::ostringstream fout;
std::string rpath_link = cli.GetRPathLinkString();
if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) {
fout << cli.GetRPathLinkFlag();
@@ -196,7 +258,10 @@ std::string cmLinkLineComputer::ComputeLinkLibraries(
fout << stdLibString << " ";
}
- return fout.str();
+ std::string remainingLibs = fout.str();
+ if (!remainingLibs.empty()) {
+ linkLibraries.emplace_back(remainingLibs);
+ }
}
std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target,
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index 2355c3270..f426976a2 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -7,12 +7,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
+#include <vector>
#include "cmStateDirectory.h"
class cmComputeLinkInformation;
class cmGeneratorTarget;
class cmOutputConverter;
+template <typename T>
+class BT;
class cmLinkLineComputer
{
@@ -34,17 +37,28 @@ public:
std::string const& libPathFlag,
std::string const& libPathTerminator);
+ void ComputeLinkPath(cmComputeLinkInformation& cli,
+ std::string const& libPathFlag,
+ std::string const& libPathTerminator,
+ std::vector<BT<std::string>>& linkPath);
+
std::string ComputeFrameworkPath(cmComputeLinkInformation& cli,
std::string const& fwSearchFlag);
- virtual std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
- std::string const& stdLibString);
+ std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
+ std::string const& stdLibString);
+
+ virtual void ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString,
+ std::vector<BT<std::string>>& linkLibraries);
virtual std::string GetLinkerLanguage(cmGeneratorTarget* target,
std::string const& config);
protected:
std::string ComputeLinkLibs(cmComputeLinkInformation& cli);
+ void ComputeLinkLibs(cmComputeLinkInformation& cli,
+ std::vector<BT<std::string>>& linkLibraries);
std::string ComputeRPath(cmComputeLinkInformation& cli);
std::string ConvertToOutputFormat(std::string const& input);
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 2cb2fd635..d8456523d 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -3,21 +3,21 @@
#include "cmLinkLineDeviceComputer.h"
-#include <algorithm>
#include <set>
-#include <sstream>
#include <utility>
-#include <vector>
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
class cmOutputConverter;
@@ -52,7 +52,7 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
{
// Determine if this item might requires device linking.
// For this we only consider targets
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
std::string config = cli.GetConfig();
for (auto const& item : items) {
@@ -68,21 +68,22 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
return false;
}
-std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
- cmComputeLinkInformation& cli, std::string const& stdLibString)
+void cmLinkLineDeviceComputer::ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString,
+ std::vector<BT<std::string>>& linkLibraries)
{
- // Write the library flags to the build rule.
- std::ostringstream fout;
-
// Generate the unique set of link items when device linking.
// The nvcc device linker is designed so that each static library
// with device symbols only needs to be listed once as it doesn't
// care about link order.
std::set<std::string> emitted;
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
std::string config = cli.GetConfig();
bool skipItemAfterFramework = false;
+ // Note:
+ // Any modification of this algorithm should be reflected also in
+ // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions
for (auto const& item : items) {
if (skipItemAfterFramework) {
skipItemAfterFramework = false;
@@ -92,6 +93,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
if (item.Target) {
bool skip = false;
switch (item.Target->GetType()) {
+ case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::INTERFACE_LIBRARY:
skip = true;
@@ -107,7 +109,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
}
}
- std::string out;
+ BT<std::string> linkLib;
if (item.IsPath) {
// nvcc understands absolute paths to libraries ending in '.a' or '.lib'.
// These should be passed to nvlink. Other extensions need to be left
@@ -115,7 +117,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
// can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'.
if (cmHasLiteralSuffix(item.Value, ".a") ||
cmHasLiteralSuffix(item.Value, ".lib")) {
- out += this->ConvertToOutputFormat(
+ linkLib.Value += this->ConvertToOutputFormat(
this->ConvertToLinkReference(item.Value));
}
} else if (item.Value == "-framework") {
@@ -124,19 +126,33 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
skipItemAfterFramework = true;
continue;
} else if (cmLinkItemValidForDevice(item.Value)) {
- out += item.Value;
+ linkLib.Value += item.Value;
}
- if (emitted.insert(out).second) {
- fout << out << " ";
+ if (emitted.insert(linkLib.Value).second) {
+ linkLib.Value += " ";
+
+ const cmLinkImplementation* linkImpl =
+ cli.GetTarget()->GetLinkImplementation(cli.GetConfig());
+
+ for (const cmLinkImplItem& iter : linkImpl->Libraries) {
+ if (iter.Target != nullptr &&
+ iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ std::string libPath = iter.Target->GetLocation(cli.GetConfig());
+ if (item.Value == libPath) {
+ linkLib.Backtrace = iter.Backtrace;
+ break;
+ }
+ }
+ }
+
+ linkLibraries.emplace_back(linkLib);
}
}
if (!stdLibString.empty()) {
- fout << stdLibString << " ";
+ linkLibraries.emplace_back(cmStrCat(stdLibString, ' '));
}
-
- return fout.str();
}
std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
@@ -156,40 +172,40 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
return false;
}
+ if (!lg.GetMakefile()->IsOn("CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE")) {
+ return false;
+ }
+
if (const char* 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 cmSystemTools::IsOn(resolveDeviceSymbols);
+ return cmIsOn(resolveDeviceSymbols);
+ }
+
+ if (const char* separableCompilation =
+ target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
+ if (cmIsOn(separableCompilation)) {
+ bool doDeviceLinking = false;
+ switch (target.GetType()) {
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::EXECUTABLE:
+ doDeviceLinking = true;
+ break;
+ default:
+ break;
+ }
+ return doDeviceLinking;
+ }
}
// Determine if we have any dependencies that require
// us to do a device link step
- const std::string cuda_lang("CUDA");
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- bool closureHasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
-
- if (closureHasCUDA) {
- if (const char* separableCompilation =
- target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
- if (cmSystemTools::IsOn(separableCompilation)) {
- bool doDeviceLinking = false;
- switch (target.GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::EXECUTABLE:
- doDeviceLinking = true;
- break;
- default:
- break;
- }
- return doDeviceLinking;
- }
- }
+ if (cmContains(closure->Languages, "CUDA")) {
cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
if (pcli) {
cmLinkLineDeviceComputer deviceLinkComputer(
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index 0ea5f69e7..a9b01cd9c 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -7,6 +7,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
+#include <vector>
#include "cmLinkLineComputer.h"
@@ -15,6 +16,8 @@ class cmGeneratorTarget;
class cmLocalGenerator;
class cmOutputConverter;
class cmStateDirectory;
+template <typename T>
+class BT;
class cmLinkLineDeviceComputer : public cmLinkLineComputer
{
@@ -29,8 +32,9 @@ public:
bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli);
- std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
- std::string const& stdLibString) override;
+ void ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString,
+ std::vector<BT<std::string>>& linkLibraries) override;
std::string GetLinkerLanguage(cmGeneratorTarget* target,
std::string const& config) override;
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index 099fb6d11..c7453eac9 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <assert.h>
+#include <cassert>
#include <vector>
/**
@@ -27,9 +27,9 @@
template <typename T>
class cmLinkedTree
{
- typedef typename std::vector<T>::size_type PositionType;
- typedef T* PointerType;
- typedef T& ReferenceType;
+ using PositionType = typename std::vector<T>::size_type;
+ using PointerType = T*;
+ using ReferenceType = T&;
public:
class iterator
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 1b01ea202..5200a160f 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -2,100 +2,49 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmListCommand.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib> // required for atoi
#include <functional>
#include <iterator>
#include <set>
#include <sstream>
#include <stdexcept>
-#include <stdio.h>
-#include <stdlib.h> // required for atoi
#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_static_string_view.hxx"
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-bool cmListCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
-{
- if (args.size() < 2) {
- this->SetError("must be called with at least two arguments.");
- return false;
- }
-
- const std::string& subCommand = args[0];
- if (subCommand == "LENGTH") {
- return this->HandleLengthCommand(args);
- }
- if (subCommand == "GET") {
- return this->HandleGetCommand(args);
- }
- if (subCommand == "APPEND") {
- return this->HandleAppendCommand(args);
- }
- if (subCommand == "PREPEND") {
- return this->HandlePrependCommand(args);
- }
- if (subCommand == "POP_BACK") {
- return this->HandlePopBackCommand(args);
- }
- if (subCommand == "POP_FRONT") {
- return this->HandlePopFrontCommand(args);
- }
- if (subCommand == "FIND") {
- return this->HandleFindCommand(args);
- }
- if (subCommand == "INSERT") {
- return this->HandleInsertCommand(args);
- }
- if (subCommand == "JOIN") {
- return this->HandleJoinCommand(args);
- }
- if (subCommand == "REMOVE_AT") {
- return this->HandleRemoveAtCommand(args);
- }
- if (subCommand == "REMOVE_ITEM") {
- return this->HandleRemoveItemCommand(args);
- }
- if (subCommand == "REMOVE_DUPLICATES") {
- return this->HandleRemoveDuplicatesCommand(args);
- }
- if (subCommand == "TRANSFORM") {
- return this->HandleTransformCommand(args);
- }
- if (subCommand == "SORT") {
- return this->HandleSortCommand(args);
- }
- if (subCommand == "SUBLIST") {
- return this->HandleSublistCommand(args);
- }
- if (subCommand == "REVERSE") {
- return this->HandleReverseCommand(args);
- }
- if (subCommand == "FILTER") {
- return this->HandleFilterCommand(args);
- }
+namespace {
- std::string e = "does not recognize sub-command " + subCommand;
- this->SetError(e);
- return false;
-}
+bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
+ std::string const& listName,
+ std::vector<std::string>& varArgsExpanded,
+ cmExecutionStatus& status);
-bool cmListCommand::GetListString(std::string& listString,
- const std::string& var)
+bool GetListString(std::string& listString, const std::string& var,
+ const cmMakefile& makefile)
{
// get the old value
- const char* cacheValue = this->Makefile->GetDefinition(var);
+ const char* cacheValue = makefile.GetDefinition(var);
if (!cacheValue) {
return false;
}
@@ -103,11 +52,11 @@ bool cmListCommand::GetListString(std::string& listString,
return true;
}
-bool cmListCommand::GetList(std::vector<std::string>& list,
- const std::string& var)
+bool GetList(std::vector<std::string>& list, const std::string& var,
+ const cmMakefile& makefile)
{
std::string listString;
- if (!this->GetListString(listString, var)) {
+ if (!GetListString(listString, var, makefile)) {
return false;
}
// if the size of the list
@@ -115,25 +64,24 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
return true;
}
// expand the variable into a list
- cmSystemTools::ExpandListArgument(listString, list, true);
+ cmExpandList(listString, list, true);
// if no empty elements then just return
- if (std::find(list.begin(), list.end(), std::string()) == list.end()) {
+ if (!cmContains(list, std::string())) {
return true;
}
// if we have empty elements we need to check policy CMP0007
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0007)) {
+ switch (makefile.GetPolicyStatus(cmPolicies::CMP0007)) {
case cmPolicies::WARN: {
// Default is to warn and use old behavior
// OLD behavior is to allow compatibility, so recall
// ExpandListArgument without the true which will remove
// empty values
list.clear();
- cmSystemTools::ExpandListArgument(listString, list);
- std::string warn = cmPolicies::GetPolicyWarning(cmPolicies::CMP0007);
- warn += " List has value = [";
- warn += listString;
- warn += "].";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, warn);
+ cmExpandList(listString, list);
+ std::string warn =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0007),
+ " List has value = [", listString, "].");
+ makefile.IssueMessage(MessageType::AUTHOR_WARNING, warn);
return true;
}
case cmPolicies::OLD:
@@ -141,13 +89,13 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
// ExpandListArgument without the true which will remove
// empty values
list.clear();
- cmSystemTools::ExpandListArgument(listString, list);
+ cmExpandList(listString, list);
return true;
case cmPolicies::NEW:
return true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
+ makefile.IssueMessage(
MessageType::FATAL_ERROR,
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007));
return false;
@@ -155,10 +103,11 @@ bool cmListCommand::GetList(std::vector<std::string>& list,
return true;
}
-bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
+bool HandleLengthCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("sub-command LENGTH requires two arguments.");
+ status.SetError("sub-command LENGTH requires two arguments.");
return false;
}
@@ -168,19 +117,20 @@ bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
// do not check the return value here
// if the list var is not found varArgsExpanded will have size 0
// and we will return 0
- this->GetList(varArgsExpanded, listName);
+ GetList(varArgsExpanded, listName, status.GetMakefile());
size_t length = varArgsExpanded.size();
char buffer[1024];
sprintf(buffer, "%d", static_cast<int>(length));
- this->Makefile->AddDefinition(variableName, buffer);
+ status.GetMakefile().AddDefinition(variableName, buffer);
return true;
}
-bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
+bool HandleGetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 4) {
- this->SetError("sub-command GET requires at least three arguments.");
+ status.SetError("sub-command GET requires at least three arguments.");
return false;
}
@@ -188,13 +138,13 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
const std::string& variableName = args.back();
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
- this->Makefile->AddDefinition(variableName, "NOTFOUND");
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+ status.GetMakefile().AddDefinition(variableName, "NOTFOUND");
return true;
}
// FIXME: Add policy to make non-existing lists an error like empty lists.
if (varArgsExpanded.empty()) {
- this->SetError("GET given empty list");
+ status.SetError("GET given empty list");
return false;
}
@@ -210,20 +160,19 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
item = static_cast<int>(nitem) + item;
}
if (item < 0 || nitem <= static_cast<size_t>(item)) {
- std::ostringstream str;
- str << "index: " << item << " out of range (-" << nitem << ", "
- << nitem - 1 << ")";
- this->SetError(str.str());
+ status.SetError(cmStrCat("index: ", item, " out of range (-", nitem,
+ ", ", nitem - 1, ")"));
return false;
}
value += varArgsExpanded[item];
}
- this->Makefile->AddDefinition(variableName, value.c_str());
+ status.GetMakefile().AddDefinition(variableName, value);
return true;
}
-bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
+bool HandleAppendCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
@@ -232,10 +181,11 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
return true;
}
+ cmMakefile& makefile = status.GetMakefile();
std::string const& listName = args[1];
// expand the variable
std::string listString;
- this->GetListString(listString, listName);
+ GetListString(listString, listName, makefile);
// If `listString` or `args` is empty, no need to append `;`,
// then index is going to be `1` and points to the end-of-string ";"
@@ -243,11 +193,12 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
std::string::size_type(listString.empty() || args.empty());
listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";");
- this->Makefile->AddDefinition(listName, listString.c_str());
+ makefile.AddDefinition(listName, listString);
return true;
}
-bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
+bool HandlePrependCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
@@ -256,10 +207,11 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
return true;
}
+ cmMakefile& makefile = status.GetMakefile();
std::string const& listName = args[1];
// expand the variable
std::string listString;
- this->GetListString(listString, listName);
+ GetListString(listString, listName, makefile);
// If `listString` or `args` is empty, no need to append `;`,
// then `offset` is going to be `1` and points to the end-of-string ";"
@@ -268,22 +220,24 @@ bool cmListCommand::HandlePrependCommand(std::vector<std::string> const& args)
listString.insert(0,
cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]);
- this->Makefile->AddDefinition(listName, listString.c_str());
+ makefile.AddDefinition(listName, listString);
return true;
}
-bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
+bool HandlePopBackCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
+ cmMakefile& makefile = status.GetMakefile();
auto ai = args.cbegin();
++ai; // Skip subcommand name
std::string const& listName = *ai++;
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, makefile)) {
// Can't get the list definition... undefine any vars given after.
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
return true;
}
@@ -296,41 +250,42 @@ bool cmListCommand::HandlePopBackCommand(std::vector<std::string> const& args)
// Ok, assign elements to be removed to the given variables
for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) {
assert(!ai->empty());
- this->Makefile->AddDefinition(*ai, varArgsExpanded.back().c_str());
+ makefile.AddDefinition(*ai, varArgsExpanded.back());
varArgsExpanded.pop_back();
}
// Undefine the rest variables if the list gets empty earlier...
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
}
- this->Makefile->AddDefinition(listName,
- cmJoin(varArgsExpanded, ";").c_str());
+ makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
} else if (ai !=
args.cend()) { // The list is empty, but some args were given
// Need to *undefine* 'em all, cuz there are no items to assign...
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
}
return true;
}
-bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
+bool HandlePopFrontCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
+ cmMakefile& makefile = status.GetMakefile();
auto ai = args.cbegin();
++ai; // Skip subcommand name
std::string const& listName = *ai++;
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, makefile)) {
// Can't get the list definition... undefine any vars given after.
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
return true;
}
@@ -344,33 +299,33 @@ bool cmListCommand::HandlePopFrontCommand(std::vector<std::string> const& args)
auto vi = varArgsExpanded.begin();
for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) {
assert(!ai->empty());
- this->Makefile->AddDefinition(*ai, vi->c_str());
+ makefile.AddDefinition(*ai, *vi);
}
varArgsExpanded.erase(varArgsExpanded.begin(), vi);
// Undefine the rest variables if the list gets empty earlier...
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
}
- this->Makefile->AddDefinition(listName,
- cmJoin(varArgsExpanded, ";").c_str());
+ makefile.AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
} else if (ai !=
args.cend()) { // The list is empty, but some args were given
// Need to *undefine* 'em all, cuz there are no items to assign...
for (; ai != args.cend(); ++ai) {
- this->Makefile->RemoveDefinition(*ai);
+ makefile.RemoveDefinition(*ai);
}
}
return true;
}
-bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
+bool HandleFindCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 4) {
- this->SetError("sub-command FIND requires three arguments.");
+ status.SetError("sub-command FIND requires three arguments.");
return false;
}
@@ -378,28 +333,28 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
const std::string& variableName = args.back();
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
- this->Makefile->AddDefinition(variableName, "-1");
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+ status.GetMakefile().AddDefinition(variableName, "-1");
return true;
}
- std::vector<std::string>::iterator it =
- std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]);
+ auto it = std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]);
if (it != varArgsExpanded.end()) {
- std::ostringstream indexStream;
- indexStream << std::distance(varArgsExpanded.begin(), it);
- this->Makefile->AddDefinition(variableName, indexStream.str().c_str());
+ status.GetMakefile().AddDefinition(
+ variableName,
+ std::to_string(std::distance(varArgsExpanded.begin(), it)));
return true;
}
- this->Makefile->AddDefinition(variableName, "-1");
+ status.GetMakefile().AddDefinition(variableName, "-1");
return true;
}
-bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
+bool HandleInsertCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 4) {
- this->SetError("sub-command INSERT requires at least three arguments.");
+ status.SetError("sub-command INSERT requires at least three arguments.");
return false;
}
@@ -408,11 +363,10 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
// expand the variable
int item = atoi(args[2].c_str());
std::vector<std::string> varArgsExpanded;
- if ((!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) &&
+ if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+ varArgsExpanded.empty()) &&
item != 0) {
- std::ostringstream str;
- str << "index: " << item << " out of range (0, 0)";
- this->SetError(str.str());
+ status.SetError(cmStrCat("index: ", item, " out of range (0, 0)"));
return false;
}
@@ -422,10 +376,9 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
item = static_cast<int>(nitem) + item;
}
if (item < 0 || nitem < static_cast<size_t>(item)) {
- std::ostringstream str;
- str << "index: " << item << " out of range (-" << varArgsExpanded.size()
- << ", " << varArgsExpanded.size() << ")";
- this->SetError(str.str());
+ status.SetError(cmStrCat("index: ", item, " out of range (-",
+ varArgsExpanded.size(), ", ",
+ varArgsExpanded.size(), ")"));
return false;
}
}
@@ -434,17 +387,16 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
args.end());
std::string value = cmJoin(varArgsExpanded, ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
-bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
+bool HandleJoinCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 4) {
- std::ostringstream error;
- error << "sub-command JOIN requires three arguments (" << args.size() - 1
- << " found).";
- this->SetError(error.str());
+ status.SetError(cmStrCat("sub-command JOIN requires three arguments (",
+ args.size() - 1, " found)."));
return false;
}
@@ -454,95 +406,93 @@ bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
- this->Makefile->AddDefinition(variableName, "");
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
+ status.GetMakefile().AddDefinition(variableName, "");
return true;
}
std::string value =
cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
- this->Makefile->AddDefinition(variableName, value.c_str());
+ status.GetMakefile().AddDefinition(variableName, value);
return true;
}
-bool cmListCommand::HandleRemoveItemCommand(
- std::vector<std::string> const& args)
+bool HandleRemoveItemCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("sub-command REMOVE_ITEM requires two or more arguments.");
+ status.SetError("sub-command REMOVE_ITEM requires two or more arguments.");
return false;
}
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
return true;
}
std::vector<std::string> remove(args.begin() + 2, args.end());
std::sort(remove.begin(), remove.end());
- std::vector<std::string>::const_iterator remEnd =
- std::unique(remove.begin(), remove.end());
- std::vector<std::string>::const_iterator remBegin = remove.begin();
+ auto remEnd = std::unique(remove.begin(), remove.end());
+ auto remBegin = remove.begin();
- std::vector<std::string>::const_iterator argsEnd =
+ auto argsEnd =
cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
- std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
+ auto argsBegin = varArgsExpanded.cbegin();
std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
-bool cmListCommand::HandleReverseCommand(std::vector<std::string> const& args)
+bool HandleReverseCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
if (args.size() > 2) {
- this->SetError("sub-command REVERSE only takes one argument.");
+ status.SetError("sub-command REVERSE only takes one argument.");
return false;
}
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
return true;
}
std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
-bool cmListCommand::HandleRemoveDuplicatesCommand(
- std::vector<std::string> const& args)
+bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
if (args.size() > 2) {
- this->SetError("sub-command REMOVE_DUPLICATES only takes one argument.");
+ status.SetError("sub-command REMOVE_DUPLICATES only takes one argument.");
return false;
}
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
return true;
}
- std::vector<std::string>::const_iterator argsEnd =
- cmRemoveDuplicates(varArgsExpanded);
- std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
+ auto argsEnd = cmRemoveDuplicates(varArgsExpanded);
+ auto argsBegin = varArgsExpanded.cbegin();
std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
// Helpers for list(TRANSFORM <list> ...)
-namespace {
using transform_type = std::function<std::string(const std::string&)>;
class transform_error : public std::runtime_error
@@ -641,11 +591,9 @@ protected:
index = static_cast<int>(count) + index;
}
if (index < 0 || count <= static_cast<std::size_t>(index)) {
- std::ostringstream str;
- str << "sub-command TRANSFORM, selector " << this->Tag
- << ", index: " << index << " out of range (-" << count << ", "
- << count - 1 << ").";
- throw transform_error(str.str());
+ throw transform_error(cmStrCat(
+ "sub-command TRANSFORM, selector ", this->Tag, ", index: ", index,
+ " out of range (-", count, ", ", count - 1, ")."));
}
return index;
}
@@ -693,7 +641,8 @@ public:
}
this->Indexes.resize(size);
- auto start = this->Start, step = this->Step;
+ auto start = this->Start;
+ auto step = this->Step;
std::generate(this->Indexes.begin(), this->Indexes.end(),
[&start, step]() -> int {
auto r = start;
@@ -725,17 +674,14 @@ public:
makefile->ClearMatches();
if (!this->ReplaceHelper.IsRegularExpressionValid()) {
- std::ostringstream error;
- error
- << "sub-command TRANSFORM, action REPLACE: Failed to compile regex \""
- << arguments[0] << "\".";
- throw transform_error(error.str());
+ throw transform_error(
+ cmStrCat("sub-command TRANSFORM, action REPLACE: Failed to compile "
+ "regex \"",
+ arguments[0], "\"."));
}
if (!this->ReplaceHelper.IsReplaceExpressionValid()) {
- std::ostringstream error;
- error << "sub-command TRANSFORM, action REPLACE: "
- << this->ReplaceHelper.GetError() << ".";
- throw transform_error(error.str());
+ throw transform_error(cmStrCat("sub-command TRANSFORM, action REPLACE: ",
+ this->ReplaceHelper.GetError(), "."));
}
}
@@ -745,10 +691,8 @@ public:
std::string output;
if (!this->ReplaceHelper.Replace(input, output)) {
- std::ostringstream error;
- error << "sub-command TRANSFORM, action REPLACE: "
- << this->ReplaceHelper.GetError() << ".";
- throw transform_error(error.str());
+ throw transform_error(cmStrCat("sub-command TRANSFORM, action REPLACE: ",
+ this->ReplaceHelper.GetError(), "."));
}
return output;
@@ -757,13 +701,12 @@ public:
private:
cmStringReplaceHelper ReplaceHelper;
};
-}
-bool cmListCommand::HandleTransformCommand(
- std::vector<std::string> const& args)
+bool HandleTransformCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError(
+ status.SetError(
"sub-command TRANSFORM requires an action to be specified.");
return false;
}
@@ -853,7 +796,7 @@ bool cmListCommand::HandleTransformCommand(
{ "STRIP", 0,
[&command](const std::string& s) -> std::string {
if (command.Selector->InSelection(s)) {
- return cmSystemTools::TrimWhitespace(s);
+ return cmTrimWhitespace(s);
}
return s;
@@ -884,19 +827,17 @@ bool cmListCommand::HandleTransformCommand(
auto descriptor = descriptors.find(args[index]);
if (descriptor == descriptors.end()) {
- std::ostringstream error;
- error << " sub-command TRANSFORM, " << args[index] << " invalid action.";
- this->SetError(error.str());
+ status.SetError(
+ cmStrCat(" sub-command TRANSFORM, ", args[index], " invalid action."));
return false;
}
// Action arguments
index += 1;
if (args.size() < index + descriptor->Arity) {
- std::ostringstream error;
- error << "sub-command TRANSFORM, action " << descriptor->Name
- << " expects " << descriptor->Arity << " argument(s).";
- this->SetError(error.str());
+ status.SetError(cmStrCat("sub-command TRANSFORM, action ",
+ descriptor->Name, " expects ", descriptor->Arity,
+ " argument(s)."));
return false;
}
@@ -909,43 +850,44 @@ bool cmListCommand::HandleTransformCommand(
if (command.Name == "REPLACE") {
try {
- command.Action =
- cm::make_unique<TransformReplace>(command.Arguments, this->Makefile);
+ command.Action = cm::make_unique<TransformReplace>(
+ command.Arguments, &status.GetMakefile());
} catch (const transform_error& e) {
- this->SetError(e.what());
+ status.SetError(e.what());
return false;
}
}
- const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" },
- OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" };
+ const std::string REGEX{ "REGEX" };
+ const std::string AT{ "AT" };
+ const std::string FOR{ "FOR" };
+ const std::string OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" };
// handle optional arguments
while (args.size() > index) {
if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) &&
command.Selector) {
- std::ostringstream error;
- error << "sub-command TRANSFORM, selector already specified ("
- << command.Selector->Tag << ").";
- this->SetError(error.str());
+ status.SetError(
+ cmStrCat("sub-command TRANSFORM, selector already specified (",
+ command.Selector->Tag, ")."));
+
return false;
}
// REGEX selector
if (args[index] == REGEX) {
if (args.size() == ++index) {
- this->SetError("sub-command TRANSFORM, selector REGEX expects "
- "'regular expression' argument.");
+ status.SetError("sub-command TRANSFORM, selector REGEX expects "
+ "'regular expression' argument.");
return false;
}
command.Selector = cm::make_unique<TransformSelectorRegex>(args[index]);
if (!command.Selector->Validate()) {
- std::ostringstream error;
- error << "sub-command TRANSFORM, selector REGEX failed to compile "
- "regex \"";
- error << args[index] << "\".";
- this->SetError(error.str());
+ status.SetError(
+ cmStrCat("sub-command TRANSFORM, selector REGEX failed to compile "
+ "regex \"",
+ args[index], "\"."));
return false;
}
@@ -975,7 +917,7 @@ bool cmListCommand::HandleTransformCommand(
}
if (indexes.empty()) {
- this->SetError(
+ status.SetError(
"sub-command TRANSFORM, selector AT expects at least one "
"numeric value.");
return false;
@@ -990,12 +932,15 @@ bool cmListCommand::HandleTransformCommand(
// FOR selector
if (args[index] == FOR) {
if (args.size() <= ++index + 1) {
- this->SetError("sub-command TRANSFORM, selector FOR expects, at least,"
- " two arguments.");
+ status.SetError(
+ "sub-command TRANSFORM, selector FOR expects, at least,"
+ " two arguments.");
return false;
}
- int start = 0, stop = 0, step = 1;
+ int start = 0;
+ int stop = 0;
+ int step = 1;
bool valid = true;
try {
std::size_t pos;
@@ -1016,8 +961,8 @@ bool cmListCommand::HandleTransformCommand(
valid = false;
}
if (!valid) {
- this->SetError("sub-command TRANSFORM, selector FOR expects, "
- "at least, two numeric values.");
+ status.SetError("sub-command TRANSFORM, selector FOR expects, "
+ "at least, two numeric values.");
return false;
}
// try to read a third numeric value for step
@@ -1038,8 +983,8 @@ bool cmListCommand::HandleTransformCommand(
}
if (step < 0) {
- this->SetError("sub-command TRANSFORM, selector FOR expects "
- "non negative numeric value for <step>.");
+ status.SetError("sub-command TRANSFORM, selector FOR expects "
+ "non negative numeric value for <step>.");
}
command.Selector =
@@ -1051,8 +996,8 @@ bool cmListCommand::HandleTransformCommand(
// output variable
if (args[index] == OUTPUT_VARIABLE) {
if (args.size() == ++index) {
- this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
- "expects variable name argument.");
+ status.SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
+ "expects variable name argument.");
return false;
}
@@ -1060,18 +1005,16 @@ bool cmListCommand::HandleTransformCommand(
continue;
}
- std::ostringstream error;
- error << "sub-command TRANSFORM, '"
- << cmJoin(cmMakeRange(args).advance(index), " ")
- << "': unexpected argument(s).";
- this->SetError(error.str());
+ status.SetError(cmStrCat("sub-command TRANSFORM, '",
+ cmJoin(cmMakeRange(args).advance(index), " "),
+ "': unexpected argument(s)."));
return false;
}
// expand the list variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, command.ListName)) {
- this->Makefile->AddDefinition(command.OutputName, "");
+ if (!GetList(varArgsExpanded, command.ListName, status.GetMakefile())) {
+ status.GetMakefile().AddDefinition(command.OutputName, "");
return true;
}
@@ -1083,12 +1026,12 @@ bool cmListCommand::HandleTransformCommand(
try {
command.Selector->Transform(varArgsExpanded, descriptor->Transform);
} catch (const transform_error& e) {
- this->SetError(e.what());
+ status.SetError(e.what());
return false;
}
- this->Makefile->AddDefinition(command.OutputName,
- cmJoin(varArgsExpanded, ";").c_str());
+ status.GetMakefile().AddDefinition(command.OutputName,
+ cmJoin(varArgsExpanded, ";"));
return true;
}
@@ -1117,7 +1060,7 @@ public:
};
protected:
- typedef std::string (*StringFilter)(const std::string& in);
+ using StringFilter = std::string (*)(const std::string&);
StringFilter GetCompareFilter(Compare compare)
{
return (compare == Compare::FILE_BASENAME) ? cmSystemTools::GetFilenameName
@@ -1168,11 +1111,12 @@ protected:
bool descending;
};
-bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
+bool HandleSortCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
assert(args.size() >= 2);
if (args.size() > 8) {
- this->SetError("sub-command SORT only takes up to six arguments.");
+ status.SetError("sub-command SORT only takes up to six arguments.");
return false;
}
@@ -1187,9 +1131,9 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
const std::string option = args[argumentIndex++];
if (option == "COMPARE") {
if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
- this->SetError(error);
+ std::string error = cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times.");
+ status.SetError(error);
return false;
}
if (argumentIndex < args.size()) {
@@ -1199,23 +1143,22 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
} else if (argument == "FILE_BASENAME") {
sortCompare = cmStringSorter::Compare::FILE_BASENAME;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ std::string error =
+ cmStrCat(messageHint, "value \"", argument, "\" for option \"",
+ option, "\" is invalid.");
+ status.SetError(error);
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else if (option == "CASE") {
if (sortCaseSensitivity !=
cmStringSorter::CaseSensitivity::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times."));
return false;
}
if (argumentIndex < args.size()) {
@@ -1225,23 +1168,21 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
} else if (argument == "INSENSITIVE") {
sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "value \"", argument,
+ "\" for option \"", option,
+ "\" is invalid."));
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else if (option == "ORDER") {
if (sortOrder != cmStringSorter::Order::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times."));
return false;
}
if (argumentIndex < args.size()) {
@@ -1251,21 +1192,19 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
} else if (argument == "DESCENDING") {
sortOrder = cmStringSorter::Order::DESCENDING;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "value \"", argument,
+ "\" for option \"", option,
+ "\" is invalid."));
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ status.SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else {
- std::string error =
- messageHint + "option \"" + option + "\" is unknown.";
- this->SetError(error);
+ status.SetError(
+ cmStrCat(messageHint, "option \"", option, "\" is unknown."));
return false;
}
}
@@ -1283,7 +1222,7 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
return true;
}
@@ -1297,17 +1236,16 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
}
std::string value = cmJoin(varArgsExpanded, ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
-bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
+bool HandleSublistCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 5) {
- std::ostringstream error;
- error << "sub-command SUBLIST requires four arguments (" << args.size() - 1
- << " found).";
- this->SetError(error.str());
+ status.SetError(cmStrCat("sub-command SUBLIST requires four arguments (",
+ args.size() - 1, " found)."));
return false;
}
@@ -1316,8 +1254,9 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) {
- this->Makefile->AddDefinition(variableName, "");
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+ varArgsExpanded.empty()) {
+ status.GetMakefile().AddDefinition(variableName, "");
return true;
}
@@ -1327,16 +1266,12 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
using size_type = decltype(varArgsExpanded)::size_type;
if (start < 0 || size_type(start) >= varArgsExpanded.size()) {
- std::ostringstream error;
- error << "begin index: " << start << " is out of range 0 - "
- << varArgsExpanded.size() - 1;
- this->SetError(error.str());
+ status.SetError(cmStrCat("begin index: ", start, " is out of range 0 - ",
+ varArgsExpanded.size() - 1));
return false;
}
if (length < -1) {
- std::ostringstream error;
- error << "length: " << length << " should be -1 or greater";
- this->SetError(error.str());
+ status.SetError(cmStrCat("length: ", length, " should be -1 or greater"));
return false;
}
@@ -1346,22 +1281,24 @@ bool cmListCommand::HandleSublistCommand(std::vector<std::string> const& args)
: size_type(start + length);
std::vector<std::string> sublist(varArgsExpanded.begin() + start,
varArgsExpanded.begin() + end);
- this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";").c_str());
+ status.GetMakefile().AddDefinition(variableName, cmJoin(sublist, ";"));
return true;
}
-bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
+bool HandleRemoveAtCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("sub-command REMOVE_AT requires at least "
- "two arguments.");
+ status.SetError("sub-command REMOVE_AT requires at least "
+ "two arguments.");
return false;
}
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile()) ||
+ varArgsExpanded.empty()) {
std::ostringstream str;
str << "index: ";
for (size_t i = 1; i < args.size(); ++i) {
@@ -1371,7 +1308,7 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
}
}
str << " out of range (0, 0)";
- this->SetError(str.str());
+ status.SetError(str.str());
return false;
}
@@ -1384,43 +1321,42 @@ bool cmListCommand::HandleRemoveAtCommand(std::vector<std::string> const& args)
item = static_cast<int>(nitem) + item;
}
if (item < 0 || nitem <= static_cast<size_t>(item)) {
- std::ostringstream str;
- str << "index: " << item << " out of range (-" << nitem << ", "
- << nitem - 1 << ")";
- this->SetError(str.str());
+ status.SetError(cmStrCat("index: ", item, " out of range (-", nitem,
+ ", ", nitem - 1, ")"));
return false;
}
removed.push_back(static_cast<size_t>(item));
}
std::sort(removed.begin(), removed.end());
- std::vector<size_t>::const_iterator remEnd =
- std::unique(removed.begin(), removed.end());
- std::vector<size_t>::const_iterator remBegin = removed.begin();
+ auto remEnd = std::unique(removed.begin(), removed.end());
+ auto remBegin = removed.begin();
- std::vector<std::string>::const_iterator argsEnd =
+ auto argsEnd =
cmRemoveIndices(varArgsExpanded, cmMakeRange(remBegin, remEnd));
- std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
+ auto argsBegin = varArgsExpanded.cbegin();
std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
-bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args)
+bool HandleFilterCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command FILTER requires a list to be specified.");
+ status.SetError("sub-command FILTER requires a list to be specified.");
return false;
}
if (args.size() < 3) {
- this->SetError("sub-command FILTER requires an operator to be specified.");
+ status.SetError(
+ "sub-command FILTER requires an operator to be specified.");
return false;
}
if (args.size() < 4) {
- this->SetError("sub-command FILTER requires a mode to be specified.");
+ status.SetError("sub-command FILTER requires a mode to be specified.");
return false;
}
@@ -1431,28 +1367,29 @@ bool cmListCommand::HandleFilterCommand(std::vector<std::string> const& args)
} else if (op == "EXCLUDE") {
includeMatches = false;
} else {
- this->SetError("sub-command FILTER does not recognize operator " + op);
+ status.SetError("sub-command FILTER does not recognize operator " + op);
return false;
}
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if (!this->GetList(varArgsExpanded, listName)) {
+ if (!GetList(varArgsExpanded, listName, status.GetMakefile())) {
return true;
}
const std::string& mode = args[3];
if (mode == "REGEX") {
if (args.size() != 5) {
- this->SetError("sub-command FILTER, mode REGEX "
- "requires five arguments.");
+ status.SetError("sub-command FILTER, mode REGEX "
+ "requires five arguments.");
return false;
}
- return this->FilterRegex(args, includeMatches, listName, varArgsExpanded);
+ return FilterRegex(args, includeMatches, listName, varArgsExpanded,
+ status);
}
- this->SetError("sub-command FILTER does not recognize mode " + mode);
+ status.SetError("sub-command FILTER does not recognize mode " + mode);
return false;
}
@@ -1475,28 +1412,60 @@ private:
const bool includeMatches;
};
-bool cmListCommand::FilterRegex(std::vector<std::string> const& args,
- bool includeMatches,
- std::string const& listName,
- std::vector<std::string>& varArgsExpanded)
+bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
+ std::string const& listName,
+ std::vector<std::string>& varArgsExpanded,
+ cmExecutionStatus& status)
{
const std::string& pattern = args[4];
cmsys::RegularExpression regex(pattern);
if (!regex.is_valid()) {
- std::string error = "sub-command FILTER, mode REGEX ";
- error += "failed to compile regex \"";
- error += pattern;
- error += "\".";
- this->SetError(error);
+ std::string error =
+ cmStrCat("sub-command FILTER, mode REGEX failed to compile regex \"",
+ pattern, "\".");
+ status.SetError(error);
return false;
}
- std::vector<std::string>::iterator argsBegin = varArgsExpanded.begin();
- std::vector<std::string>::iterator argsEnd = varArgsExpanded.end();
- std::vector<std::string>::iterator newArgsEnd =
+ auto argsBegin = varArgsExpanded.begin();
+ auto argsEnd = varArgsExpanded.end();
+ auto newArgsEnd =
std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches));
std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";");
- this->Makefile->AddDefinition(listName, value.c_str());
+ status.GetMakefile().AddDefinition(listName, value);
return true;
}
+
+} // namespace
+
+bool cmListCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 2) {
+ status.SetError("must be called with at least two arguments.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "LENGTH"_s, HandleLengthCommand },
+ { "GET"_s, HandleGetCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "PREPEND"_s, HandlePrependCommand },
+ { "POP_BACK"_s, HandlePopBackCommand },
+ { "POP_FRONT"_s, HandlePopFrontCommand },
+ { "FIND"_s, HandleFindCommand },
+ { "INSERT"_s, HandleInsertCommand },
+ { "JOIN"_s, HandleJoinCommand },
+ { "REMOVE_AT"_s, HandleRemoveAtCommand },
+ { "REMOVE_ITEM"_s, HandleRemoveItemCommand },
+ { "REMOVE_DUPLICATES"_s, HandleRemoveDuplicatesCommand },
+ { "TRANSFORM"_s, HandleTransformCommand },
+ { "SORT"_s, HandleSortCommand },
+ { "SUBLIST"_s, HandleSublistCommand },
+ { "REVERSE"_s, HandleReverseCommand },
+ { "FILTER"_s, HandleFilterCommand },
+ };
+
+ return subcommand(args[0], args, status);
+}
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index ea3d64399..274d9fdbd 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -8,53 +8,13 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmListCommand
+/**
* \brief Common list operations
*
*/
-class cmListCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmListCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool HandleLengthCommand(std::vector<std::string> const& args);
- bool HandleGetCommand(std::vector<std::string> const& args);
- bool HandleAppendCommand(std::vector<std::string> const& args);
- bool HandlePrependCommand(std::vector<std::string> const& args);
- bool HandlePopBackCommand(std::vector<std::string> const& args);
- bool HandlePopFrontCommand(std::vector<std::string> const& args);
- bool HandleFindCommand(std::vector<std::string> const& args);
- bool HandleInsertCommand(std::vector<std::string> const& args);
- bool HandleJoinCommand(std::vector<std::string> const& args);
- bool HandleRemoveAtCommand(std::vector<std::string> const& args);
- bool HandleRemoveItemCommand(std::vector<std::string> const& args);
- bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
- bool HandleTransformCommand(std::vector<std::string> const& args);
- bool HandleSortCommand(std::vector<std::string> const& args);
- bool HandleSublistCommand(std::vector<std::string> const& args);
- bool HandleReverseCommand(std::vector<std::string> const& args);
- bool HandleFilterCommand(std::vector<std::string> const& args);
- bool FilterRegex(std::vector<std::string> const& args, bool includeMatches,
- std::string const& listName,
- std::vector<std::string>& varArgsExpanded);
-
- bool GetList(std::vector<std::string>& list, const std::string& var);
- bool GetListString(std::string& listString, const std::string& var);
-};
+bool cmListCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index df0d00c59..47679c932 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -2,18 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmListFileCache.h"
+#include <cassert>
+#include <memory>
+#include <sstream>
+#include <utility>
+
#include "cmListFileLexer.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <assert.h>
-#include <memory>
-#include <sstream>
-#include <utility>
-
cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=(
std::string const& name)
{
@@ -325,6 +326,7 @@ cmListFileBacktrace::cmListFileBacktrace(cmStateSnapshot const& snapshot)
{
}
+/* NOLINTNEXTLINE(performance-unnecessary-value-param) */
cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent,
cmListFileContext const& lfc)
: TopEntry(std::make_shared<Entry const>(std::move(parent), lfc))
@@ -482,8 +484,7 @@ std::vector<BT<std::string>> ExpandListWithBacktrace(
std::string const& list, cmListFileBacktrace const& bt)
{
std::vector<BT<std::string>> result;
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(list, tmp);
+ std::vector<std::string> tmp = cmExpandedList(list);
result.reserve(tmp.size());
for (std::string& i : tmp) {
result.emplace_back(std::move(i), bt);
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 945741540..9cae8277b 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -5,9 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <iosfwd>
-#include <memory> // IWYU pragma: keep
-#include <stddef.h>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h
index 8962396fd..ec6b3cd77 100644
--- a/Source/cmListFileLexer.h
+++ b/Source/cmListFileLexer.h
@@ -3,6 +3,11 @@
#ifndef cmListFileLexer_h
#define cmListFileLexer_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef enum cmListFileLexer_Type_e
{
cmListFileLexer_Token_None,
@@ -20,6 +25,7 @@ typedef enum cmListFileLexer_Type_e
cmListFileLexer_Token_BadString
} cmListFileLexer_Type;
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef struct cmListFileLexer_Token_s cmListFileLexer_Token;
struct cmListFileLexer_Token_s
{
@@ -40,14 +46,13 @@ enum cmListFileLexer_BOM_e
cmListFileLexer_BOM_UTF32BE,
cmListFileLexer_BOM_UTF32LE
};
+
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef enum cmListFileLexer_BOM_e cmListFileLexer_BOM;
+/* NOLINTNEXTLINE(modernize-use-using) */
typedef struct cmListFileLexer_s cmListFileLexer;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
cmListFileLexer* cmListFileLexer_New(void);
int cmListFileLexer_SetFileName(cmListFileLexer*, const char*,
cmListFileLexer_BOM* bom);
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index b1fee8dc6..1184bcb58 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -2,25 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLoadCacheCommand.h"
+#include <set>
+
#include "cmsys/FStream.hxx"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmake.h"
-class cmExecutionStatus;
+static bool ReadWithPrefix(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
+static void CheckLine(cmMakefile& mf, std::string const& prefix,
+ std::set<std::string> const& variablesToRead,
+ const char* line);
-// cmLoadCacheCommand
-bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmLoadCacheCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with wrong number of arguments.");
+ status.SetError("called with wrong number of arguments.");
}
if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") {
- return this->ReadWithPrefix(args);
+ return ReadWithPrefix(args, status);
}
// Cache entries to be excluded from the import list.
@@ -59,24 +66,26 @@ bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args,
}
}
+ cmMakefile& mf = status.GetMakefile();
+
// Loop over each build directory listed in the arguments. Each
// directory has a cache file.
for (std::string const& arg : args) {
if ((arg == "EXCLUDE") || (arg == "INCLUDE_INTERNALS")) {
break;
}
- this->Makefile->GetCMakeInstance()->LoadCache(arg, false, excludes,
- includes);
+ mf.GetCMakeInstance()->LoadCache(arg, false, excludes, includes);
}
return true;
}
-bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
+static bool ReadWithPrefix(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Make sure we have a prefix.
if (args.size() < 3) {
- this->SetError("READ_WITH_PREFIX form must specify a prefix.");
+ status.SetError("READ_WITH_PREFIX form must specify a prefix.");
return false;
}
@@ -84,17 +93,19 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
std::string cacheFile = args[0] + "/CMakeCache.txt";
if (!cmSystemTools::FileExists(cacheFile)) {
std::string e = "Cannot load cache file from " + cacheFile;
- this->SetError(e);
+ status.SetError(e);
return false;
}
// Prepare the table of variables to read.
- this->Prefix = args[2];
- this->VariablesToRead.insert(args.begin() + 3, args.end());
+ std::string const prefix = args[2];
+ std::set<std::string> const variablesToRead(args.begin() + 3, args.end());
// Read the cache file.
cmsys::ifstream fin(cacheFile.c_str());
+ cmMakefile& mf = status.GetMakefile();
+
// This is a big hack read loop to overcome a buggy ifstream
// implementation on HP-UX. This should work on all platforms even
// for small buffer sizes.
@@ -123,7 +134,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
}
if (i != end) {
// Completed a line.
- this->CheckLine(line.c_str());
+ CheckLine(mf, prefix, variablesToRead, line.c_str());
line.clear();
// Skip the newline character.
@@ -134,13 +145,15 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
}
if (!line.empty()) {
// Partial last line.
- this->CheckLine(line.c_str());
+ CheckLine(mf, prefix, variablesToRead, line.c_str());
}
return true;
}
-void cmLoadCacheCommand::CheckLine(const char* line)
+static void CheckLine(cmMakefile& mf, std::string const& prefix,
+ std::set<std::string> const& variablesToRead,
+ const char* line)
{
// Check one line of the cache file.
std::string var;
@@ -148,14 +161,14 @@ void cmLoadCacheCommand::CheckLine(const char* line)
cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
if (cmake::ParseCacheEntry(line, var, value, type)) {
// Found a real entry. See if this one was requested.
- if (this->VariablesToRead.find(var) != this->VariablesToRead.end()) {
+ if (variablesToRead.find(var) != variablesToRead.end()) {
// This was requested. Set this variable locally with the given
// prefix.
- var = this->Prefix + var;
+ var = prefix + var;
if (!value.empty()) {
- this->Makefile->AddDefinition(var, value.c_str());
+ mf.AddDefinition(var, value);
} else {
- this->Makefile->RemoveDefinition(var);
+ mf.RemoveDefinition(var);
}
}
}
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index e0f6e4f48..7cee6637c 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -5,40 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <set>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmLoadCacheCommand
- * \brief load a cache file
- *
- * cmLoadCacheCommand loads the non internal values of a cache file
- */
-class cmLoadCacheCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmLoadCacheCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- std::set<std::string> VariablesToRead;
- std::string Prefix;
-
- bool ReadWithPrefix(std::vector<std::string> const& args);
- void CheckLine(const char* line);
-};
+bool cmLoadCacheCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 69751b62b..23ace649a 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -2,49 +2,121 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLoadCommandCommand.h"
-#include <signal.h>
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <csignal>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <utility>
+
+#include <cm/memory>
-#include "cmCPluginAPI.cxx"
#include "cmCPluginAPI.h"
+#include "cmCommand.h"
#include "cmDynamicLoader.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+#include "cmCPluginAPI.cxx"
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
-extern "C" void TrapsForSignalsCFunction(int sig);
+namespace {
+
+const char* LastName = nullptr;
+
+extern "C" void TrapsForSignals(int sig)
+{
+ fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
+ LastName, sig);
+}
+
+struct SignalHandlerGuard
+{
+ explicit SignalHandlerGuard(const char* name)
+ {
+ LastName = name != nullptr ? name : "????";
+
+ signal(SIGSEGV, TrapsForSignals);
+#ifdef SIGBUS
+ signal(SIGBUS, TrapsForSignals);
+#endif
+ signal(SIGILL, TrapsForSignals);
+ }
+
+ ~SignalHandlerGuard()
+ {
+ signal(SIGSEGV, nullptr);
+#ifdef SIGBUS
+ signal(SIGBUS, nullptr);
+#endif
+ signal(SIGILL, nullptr);
+ }
+
+ SignalHandlerGuard(SignalHandlerGuard const&) = delete;
+ SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete;
+};
+
+struct LoadedCommandImpl : cmLoadedCommandInfo
+{
+ explicit LoadedCommandImpl(CM_INIT_FUNCTION init)
+ : cmLoadedCommandInfo{ 0, 0, &cmStaticCAPI, 0,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr }
+ {
+ init(this);
+ }
+
+ ~LoadedCommandImpl()
+ {
+ if (this->Destructor) {
+ SignalHandlerGuard guard(this->Name);
+ this->Destructor(this);
+ }
+ if (this->Error != nullptr) {
+ free(this->Error);
+ }
+ }
+
+ LoadedCommandImpl(LoadedCommandImpl const&) = delete;
+ LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete;
+
+ int DoInitialPass(cmMakefile* mf, int argc, char* argv[])
+ {
+ SignalHandlerGuard guard(this->Name);
+ return this->InitialPass(this, mf, argc, argv);
+ }
+
+ void DoFinalPass(cmMakefile* mf)
+ {
+ SignalHandlerGuard guard(this->Name);
+ this->FinalPass(this, mf);
+ }
+};
// a class for loadabple commands
class cmLoadedCommand : public cmCommand
{
public:
- cmLoadedCommand()
+ cmLoadedCommand() = default;
+ explicit cmLoadedCommand(CM_INIT_FUNCTION init)
+ : Impl(std::make_shared<LoadedCommandImpl>(init))
{
- memset(&this->info, 0, sizeof(this->info));
- this->info.CAPI = &cmStaticCAPI;
}
- //! clean up any memory allocated by the plugin
- ~cmLoadedCommand() override;
-
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override
+ std::unique_ptr<cmCommand> Clone() override
{
- cmLoadedCommand* newC = new cmLoadedCommand;
+ auto newC = cm::make_unique<cmLoadedCommand>();
// we must copy when we clone
- memcpy(&newC->info, &this->info, sizeof(info));
- return newC;
+ newC->Impl = this->Impl;
+ return std::unique_ptr<cmCommand>(std::move(newC));
}
/**
@@ -54,66 +126,20 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&) override;
- /**
- * This is called at the end after all the information
- * specified by the command is accumulated. Most commands do
- * not implement this method. At this point, reading and
- * writing to the cache can be done.
- */
- void FinalPass() override;
- bool HasFinalPass() const override
- {
- return this->info.FinalPass != nullptr;
- }
-
- static const char* LastName;
- static void TrapsForSignals(int sig)
- {
- fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
- cmLoadedCommand::LastName, sig);
- }
- static void InstallSignalHandlers(const char* name, int remove = 0)
- {
- cmLoadedCommand::LastName = name;
- if (!name) {
- cmLoadedCommand::LastName = "????";
- }
-
- if (!remove) {
- signal(SIGSEGV, TrapsForSignalsCFunction);
-#ifdef SIGBUS
- signal(SIGBUS, TrapsForSignalsCFunction);
-#endif
- signal(SIGILL, TrapsForSignalsCFunction);
- } else {
- signal(SIGSEGV, nullptr);
-#ifdef SIGBUS
- signal(SIGBUS, nullptr);
-#endif
- signal(SIGILL, nullptr);
- }
- }
-
- cmLoadedCommandInfo info;
+private:
+ std::shared_ptr<LoadedCommandImpl> Impl;
};
-extern "C" void TrapsForSignalsCFunction(int sig)
-{
- cmLoadedCommand::TrapsForSignals(sig);
-}
-
-const char* cmLoadedCommand::LastName = nullptr;
-
bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (!info.InitialPass) {
+ if (!this->Impl->InitialPass) {
return true;
}
// clear the error string
- if (this->info.Error) {
- free(this->info.Error);
+ if (this->Impl->Error) {
+ free(this->Impl->Error);
}
// create argc and argv and then invoke the command
@@ -126,46 +152,30 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
for (i = 0; i < argc; ++i) {
argv[i] = strdup(args[i].c_str());
}
- cmLoadedCommand::InstallSignalHandlers(info.Name);
- int result = info.InitialPass(&info, this->Makefile, argc, argv);
- cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
+ int result = this->Impl->DoInitialPass(this->Makefile, argc, argv);
cmFreeArguments(argc, argv);
if (result) {
+ if (this->Impl->FinalPass) {
+ auto impl = this->Impl;
+ this->Makefile->AddFinalAction(
+ [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); });
+ }
return true;
}
/* Initial Pass must have failed so set the error string */
- if (this->info.Error) {
- this->SetError(this->info.Error);
+ if (this->Impl->Error) {
+ this->SetError(this->Impl->Error);
}
return false;
}
-void cmLoadedCommand::FinalPass()
-{
- if (this->info.FinalPass) {
- cmLoadedCommand::InstallSignalHandlers(info.Name);
- this->info.FinalPass(&this->info, this->Makefile);
- cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
- }
-}
-
-cmLoadedCommand::~cmLoadedCommand()
-{
- if (this->info.Destructor) {
- cmLoadedCommand::InstallSignalHandlers(info.Name);
- this->info.Destructor(&this->info);
- cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
- }
- if (this->info.Error) {
- free(this->info.Error);
- }
-}
+} // namespace
// cmLoadCommandCommand
-bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmLoadCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
@@ -173,16 +183,14 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
// Construct a variable to report what file was loaded, if any.
// Start by removing the definition in case of failure.
- std::string reportVar = "CMAKE_LOADED_COMMAND_";
- reportVar += args[0];
- this->Makefile->RemoveDefinition(reportVar);
+ std::string reportVar = cmStrCat("CMAKE_LOADED_COMMAND_", args[0]);
+ status.GetMakefile().RemoveDefinition(reportVar);
// the file must exist
- std::string moduleName =
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX");
- moduleName += "cm" + args[0];
- moduleName +=
- this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX");
+ std::string moduleName = cmStrCat(
+ status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"),
+ "cm", args[0],
+ status.GetMakefile().GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX"));
// search for the file
std::vector<std::string> path;
@@ -198,9 +206,8 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
// Try to find the program.
std::string fullPath = cmSystemTools::FindFile(moduleName, path);
if (fullPath.empty()) {
- std::ostringstream e;
- e << "Attempt to load command failed from file \"" << moduleName << "\"";
- this->SetError(e.str());
+ status.SetError(cmStrCat("Attempt to load command failed from file \"",
+ moduleName, "\""));
return false;
}
@@ -208,41 +215,38 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
cmsys::DynamicLoader::LibraryHandle lib =
cmDynamicLoader::OpenLibrary(fullPath.c_str());
if (!lib) {
- std::string err = "Attempt to load the library ";
- err += fullPath + " failed.";
+ std::string err =
+ cmStrCat("Attempt to load the library ", fullPath, " failed.");
const char* error = cmsys::DynamicLoader::LastError();
if (error) {
err += " Additional error info is:\n";
err += error;
}
- this->SetError(err);
+ status.SetError(err);
return false;
}
// Report what file was loaded for this command.
- this->Makefile->AddDefinition(reportVar, fullPath.c_str());
+ status.GetMakefile().AddDefinition(reportVar, fullPath);
// find the init function
std::string initFuncName = args[0] + "Init";
CM_INIT_FUNCTION initFunction = reinterpret_cast<CM_INIT_FUNCTION>(
cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName));
if (!initFunction) {
- initFuncName = "_";
- initFuncName += args[0];
- initFuncName += "Init";
+ initFuncName = cmStrCat('_', args[0], "Init");
initFunction = reinterpret_cast<CM_INIT_FUNCTION>(
cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName));
}
// if the symbol is found call it to set the name on the
// function blocker
if (initFunction) {
- // create a function blocker and set it up
- cmLoadedCommand* f = new cmLoadedCommand();
- (*initFunction)(&f->info);
- this->Makefile->GetState()->AddScriptedCommand(args[0], f);
+ status.GetMakefile().GetState()->AddScriptedCommand(
+ args[0],
+ cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
return true;
}
- this->SetError("Attempt to load command failed. "
- "No init function found.");
+ status.SetError("Attempt to load command failed. "
+ "No init function found.");
return false;
}
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index 021e6c7bb..f5fd754b1 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -8,16 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmLoadCommandCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmLoadCommandCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmLoadCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 75ad2a658..f86955dd0 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratorTarget.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
+#include "cmStringAlgorithms.h"
class cmGlobalGenerator;
@@ -34,10 +35,8 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
std::string flags;
// Enable module output if necessary.
- if (const char* modout_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG")) {
- this->AppendFlags(flags, modout_flag);
- }
+ this->AppendFlags(
+ flags, this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODOUT_FLAG"));
// Add a module output directory flag if necessary.
std::string mod_dir =
@@ -51,9 +50,9 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
}
if (!mod_dir.empty()) {
- std::string modflag =
- this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
- modflag += mod_dir;
+ std::string modflag = cmStrCat(
+ this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
+ mod_dir);
this->AppendFlags(flags, modflag);
}
@@ -65,8 +64,9 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
std::vector<std::string> includes;
this->GetIncludeDirectories(includes, target, "C", config);
for (std::string const& id : includes) {
- std::string flg = modpath_flag;
- flg += this->ConvertToOutputFormat(id, cmOutputConverter::SHELL);
+ std::string flg =
+ cmStrCat(modpath_flag,
+ this->ConvertToOutputFormat(id, cmOutputConverter::SHELL));
this->AppendFlags(flags, flg);
}
}
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index abebbc2a7..eaef6ab53 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -25,7 +25,7 @@ public:
std::string wd);
~cmLocalCommonGenerator() override;
- std::string const& GetConfigName() { return this->ConfigName; }
+ std::string const& GetConfigName() const { return this->ConfigName; }
std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 3abf2ddda..2e499b348 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2,9 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalGenerator.h"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
+#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmCustomCommandLines.h"
+#include "cmCustomCommandTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -14,34 +19,40 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmSourceFileLocationKind.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTestGenerator.h"
#include "cmVersion.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# define CM_LG_ENCODE_OBJECT_NAMES
# include "cmCryptoHash.h"
#endif
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <initializer_list>
#include <iterator>
#include <sstream>
-#include <stdio.h>
-#include <string.h>
#include <unordered_set>
#include <utility>
+#include <vector>
+
+#include <cm/string_view>
#if defined(__HAIKU__)
# include <FindDirectory.h>
@@ -251,14 +262,6 @@ static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs,
void cmLocalGenerator::TraceDependencies()
{
- std::vector<std::string> configs;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
- for (std::string const& c : configs) {
- this->GlobalGenerator->CreateEvaluationSourceFiles(c);
- }
// Generate the rule files for each target.
const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
for (cmGeneratorTarget* target : targets) {
@@ -280,9 +283,9 @@ void cmLocalGenerator::GenerateTestFiles()
const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
- std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
- file += "/";
- file += "CTestTestfile.cmake";
+ std::string file =
+ cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentBinary(),
+ "/CTestTestfile.cmake");
cmGeneratedFileStream fout(file);
fout.SetCopyIfDifferent(true);
@@ -307,8 +310,7 @@ void cmLocalGenerator::GenerateTestFiles()
const char* testIncludeFiles =
this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList;
- cmSystemTools::ExpandListArgument(testIncludeFiles, includesList);
+ std::vector<std::string> includesList = cmExpandedList(testIncludeFiles);
for (std::string const& i : includesList) {
fout << "include(\"" << i << "\")" << std::endl;
}
@@ -321,7 +323,7 @@ void cmLocalGenerator::GenerateTestFiles()
tester->Compute(this);
tester->Generate(fout, config, configurationTypes);
}
- typedef std::vector<cmStateSnapshot> vec_t;
+ using vec_t = std::vector<cmStateSnapshot>;
vec_t const& children = this->Makefile->GetStateSnapshot().GetChildren();
std::string parentBinDir = this->GetCurrentBinaryDirectory();
for (cmStateSnapshot const& i : children) {
@@ -352,6 +354,15 @@ void cmLocalGenerator::GenerateTestFiles()
}
}
+void cmLocalGenerator::CreateEvaluationFileOutputs()
+{
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs();
+ for (std::string const& c : configs) {
+ this->CreateEvaluationFileOutputs(c);
+ }
+}
+
void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
{
std::vector<cmGeneratorExpressionEvaluationFile*> ef =
@@ -645,8 +656,7 @@ void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt)
cmGeneratorTarget* cmLocalGenerator::FindLocalNonAliasGeneratorTarget(
const std::string& name) const
{
- GeneratorTargetMap::const_iterator ti =
- this->GeneratorTargetSearchIndex.find(name);
+ auto ti = this->GeneratorTargetSearchIndex.find(name);
if (ti != this->GeneratorTargetSearchIndex.end()) {
return ti->second;
}
@@ -683,6 +693,16 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
configNames.emplace_back();
}
+ using LanguagePair = std::pair<std::string, std::string>;
+ std::vector<LanguagePair> pairedLanguages{ { "OBJC", "C" },
+ { "OBJCXX", "CXX" } };
+ std::set<LanguagePair> objcEnabledLanguages;
+ for (auto const& lang : pairedLanguages) {
+ if (this->Makefile->GetState()->GetLanguageEnabled(lang.first)) {
+ objcEnabledLanguages.insert(lang);
+ }
+ }
+
// Process compile features of all targets.
const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
for (cmGeneratorTarget* target : targets) {
@@ -691,6 +711,40 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
return false;
}
}
+
+ // Now that C/C++ _STANDARD values have been computed
+ // set the values to ObjC/ObjCXX _STANDARD variables
+ if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
+ if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
+ auto* standard =
+ target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
+ if (!standard) {
+ standard = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
+ }
+ target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
+ standard);
+ return true;
+ }
+ return false;
+ };
+ auto copyPropertyToObjLang = [&](LanguagePair const& lang,
+ 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)));
+ }
+ };
+ for (auto const& lang : objcEnabledLanguages) {
+ if (copyStandardToObjLang(lang)) {
+ copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
+ copyPropertyToObjLang(lang, "_EXTENSIONS");
+ }
+ }
+ }
}
return true;
@@ -742,12 +796,10 @@ std::string cmLocalGenerator::GetIncludeFlags(
OutputFormat shellFormat = forResponseFile ? RESPONSE : SHELL;
std::ostringstream includeFlags;
- std::string flagVar = "CMAKE_INCLUDE_FLAG_";
- flagVar += lang;
- std::string const& includeFlag = this->Makefile->GetSafeDefinition(flagVar);
- flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
- flagVar += lang;
- const char* sep = this->Makefile->GetDefinition(flagVar);
+ std::string const& includeFlag =
+ this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang));
+ const char* sep =
+ this->Makefile->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_SEP_", lang));
bool quotePaths = false;
if (this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS")) {
quotePaths = true;
@@ -764,23 +816,16 @@ std::string cmLocalGenerator::GetIncludeFlags(
// Support special system include flag if it is available and the
// normal flag is repeated for each directory.
- std::string sysFlagVar = "CMAKE_INCLUDE_SYSTEM_FLAG_";
- sysFlagVar += lang;
const char* sysIncludeFlag = nullptr;
if (repeatFlag) {
- sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar);
+ sysIncludeFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
}
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += lang;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- const char* fwSearchFlag = this->Makefile->GetDefinition(fwSearchFlagVar);
-
- std::string sysFwSearchFlagVar = "CMAKE_";
- sysFwSearchFlagVar += lang;
- sysFwSearchFlagVar += "_SYSTEM_FRAMEWORK_SEARCH_FLAG";
- const char* sysFwSearchFlag =
- this->Makefile->GetDefinition(sysFwSearchFlagVar);
+ const char* fwSearchFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_FRAMEWORK_SEARCH_FLAG"));
+ const char* sysFwSearchFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG"));
bool flagUsed = false;
std::set<std::string> emitted;
@@ -790,9 +835,8 @@ std::string cmLocalGenerator::GetIncludeFlags(
for (std::string const& i : includes) {
if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") &&
cmSystemTools::IsPathToFramework(i)) {
- std::string frameworkDir = i;
- frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+ std::string const frameworkDir =
+ cmSystemTools::CollapseFullPath(cmStrCat(i, "/../"));
if (emitted.insert(frameworkDir).second) {
if (sysFwSearchFlag && target &&
target->IsSystemIncludeDirectory(i, config, lang)) {
@@ -839,29 +883,50 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags,
const std::string& lang,
const std::string& config)
{
+ std::vector<BT<std::string>> tmpFlags;
+ this->AddCompileOptions(tmpFlags, target, lang, config);
+ this->AppendFlags(flags, tmpFlags);
+}
+
+void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
+ cmGeneratorTarget* target,
+ const std::string& lang,
+ const std::string& config)
+{
std::string langFlagRegexVar = std::string("CMAKE_") + lang + "_FLAG_REGEX";
if (const char* langFlagRegexStr =
this->Makefile->GetDefinition(langFlagRegexVar)) {
// Filter flags acceptable to this language.
- std::vector<std::string> opts;
if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+ std::vector<std::string> opts;
cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+ // Re-escape these flags since COMPILE_FLAGS were already parsed
+ // as a command line above.
+ std::string compileOpts;
+ this->AppendCompileOptions(compileOpts, opts, langFlagRegexStr);
+ if (!compileOpts.empty()) {
+ flags.emplace_back(std::move(compileOpts));
+ }
}
- target->GetCompileOptions(opts, config, lang);
- // (Re-)Escape these flags. COMPILE_FLAGS were already parsed
- // as a command line above, and COMPILE_OPTIONS are escaped.
- this->AppendCompileOptions(flags, opts, langFlagRegexStr);
+ std::vector<BT<std::string>> targetCompileOpts =
+ target->GetCompileOptions(config, lang);
+ // COMPILE_OPTIONS are escaped.
+ this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr);
} else {
// Use all flags.
if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
// COMPILE_FLAGS are not escaped for historical reasons.
- this->AppendFlags(flags, targetFlags);
+ std::string compileFlags;
+ this->AppendFlags(compileFlags, targetFlags);
+ if (!compileFlags.empty()) {
+ flags.emplace_back(std::move(compileFlags));
+ }
}
- std::vector<std::string> opts;
- target->GetCompileOptions(opts, config, lang);
+ std::vector<BT<std::string>> targetCompileOpts =
+ target->GetCompileOptions(config, lang);
// COMPILE_OPTIONS are escaped.
- this->AppendCompileOptions(flags, opts);
+ this->AppendCompileOptions(flags, targetCompileOpts);
}
for (auto const& it : target->GetMaxLanguageStandards()) {
@@ -888,7 +953,12 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags,
return;
}
}
- this->AddCompilerRequirementFlag(flags, target, lang);
+
+ std::string compReqFlag;
+ this->AddCompilerRequirementFlag(compReqFlag, target, lang);
+ if (!compReqFlag.empty()) {
+ flags.emplace_back(std::move(compReqFlag));
+ }
// Add compile flag for the MSVC compiler only.
cmMakefile* mf = this->GetMakefile();
@@ -903,14 +973,15 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags,
// to ON
if (char const* jmcExprGen =
target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(jmcExprGen);
- std::string isJMCEnabled = cge->Evaluate(this, config);
- if (cmSystemTools::IsOn(isJMCEnabled)) {
- std::vector<std::string> optVec;
- cmSystemTools::ExpandListArgument(jmc, optVec);
- this->AppendCompileOptions(flags, optVec);
+ std::string isJMCEnabled =
+ cmGeneratorExpression::Evaluate(jmcExprGen, this, config);
+ if (cmIsOn(isJMCEnabled)) {
+ std::vector<std::string> optVec = cmExpandedList(jmc);
+ std::string jmcFlags;
+ this->AppendCompileOptions(jmcFlags, optVec);
+ if (!jmcFlags.empty()) {
+ flags.emplace_back(std::move(jmcFlags));
+ }
}
}
}
@@ -960,11 +1031,9 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// These are intended to simulate additional implicit include directories.
std::vector<std::string> userStandardDirs;
{
- std::string key = "CMAKE_";
- key += lang;
- key += "_STANDARD_INCLUDE_DIRECTORIES";
- std::string const value = this->Makefile->GetSafeDefinition(key);
- cmSystemTools::ExpandListArgument(value, userStandardDirs);
+ std::string const value = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_STANDARD_INCLUDE_DIRECTORIES"));
+ cmExpandList(value, userStandardDirs);
for (std::string& usd : userStandardDirs) {
cmSystemTools::ConvertToUnixSlashes(usd);
}
@@ -986,12 +1055,11 @@ 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") {
- std::string key = "CMAKE_";
- key += lang;
- key += "_IMPLICIT_INCLUDE_DIRECTORIES";
- if (const char* value = this->Makefile->GetDefinition(key)) {
+ const char* value = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"));
+ if (value != nullptr) {
size_t const impDirVecOldSize = impDirVec.size();
- cmSystemTools::ExpandListArgument(value, impDirVec);
+ cmExpandList(value, impDirVec);
// FIXME: Use cmRange with 'advance()' when it supports non-const.
for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
@@ -1006,8 +1074,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") &&
- std::find(impDirVec.begin(), impDirVec.end(), "/usr/include") ==
- impDirVec.end() &&
+ !cmContains(impDirVec, "/usr/include") &&
std::find_if(impDirVec.begin(), impDirVec.end(),
[](std::string const& d) {
return cmHasLiteralSuffix(d, "/usr/include");
@@ -1017,7 +1084,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
}
for (std::string const& i : impDirVec) {
- if (implicitSet.insert(i).second) {
+ if (implicitSet.insert(cmSystemTools::GetRealPath(i)).second) {
implicitDirs.emplace_back(i);
}
}
@@ -1028,14 +1095,13 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
&lang](std::string const& dir) {
return (
// Do not exclude directories that are not in an excluded set.
- ((implicitSet.find(dir) == implicitSet.end()) &&
- (implicitExclude.find(dir) == implicitExclude.end()))
+ ((!cmContains(implicitSet, cmSystemTools::GetRealPath(dir))) &&
+ (!cmContains(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") &&
- (this->EnvCPATH.find(dir) != this->EnvCPATH.end())));
+ || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir)));
};
// Get the target-specific include directories.
@@ -1045,8 +1111,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// Support putting all the in-project include directories first if
// it is requested by the project.
if (this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")) {
- std::string const &topSourceDir = this->GetState()->GetSourceDirectory(),
- &topBinaryDir = this->GetState()->GetBinaryDirectory();
+ std::string const& topSourceDir = this->GetState()->GetSourceDirectory();
+ std::string const& topBinaryDir = this->GetState()->GetBinaryDirectory();
for (BT<std::string> const& udr : userDirs) {
// Emit this directory only if it is a subdirectory of the
// top-level source or binary tree.
@@ -1082,7 +1148,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 (implicitSet.find(udr.Value) != implicitSet.end()) {
+ if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
emitBT(udr);
}
}
@@ -1130,22 +1196,49 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
std::string const& linkLanguage,
cmGeneratorTarget* target)
{
- this->AppendFlags(
- flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
- if (!config.empty()) {
- std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
- this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
+ std::vector<BT<std::string>> tmpFlags =
+ this->GetStaticLibraryFlags(config, linkLanguage, target);
+ this->AppendFlags(flags, tmpFlags);
+}
+
+std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
+ std::string const& config, std::string const& linkLanguage,
+ cmGeneratorTarget* target)
+{
+ 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;
+ this->AppendFlags(staticLibFlags,
+ this->Makefile->GetSafeDefinition(name));
+ }
+ if (!staticLibFlags.empty()) {
+ flags.emplace_back(std::move(staticLibFlags));
+ }
}
- this->AppendFlags(flags, target->GetProperty("STATIC_LIBRARY_FLAGS"));
+
+ std::string staticLibFlags;
+ this->AppendFlags(staticLibFlags,
+ target->GetSafeProperty("STATIC_LIBRARY_FLAGS"));
if (!config.empty()) {
std::string name = "STATIC_LIBRARY_FLAGS_" + config;
- this->AppendFlags(flags, target->GetProperty(name));
+ this->AppendFlags(staticLibFlags, target->GetSafeProperty(name));
}
- std::vector<std::string> options;
- target->GetStaticLibraryLinkOptions(options, config, linkLanguage);
+ if (!staticLibFlags.empty()) {
+ flags.emplace_back(std::move(staticLibFlags));
+ }
+
+ std::vector<BT<std::string>> staticLibOpts =
+ target->GetStaticLibraryLinkOptions(config, linkLanguage);
// STATIC_LIBRARY_OPTIONS are escaped.
- this->AppendCompileOptions(flags, options);
+ this->AppendCompileOptions(flags, staticLibOpts);
+
+ return flags;
}
void cmLocalGenerator::GetTargetFlags(
@@ -1153,6 +1246,22 @@ void cmLocalGenerator::GetTargetFlags(
std::string& linkLibs, std::string& flags, std::string& linkFlags,
std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target)
{
+ std::vector<BT<std::string>> linkFlagsList;
+ std::vector<BT<std::string>> linkPathList;
+ std::vector<BT<std::string>> linkLibsList;
+ this->GetTargetFlags(linkLineComputer, config, linkLibsList, flags,
+ linkFlagsList, frameworkPath, linkPathList, target);
+ this->AppendFlags(linkFlags, linkFlagsList);
+ this->AppendFlags(linkPath, linkPathList);
+ this->AppendFlags(linkLibs, linkLibsList);
+}
+
+void cmLocalGenerator::GetTargetFlags(
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::vector<BT<std::string>>& linkLibs, std::string& flags,
+ std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
+ std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target)
+{
const std::string buildType = cmSystemTools::UpperCase(config);
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const char* libraryLinkVariable =
@@ -1163,21 +1272,26 @@ void cmLocalGenerator::GetTargetFlags(
switch (target->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
- this->GetStaticLibraryFlags(linkFlags, buildType, linkLanguage, target);
+ 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);
+ }
break;
case cmStateEnums::MODULE_LIBRARY:
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
CM_FALLTHROUGH;
case cmStateEnums::SHARED_LIBRARY: {
+ std::string sharedLibFlags;
if (linkLanguage != "Swift") {
- linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable);
- linkFlags += " ";
+ sharedLibFlags = cmStrCat(
+ this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
if (!buildType.empty()) {
- std::string build = libraryLinkVariable;
- build += "_";
- build += buildType;
- linkFlags += this->Makefile->GetSafeDefinition(build);
- linkFlags += " ";
+ std::string build = cmStrCat(libraryLinkVariable, '_', buildType);
+ sharedLibFlags += this->Makefile->GetSafeDefinition(build);
+ sharedLibFlags += " ";
}
if (this->Makefile->IsOn("WIN32") &&
!(this->Makefile->IsOn("CYGWIN") ||
@@ -1188,10 +1302,10 @@ void cmLocalGenerator::GetTargetFlags(
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
for (cmSourceFile* sf : sources) {
if (sf->GetExtension() == "def") {
- linkFlags += defFlag;
- linkFlags += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(sf->GetFullPath()), SHELL);
- linkFlags += " ";
+ sharedLibFlags += defFlag;
+ sharedLibFlags += this->ConvertToOutputFormat(
+ cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL);
+ sharedLibFlags += " ";
}
}
}
@@ -1199,38 +1313,40 @@ void cmLocalGenerator::GetTargetFlags(
const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- linkFlags += targetLinkFlags;
- linkFlags += " ";
+ sharedLibFlags += targetLinkFlags;
+ sharedLibFlags += " ";
}
if (!buildType.empty()) {
- std::string configLinkFlags = "LINK_FLAGS_";
- configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags);
+ targetLinkFlags =
+ target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
if (targetLinkFlags) {
- linkFlags += targetLinkFlags;
- linkFlags += " ";
+ sharedLibFlags += targetLinkFlags;
+ sharedLibFlags += " ";
}
}
- std::vector<std::string> opts;
- target->GetLinkOptions(opts, config, linkLanguage);
+ if (!sharedLibFlags.empty()) {
+ linkFlags.emplace_back(std::move(sharedLibFlags));
+ }
+
+ std::vector<BT<std::string>> linkOpts =
+ target->GetLinkOptions(config, linkLanguage);
// LINK_OPTIONS are escaped.
- this->AppendCompileOptions(linkFlags, opts);
+ this->AppendCompileOptions(linkFlags, linkOpts);
if (pcli) {
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
}
} break;
case cmStateEnums::EXECUTABLE: {
+ std::string exeFlags;
if (linkLanguage != "Swift") {
- linkFlags +=
- this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
- linkFlags += " ";
+ exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
+ exeFlags += " ";
if (!buildType.empty()) {
- std::string build = "CMAKE_EXE_LINKER_FLAGS_";
- build += buildType;
- linkFlags += this->Makefile->GetSafeDefinition(build);
- linkFlags += " ";
+ exeFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType));
+ exeFlags += " ";
}
if (linkLanguage.empty()) {
cmSystemTools::Error(
@@ -1240,22 +1356,19 @@ void cmLocalGenerator::GetTargetFlags(
}
if (target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
- linkFlags +=
+ exeFlags +=
this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
- linkFlags += " ";
+ exeFlags += " ";
} else {
- linkFlags +=
+ exeFlags +=
this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
- linkFlags += " ";
+ exeFlags += " ";
}
if (target->IsExecutableWithExports()) {
- std::string exportFlagVar = "CMAKE_EXE_EXPORTS_";
- exportFlagVar += linkLanguage;
- exportFlagVar += "_FLAG";
-
- linkFlags += this->Makefile->GetSafeDefinition(exportFlagVar);
- linkFlags += " ";
+ exeFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
+ exeFlags += " ";
}
}
@@ -1265,48 +1378,55 @@ void cmLocalGenerator::GetTargetFlags(
frameworkPath, linkPath);
}
- if (cmSystemTools::IsOn(
- this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
+ if (cmIsOn(this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
linkLanguage + std::string("_FLAGS");
- linkFlags += this->Makefile->GetSafeDefinition(sFlagVar);
- linkFlags += " ";
+ exeFlags += this->Makefile->GetSafeDefinition(sFlagVar);
+ exeFlags += " ";
}
std::string cmp0065Flags =
this->GetLinkLibsCMP0065(linkLanguage, *target);
if (!cmp0065Flags.empty()) {
- linkFlags += cmp0065Flags;
- linkFlags += " ";
+ exeFlags += cmp0065Flags;
+ exeFlags += " ";
}
const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- linkFlags += targetLinkFlags;
- linkFlags += " ";
+ exeFlags += targetLinkFlags;
+ exeFlags += " ";
}
if (!buildType.empty()) {
- std::string configLinkFlags = "LINK_FLAGS_";
- configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags);
+ targetLinkFlags =
+ target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
if (targetLinkFlags) {
- linkFlags += targetLinkFlags;
- linkFlags += " ";
+ exeFlags += targetLinkFlags;
+ exeFlags += " ";
}
}
- std::vector<std::string> opts;
- target->GetLinkOptions(opts, config, linkLanguage);
+ if (!exeFlags.empty()) {
+ linkFlags.emplace_back(std::move(exeFlags));
+ }
+
+ std::vector<BT<std::string>> linkOpts =
+ target->GetLinkOptions(config, linkLanguage);
// LINK_OPTIONS are escaped.
- this->AppendCompileOptions(linkFlags, opts);
+ this->AppendCompileOptions(linkFlags, linkOpts);
} break;
default:
break;
}
- this->AppendPositionIndependentLinkerFlags(linkFlags, target, config,
+ std::string extraLinkFlags;
+ this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
- this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage);
+ this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
+
+ if (!extraLinkFlags.empty()) {
+ linkFlags.emplace_back(std::move(extraLinkFlags));
+ }
}
void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
@@ -1314,26 +1434,45 @@ void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
std::string const& lang,
std::string& flags)
{
+ std::vector<BT<std::string>> tmpFlags =
+ this->GetTargetCompileFlags(target, config, lang);
+ this->AppendFlags(flags, tmpFlags);
+}
+
+std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
+ cmGeneratorTarget* target, std::string const& config,
+ std::string const& lang)
+{
+ std::vector<BT<std::string>> flags;
+ std::string compileFlags;
+
cmMakefile* mf = this->GetMakefile();
// Add language-specific flags.
- this->AddLanguageFlags(flags, target, lang, config);
+ this->AddLanguageFlags(compileFlags, target, lang, config);
if (target->IsIPOEnabled(lang, config)) {
- this->AppendFeatureOptions(flags, lang, "IPO");
+ this->AppendFeatureOptions(compileFlags, lang, "IPO");
}
- this->AddArchitectureFlags(flags, target, lang, config);
+ this->AddArchitectureFlags(compileFlags, target, lang, config);
if (lang == "Fortran") {
- this->AppendFlags(flags, this->GetTargetFortranFlags(target, config));
+ this->AppendFlags(compileFlags,
+ this->GetTargetFortranFlags(target, config));
}
- this->AddCMP0018Flags(flags, target, lang, config);
- this->AddVisibilityPresetFlags(flags, target, lang);
- this->AppendFlags(flags, mf->GetDefineFlags());
- this->AppendFlags(flags, this->GetFrameworkFlags(lang, config, target));
+ this->AddCMP0018Flags(compileFlags, target, lang, config);
+ this->AddVisibilityPresetFlags(compileFlags, target, lang);
+ this->AppendFlags(compileFlags, mf->GetDefineFlags());
+ this->AppendFlags(compileFlags,
+ this->GetFrameworkFlags(lang, config, target));
+
+ if (!compileFlags.empty()) {
+ flags.emplace_back(std::move(compileFlags));
+ }
this->AddCompileOptions(flags, target, lang, config);
+ return flags;
}
static std::string GetFrameworkFlags(const std::string& lang,
@@ -1364,8 +1503,7 @@ static std::string GetFrameworkFlags(const std::string& lang,
// will already have added a -F for the framework
for (std::string const& include : includes) {
if (lg->GetGlobalGenerator()->NameResolvesToFramework(include)) {
- std::string frameworkDir = include;
- frameworkDir += "/../";
+ std::string frameworkDir = cmStrCat(include, "/../");
frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
emitted.insert(frameworkDir);
}
@@ -1440,6 +1578,19 @@ void cmLocalGenerator::OutputLinkLibraries(
std::string& linkLibraries, std::string& frameworkPath,
std::string& linkPath)
{
+ std::vector<BT<std::string>> linkLibrariesList;
+ std::vector<BT<std::string>> linkPathList;
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibrariesList,
+ frameworkPath, linkPathList);
+ pcli->AppendValues(linkLibraries, linkLibrariesList);
+ pcli->AppendValues(linkPath, linkPathList);
+}
+
+void cmLocalGenerator::OutputLinkLibraries(
+ cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer,
+ std::vector<BT<std::string>>& linkLibraries, std::string& frameworkPath,
+ std::vector<BT<std::string>>& linkPath)
+{
cmComputeLinkInformation& cli = *pcli;
std::string linkLanguage = cli.GetLinkLanguage();
@@ -1463,26 +1614,17 @@ void cmLocalGenerator::OutputLinkLibraries(
}
// Add standard libraries for this language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += cli.GetLinkLanguage();
- standardLibsVar += "_STANDARD_LIBRARIES";
- std::string stdLibString;
- if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
- stdLibString = stdLibs;
- }
+ std::string stdLibString = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES"));
// Append the framework search path flags.
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += linkLanguage;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- std::string fwSearchFlag =
- this->Makefile->GetSafeDefinition(fwSearchFlagVar);
+ std::string fwSearchFlag = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG"));
frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
- linkPath =
- linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator);
-
- linkLibraries = linkLineComputer->ComputeLinkLibraries(cli, stdLibString);
+ linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator,
+ linkPath);
+ linkLineComputer->ComputeLinkLibraries(cli, stdLibString, linkLibraries);
}
std::string cmLocalGenerator::GetLinkLibsCMP0065(
@@ -1511,8 +1653,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
- // OLD behavior is to always add the flags
- add_shlib_flags = true;
+ // OLD behavior is to always add the flags, except on AIX where
+ // we compute symbol exports if ENABLE_EXPORTS is on.
+ add_shlib_flags =
+ !(tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
@@ -1521,16 +1665,16 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065));
CM_FALLTHROUGH;
case cmPolicies::NEW:
- // NEW behavior is to only add the flags if ENABLE_EXPORTS is on
- add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+ // NEW behavior is to only add the flags if ENABLE_EXPORTS is on,
+ // except on AIX where we compute symbol exports.
+ add_shlib_flags =
+ !tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS");
break;
}
if (add_shlib_flags) {
- std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
- linkFlagsVar += linkLanguage;
- linkFlagsVar += "_FLAGS";
- linkFlags = this->Makefile->GetSafeDefinition(linkFlagsVar);
+ linkFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_SHARED_LIBRARY_LINK_", linkLanguage, "_FLAGS"));
}
}
return linkFlags;
@@ -1559,7 +1703,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
const char* deploymentTargetFlag =
this->Makefile->GetDefinition(deploymentTargetFlagVar);
if (!archs.empty() && !lang.empty() &&
- (lang[0] == 'C' || lang[0] == 'F')) {
+ (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
for (std::string const& arch : archs) {
flags += " -arch ";
flags += arch;
@@ -1588,10 +1732,19 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
const std::string& config)
{
// Add language-specific flags.
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
- this->AddConfigVariableFlags(flags, flagsVar, config);
+ this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
+ config);
+
+ if (lang == "Swift") {
+ if (const char* 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));
+ }
+ }
+ }
// Add MSVC runtime library flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
@@ -1603,11 +1756,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
if (!msvcRuntimeLibraryValue) {
msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault;
}
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(msvcRuntimeLibraryValue);
- std::string const msvcRuntimeLibrary =
- cge->Evaluate(this, config, false, target);
+ std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate(
+ msvcRuntimeLibraryValue, this, config, target);
if (!msvcRuntimeLibrary.empty()) {
if (const char* msvcRuntimeLibraryOptions =
this->Makefile->GetDefinition(
@@ -1652,8 +1802,7 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
cmGeneratorTarget* cmLocalGenerator::FindGeneratorTargetToUse(
const std::string& name) const
{
- GeneratorTargetMap::const_iterator imported =
- this->ImportedGeneratorTargets.find(name);
+ auto imported = this->ImportedGeneratorTargets.find(name);
if (imported != this->ImportedGeneratorTargets.end()) {
return imported->second;
}
@@ -1743,15 +1892,14 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
// Check for a source file in this directory that matches the
// dependency.
if (cmSourceFile* sf = this->Makefile->GetSource(inName)) {
- dep = sf->GetFullPath();
+ dep = sf->ResolveFullPath();
return true;
}
// Treat the name as relative to the source directory in which it
// was given.
- dep = this->StateSnapshot.GetDirectory().GetCurrentSource();
- dep += "/";
- dep += inName;
+ dep = cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentSource(), '/',
+ inName);
return true;
}
@@ -1762,10 +1910,9 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
// Add flags for dealing with shared libraries for this language.
if (shared) {
- flagsVar = "CMAKE_SHARED_LIBRARY_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
+ this->AppendFlags(flags,
+ this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS")));
}
}
@@ -1784,7 +1931,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
std::string extProp = lang + "_EXTENSIONS";
bool ext = true;
if (const char* extPropValue = target->GetProperty(extProp)) {
- if (cmSystemTools::IsOff(extPropValue)) {
+ if (cmIsOff(extPropValue)) {
ext = false;
}
}
@@ -1798,8 +1945,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
"CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION";
if (const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag)) {
- std::vector<std::string> optVec;
- cmSystemTools::ExpandListArgument(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1827,8 +1973,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
"does not know the compile flags to use to enable it.";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
} else {
- std::vector<std::string> optVec;
- cmSystemTools::ExpandListArgument(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1845,10 +1990,20 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
langStdMap["CXX"].emplace_back("11");
langStdMap["CXX"].emplace_back("98");
+ langStdMap["OBJCXX"].emplace_back("20");
+ langStdMap["OBJCXX"].emplace_back("17");
+ langStdMap["OBJCXX"].emplace_back("14");
+ langStdMap["OBJCXX"].emplace_back("11");
+ langStdMap["OBJCXX"].emplace_back("98");
+
langStdMap["C"].emplace_back("11");
langStdMap["C"].emplace_back("99");
langStdMap["C"].emplace_back("90");
+ langStdMap["OBJC"].emplace_back("11");
+ langStdMap["OBJC"].emplace_back("99");
+ langStdMap["OBJC"].emplace_back("90");
+
langStdMap["CUDA"].emplace_back("14");
langStdMap["CUDA"].emplace_back("11");
langStdMap["CUDA"].emplace_back("98");
@@ -1858,8 +2013,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
std::vector<std::string>& stds = langStdMap[lang];
- std::vector<std::string>::const_iterator stdIt =
- std::find(stds.begin(), stds.end(), standard);
+ auto stdIt = std::find(stds.begin(), stds.end(), standard);
if (stdIt == stds.end()) {
std::string e =
lang + "_STANDARD is set to invalid value '" + standard + "'";
@@ -1868,8 +2022,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
return;
}
- std::vector<std::string>::const_iterator defaultStdIt =
- std::find(stds.begin(), stds.end(), defaultStd);
+ auto defaultStdIt = std::find(stds.begin(), stds.end(), defaultStd);
if (defaultStdIt == stds.end()) {
std::string e = "CMAKE_" + lang +
"_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) +
@@ -1888,8 +2041,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
std::string const& opt =
target->Target->GetMakefile()->GetRequiredDefinition(option_flag);
- std::vector<std::string> optVec;
- cmSystemTools::ExpandListArgument(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -1901,12 +2053,11 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
// for which a flag is defined.
for (; stdIt < defaultStdIt; ++stdIt) {
std::string option_flag =
- "CMAKE_" + lang + *stdIt + "_" + type + "_COMPILE_OPTION";
+ cmStrCat("CMAKE_", lang, *stdIt, "_", type, "_COMPILE_OPTION");
if (const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag)) {
- std::vector<std::string> optVec;
- cmSystemTools::ExpandListArgument(opt, optVec);
+ std::vector<std::string> optVec = cmExpandedList(opt);
for (std::string const& i : optVec) {
this->AppendFlagEscape(flags, i);
}
@@ -2054,9 +2205,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
std::string originalFlags =
this->GlobalGenerator->GetSharedLibFlagsForLanguage(lang);
if (shared) {
- std::string flagsVar = "CMAKE_SHARED_LIBRARY_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
+ std::string flagsVar = cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS");
std::string const& flags = this->Makefile->GetSafeDefinition(flagsVar);
if (flags != originalFlags) {
@@ -2095,20 +2244,15 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
std::string picFlags;
if (targetType == cmStateEnums::EXECUTABLE) {
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_COMPILE_OPTIONS_PIE";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar);
+ picFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIE"));
}
if (picFlags.empty()) {
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_COMPILE_OPTIONS_PIC";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar);
+ picFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC"));
}
if (!picFlags.empty()) {
- std::vector<std::string> options;
- cmSystemTools::ExpandListArgument(picFlags, options);
+ std::vector<std::string> options = cmExpandedList(picFlags);
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2120,13 +2264,12 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
const std::string& config)
{
// Add the flags from the variable itself.
- std::string flagsVar = var;
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
+ this->AppendFlags(flags, this->Makefile->GetSafeDefinition(var));
// Add the flags from the build-type specific variable.
if (!config.empty()) {
- flagsVar += "_";
- flagsVar += cmSystemTools::UpperCase(config);
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
+ const std::string flagsVar =
+ cmStrCat(var, '_', cmSystemTools::UpperCase(config));
+ this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar));
}
}
@@ -2141,11 +2284,11 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
}
}
-void cmLocalGenerator::AppendFlags(std::string& flags,
- const char* newFlags) const
+void cmLocalGenerator::AppendFlags(
+ std::string& flags, const std::vector<BT<std::string>>& newFlags) const
{
- if (newFlags && *newFlags) {
- this->AppendFlags(flags, std::string(newFlags));
+ for (BT<std::string> const& flag : newFlags) {
+ this->AppendFlags(flags, flag.Value);
}
}
@@ -2155,6 +2298,257 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
this->AppendFlags(flags, this->EscapeForShell(rawFlag));
}
+void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
+{
+ // FIXME: Handle all configurations in multi-config generators.
+ std::string config;
+ if (!this->GetGlobalGenerator()->IsMultiConfig()) {
+ config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ }
+ const std::string buildType = cmSystemTools::UpperCase(config);
+
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
+
+ for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
+ auto langSources =
+ std::count_if(sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
+ return lang == sf->GetLanguage() &&
+ !sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
+ });
+ if (langSources == 0) {
+ continue;
+ }
+
+ const std::string pchSource = target->GetPchSource(config, lang);
+ const std::string pchHeader = target->GetPchHeader(config, lang);
+
+ if (pchSource.empty() || pchHeader.empty()) {
+ continue;
+ }
+
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+ if (pchExtension.empty()) {
+ continue;
+ }
+
+ const char* pchReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
+
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!pchReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
+
+ const std::string pchFile = target->GetPchFile(config, lang);
+
+ // 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")) {
+
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig()
+ ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+ : "";
+
+ 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";
+ for (auto extension : { ".pdb", ".idb" }) {
+ const std::string from_file = cmStrCat(
+ reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
+ extension);
+
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+ target->GetName(), ".dir/${PDB_PREFIX}");
+
+ file << "if (EXISTS \"" << from_file << "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ file << "endif()\n";
+ }
+
+ cmCustomCommandLines commandLines;
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(cmSystemTools::GetCMakeCommand());
+ currentLine.push_back(cmStrCat("-DPDB_PREFIX=", pdb_prefix));
+ currentLine.push_back("-P");
+ currentLine.push_back(copy_script);
+ commandLines.push_back(std::move(currentLine));
+
+ 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()->IsMultiConfig()) {
+ this->Makefile->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule =
+ this->Makefile->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());
+ }
+ }
+
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir.c_str());
+ }
+
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang);
+
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ "LINK_FLAGS",
+ cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL))
+ .c_str(),
+ true);
+ }
+ } else {
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ }
+
+ // Add pchHeader to source files, which will
+ // be grouped as "Precompile Header File"
+ auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+ pchHeader, false, cmSourceFileLocationKind::Known);
+ std::string err;
+ pchHeader_sf->ResolveFullPath(&err);
+ target->AddSource(pchHeader);
+ }
+ }
+}
+
+void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
+{
+ if (!target->GetPropertyAsBool("UNITY_BUILD")) {
+ return;
+ }
+
+ // FIXME: Handle all configurations in multi-config generators.
+ std::string config;
+ if (!this->GetGlobalGenerator()->IsMultiConfig()) {
+ config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ }
+
+ const std::string buildType = cmSystemTools::UpperCase(config);
+
+ std::string filename_base =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ target->GetName(), ".dir/Unity/");
+
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
+
+ auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+ const size_t unityBatchSize =
+ static_cast<size_t>(std::atoi(batchSizeString));
+
+ auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+ auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+
+ for (std::string lang : { "C", "CXX" }) {
+ std::vector<cmSourceFile*> filtered_sources;
+ std::copy_if(sources.begin(), sources.end(),
+ std::back_inserter(filtered_sources), [&](cmSourceFile* sf) {
+ return sf->GetLanguage() == lang &&
+ !sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") &&
+ !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
+ !sf->GetProperty("COMPILE_OPTIONS") &&
+ !sf->GetProperty("COMPILE_DEFINITIONS") &&
+ !sf->GetProperty("COMPILE_FLAGS") &&
+ !sf->GetProperty("INCLUDE_DIRECTORIES");
+ });
+
+ size_t batchSize = unityBatchSize;
+ if (unityBatchSize == 0) {
+ batchSize = filtered_sources.size();
+ }
+
+ for (size_t itemsLeft = filtered_sources.size(), chunk = batchSize,
+ batch = 0;
+ itemsLeft > 0; itemsLeft -= chunk, ++batch) {
+
+ chunk = std::min(itemsLeft, batchSize);
+
+ std::string filename = cmStrCat(filename_base, "unity_", batch,
+ (lang == "C") ? ".c" : ".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];
+
+ // Only in Visual Studio generator we keep the source files
+ // for explicit processing.
+ if (!this->GetGlobalGenerator()->IsMultiConfig() ||
+ this->GetGlobalGenerator()->IsXcode()) {
+ 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);
+ unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
+ unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ }
+ }
+}
+
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
@@ -2179,8 +2573,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
return;
}
- std::vector<std::string> flagsList;
- cmSystemTools::ExpandListArgument(rawFlagsList, flagsList);
+ std::vector<std::string> flagsList = cmExpandedList(rawFlagsList);
for (std::string const& o : flagsList) {
this->AppendFlagEscape(flags, o);
}
@@ -2201,10 +2594,10 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- const std::string mode = cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE";
+ const std::string mode = cmIsOn(PICValue) ? "PIE" : "NO_PIE";
std::string supported = "CMAKE_" + lang + "_LINK_" + mode + "_SUPPORTED";
- if (cmSystemTools::IsOff(this->Makefile->GetDefinition(supported))) {
+ if (cmIsOff(this->Makefile->GetDefinition(supported))) {
return;
}
@@ -2215,8 +2608,7 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- std::vector<std::string> flagsList;
- cmSystemTools::ExpandListArgument(pieFlags, flagsList);
+ std::vector<std::string> flagsList = cmExpandedList(pieFlags);
for (const auto& flag : flagsList) {
this->AppendFlagEscape(flags, flag);
}
@@ -2232,8 +2624,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options,
}
// Expand the list of options.
- std::vector<std::string> options_vec;
- cmSystemTools::ExpandListArgument(options_list, options_vec);
+ std::vector<std::string> options_vec = cmExpandedList(options_list);
this->AppendCompileOptions(options, options_vec, regex);
}
@@ -2257,6 +2648,30 @@ void cmLocalGenerator::AppendCompileOptions(
}
}
+void cmLocalGenerator::AppendCompileOptions(
+ std::vector<BT<std::string>>& options,
+ const std::vector<BT<std::string>>& options_vec, const char* regex) const
+{
+ if (regex != nullptr) {
+ // Filter flags upon specified regular expressions.
+ cmsys::RegularExpression r(regex);
+
+ for (BT<std::string> const& opt : options_vec) {
+ if (r.find(opt.Value)) {
+ std::string flag;
+ this->AppendFlagEscape(flag, opt.Value);
+ options.emplace_back(std::move(flag), opt.Backtrace);
+ }
+ }
+ } else {
+ for (BT<std::string> const& opt : options_vec) {
+ std::string flag;
+ this->AppendFlagEscape(flag, opt.Value);
+ options.emplace_back(std::move(flag), opt.Backtrace);
+ }
+ }
+}
+
void cmLocalGenerator::AppendIncludeDirectories(
std::vector<std::string>& includes, const char* includes_list,
const cmSourceFile& sourceFile) const
@@ -2267,8 +2682,7 @@ void cmLocalGenerator::AppendIncludeDirectories(
}
// Expand the list of includes.
- std::vector<std::string> includes_vec;
- cmSystemTools::ExpandListArgument(includes_list, includes_vec);
+ std::vector<std::string> includes_vec = cmExpandedList(includes_list);
this->AppendIncludeDirectories(includes, includes_vec, sourceFile);
}
@@ -2293,7 +2707,7 @@ void cmLocalGenerator::AppendIncludeDirectories(
std::string inc = include;
- if (!cmSystemTools::IsOff(inc)) {
+ if (!cmIsOff(inc)) {
cmSystemTools::ConvertToUnixSlashes(inc);
}
@@ -2345,10 +2759,8 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
// Lookup the define flag for the current language.
std::string dflag = "-D";
if (!lang.empty()) {
- std::string defineFlagVar = "CMAKE_";
- defineFlagVar += lang;
- defineFlagVar += "_DEFINE_FLAG";
- const char* df = this->Makefile->GetDefinition(defineFlagVar);
+ const char* df =
+ this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG"));
if (df && *df) {
dflag = df;
}
@@ -2394,13 +2806,10 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags,
const std::string& lang,
const char* feature)
{
- std::string optVar = "CMAKE_";
- optVar += lang;
- optVar += "_COMPILE_OPTIONS_";
- optVar += feature;
- if (const char* optionList = this->Makefile->GetDefinition(optVar)) {
- std::vector<std::string> options;
- cmSystemTools::ExpandListArgument(optionList, options);
+ const char* optionList = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature));
+ if (optionList != nullptr) {
+ std::vector<std::string> options = cmExpandedList(optionList);
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2555,8 +2964,8 @@ static bool cmLocalGeneratorShortenObjectName(std::string& objName,
objName.find('/', objName.size() - max_len + 32);
if (pos != std::string::npos) {
cmCryptoHash md5(cmCryptoHash::AlgoMD5);
- std::string md5name = md5.HashString(objName.substr(0, pos));
- md5name += objName.substr(pos);
+ std::string md5name = cmStrCat(md5.HashString(objName.substr(0, pos)),
+ cm::string_view(objName).substr(pos));
objName = md5name;
// The object name is now short enough.
@@ -2591,8 +3000,7 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
const std::string& sin, std::string const& dir_max)
{
// Look for an existing mapped name for this object file.
- std::map<std::string, std::string>::iterator it =
- this->UniqueObjectNamesMap.find(sin);
+ auto it = this->UniqueObjectNamesMap.find(sin);
// If no entry exists create one.
if (it == this->UniqueObjectNamesMap.end()) {
@@ -2740,6 +3148,22 @@ 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");
+ if (unitySourceFile || pchExtension) {
+ if (pchExtension) {
+ customOutputExtension = pchExtension;
+ }
+
+ cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
+ if (var.find(objectName)) {
+ objectName.erase(var.start(), var.end() - var.start());
+ }
+ }
+
// Replace the original source file extension with the object file
// extension.
bool keptSourceExtension = true;
@@ -2751,10 +3175,8 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
if (!replaceExt) {
std::string lang = source.GetLanguage();
if (!lang.empty()) {
- std::string repVar = "CMAKE_";
- repVar += lang;
- repVar += "_OUTPUT_EXTENSION_REPLACE";
- replaceExt = this->Makefile->IsOn(repVar);
+ replaceExt = this->Makefile->IsOn(
+ cmStrCat("CMAKE_", lang, "_OUTPUT_EXTENSION_REPLACE"));
}
}
@@ -2963,7 +3385,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
// back to the directory-level values set by the user.
cmMakefile* mf = this->Makefile;
cmMakefile::ScopePushPop varScope(mf);
- mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName.c_str());
+ mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName);
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_INFO_STRING");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_ICON_FILE");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_GUI_IDENTIFIER");
@@ -3002,7 +3424,7 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
// back to the directory-level values set by the user.
cmMakefile* mf = this->Makefile;
cmMakefile::ScopePushPop varScope(mf);
- mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName.c_str());
+ mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName);
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f0c6806fb..12359dbdd 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -5,7 +5,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_kwiml.h"
#include <iosfwd>
#include <map>
#include <set>
@@ -13,6 +12,8 @@
#include <unordered_map>
#include <vector>
+#include "cm_kwiml.h"
+
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -121,9 +122,12 @@ public:
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
const std::string& newFlags) const;
- virtual void AppendFlags(std::string& flags, const char* newFlags) const;
+ virtual void AppendFlags(std::string& flags,
+ const std::vector<BT<std::string>>& newFlags) const;
virtual void AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const;
+ void AddPchDependencies(cmGeneratorTarget* target);
+ void AddUnityBuild(cmGeneratorTarget* target);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
@@ -195,6 +199,9 @@ public:
void AppendCompileOptions(std::string& options,
const std::vector<std::string>& options_vec,
const char* regex = nullptr) const;
+ void AppendCompileOptions(std::vector<BT<std::string>>& options,
+ const std::vector<BT<std::string>>& options_vec,
+ const char* regex = nullptr) const;
/**
* Join a set of defines into a definesString with a space separator.
@@ -281,6 +288,9 @@ public:
void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
const std::string& lang, const std::string& config);
+ void AddCompileOptions(std::vector<BT<std::string>>& flags,
+ cmGeneratorTarget* target, const std::string& lang,
+ const std::string& config);
std::string GetProjectName() const;
@@ -361,6 +371,9 @@ public:
void GetStaticLibraryFlags(std::string& flags, std::string const& config,
std::string const& linkLanguage,
cmGeneratorTarget* target);
+ std::vector<BT<std::string>> GetStaticLibraryFlags(
+ std::string const& config, std::string const& linkLanguage,
+ cmGeneratorTarget* target);
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
@@ -369,6 +382,11 @@ public:
std::string& flags, std::string& linkFlags,
std::string& frameworkPath, std::string& linkPath,
cmGeneratorTarget* target);
+ void GetTargetFlags(
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::vector<BT<std::string>>& linkLibs, std::string& flags,
+ std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
+ std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target);
void GetTargetDefines(cmGeneratorTarget const* target,
std::string const& config, std::string const& lang,
std::set<std::string>& defines) const;
@@ -378,6 +396,9 @@ public:
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 GetFrameworkFlags(std::string const& l,
std::string const& config,
@@ -396,6 +417,7 @@ public:
void IssueMessage(MessageType t, std::string const& text) const;
+ void CreateEvaluationFileOutputs();
void CreateEvaluationFileOutputs(const std::string& config);
void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
@@ -408,6 +430,11 @@ protected:
cmLinkLineComputer* linkLineComputer,
std::string& linkLibraries,
std::string& frameworkPath, std::string& linkPath);
+ void OutputLinkLibraries(cmComputeLinkInformation* pcli,
+ cmLinkLineComputer* linkLineComputer,
+ std::vector<BT<std::string>>& linkLibraries,
+ std::string& frameworkPath,
+ std::vector<BT<std::string>>& linkPath);
// Handle old-style install rules stored in the targets.
void GenerateTargetInstallRules(
@@ -431,8 +458,8 @@ protected:
std::set<std::string> EnvCPATH;
- typedef std::unordered_map<std::string, cmGeneratorTarget*>
- GeneratorTargetMap;
+ using GeneratorTargetMap =
+ std::unordered_map<std::string, cmGeneratorTarget*>;
GeneratorTargetMap GeneratorTargetSearchIndex;
std::vector<cmGeneratorTarget*> GeneratorTargets;
@@ -461,7 +488,7 @@ private:
void ComputeObjectMaxPath();
};
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
bool cmLocalGeneratorCheckObjectName(std::string& objName,
std::string::size_type dir_len,
std::string::size_type max_total_len);
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index bf25f98ea..4b10798e1 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -2,16 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalGhsMultiGenerator.h"
+#include <algorithm>
+#include <utility>
+
#include "cmGeneratorTarget.h"
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <algorithm>
-#include <utility>
-
cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
: cmLocalGenerator(gg, mf)
@@ -23,9 +24,7 @@ cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator() = default;
std::string cmLocalGhsMultiGenerator::GetTargetDirectory(
cmGeneratorTarget const* target) const
{
- std::string dir;
- dir += target->GetName();
- dir += ".dir";
+ std::string dir = cmStrCat(target->GetName(), ".dir");
return dir;
}
@@ -63,11 +62,8 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* gt)
{
- std::string dir_max;
- dir_max += this->GetCurrentBinaryDirectory();
- dir_max += "/";
- dir_max += this->GetTargetDirectory(gt);
- dir_max += "/";
+ std::string dir_max = cmStrCat(this->GetCurrentBinaryDirectory(), '/',
+ this->GetTargetDirectory(gt), '/');
// Count the number of object files with each name. Note that
// filesystem may not be case sensitive.
@@ -75,9 +71,10 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
for (auto const& si : mapping) {
cmSourceFile const* sf = si.first;
- std::string objectNameLower = cmSystemTools::LowerCase(
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
- objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
+ std::string objectNameLower = cmStrCat(
+ cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())),
+ this->GlobalGenerator->GetLanguageOutputExtension(*sf));
counts[objectNameLower] += 1;
}
@@ -85,9 +82,9 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
// object name computation.
for (auto& si : mapping) {
cmSourceFile const* sf = si.first;
- std::string objectName =
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
- objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
+ std::string objectName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()),
+ this->GlobalGenerator->GetLanguageOutputExtension(*sf));
if (counts[cmSystemTools::LowerCase(objectName)] > 1) {
const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
index b6ccd0815..2250e5745 100644
--- a/Source/cmLocalGhsMultiGenerator.h
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -3,12 +3,12 @@
#ifndef cmLocalGhsMultiGenerator_h
#define cmLocalGhsMultiGenerator_h
-#include "cmLocalGenerator.h"
-
#include <map>
#include <string>
#include <vector>
+#include "cmLocalGenerator.h"
+
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 90666fc18..134bbe18a 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -3,13 +3,15 @@
#include "cmLocalNinjaGenerator.h"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstdio>
#include <iterator>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
-#include <stdio.h>
#include <utility>
+#include "cmsys/FStream.hxx"
+
#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -25,9 +27,9 @@
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cmsys/FStream.hxx"
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
@@ -87,12 +89,6 @@ void cmLocalNinjaGenerator::Generate()
auto tg = cmNinjaTargetGenerator::New(target);
if (tg) {
tg->Generate();
- // Add the target to "all" if required.
- if (!this->GetGlobalNinjaGenerator()->IsExcluded(
- this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
- target)) {
- this->GetGlobalNinjaGenerator()->AddDependencyToAll(target);
- }
}
}
@@ -104,8 +100,7 @@ void cmLocalNinjaGenerator::Generate()
std::string cmLocalNinjaGenerator::GetTargetDirectory(
cmGeneratorTarget const* target) const
{
- std::string dir = "CMakeFiles/";
- dir += target->GetName();
+ std::string dir = cmStrCat("CMakeFiles/", target->GetName());
#if defined(__VMS)
dir += "_dir";
#else
@@ -223,8 +218,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools;
- cmSystemTools::ExpandListArgument(jobpools, pools);
+ std::vector<std::string> pools = cmExpandedList(jobpools);
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
@@ -302,8 +296,7 @@ std::string cmLocalNinjaGenerator::WriteCommandScript(
if (target) {
scriptPath = target->GetSupportDirectory();
} else {
- scriptPath = this->GetCurrentBinaryDirectory();
- scriptPath += "/CMakeFiles";
+ scriptPath = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
}
cmSystemTools::MakeDirectory(scriptPath);
scriptPath += '/';
@@ -390,8 +383,7 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
}
std::ostringstream cmd;
- for (std::vector<std::string>::const_iterator li = cmdLines.begin();
- li != cmdLines.end(); ++li)
+ for (auto li = cmdLines.begin(); li != cmdLines.end(); ++li)
#ifdef _WIN32
{
if (li != cmdLines.begin()) {
@@ -535,8 +527,7 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
{
for (cmCustomCommand const* customCommand : this->CustomCommands) {
- CustomCommandTargetMap::iterator i =
- this->CustomCommandTargets.find(customCommand);
+ auto i = this->CustomCommandTargets.find(customCommand);
assert(i != this->CustomCommandTargets.end());
// A custom command may appear on multiple targets. However, some build
@@ -548,7 +539,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
//
// FIXME: This won't work in certain obscure scenarios involving indirect
// dependencies.
- std::set<cmGeneratorTarget*>::iterator j = i->second.begin();
+ auto j = i->second.begin();
assert(j != i->second.end());
std::vector<std::string> ccTargetDeps;
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j,
@@ -557,7 +548,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
++j;
for (; j != i->second.end(); ++j) {
- std::vector<std::string> jDeps, depsIntersection;
+ std::vector<std::string> jDeps;
+ std::vector<std::string> depsIntersection;
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps);
std::sort(jDeps.begin(), jDeps.end());
std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
@@ -613,12 +605,10 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles()
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
std::vector<std::string> cleanFiles;
{
- cmGeneratorExpression ge;
- auto cge = ge.Parse(prop_value);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
- cleanFiles);
+ cmExpandList(cmGeneratorExpression::Evaluate(
+ prop_value, this,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+ cleanFiles);
}
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 3a30bbb7b..f64534ce1 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -93,7 +93,6 @@ private:
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
- void WriteCustomCommandRule();
void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
const cmNinjaDeps& orderOnlyDeps);
@@ -109,8 +108,8 @@ private:
std::string HomeRelativeOutputPath;
- typedef std::map<cmCustomCommand const*, std::set<cmGeneratorTarget*>>
- CustomCommandTargetMap;
+ using CustomCommandTargetMap =
+ std::map<cmCustomCommand const*, std::set<cmGeneratorTarget*>>;
CustomCommandTargetMap CustomCommandTargets;
std::vector<cmCustomCommand const*> CustomCommands;
};
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c392e9787..4a70248d6 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2,14 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalUnixMakefileGenerator3.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Terminal.h"
#include <algorithm>
-#include <memory> // IWYU pragma: keep
+#include <cstdio>
#include <sstream>
-#include <stdio.h>
#include <utility>
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Terminal.h"
+
#include "cmAlgorithms.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
@@ -31,6 +33,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -38,7 +41,7 @@
// Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake.
#include "cmDependsC.h"
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmDependsFortran.h"
# include "cmDependsJava.h"
#endif
@@ -159,14 +162,10 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
continue;
}
std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(
- objectSources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ gt->GetObjectSources(objectSources, this->ConfigName);
// Compute full path to object file directory for this target.
- std::string dir;
- dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
- dir += "/";
- dir += this->GetTargetDirectory(gt);
- dir += "/";
+ std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
+ '/', this->GetTargetDirectory(gt), '/');
// Compute the name of each object file.
for (cmSourceFile const* sf : objectSources) {
bool hasSourceExtension = true;
@@ -363,14 +362,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
emitted.insert(target->GetName());
// for subdirs add a rule to build this specific target by name.
- localName = this->GetRelativeTargetDirectory(target);
- localName += "/rule";
+ localName = cmStrCat(this->GetRelativeTargetDirectory(target), "/rule");
commands.clear();
depends.clear();
// Build the target for this pass.
- std::string makefile2 = "CMakeFiles/";
- makefile2 += "Makefile2";
+ std::string makefile2 = "CMakeFiles/Makefile2";
commands.push_back(this->GetRecursiveMakeCall(makefile2, localName));
this->CreateCDCommand(commands, this->GetBinaryDirectory(),
this->GetCurrentBinaryDirectory());
@@ -386,13 +383,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
}
// Add a fast rule to build the target
- std::string makefileName = this->GetRelativeTargetDirectory(target);
- makefileName += "/build.make";
+ std::string makefileName =
+ cmStrCat(this->GetRelativeTargetDirectory(target), "/build.make");
// make sure the makefile name is suitable for a makefile
- std::string makeTargetName = this->GetRelativeTargetDirectory(target);
- makeTargetName += "/build";
- localName = target->GetName();
- localName += "/fast";
+ std::string makeTargetName =
+ cmStrCat(this->GetRelativeTargetDirectory(target), "/build");
+ localName = cmStrCat(target->GetName(), "/fast");
depends.clear();
commands.clear();
commands.push_back(
@@ -405,10 +401,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// Add a local name for the rule to relink the target before
// installation.
if (target->NeedRelinkBeforeInstall(this->ConfigName)) {
- makeTargetName = this->GetRelativeTargetDirectory(target);
- makeTargetName += "/preinstall";
- localName = target->GetName();
- localName += "/preinstall";
+ makeTargetName =
+ cmStrCat(this->GetRelativeTargetDirectory(target), "/preinstall");
+ localName = cmStrCat(target->GetName(), "/preinstall");
depends.clear();
commands.clear();
commands.push_back(
@@ -425,9 +420,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
{
- std::string infoFileName = this->GetCurrentBinaryDirectory();
- infoFileName += "/CMakeFiles";
- infoFileName += "/CMakeDirectoryInformation.cmake";
+ std::string infoFileName =
+ cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeDirectoryInformation.cmake");
// Open the output file.
cmGeneratedFileStream infoFileStream(infoFileName);
@@ -483,9 +478,8 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
std::string cmLocalUnixMakefileGenerator3::ConvertToFullPath(
const std::string& localPath)
{
- std::string dir = this->GetCurrentBinaryDirectory();
- dir += "/";
- dir += localPath;
+ std::string dir =
+ cmStrCat(this->GetCurrentBinaryDirectory(), '/', localPath);
return dir;
}
@@ -766,19 +760,18 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
std::vector<std::string> commands;
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
- std::string rescanRule = "$(CMAKE_COMMAND) -P ";
- rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
- cmOutputConverter::SHELL);
+ std::string rescanRule =
+ cmStrCat("$(CMAKE_COMMAND) -P ",
+ this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL));
commands.push_back(rescanRule);
}
- std::string cmakefileName = "CMakeFiles/";
- cmakefileName += "Makefile.cmake";
- std::string runRule =
- "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
- runRule += " --check-build-system ";
- runRule +=
- this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL);
- runRule += " 0";
+ std::string cmakefileName = "CMakeFiles/Makefile.cmake";
+ std::string runRule = cmStrCat(
+ "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) "
+ "--check-build-system ",
+ this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
+ " 0");
std::vector<std::string> no_depends;
commands.push_back(std::move(runRule));
@@ -817,10 +810,10 @@ void cmLocalUnixMakefileGenerator3::WriteConvenienceRule(
}
std::string cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(
- cmGeneratorTarget* target)
+ cmGeneratorTarget const* target) const
{
- std::string dir = this->HomeRelativeOutputPath;
- dir += this->GetTargetDirectory(target);
+ std::string dir =
+ cmStrCat(this->HomeRelativeOutputPath, this->GetTargetDirectory(target));
return dir;
}
@@ -838,12 +831,6 @@ void cmLocalUnixMakefileGenerator3::AppendFlags(
this->cmLocalGenerator::AppendFlags(flags, newFlags);
}
-void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
- const char* newFlags) const
-{
- this->cmLocalGenerator::AppendFlags(flags, newFlags);
-}
-
void cmLocalUnixMakefileGenerator3::AppendRuleDepend(
std::vector<std::string>& depends, const char* ruleFileName)
{
@@ -851,7 +838,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepend(
// it is specifically enabled by the user or project.
const char* nodep =
this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
- if (!nodep || cmSystemTools::IsOff(nodep)) {
+ if (!nodep || cmIsOff(nodep)) {
depends.emplace_back(ruleFileName);
}
}
@@ -961,7 +948,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// This command was specified as a path to a file in the
// current directory. Add a leading "./" so it can run
// without the current directory being in the search path.
- cmd = "./" + cmd;
+ cmd = cmStrCat("./", cmd);
}
std::string launcher;
@@ -1015,18 +1002,16 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
std::string::size_type rcurly = cmd.find('}');
if (rcurly == std::string::npos || rcurly > lcurly) {
// The first curly is a left curly. Use the hack.
- std::string hack_cmd = cmd.substr(0, lcurly);
- hack_cmd += "{{}";
- hack_cmd += cmd.substr(lcurly + 1);
- cmd = hack_cmd;
+ cmd =
+ cmStrCat(cmd.substr(0, lcurly), "{{}", cmd.substr(lcurly + 1));
}
}
}
if (launcher.empty()) {
if (useCall) {
- cmd = "call " + cmd;
+ cmd = cmStrCat("call ", cmd);
} else if (this->IsNMake() && cmd[0] == '"') {
- cmd = "echo >nul && " + cmd;
+ cmd = cmStrCat("echo >nul && ", cmd);
}
}
commands1.push_back(std::move(cmd));
@@ -1045,10 +1030,8 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
cmGeneratorTarget* target, const char* filename)
{
std::string currentBinDir = this->GetCurrentBinaryDirectory();
- std::string cleanfile = currentBinDir;
- cleanfile += "/";
- cleanfile += this->GetTargetDirectory(target);
- cleanfile += "/cmake_clean";
+ std::string cleanfile = cmStrCat(
+ currentBinDir, '/', this->GetTargetDirectory(target), "/cmake_clean");
if (filename) {
cleanfile += "_";
cleanfile += filename;
@@ -1068,11 +1051,12 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
fout << ")\n";
}
{
- std::string remove = "$(CMAKE_COMMAND) -P ";
- remove += this->ConvertToOutputFormat(
- this->MaybeConvertToRelativePath(this->GetCurrentBinaryDirectory(),
- cleanfile),
- cmOutputConverter::SHELL);
+ std::string remove =
+ cmStrCat("$(CMAKE_COMMAND) -P ",
+ this->ConvertToOutputFormat(
+ this->MaybeConvertToRelativePath(
+ this->GetCurrentBinaryDirectory(), cleanfile),
+ cmOutputConverter::SHELL));
commands.push_back(std::move(remove));
}
@@ -1100,12 +1084,10 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
// Look for additional files registered for cleaning in this directory.
if (const char* prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
- cleanFiles);
+ cmExpandList(cmGeneratorExpression::Evaluate(
+ prop_value, this,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+ cleanFiles);
}
if (cleanFiles.empty()) {
return;
@@ -1115,8 +1097,8 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
this->GetGlobalGenerator()->GetLocalGenerators().at(0);
std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory();
std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
- std::string cleanfile = currentBinaryDir;
- cleanfile += "/CMakeFiles/cmake_directory_clean.cmake";
+ std::string cleanfile =
+ cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake");
// Write clean script
{
std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
@@ -1135,10 +1117,11 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
}
// Create command
{
- std::string remove = "$(CMAKE_COMMAND) -P ";
- remove += this->ConvertToOutputFormat(
- rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile),
- cmOutputConverter::SHELL);
+ std::string remove =
+ cmStrCat("$(CMAKE_COMMAND) -P ",
+ this->ConvertToOutputFormat(
+ rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile),
+ cmOutputConverter::SHELL));
commands.push_back(std::move(remove));
}
}
@@ -1184,12 +1167,12 @@ void cmLocalUnixMakefileGenerator3::AppendEcho(
std::string cmd;
if (color_name.empty() && !progress) {
// Use the native echo command.
- cmd = "@echo ";
- cmd += this->EscapeForShell(line, false, true);
+ cmd = cmStrCat("@echo ", this->EscapeForShell(line, false, true));
} else {
// Use cmake to echo the text in color.
- cmd = "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) ";
- cmd += color_name;
+ cmd = cmStrCat(
+ "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) ",
+ color_name);
if (progress) {
cmd += "--progress-dir=";
cmd += this->ConvertToOutputFormat(
@@ -1225,8 +1208,7 @@ void cmLocalUnixMakefileGenerator3::AppendEcho(
std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable(
std::string const& s, std::string const& s2)
{
- std::string unmodified = s;
- unmodified += s2;
+ std::string unmodified = cmStrCat(s, s2);
// if there is no restriction on the length of make variables
// and there are no "." characters in the string, then return the
// unmodified combination.
@@ -1241,8 +1223,7 @@ std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable(
// see if the variable has been defined before and return
// the modified version of the variable
- std::map<std::string, std::string>::iterator i =
- this->MakeVariableMap.find(unmodified);
+ auto i = this->MakeVariableMap.find(unmodified);
if (i != this->MakeVariableMap.end()) {
return i->second;
}
@@ -1344,9 +1325,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
// may have changed. In this case discard all old dependencies.
bool needRescanDirInfo = false;
{
- std::string dirInfoFile = this->GetCurrentBinaryDirectory();
- dirInfoFile += "/CMakeFiles";
- dirInfoFile += "/CMakeDirectoryInformation.cmake";
+ std::string dirInfoFile =
+ cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeDirectoryInformation.cmake");
int result;
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
result < 0) {
@@ -1388,8 +1369,8 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
// The dependencies must be regenerated.
std::string targetName = cmSystemTools::GetFilenameName(targetDir);
targetName = targetName.substr(0, targetName.length() - 4);
- std::string message = "Scanning dependencies of target ";
- message += targetName;
+ std::string message =
+ cmStrCat("Scanning dependencies of target ", targetName);
cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, color);
@@ -1410,9 +1391,9 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
cmMakefile* mf = this->Makefile;
bool haveDirectoryInfo = false;
{
- std::string dirInfoFile = this->GetCurrentBinaryDirectory();
- dirInfoFile += "/CMakeFiles";
- dirInfoFile += "/CMakeDirectoryInformation.cmake";
+ std::string dirInfoFile =
+ cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeDirectoryInformation.cmake");
if (mf->ReadListFile(dirInfoFile) &&
!cmSystemTools::GetErrorOccuredFlag()) {
haveDirectoryInfo = true;
@@ -1423,7 +1404,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
if (haveDirectoryInfo) {
// Test whether we need to force Unix paths.
if (const char* force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS")) {
- if (!cmSystemTools::IsOff(force)) {
+ if (!cmIsOff(force)) {
cmSystemTools::SetForceUnixPaths(true);
}
}
@@ -1465,9 +1446,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
this->WriteDisclaimer(internalRuleFileStream);
// for each language we need to scan, scan it
- std::vector<std::string> langs;
- cmSystemTools::ExpandListArgument(
- mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"), langs);
+ std::vector<std::string> langs =
+ cmExpandedList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"));
for (std::string const& lang : langs) {
// construct the checker
// Create the scanner for this language
@@ -1477,7 +1457,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
// TODO: Handle RC (resource files) dependencies correctly.
scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
else if (lang == "Fortran") {
ruleFileStream << "# Note that incremental build could trigger "
<< "a call to cmake_copy_f90_mod on each re-build\n";
@@ -1511,10 +1491,8 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
}
// Convert the string to a list and preserve empty entries.
- std::vector<std::string> pairs;
- cmSystemTools::ExpandListArgument(pairs_string, pairs, true);
- for (std::vector<std::string>::const_iterator i = pairs.begin();
- i != pairs.end() && (i + 1) != pairs.end();) {
+ std::vector<std::string> pairs = cmExpandedList(pairs_string, true);
+ for (auto i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) {
const std::string& depender = *i++;
const std::string& dependee = *i++;
@@ -1625,8 +1603,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
std::vector<std::string> commands;
// Write the all rule.
- std::string recursiveTarget = this->GetCurrentBinaryDirectory();
- recursiveTarget += "/all";
+ std::string recursiveTarget =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/all");
bool regenerate =
!this->GlobalGenerator->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
@@ -1634,16 +1612,15 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
depends.emplace_back("cmake_check_build_system");
}
- std::string progressDir = this->GetBinaryDirectory();
- progressDir += "/CMakeFiles";
+ std::string progressDir =
+ cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles");
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
progCmd << this->ConvertToOutputFormat(
cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
- std::string progressFile = "/CMakeFiles";
- progressFile += "/progress.marks";
+ std::string progressFile = "/CMakeFiles/progress.marks";
std::string progressFileNameFull = this->ConvertToFullPath(progressFile);
progCmd << " "
<< this->ConvertToOutputFormat(
@@ -1651,8 +1628,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
cmOutputConverter::SHELL);
commands.push_back(progCmd.str());
}
- std::string mf2Dir = "CMakeFiles/";
- mf2Dir += "Makefile2";
+ std::string mf2Dir = "CMakeFiles/Makefile2";
commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
this->CreateCDCommand(commands, this->GetBinaryDirectory(),
this->GetCurrentBinaryDirectory());
@@ -1668,8 +1644,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
commands, true);
// Write the clean rule.
- recursiveTarget = this->GetCurrentBinaryDirectory();
- recursiveTarget += "/clean";
+ recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/clean");
commands.clear();
depends.clear();
commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
@@ -1684,13 +1659,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
depends, commands, true);
// Write the preinstall rule.
- recursiveTarget = this->GetCurrentBinaryDirectory();
- recursiveTarget += "/preinstall";
+ recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/preinstall");
commands.clear();
depends.clear();
const char* noall =
this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
- if (!noall || cmSystemTools::IsOff(noall)) {
+ if (!noall || cmIsOff(noall)) {
// Drive the build before installing.
depends.emplace_back("all");
} else if (regenerate) {
@@ -1712,20 +1686,19 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
commands.clear();
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
- std::string rescanRule = "$(CMAKE_COMMAND) -P ";
- rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
- cmOutputConverter::SHELL);
+ std::string rescanRule =
+ cmStrCat("$(CMAKE_COMMAND) -P ",
+ this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL));
commands.push_back(rescanRule);
}
- std::string cmakefileName = "CMakeFiles/";
- cmakefileName += "Makefile.cmake";
+ std::string cmakefileName = "CMakeFiles/Makefile.cmake";
{
- std::string runRule =
- "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
- runRule += " --check-build-system ";
- runRule +=
- this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL);
- runRule += " 1";
+ std::string runRule = cmStrCat(
+ "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) "
+ "--check-build-system ",
+ this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
+ " 1");
commands.push_back(std::move(runRule));
}
this->CreateCDCommand(commands, this->GetBinaryDirectory(),
@@ -1743,8 +1716,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
if (!infoDef) {
return;
}
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(infoDef, files);
+ std::vector<std::string> files = cmExpandedList(infoDef);
// Each depend information file corresponds to a target. Clear the
// dependencies for that target.
@@ -1846,9 +1818,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
cmakefileStream << " )\n";
// Tell the dependency scanner what compiler is used.
- std::string cidVar = "CMAKE_";
- cidVar += implicitLang.first;
- cidVar += "_COMPILER_ID";
+ std::string cidVar =
+ cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
const char* cid = this->Makefile->GetDefinition(cidVar);
if (cid && *cid) {
cmakefileStream << "set(CMAKE_" << implicitLang.first
@@ -1891,9 +1862,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
<< "_TARGET_INCLUDE_PATH\n";
std::vector<std::string> includes;
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->GetIncludeDirectories(includes, target, implicitLang.first, config);
+ this->GetIncludeDirectories(includes, target, implicitLang.first,
+ this->ConfigName);
std::string binaryDir = this->GetState()->GetBinaryDirectory();
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
@@ -1912,11 +1882,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
std::vector<std::string> transformRules;
if (const char* xform =
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmSystemTools::ExpandListArgument(xform, transformRules);
+ cmExpandList(xform, transformRules);
}
if (const char* xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmSystemTools::ExpandListArgument(xform, transformRules);
+ cmExpandList(xform, transformRules);
}
if (!transformRules.empty()) {
cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -1939,10 +1909,9 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
const std::string& makefile, const std::string& tgt)
{
// Call make on the given file.
- std::string cmd;
- cmd += "$(MAKE) -f ";
- cmd += this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL);
- cmd += " ";
+ std::string cmd = cmStrCat(
+ "$(MAKE) -f ",
+ this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL), ' ');
cmGlobalUnixMakefileGenerator3* gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
@@ -2045,10 +2014,9 @@ std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
if (components.size() > 1) {
// Now add the rest of the components separated by the proper slash
// direction for this platform.
- std::vector<std::string>::const_iterator compEnd = std::remove(
- components.begin() + 1, components.end() - 1, std::string());
- std::vector<std::string>::const_iterator compStart =
- components.begin() + 1;
+ auto compEnd = std::remove(components.begin() + 1, components.end() - 1,
+ std::string());
+ auto compStart = components.begin() + 1;
result += cmJoin(cmMakeRange(compStart, compEnd), slash);
// Only the last component can be empty to avoid double slashes.
result += slash;
@@ -2073,8 +2041,7 @@ std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(
cmGeneratorTarget const* target) const
{
- std::string dir = "CMakeFiles/";
- dir += target->GetName();
+ std::string dir = cmStrCat("CMakeFiles/", target->GetName());
#if defined(__VMS)
dir += "_dir";
#else
@@ -2117,13 +2084,12 @@ void cmLocalUnixMakefileGenerator3::CreateCDCommand(
// On Windows we must perform each step separately and then change
// back because the shell keeps the working directory between
// commands.
- std::string cmd = cd_cmd;
- cmd += this->ConvertToOutputForExisting(tgtDir);
+ std::string cmd =
+ cmStrCat(cd_cmd, this->ConvertToOutputForExisting(tgtDir));
commands.insert(commands.begin(), cmd);
// Change back to the starting directory.
- cmd = cd_cmd;
- cmd += this->ConvertToOutputForExisting(relDir);
+ cmd = cmStrCat(cd_cmd, this->ConvertToOutputForExisting(relDir));
commands.push_back(std::move(cmd));
} else {
// On UNIX we must construct a single shell command to change
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index c8e4b0e97..f12ae8b16 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -5,9 +5,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmDepends.h"
-#include "cmLocalCommonGenerator.h"
-
#include <iosfwd>
#include <map>
#include <set>
@@ -15,6 +12,9 @@
#include <utility>
#include <vector>
+#include "cmDepends.h"
+#include "cmLocalCommonGenerator.h"
+
class cmCustomCommand;
class cmCustomCommandGenerator;
class cmGeneratorTarget;
@@ -90,7 +90,7 @@ public:
// append flags to a string
void AppendFlags(std::string& flags,
const std::string& newFlags) const override;
- void AppendFlags(std::string& flags, const char* newFlags) const override;
+ using cmLocalCommonGenerator::AppendFlags;
// append an echo command
enum EchoColor
@@ -139,7 +139,8 @@ public:
void WriteSpecialTargetsTop(std::ostream& makefileStream);
void WriteSpecialTargetsBottom(std::ostream& makefileStream);
- std::string GetRelativeTargetDirectory(cmGeneratorTarget* target);
+ std::string GetRelativeTargetDirectory(
+ cmGeneratorTarget const* target) const;
// File pairs for implicit dependency scanning. The key of the map
// is the depender and the value is the explicit dependee.
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index d45c3356d..f3d828b28 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio10Generator.h"
+#include "cm_expat.h"
+
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -9,8 +11,6 @@
#include "cmXMLParser.h"
#include "cmake.h"
-#include "cm_expat.h"
-
class cmVS10XMLParser : public cmXMLParser
{
public:
@@ -121,8 +121,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
return;
}
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
+ std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
// save the GUID in the cache
this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 82a117060..ff1eaec93 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2,8 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio7Generator.h"
+#include <windows.h>
+
+#include <ctype.h> // for isspace
+
+#include "cm_expat.h"
+
+#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -11,15 +20,8 @@
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cm_expat.h"
#include "cmake.h"
-#include "cmComputeLinkInformation.h"
-#include "cmGeneratedFileStream.h"
-
-#include <ctype.h> // for isspace
-#include <windows.h>
-
static bool cmLVS7G_IsFAT(const char* dir);
class cmLocalVisualStudio7GeneratorInternals
@@ -29,7 +31,7 @@ public:
: LocalGenerator(e)
{
}
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
std::string const& config, const char* isep = 0);
@@ -91,25 +93,19 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
for (cmGeneratorTarget* l : tgts) {
if (l->GetType() == cmStateEnums::GLOBAL_TARGET) {
std::vector<std::string> no_depends;
- cmCustomCommandLine force_command;
- force_command.push_back("cd");
- force_command.push_back(".");
- cmCustomCommandLines force_commands;
- force_commands.push_back(force_command);
+ cmCustomCommandLines force_commands =
+ cmMakeSingleCommandLine({ "cd", "." });
std::string no_main_dependency;
- std::string force = this->GetCurrentBinaryDirectory();
- force += "/CMakeFiles";
- force += "/";
- force += l->GetName();
- force += "_force";
- if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(
- force, true, cmSourceFileLocationKind::Known)) {
+ std::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", l->GetName(), "_force");
+ if (cmSourceFile* sf =
+ this->Makefile->GetOrCreateGeneratedSource(force)) {
sf->SetProperty("SYMBOLIC", "1");
}
if (cmSourceFile* file = this->Makefile->AddCustomCommandToOutput(
force.c_str(), no_depends, no_main_dependency, force_commands, " ",
0, true)) {
- l->AddSource(file->GetFullPath());
+ l->AddSource(file->ResolveFullPath());
}
}
}
@@ -148,11 +144,10 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
{
// Touch a timestamp file used to determine when the project file is
// out of date.
- std::string stampName = this->GetCurrentBinaryDirectory();
- stampName += "/CMakeFiles";
+ std::string stampName =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
cmSystemTools::MakeDirectory(stampName.c_str());
- stampName += "/";
- stampName += "generate.stamp";
+ stampName += "/generate.stamp";
cmsys::ofstream stamp(stampName.c_str());
stamp << "# CMake generation timestamp file for this directory.\n";
@@ -162,8 +157,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
// dependencies. If any file listed in it is newer than itself then
// CMake must rerun. Otherwise the project files are up to date and
// the stamp file can just be touched.
- std::string depName = stampName;
- depName += ".depend";
+ std::string depName = cmStrCat(stampName, ".depend");
cmsys::ofstream depFile(depName.c_str());
depFile << "# CMake generation dependency list for this directory.\n";
@@ -203,9 +197,7 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(
target->Target->SetProperty("GENERATOR_FILE_NAME", lname.c_str());
// create the dsp.cmake file
std::string fname;
- fname = this->GetCurrentBinaryDirectory();
- fname += "/";
- fname += lname;
+ fname = cmStrCat(this->GetCurrentBinaryDirectory(), '/', lname);
if (this->FortranProject) {
fname += ".vfproj";
} else {
@@ -232,9 +224,8 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
return nullptr;
}
- std::string makefileIn = this->GetCurrentSourceDirectory();
- makefileIn += "/";
- makefileIn += "CMakeLists.txt";
+ std::string makefileIn =
+ cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
if (file->GetCustomCommand()) {
@@ -257,26 +248,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
std::unique(listFiles.begin(), listFiles.end());
listFiles.erase(new_end, listFiles.end());
- std::string stampName = this->GetCurrentBinaryDirectory();
- stampName += "/";
- stampName += "CMakeFiles/";
- stampName += "generate.stamp";
- cmCustomCommandLine commandLine;
- commandLine.push_back(cmSystemTools::GetCMakeCommand());
- std::string comment = "Building Custom Rule ";
- comment += makefileIn;
- std::string args;
- args = "-S";
- args += this->GetSourceDirectory();
- commandLine.push_back(args);
- args = "-B";
- args += this->GetBinaryDirectory();
- commandLine.push_back(args);
- commandLine.push_back("--check-stamp-file");
- commandLine.push_back(stampName);
- cmCustomCommandLines commandLines;
- commandLines.push_back(commandLine);
- const char* no_working_directory = 0;
+ std::string argS = cmStrCat("-S", this->GetSourceDirectory());
+ std::string argB = cmStrCat("-B", this->GetBinaryDirectory());
+ std::string stampName =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp");
+ 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.c_str());
this->Makefile->AddCustomCommandToOutput(
@@ -285,7 +265,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
// Finalize the source file path now since we're adding this after
// the generator validated all project-named sources.
- file->GetFullPath();
+ file->ResolveFullPath();
return file;
} else {
cmSystemTools::Error("Error adding rule for " + makefileIn);
@@ -725,9 +705,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
// Add a definition for the configuration name.
- std::string configDefine = "CMAKE_INTDIR=\"";
- configDefine += configName;
- configDefine += "\"";
+ std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"');
targetOptions.AddDefine(configDefine);
// Add the export symbol definition for shared library objects.
@@ -737,9 +715,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
// The intermediate directory name consists of a directory for the
// target and a subdirectory for the configuration name.
- std::string intermediateDir = this->GetTargetDirectory(target);
- intermediateDir += "/";
- intermediateDir += configName;
+ std::string intermediateDir =
+ cmStrCat(this->GetTargetDirectory(target), '/', configName);
if (target->GetType() < cmStateEnums::UTILITY) {
std::string const& outDir =
@@ -960,8 +937,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
extraLinkOptions += targetLinkFlags;
}
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
- std::string linkFlagsConfig = "LINK_FLAGS_";
- linkFlagsConfig += configTypeUpper;
+ std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str());
if (targetLinkFlags) {
extraLinkOptions += " ";
@@ -993,12 +969,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
case cmStateEnums::UNKNOWN_LIBRARY:
break;
case cmStateEnums::OBJECT_LIBRARY: {
- std::string libpath = this->GetTargetDirectory(target);
- libpath += "/";
- libpath += configName;
- libpath += "/";
- libpath += target->GetName();
- libpath += ".lib";
+ std::string libpath =
+ cmStrCat(this->GetTargetDirectory(target), '/', configName, '/',
+ target->GetName(), ".lib");
const char* tool =
this->FortranProject ? "VFLibrarianTool" : "VCLibrarianTool";
fout << "\t\t\t<Tool\n"
@@ -1009,9 +982,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
case cmStateEnums::STATIC_LIBRARY: {
std::string targetNameFull = target->GetFullName(configName);
- std::string libpath = target->GetDirectory(configName);
- libpath += "/";
- libpath += targetNameFull;
+ std::string libpath =
+ cmStrCat(target->GetDirectory(configName), '/', targetNameFull);
const char* tool = "VCLibrarianTool";
if (this->FortranProject) {
tool = "VFLibrarianTool";
@@ -1053,9 +1025,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
// Compute the variable name to lookup standard libraries for this
// language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += linkLanguage;
- standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string standardLibsVar =
+ cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
const char* tool = "VCLinkerTool";
if (this->FortranProject) {
tool = "VFLinkerTool";
@@ -1075,9 +1046,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
- temp = target->GetDirectory(configName);
- temp += "/";
- temp += targetNames.Output;
+ temp =
+ cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
@@ -1085,9 +1055,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n";
- temp = target->GetPDBDirectory(configName);
- temp += "/";
- temp += targetNames.PDB;
+ temp =
+ cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
fout << "\t\t\t\tProgramDatabaseFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
if (targetOptions.IsDebug()) {
@@ -1100,17 +1069,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tSubSystem=\"8\"\n";
}
}
- std::string stackVar = "CMAKE_";
- stackVar += linkLanguage;
- stackVar += "_STACK_SIZE";
+ std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
}
- temp =
- target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact);
- temp += "/";
- temp += targetNames.ImportLibrary;
+ temp = cmStrCat(
+ target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
+ '/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
if (this->FortranProject) {
@@ -1134,9 +1100,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
// Compute the variable name to lookup standard libraries for this
// language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += linkLanguage;
- standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string standardLibsVar =
+ cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
const char* tool = "VCLinkerTool";
if (this->FortranProject) {
tool = "VFLinkerTool";
@@ -1156,9 +1121,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
- temp = target->GetDirectory(configName);
- temp += "/";
- temp += targetNames.Output;
+ temp =
+ cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
@@ -1194,17 +1158,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tSubSystem=\"" << (isWin32Executable ? "2" : "1")
<< "\"\n";
}
- std::string stackVar = "CMAKE_";
- stackVar += linkLanguage;
- stackVar += "_STACK_SIZE";
+ std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
}
- temp =
- target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact);
- temp += "/";
- temp += targetNames.ImportLibrary;
+ temp = cmStrCat(
+ target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
+ '/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
break;
@@ -1493,6 +1454,22 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
fc.CompileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
needfc = true;
}
+ // Add precompile headers compile options.
+ const std::string pchSource = gt->GetPchSource(config, lang);
+ if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ std::string pchOptions;
+ if (sf.GetFullPath() == pchSource) {
+ pchOptions = gt->GetPchCreateCompileOptions(config, lang);
+ } else {
+ pchOptions = gt->GetPchUseCompileOptions(config, lang);
+ }
+
+ lg->AppendCompileOptions(
+ fc.CompileFlags,
+ genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
+ needfc = true;
+ }
+
if (lg->FortranProject) {
switch (cmOutputConverter::GetFortranFormat(
sf.GetProperty("Fortran_FORMAT"))) {
@@ -1513,8 +1490,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
fc.CompileDefs = genexInterpreter.Evaluate(cdefs, COMPILE_DEFINITIONS);
needfc = true;
}
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += configUpper;
+ std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
if (const char* ccdefs = sf.GetProperty(defPropName)) {
fc.CompileDefsConfig =
genexInterpreter.Evaluate(ccdefs, COMPILE_DEFINITIONS);
@@ -1529,8 +1505,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// Check for extra object-file dependencies.
if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends;
- cmSystemTools::ExpandListArgument(deps, depends);
+ std::vector<std::string> depends = cmExpandedList(deps);
const char* sep = "";
for (std::vector<std::string>::iterator j = depends.begin();
j != depends.end(); ++j) {
@@ -1545,8 +1520,10 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
- std::find(acs.Configs.begin(), acs.Configs.end(), ci) ==
- acs.Configs.end();
+ !cmContains(acs.Configs, ci) ||
+ (gt->GetPropertyAsBool("UNITY_BUILD") &&
+ sf.GetProperty("UNITY_SOURCE_FILE") &&
+ !sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
if (fc.ExcludedFromBuild) {
needfc = true;
}
@@ -1590,13 +1567,9 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
// Compute the maximum length full path to the intermediate
// files directory for any configuration. This is used to construct
// object file names that do not produce paths that are too long.
- std::string dir_max;
- dir_max += this->GetCurrentBinaryDirectory();
- dir_max += "/";
- dir_max += this->GetTargetDirectory(target);
- dir_max += "/";
- dir_max += config_max;
- dir_max += "/";
+ std::string dir_max =
+ cmStrCat(this->GetCurrentBinaryDirectory(), '/',
+ this->GetTargetDirectory(target), '/', config_max, '/');
return dir_max;
}
@@ -2146,8 +2119,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
if (parser.GUID.empty()) {
return;
}
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
+ std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
// save the GUID in the cache
this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
@@ -2157,9 +2129,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
std::string cmLocalVisualStudio7Generator::GetTargetDirectory(
cmGeneratorTarget const* target) const
{
- std::string dir;
- dir += target->GetName();
- dir += ".dir";
+ std::string dir = cmStrCat(target->GetName(), ".dir");
return dir;
}
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index ce8eceb7e..671783fa5 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -83,8 +83,8 @@ protected:
void CreateSingleVCProj(const std::string& lname, cmGeneratorTarget* tgt);
private:
- typedef cmVS7GeneratorOptions Options;
- typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo;
+ using Options = cmVS7GeneratorOptions;
+ using FCInfo = cmLocalVisualStudio7GeneratorFCInfo;
std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
const std::string& configName);
void FixGlobalTargets();
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index f3f2042ec..336e3a5a1 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudioGenerator.h"
+#include "windows.h"
+
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratorTarget.h"
@@ -9,7 +11,6 @@
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
-#include "windows.h"
cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator(
cmGlobalGenerator* gg, cmMakefile* mf)
@@ -98,16 +99,11 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
}
// Add a pre-build event to create the directory.
- cmCustomCommandLine command;
- command.push_back(cmSystemTools::GetCMakeCommand());
- command.push_back("-E");
- command.push_back("make_directory");
- command.push_back(impDir);
std::vector<std::string> no_output;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
- cmCustomCommandLines commands;
- commands.push_back(command);
+ cmCustomCommandLines commands = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, no_depends,
commands, 0, 0));
pcc->SetEscapeOldStyle(false);
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index 3fdafd2b2..585eb3c33 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include "cmGlobalVisualStudioGenerator.h"
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 9c36627b5..5a06d4a53 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -65,9 +65,8 @@ void cmLocalXCodeGenerator::ComputeObjectFilenames(
std::map<std::string, int> counts;
for (auto& si : mapping) {
cmSourceFile const* sf = si.first;
- std::string objectName =
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
- objectName += ".o";
+ std::string objectName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), ".o");
std::string objectNameLower = cmSystemTools::LowerCase(objectName);
counts[objectNameLower] += 1;
diff --git a/Source/cmLocale.h b/Source/cmLocale.h
index 3580ec812..c44a42db7 100644
--- a/Source/cmLocale.h
+++ b/Source/cmLocale.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <locale.h>
+#include <clocale>
#include <string>
class cmLocaleRAII
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index d4af1e0f3..6cbed36d9 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -2,12 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMachO.h"
-#include "cmsys/FStream.hxx"
-#include <algorithm>
-#include <stddef.h>
+#include <cstddef>
#include <string>
#include <vector>
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmAlgorithms.h"
+
// Include the Mach-O format information system header.
#include <mach-o/fat.h>
#include <mach-o/loader.h>
@@ -120,7 +124,7 @@ protected:
// Implementation for reading Mach-O header and load commands.
// This is 32 or 64 bit arch specific.
-template <class T>
+template <typename T>
class cmMachOHeaderAndLoadCommandsImpl : public cmMachOHeaderAndLoadCommands
{
public:
@@ -306,15 +310,11 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset)
// External class implementation.
cmMachO::cmMachO(const char* fname)
- : Internal(nullptr)
+ : Internal(cm::make_unique<cmMachOInternal>(fname))
{
- this->Internal = new cmMachOInternal(fname);
}
-cmMachO::~cmMachO()
-{
- delete this->Internal;
-}
+cmMachO::~cmMachO() = default;
std::string const& cmMachO::GetErrorMessage() const
{
diff --git a/Source/cmMachO.h b/Source/cmMachO.h
index 5482465d3..0c44b5564 100644
--- a/Source/cmMachO.h
+++ b/Source/cmMachO.h
@@ -41,7 +41,7 @@ public:
private:
friend class cmMachOInternal;
bool Valid() const;
- cmMachOInternal* Internal;
+ std::unique_ptr<cmMachOInternal> Internal;
};
#endif
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index e9c6aea73..ba9947a33 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -2,48 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMacroCommand.h"
-#include <sstream>
-#include <stdio.h>
+#include <cstdio>
#include <utility>
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+namespace {
+
// define the class for macro commands
-class cmMacroHelperCommand : public cmCommand
+class cmMacroHelperCommand
{
public:
/**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override
- {
- cmMacroHelperCommand* newC = new cmMacroHelperCommand;
- // we must copy when we clone
- newC->Args = this->Args;
- newC->Functions = this->Functions;
- newC->FilePath = this->FilePath;
- newC->Policies = this->Policies;
- return newC;
- }
-
- /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
+ bool operator()(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const;
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
@@ -51,33 +40,33 @@ public:
std::string FilePath;
};
-bool cmMacroHelperCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmMacroHelperCommand::operator()(
+ std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& inStatus) const
{
+ cmMakefile& makefile = inStatus.GetMakefile();
+
// Expand the argument list to the macro.
std::vector<std::string> expandedArgs;
- this->Makefile->ExpandArguments(args, expandedArgs);
+ makefile.ExpandArguments(args, expandedArgs);
// make sure the number of arguments passed is at least the number
// required by the signature
if (expandedArgs.size() < this->Args.size() - 1) {
std::string errorMsg =
- "Macro invoked with incorrect arguments for macro named: ";
- errorMsg += this->Args[0];
- this->SetError(errorMsg);
+ cmStrCat("Macro invoked with incorrect arguments for macro named: ",
+ this->Args[0]);
+ inStatus.SetError(errorMsg);
return false;
}
- cmMakefile::MacroPushPop macroScope(this->Makefile, this->FilePath,
+ cmMakefile::MacroPushPop macroScope(&makefile, this->FilePath,
this->Policies);
// set the value of argc
- std::ostringstream argcDefStream;
- argcDefStream << expandedArgs.size();
- std::string argcDef = argcDefStream.str();
+ std::string argcDef = std::to_string(expandedArgs.size());
- std::vector<std::string>::const_iterator eit =
- expandedArgs.begin() + (this->Args.size() - 1);
+ auto eit = expandedArgs.begin() + (this->Args.size() - 1);
std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
std::string expandedArgv = cmJoin(expandedArgs, ";");
std::vector<std::string> variables;
@@ -130,9 +119,8 @@ bool cmMacroHelperCommand::InvokeInitialPass(
arg.Line = k.Line;
newLFF.Arguments.push_back(std::move(arg));
}
- cmExecutionStatus status;
- if (!this->Makefile->ExecuteCommand(newLFF, status) ||
- status.GetNestedError()) {
+ cmExecutionStatus status(makefile);
+ if (!makefile.ExecuteCommand(newLFF, status) || status.GetNestedError()) {
// The error message should have already included the call stack
// so we do not need to report an error here.
macroScope.Quiet();
@@ -151,68 +139,59 @@ bool cmMacroHelperCommand::InvokeInitialPass(
return true;
}
-bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus&)
+class cmMacroFunctionBlocker : public cmFunctionBlocker
{
- // record commands until we hit the ENDMACRO
- // at the ENDMACRO call we shift gears and start looking for invocations
- if (lff.Name.Lower == "macro") {
- this->Depth++;
- } else if (lff.Name.Lower == "endmacro") {
- // if this is the endmacro for this macro then execute
- if (!this->Depth) {
- mf.AppendProperty("MACROS", this->Args[0].c_str());
- // create a new command and add it to cmake
- cmMacroHelperCommand* f = new cmMacroHelperCommand();
- f->Args = this->Args;
- f->Functions = this->Functions;
- f->FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f->Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], f);
- // remove the function blocker now that the macro is defined
- mf.RemoveFunctionBlocker(this, lff);
- return true;
- }
- // decrement for each nested macro that ends
- this->Depth--;
- }
+public:
+ cm::string_view StartCommandName() const override { return "macro"_s; }
+ cm::string_view EndCommandName() const override { return "endmacro"_s; }
- // if it wasn't an endmacro and we are not executing then we must be
- // recording
- this->Functions.push_back(lff);
- return true;
-}
+ bool ArgumentsMatch(cmListFileFunction const&,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) override;
-bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
+ std::vector<std::string> Args;
+};
+
+bool cmMacroFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
{
- if (lff.Name.Lower == "endmacro") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments,
- this->GetStartingContext().FilePath.c_str());
- // if the endmacro has arguments make sure they
- // match the arguments of the macro
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
- }
- }
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+}
- return false;
+bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status)
+{
+ cmMakefile& mf = status.GetMakefile();
+ mf.AppendProperty("MACROS", this->Args[0].c_str());
+ // create a new command and add it to cmake
+ cmMacroHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = std::move(functions);
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
+ mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ return true;
+}
}
-bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmMacroCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// create a function blocker
- cmMacroFunctionBlocker* f = new cmMacroFunctionBlocker();
- cmAppend(f->Args, args);
- this->Makefile->AddFunctionBlocker(f);
+ {
+ auto fb = cm::make_unique<cmMacroFunctionBlocker>();
+ cmAppend(fb->Args, args);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
+ }
return true;
}
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index b54ed6605..25091eacf 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -8,40 +8,10 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmMacroFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
- int Depth = 0;
-};
/// Starts macro() ... endmacro() block
-class cmMacroCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmMacroCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmMacroCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmMakeDirectoryCommand.cxx b/Source/cmMakeDirectoryCommand.cxx
index aff4ca650..cdde6f990 100644
--- a/Source/cmMakeDirectoryCommand.cxx
+++ b/Source/cmMakeDirectoryCommand.cxx
@@ -2,23 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakeDirectoryCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmMakeDirectoryCommand
-bool cmMakeDirectoryCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmMakeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 1) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- if (!this->Makefile->CanIWriteThisFile(args[0])) {
+ if (!status.GetMakefile().CanIWriteThisFile(args[0])) {
std::string e = "attempted to create a directory: " + args[0] +
" into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index d2637f388..2474383bb 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -8,11 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmMakeDirectoryCommand
+/**
* \brief Specify auxiliary source code directories.
*
* cmMakeDirectoryCommand specifies source code directories
@@ -21,20 +19,7 @@ class cmExecutionStatus;
* A side effect of this command is to create a subdirectory in the build
* directory structure.
*/
-class cmMakeDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmMakeDirectoryCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmMakeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3f8bd4e41..f143ef704 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1,22 +1,27 @@
/* 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 "cmMakefile.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
#include <cstring>
-#include <ctype.h>
-#include <iterator>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
#include <utility>
+#include <cm/iterator>
+#include <cm/memory>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_sys_stat.h"
+
#include "cmAlgorithms.h"
-#include "cmCommand.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -24,6 +29,7 @@
#include "cmExpandedCommandArgument.h" // IWYU pragma: keep
#include "cmFileLockPool.h"
#include "cmFunctionBlocker.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmGlobalGenerator.h"
@@ -37,18 +43,17 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmTest.h"
#include "cmTestGenerator.h" // IWYU pragma: keep
#include "cmVersion.h"
#include "cmWorkingDirectory.h"
-#include "cm_sys_stat.h"
#include "cmake.h"
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmVariableWatch.h"
#endif
@@ -98,10 +103,11 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
// cmListFileCache in the top level if necessary.
this->CheckCMP0000 = false;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->AddSourceGroup("", "^.*$");
this->AddSourceGroup("Source Files", CM_SOURCE_REGEX);
this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
+ this->AddSourceGroup("Precompile Header File", CM_PCH_REGEX);
this->AddSourceGroup("CMake Rules", "\\.rule$");
this->AddSourceGroup("Resources", CM_RESOURCE_REGEX);
this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
@@ -118,8 +124,6 @@ cmMakefile::~cmMakefile()
cmDeleteAll(this->SourceFiles);
cmDeleteAll(this->Tests);
cmDeleteAll(this->ImportedTargetsOwned);
- cmDeleteAll(this->FinalPassCommands);
- cmDeleteAll(this->FunctionBlockers);
cmDeleteAll(this->EvaluationFiles);
}
@@ -324,7 +328,13 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
msg << " ";
}
msg << ")";
- cmSystemTools::Message(msg.str());
+
+ auto& f = this->GetCMakeInstance()->GetTraceFile();
+ if (f) {
+ f << msg.str() << '\n';
+ } else {
+ cmSystemTools::Message(msg.str());
+ }
}
// Helper class to make sure the call stack is valid.
@@ -356,6 +366,11 @@ private:
cmMakefile* Makefile;
};
+void cmMakefile::OnExecuteCommand(std::function<void()> callback)
+{
+ this->ExecuteCommandCallback = std::move(callback);
+}
+
bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
cmExecutionStatus& status)
{
@@ -367,6 +382,10 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
return result;
}
+ if (this->ExecuteCommandCallback) {
+ this->ExecuteCommandCallback();
+ }
+
// Place this call on the call stack.
cmMakefileCall stack_manager(this, lff, status);
static_cast<void>(stack_manager);
@@ -390,12 +409,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
}
// Lookup the command prototype.
- if (cmCommand* proto =
+ if (cmState::Command command =
this->GetState()->GetCommandByExactName(lff.Name.Lower)) {
- // Clone the prototype.
- std::unique_ptr<cmCommand> pcmd(proto->Clone());
- pcmd->SetMakefile(this);
-
// Decide whether to invoke the command.
if (!cmSystemTools::GetFatalErrorOccured()) {
// if trace is enabled, print out invoke information
@@ -403,29 +418,25 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
this->PrintCommandTrace(lff);
}
// Try invoking the command.
- bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status);
+ bool invokeSucceeded = command(lff.Arguments, status);
bool hadNestedError = status.GetNestedError();
if (!invokeSucceeded || hadNestedError) {
if (!hadNestedError) {
// The command invocation requested that we report an error.
std::string const error =
- std::string(lff.Name.Original) + " " + pcmd->GetError();
+ std::string(lff.Name.Original) + " " + status.GetError();
this->IssueMessage(MessageType::FATAL_ERROR, error);
}
result = false;
if (this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) {
cmSystemTools::SetFatalErrorOccured();
}
- } else if (pcmd->HasFinalPass()) {
- // use the command
- this->FinalPassCommands.push_back(pcmd.release());
}
}
} else {
if (!cmSystemTools::GetFatalErrorOccured()) {
- std::string error = "Unknown CMake command \"";
- error += lff.Name.Original;
- error += "\".";
+ std::string error =
+ cmStrCat("Unknown CMake command \"", lff.Name.Original, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, error);
result = false;
cmSystemTools::SetFatalErrorOccured();
@@ -567,8 +578,9 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
bool cmMakefile::ReadDependentFile(const std::string& filename,
bool noPolicyScope)
{
- this->AddDefinition("CMAKE_PARENT_LIST_FILE",
- this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
+ if (const char* def = this->GetDefinition("CMAKE_CURRENT_LIST_FILE")) {
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", def);
+ }
std::string filenametoread = cmSystemTools::CollapseFullPath(
filename, this->GetCurrentSourceDirectory());
@@ -651,9 +663,9 @@ void cmMakefile::ReadListFile(cmListFile const& listFile,
this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
std::string currentFile = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
- this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread.c_str());
+ this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
- cmSystemTools::GetFilenamePath(filenametoread).c_str());
+ cmSystemTools::GetFilenamePath(filenametoread));
this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
@@ -662,7 +674,7 @@ void cmMakefile::ReadListFile(cmListFile const& listFile,
// Run the parsed commands.
const size_t numberFunctions = listFile.Functions.size();
for (size_t i = 0; i < numberFunctions; ++i) {
- cmExecutionStatus status;
+ cmExecutionStatus status(*this);
this->ExecuteCommand(listFile.Functions[i], status);
if (cmSystemTools::GetFatalErrorOccured()) {
break;
@@ -674,10 +686,10 @@ void cmMakefile::ReadListFile(cmListFile const& listFile,
}
this->CheckForUnusedVariables();
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
- this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile);
+ this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile);
this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
- cmSystemTools::GetFilenamePath(currentFile).c_str());
+ cmSystemTools::GetFilenamePath(currentFile));
this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
@@ -745,9 +757,8 @@ cmMakefile::GetExportBuildFileGenerators() const
void cmMakefile::RemoveExportBuildFileGeneratorCMP0024(
cmExportBuildFileGenerator* gen)
{
- std::vector<cmExportBuildFileGenerator*>::iterator it =
- std::find(this->ExportBuildFileGenerators.begin(),
- this->ExportBuildFileGenerators.end(), gen);
+ auto it = std::find(this->ExportBuildFileGenerators.begin(),
+ this->ExportBuildFileGenerators.end(), gen);
if (it != this->ExportBuildFileGenerators.end()) {
this->ExportBuildFileGenerators.erase(it);
}
@@ -769,6 +780,11 @@ struct file_not_persistent
};
}
+void cmMakefile::AddFinalAction(FinalAction action)
+{
+ this->FinalActions.push_back(std::move(action));
+}
+
void cmMakefile::FinalPass()
{
// do all the variable expansions here
@@ -776,8 +792,8 @@ void cmMakefile::FinalPass()
// give all the commands a chance to do something
// after the file has been parsed before generation
- for (cmCommand* fpCommand : this->FinalPassCommands) {
- fpCommand->FinalPass();
+ for (FinalAction& action : this->FinalActions) {
+ action(*this);
}
// go through all configured files and see which ones still exist.
@@ -809,16 +825,27 @@ void cmMakefile::ConfigureFinalPass()
}
}
-void cmMakefile::AddCustomCommandToTarget(
- const std::string& target, const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType 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, ObjectLibraryCommands objLibraryCommands)
+bool cmMakefile::ValidateCustomCommand(
+ const cmCustomCommandLines& commandLines) const
+{
+ // TODO: More strict?
+ for (cmCustomCommandLine const& cl : commandLines) {
+ if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') {
+ std::ostringstream e;
+ e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n";
+ this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+cmTarget* cmMakefile::GetCustomCommandTarget(
+ const std::string& target, cmObjectLibraryCommands objLibCommands) const
{
// Find the target to which to add the custom command.
- cmTargetMap::iterator ti = this->Targets.find(target);
+ auto ti = this->Targets.find(target);
if (ti == this->Targets.end()) {
MessageType messageType = MessageType::AUTHOR_WARNING;
@@ -849,38 +876,67 @@ void cmMakefile::AddCustomCommandToTarget(
e << "No TARGET '" << target
<< "' has been created in this directory.";
}
- IssueMessage(messageType, e.str());
+ this->IssueMessage(messageType, e.str());
}
- return;
+ return nullptr;
}
- cmTarget& t = ti->second;
- if (objLibraryCommands == RejectObjectLibraryCommands &&
- t.GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ cmTarget* t = &ti->second;
+ if (objLibCommands == cmObjectLibraryCommands::Reject &&
+ t->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::ostringstream e;
e << "Target \"" << target
<< "\" is an OBJECT library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return;
+ return nullptr;
}
- if (t.GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "Target \"" << target
<< "\" is an INTERFACE library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return;
+ return nullptr;
}
- // Always create the byproduct sources and mark them generated.
- for (std::string const& o : byproducts) {
- if (cmSourceFile* out = this->GetOrCreateSource(o, true)) {
- out->SetProperty("GENERATED", "1");
- }
+ return t;
+}
+
+cmTarget* cmMakefile::AddCustomCommandToTarget(
+ const std::string& target, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ 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)
+{
+ cmTarget* t = this->GetCustomCommandTarget(target, objLibCommands);
+
+ // Validate custom commands.
+ if (!t || !this->ValidateCustomCommand(commandLines)) {
+ return t;
}
+ // Always create the byproduct sources and mark them generated.
+ this->CreateGeneratedSources(byproducts);
+
+ this->CommitCustomCommandToTarget(
+ t, byproducts, depends, commandLines, type, comment, workingDir,
+ escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists);
+
+ return t;
+}
+
+void cmMakefile::CommitCustomCommandToTarget(
+ cmTarget* target, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ 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)
+{
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(this, no_output, byproducts, depends, commandLines,
@@ -892,22 +948,42 @@ void cmMakefile::AddCustomCommandToTarget(
cc.SetDepfile(depfile);
cc.SetJobPool(job_pool);
switch (type) {
- case cmTarget::PRE_BUILD:
- t.AddPreBuildCommand(cc);
+ case cmCustomCommandType::PRE_BUILD:
+ target->AddPreBuildCommand(std::move(cc));
break;
- case cmTarget::PRE_LINK:
- t.AddPreLinkCommand(cc);
+ case cmCustomCommandType::PRE_LINK:
+ target->AddPreLinkCommand(std::move(cc));
break;
- case cmTarget::POST_BUILD:
- t.AddPostBuildCommand(cc);
+ case cmCustomCommandType::POST_BUILD:
+ target->AddPostBuildCommand(std::move(cc));
break;
}
+
+ this->AddTargetByproducts(target, byproducts);
+}
+
+cmSourceFile* cmMakefile::AddCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ 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)
+{
+ std::vector<std::string> outputs;
+ outputs.push_back(output);
+ std::vector<std::string> no_byproducts;
+ cmImplicitDependsList no_implicit_depends;
+ return this->AddCustomCommandToOutput(
+ outputs, no_byproducts, depends, main_dependency, no_implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
}
cmSourceFile* cmMakefile::AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
bool uses_terminal, bool command_expand_lists, const std::string& depfile,
@@ -919,16 +995,31 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
return nullptr;
}
- // Validate custom commands. TODO: More strict?
- for (cmCustomCommandLine const& cl : commandLines) {
- if (!cl.empty() && !cl[0].empty() && cl[0][0] == '"') {
- std::ostringstream e;
- e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return nullptr;
- }
+ // Validate custom commands.
+ if (!this->ValidateCustomCommand(commandLines)) {
+ return nullptr;
}
+ // Always create the output sources and mark them generated.
+ this->CreateGeneratedSources(outputs);
+ this->CreateGeneratedSources(byproducts);
+
+ return this->CommitCustomCommandToOutput(
+ outputs, byproducts, depends, main_dependency, implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
+}
+
+cmSourceFile* cmMakefile::CommitCustomCommandToOutput(
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ 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)
+{
// Choose a source file on which to store the custom command.
cmSourceFile* file = nullptr;
if (!commandLines.empty() && !main_dependency.empty()) {
@@ -976,20 +1067,6 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
file->SetProperty("__CMAKE_RULE", "1");
}
- // Always create the output sources and mark them generated.
- for (std::string const& o : outputs) {
- if (cmSourceFile* out =
- this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) {
- out->SetProperty("GENERATED", "1");
- }
- }
- for (std::string const& o : byproducts) {
- if (cmSourceFile* out =
- this->GetOrCreateSource(o, true, cmSourceFileLocationKind::Known)) {
- out->SetProperty("GENERATED", "1");
- }
- }
-
// Attach the custom command to the file.
if (file) {
// Construct a complete list of dependencies.
@@ -998,60 +1075,20 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
depends2.push_back(main_dependency);
}
- cmCustomCommand* cc = new cmCustomCommand(
+ std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
this, outputs, byproducts, depends2, commandLines, comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
+ cc->SetImplicitDepends(implicit_depends);
cc->SetUsesTerminal(uses_terminal);
cc->SetCommandExpandLists(command_expand_lists);
cc->SetDepfile(depfile);
cc->SetJobPool(job_pool);
- file->SetCustomCommand(cc);
- this->UpdateOutputToSourceMap(outputs, file);
- }
- return file;
-}
+ file->SetCustomCommand(std::move(cc));
-void cmMakefile::UpdateOutputToSourceMap(
- std::vector<std::string> const& outputs, cmSourceFile* source)
-{
- for (std::string const& o : outputs) {
- this->UpdateOutputToSourceMap(o, source);
- }
-}
-
-void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
- cmSourceFile* source)
-{
- OutputToSourceMap::iterator i = this->OutputToSource.find(output);
- if (i != this->OutputToSource.end()) {
- // Multiple custom commands produce the same output but may
- // be attached to a different source file (MAIN_DEPENDENCY).
- // LinearGetSourceFileWithOutput would return the first one,
- // so keep the mapping for the first one.
- //
- // TODO: Warn the user about this case. However, the VS 8 generator
- // triggers it for separate generate.stamp rules in ZERO_CHECK and
- // individual targets.
- return;
+ this->AddSourceOutputs(file, outputs, byproducts);
}
- this->OutputToSource[output] = source;
-}
-
-cmSourceFile* cmMakefile::AddCustomCommandToOutput(
- const std::string& output, const std::vector<std::string>& depends,
- 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)
-{
- std::vector<std::string> outputs;
- outputs.push_back(output);
- std::vector<std::string> no_byproducts;
- return this->AddCustomCommandToOutput(
- outputs, no_byproducts, depends, main_dependency, commandLines, comment,
- workingDir, replace, escapeOldStyle, uses_terminal, command_expand_lists,
- depfile, job_pool);
+ return file;
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1066,146 +1103,176 @@ void cmMakefile::AddCustomCommandOldStyle(
// same then it added a post-build rule to the target. Preserve
// this behavior.
std::vector<std::string> no_byproducts;
- this->AddCustomCommandToTarget(target, no_byproducts, depends,
- commandLines, cmTarget::POST_BUILD, comment,
- nullptr);
+ this->AddCustomCommandToTarget(
+ target, no_byproducts, depends, commandLines,
+ cmCustomCommandType::POST_BUILD, comment, nullptr);
return;
}
- // Each output must get its own copy of this rule.
- cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|"
- "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
- "hm|hpp|hxx|in|txx|inl)$");
- for (std::string const& oi : outputs) {
- // Get the name of this output.
- const char* output = oi.c_str();
- cmSourceFile* sf;
-
- // Choose whether to use a main dependency.
- if (sourceFiles.find(source)) {
- // The source looks like a real file. Use it as the main dependency.
- sf = this->AddCustomCommandToOutput(output, depends, source,
- commandLines, comment, nullptr);
- } else {
- // The source may not be a real file. Do not use a main dependency.
- std::string no_main_dependency;
- std::vector<std::string> depends2 = depends;
- depends2.push_back(source);
- sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
- commandLines, comment, nullptr);
- }
+ auto ti = this->Targets.find(target);
+ cmTarget* t = ti != this->Targets.end() ? &ti->second : nullptr;
+ auto addRuleFileToTarget = [=](cmSourceFile* sf) {
// If the rule was added to the source (and not a .rule file),
// then add the source to the target to make sure the rule is
// included.
- if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) {
- cmTargetMap::iterator ti = this->Targets.find(target);
- if (ti != this->Targets.end()) {
- ti->second.AddSource(sf->GetFullPath());
+ if (!sf->GetPropertyAsBool("__CMAKE_RULE")) {
+ if (t) {
+ t->AddSource(sf->ResolveFullPath());
} else {
cmSystemTools::Error("Attempt to add a custom rule to a target "
"that does not exist yet for target " +
target);
- return;
+ }
+ }
+ };
+
+ // Each output must get its own copy of this rule.
+ cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|"
+ "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
+ "hm|hpp|hxx|in|txx|inl)$");
+
+ // Choose whether to use a main dependency.
+ if (sourceFiles.find(source)) {
+ // The source looks like a real file. Use it as the main dependency.
+ for (std::string const& output : outputs) {
+ cmSourceFile* sf = this->AddCustomCommandToOutput(
+ output, depends, source, commandLines, comment, nullptr);
+ if (sf) {
+ addRuleFileToTarget(sf);
+ }
+ }
+ } else {
+ std::string no_main_dependency;
+ std::vector<std::string> depends2 = depends;
+ depends2.push_back(source);
+
+ // The source may not be a real file. Do not use a main dependency.
+ for (std::string const& output : outputs) {
+ cmSourceFile* sf = this->AddCustomCommandToOutput(
+ output, depends2, no_main_dependency, commandLines, comment, nullptr);
+ if (sf) {
+ addRuleFileToTarget(sf);
}
}
}
}
-cmTarget* cmMakefile::AddUtilityCommand(
- const std::string& utilityName, TargetOrigin origin, bool excludeFromAll,
- const std::vector<std::string>& depends, const char* workingDirectory,
- const char* command, const char* arg1, const char* arg2, const char* arg3,
- const char* arg4)
+bool cmMakefile::AppendCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines)
{
- // Construct the command line for the custom command.
- cmCustomCommandLine commandLine;
- commandLine.push_back(command);
- if (arg1) {
- commandLine.push_back(arg1);
- }
- if (arg2) {
- commandLine.push_back(arg2);
- }
- if (arg3) {
- commandLine.push_back(arg3);
+ // Check as good as we can if there will be a command for this output.
+ if (!this->MightHaveCustomCommand(output)) {
+ return false;
}
- if (arg4) {
- commandLine.push_back(arg4);
+
+ // Validate custom commands.
+ if (this->ValidateCustomCommand(commandLines)) {
+ // Add command factory to allow generator expressions in output.
+ this->CommitAppendCustomCommandToOutput(output, depends, implicit_depends,
+ commandLines);
}
- cmCustomCommandLines commandLines;
- commandLines.push_back(std::move(commandLine));
- // Call the real signature of this method.
- return this->AddUtilityCommand(utilityName, origin, excludeFromAll,
- workingDirectory, depends, commandLines);
+ return true;
}
-cmTarget* cmMakefile::AddUtilityCommand(
- const std::string& utilityName, TargetOrigin origin, bool excludeFromAll,
- const char* workingDirectory, 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)
+void cmMakefile::CommitAppendCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines)
+{
+ // Lookup an existing command.
+ if (cmSourceFile* sf = this->GetSourceFileWithOutput(output)) {
+ if (cmCustomCommand* cc = sf->GetCustomCommand()) {
+ cc->AppendCommands(commandLines);
+ cc->AppendDepends(depends);
+ cc->AppendImplicitDepends(implicit_depends);
+ }
+ }
+}
+
+cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
{
- std::vector<std::string> no_byproducts;
- return this->AddUtilityCommand(
- utilityName, origin, excludeFromAll, workingDirectory, no_byproducts,
- depends, commandLines, escapeOldStyle, comment, uses_terminal,
- command_expand_lists, job_pool);
+ std::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/", target->GetName());
+ std::string forceCMP0049 = target->GetSourceCMP0049(force);
+ {
+ cmSourceFile* sf = nullptr;
+ if (!forceCMP0049.empty()) {
+ sf = this->GetOrCreateSource(forceCMP0049, false,
+ cmSourceFileLocationKind::Known);
+ }
+ // The output is not actually created so mark it symbolic.
+ if (sf) {
+ sf->SetProperty("SYMBOLIC", "1");
+ } else {
+ cmSystemTools::Error("Could not get source file entry for " + force);
+ }
+ }
+ return { std::move(force), std::move(forceCMP0049) };
}
cmTarget* cmMakefile::AddUtilityCommand(
- const std::string& utilityName, TargetOrigin origin, bool excludeFromAll,
+ const std::string& utilityName, cmCommandOrigin origin, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& byproducts,
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)
{
- // Create a target instance for this utility.
- cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
- target->SetIsGeneratorProvided(origin == TargetOrigin::Generator);
- if (excludeFromAll) {
- target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ cmTarget* target =
+ this->AddNewUtilityTarget(utilityName, origin, excludeFromAll);
+
+ // Validate custom commands.
+ if ((commandLines.empty() && depends.empty()) ||
+ !this->ValidateCustomCommand(commandLines)) {
+ return target;
}
+
+ // Get the output name of the utility target and mark it generated.
+ cmUtilityOutput force = this->GetUtilityOutput(target);
+ this->GetOrCreateGeneratedSource(force.Name);
+
+ // Always create the byproduct sources and mark them generated.
+ this->CreateGeneratedSources(byproducts);
+
if (!comment) {
// Use an empty comment to avoid generation of default comment.
comment = "";
}
- // Store the custom command in the target.
- if (!commandLines.empty() || !depends.empty()) {
- std::string force = this->GetCurrentBinaryDirectory();
- force += "/CMakeFiles";
- force += "/";
- force += utilityName;
- std::vector<std::string> forced;
- forced.push_back(force);
- std::string no_main_dependency;
- bool no_replace = false;
- this->AddCustomCommandToOutput(
- forced, byproducts, depends, no_main_dependency, commandLines, comment,
- workingDirectory, no_replace, escapeOldStyle, uses_terminal,
- command_expand_lists, /*depfile=*/"", job_pool);
- cmSourceFile* sf = target->AddSourceCMP0049(force);
+ this->CommitUtilityCommand(target, force, workingDirectory, byproducts,
+ depends, commandLines, escapeOldStyle, comment,
+ uses_terminal, command_expand_lists, job_pool);
- // The output is not actually created so mark it symbolic.
- if (sf) {
- sf->SetProperty("SYMBOLIC", "1");
- } else {
- cmSystemTools::Error("Could not get source file entry for " + force);
- }
+ return target;
+}
- // Always create the byproduct sources and mark them generated.
- for (std::string const& byproduct : byproducts) {
- if (cmSourceFile* out = this->GetOrCreateSource(
- byproduct, true, cmSourceFileLocationKind::Known)) {
- out->SetProperty("GENERATED", "1");
- }
- }
+void cmMakefile::CommitUtilityCommand(
+ cmTarget* target, const cmUtilityOutput& force, const char* workingDirectory,
+ const std::vector<std::string>& byproducts,
+ 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)
+{
+ std::vector<std::string> forced;
+ forced.push_back(force.Name);
+ std::string no_main_dependency;
+ cmImplicitDependsList no_implicit_depends;
+ bool no_replace = false;
+ cmSourceFile* sf = this->AddCustomCommandToOutput(
+ forced, byproducts, depends, no_main_dependency, no_implicit_depends,
+ commandLines, comment, workingDirectory, no_replace, escapeOldStyle,
+ uses_terminal, command_expand_lists, /*depfile=*/"", job_pool);
+ if (!force.NameCMP0049.empty()) {
+ target->AddSource(force.NameCMP0049);
+ }
+ if (sf) {
+ this->AddTargetByproducts(target, byproducts);
}
- return target;
}
static void s_AddDefineFlag(std::string const& flag, std::string& dflags)
@@ -1343,13 +1410,11 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
if (remove) {
if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs;
- cmSystemTools::ExpandListArgument(cdefs, defs);
+ std::vector<std::string> defs = cmExpandedList(cdefs);
// Recompose the list without the definition.
- std::vector<std::string>::const_iterator defEnd =
- std::remove(defs.begin(), defs.end(), define);
- std::vector<std::string>::const_iterator defBegin = defs.begin();
+ auto defEnd = std::remove(defs.begin(), defs.end(), define);
+ auto defBegin = defs.begin();
std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
// Store the new list.
@@ -1385,8 +1450,8 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
std::vector<std::string> configs;
this->GetConfigurations(configs);
for (std::string const& config : configs) {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(config);
+ std::string defPropName =
+ cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
const char* prop = parent->GetProperty(defPropName);
this->SetProperty(defPropName, prop);
}
@@ -1420,7 +1485,7 @@ void cmMakefile::PushFunctionScope(std::string const& fileName,
this->PushLoopBlockBarrier();
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
#endif
@@ -1437,7 +1502,7 @@ void cmMakefile::PopFunctionScope(bool reportError)
this->PopFunctionBlockerBarrier(reportError);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
#endif
@@ -1479,8 +1544,8 @@ public:
, ReportError(true)
{
std::string currentStart =
- this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
- currentStart += "/CMakeLists.txt";
+ cmStrCat(this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(),
+ "/CMakeLists.txt");
this->Makefile->StateSnapshot.SetListFile(currentStart);
this->Makefile->StateSnapshot =
this->Makefile->StateSnapshot.GetState()->CreatePolicyScopeSnapshot(
@@ -1492,7 +1557,7 @@ public:
this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
this->GG->SetCurrentMakefile(mf);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GG->GetFileLockPool().PushFileScope();
#endif
}
@@ -1501,7 +1566,7 @@ public:
{
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
this->Makefile->PopSnapshot(this->ReportError);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GG->GetFileLockPool().PopFileScope();
#endif
this->GG->SetCurrentMakefile(this->CurrentMakefile);
@@ -1523,9 +1588,8 @@ private:
void cmMakefile::Configure()
{
- std::string currentStart =
- this->StateSnapshot.GetDirectory().GetCurrentSource();
- currentStart += "/CMakeLists.txt";
+ std::string currentStart = cmStrCat(
+ this->StateSnapshot.GetDirectory().GetCurrentSource(), "/CMakeLists.txt");
// Add the bottom of all backtraces within this directory.
// We will never pop this scope because it should be available
@@ -1535,12 +1599,12 @@ void cmMakefile::Configure()
BuildsystemFileScope scope(this);
// make sure the CMakeFiles dir is there
- std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
- filesDir += "/CMakeFiles";
+ std::string filesDir = cmStrCat(
+ this->StateSnapshot.GetDirectory().GetCurrentBinary(), "/CMakeFiles");
cmSystemTools::MakeDirectory(filesDir);
assert(cmSystemTools::FileExists(currentStart, true));
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart);
cmListFile listFile;
if (!listFile.ParseFile(currentStart.c_str(), this->GetMessenger(),
@@ -1578,7 +1642,7 @@ void cmMakefile::Configure()
allowedCommands.insert("message");
isProblem = false;
for (cmListFileFunction const& func : listFile.Functions) {
- if (allowedCommands.find(func.Name.Lower) == allowedCommands.end()) {
+ if (!cmContains(allowedCommands, func.Name.Lower)) {
isProblem = true;
break;
}
@@ -1633,7 +1697,7 @@ void cmMakefile::Configure()
std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories;
// for each subdir recurse
- std::vector<cmMakefile*>::iterator sdi = subdirs.begin();
+ auto sdi = subdirs.begin();
for (; sdi != subdirs.end(); ++sdi) {
(*sdi)->StateSnapshot.InitializeFromParent_ForSubdirsCommand();
this->ConfigureSubDirectory(*sdi);
@@ -1647,8 +1711,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf)
mf->InitializeFromParent(this);
std::string currentStart = mf->GetCurrentSourceDirectory();
if (this->GetCMakeInstance()->GetDebugOutput()) {
- std::string msg = " Entering ";
- msg += currentStart;
+ std::string msg = cmStrCat(" Entering ", currentStart);
cmSystemTools::Message(msg);
}
@@ -1690,8 +1753,8 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf)
mf->Configure();
if (this->GetCMakeInstance()->GetDebugOutput()) {
- std::string msg = " Returning to ";
- msg += this->GetCurrentSourceDirectory();
+ std::string msg =
+ cmStrCat(" Returning to ", this->GetCurrentSourceDirectory());
cmSystemTools::Message(msg);
}
}
@@ -1788,26 +1851,27 @@ void cmMakefile::AddSystemIncludeDirectories(const std::set<std::string>& incs)
}
}
-void cmMakefile::AddDefinition(const std::string& name, const char* value)
+void cmMakefile::AddDefinition(const std::string& name, cm::string_view value)
{
- if (!value) {
- return;
- }
-
if (this->VariableInitialized(name)) {
this->LogUnused("changing definition", name);
}
this->StateSnapshot.SetDefinition(name, value);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
- value, this);
+ value.data(), this);
}
#endif
}
+void cmMakefile::AddDefinitionBool(const std::string& name, bool value)
+{
+ this->AddDefinition(name, value ? "ON" : "OFF");
+}
+
void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
const char* doc,
cmStateEnums::CacheEntryType type,
@@ -1831,10 +1895,10 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
std::vector<std::string> files;
nvalue = value ? value : "";
- cmSystemTools::ExpandListArgument(nvalue, files);
+ cmExpandList(nvalue, files);
nvalue.clear();
for (cc = 0; cc < files.size(); cc++) {
- if (!cmSystemTools::IsOff(files[cc])) {
+ if (!cmIsOff(files[cc])) {
files[cc] = cmSystemTools::CollapseFullPath(files[cc]);
}
if (cc > 0) {
@@ -1853,23 +1917,6 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
this->StateSnapshot.RemoveDefinition(name);
}
-void cmMakefile::AddDefinition(const std::string& name, bool value)
-{
- if (this->VariableInitialized(name)) {
- this->LogUnused("changing definition", name);
- }
-
- this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF");
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
- cmVariableWatch* vv = this->GetVariableWatch();
- if (vv) {
- vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
- value ? "ON" : "OFF", this);
- }
-#endif
-}
-
void cmMakefile::CheckForUnusedVariables() const
{
if (!this->WarnUnused) {
@@ -1914,8 +1961,7 @@ void cmMakefile::LogUnused(const char* reason, const std::string& name) const
if (!this->ExecutionStatusStack.empty()) {
path = this->GetExecutionContext().FilePath;
} else {
- path = this->GetCurrentSourceDirectory();
- path += "/CMakeLists.txt";
+ path = cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
}
if (this->CheckSystemVars || this->IsProjectFile(path.c_str())) {
@@ -1932,7 +1978,7 @@ void cmMakefile::RemoveDefinition(const std::string& name)
this->LogUnused("unsetting", name);
}
this->StateSnapshot.RemoveDefinition(name);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
@@ -1963,11 +2009,9 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
}
if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs;
- cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs);
+ std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
- for (std::vector<std::string>::iterator j = linkLibs.begin();
- j != linkLibs.end(); ++j) {
+ for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
cmTargetLinkLibraryType libType = GENERAL_LibraryType;
if (libraryName == "optimized") {
@@ -2034,61 +2078,229 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName,
cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
const std::string& name)
{
- cmTargetMap::iterator it =
+ auto it =
this->Targets
.emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this))
.first;
+ this->OrderedTargets.push_back(&it->second);
this->GetGlobalGenerator()->IndexTarget(&it->second);
this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
return &it->second;
}
+cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
+ cmCommandOrigin origin,
+ bool excludeFromAll)
+{
+ cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
+ target->SetIsGeneratorProvided(origin == cmCommandOrigin::Generator);
+ if (excludeFromAll) {
+ target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ }
+ return target;
+}
+
+namespace {
+bool AnyOutputMatches(const std::string& name,
+ const std::vector<std::string>& outputs)
+{
+ for (std::string const& output : outputs) {
+ std::string::size_type pos = output.rfind(name);
+ // If the output matches exactly
+ if (pos != std::string::npos && pos == output.size() - name.size() &&
+ (pos == 0 || output[pos - 1] == '/')) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AnyTargetCommandOutputMatches(
+ const std::string& name, const std::vector<cmCustomCommand>& commands)
+{
+ for (cmCustomCommand const& command : commands) {
+ if (AnyOutputMatches(name, command.GetByproducts())) {
+ return true;
+ }
+ }
+ return false;
+}
+}
+
+cmTarget* cmMakefile::LinearGetTargetWithOutput(const std::string& name) const
+{
+ // We go through the ordered vector of targets to get reproducible results
+ // should multiple names match.
+ for (cmTarget* t : this->OrderedTargets) {
+ // Does the output of any command match the source file name?
+ if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
+ return t;
+ }
+ if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
+ return t;
+ }
+ if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
+ return t;
+ }
+ }
+ return nullptr;
+}
+
cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
- const std::string& name) const
+ const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
{
- std::string out;
+ // Outputs take precedence over byproducts.
+ byproduct = false;
+ cmSourceFile* fallback = nullptr;
- // look through all the source files that have custom commands
- // and see if the custom command has the passed source file as an output
+ // Look through all the source files that have custom commands and see if the
+ // custom command has the passed source file as an output.
for (cmSourceFile* src : this->SourceFiles) {
- // does this source file have a custom command?
+ // Does this source file have a custom command?
if (src->GetCustomCommand()) {
// Does the output of the custom command match the source file name?
- const std::vector<std::string>& outputs =
- src->GetCustomCommand()->GetOutputs();
- for (std::string const& output : outputs) {
- out = output;
- std::string::size_type pos = out.rfind(name);
- // If the output matches exactly
- if (pos != std::string::npos && pos == out.size() - name.size() &&
- (pos == 0 || out[pos - 1] == '/')) {
- return src;
+ if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
+ // Return the first matching output.
+ return src;
+ }
+ if (kind == cmSourceOutputKind::OutputOrByproduct) {
+ if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
+ // Do not return the source yet as there might be a matching output.
+ fallback = src;
}
}
}
}
- // otherwise return NULL
- return nullptr;
+ // Did we find a byproduct?
+ byproduct = fallback != nullptr;
+ return fallback;
}
-cmSourceFile* cmMakefile::GetSourceFileWithOutput(
+cmSourcesWithOutput cmMakefile::GetSourcesWithOutput(
const std::string& name) const
{
+ // Linear search? Also see GetSourceFileWithOutput for detail.
+ if (!cmSystemTools::FileIsFullPath(name)) {
+ cmSourcesWithOutput sources;
+ sources.Target = this->LinearGetTargetWithOutput(name);
+ sources.Source = this->LinearGetSourceFileWithOutput(
+ name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
+ return sources;
+ }
+ // Otherwise we use an efficient lookup map.
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end()) {
+ return o->second.Sources;
+ }
+ return {};
+}
+
+cmSourceFile* cmMakefile::GetSourceFileWithOutput(
+ const std::string& name, cmSourceOutputKind kind) const
+{
// If the queried path is not absolute we use the backward compatible
// linear-time search for an output with a matching suffix.
if (!cmSystemTools::FileIsFullPath(name)) {
- return this->LinearGetSourceFileWithOutput(name);
+ bool byproduct = false;
+ return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
}
// Otherwise we use an efficient lookup map.
- OutputToSourceMap::const_iterator o = this->OutputToSource.find(name);
- if (o != this->OutputToSource.end()) {
- return (*o).second;
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end() &&
+ (!o->second.Sources.SourceIsByproduct ||
+ kind == cmSourceOutputKind::OutputOrByproduct)) {
+ // Source file could also be null pointer for example if we found the
+ // byproduct of a utility target or a PRE_BUILD, PRE_LINK, or POST_BUILD
+ // command of a target.
+ return o->second.Sources.Source;
}
return nullptr;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+bool cmMakefile::MightHaveCustomCommand(const std::string& name) const
+{
+ // This will have to be changed for delaying custom command creation, because
+ // GetSourceFileWithOutput requires the command to be already created.
+ if (cmSourceFile* sf = this->GetSourceFileWithOutput(name)) {
+ if (sf->GetCustomCommand()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void cmMakefile::AddTargetByproducts(
+ cmTarget* target, const std::vector<std::string>& byproducts)
+{
+ for (std::string const& o : byproducts) {
+ this->UpdateOutputToSourceMap(o, target);
+ }
+}
+
+void cmMakefile::AddSourceOutputs(cmSourceFile* source,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts)
+{
+ for (std::string const& o : outputs) {
+ this->UpdateOutputToSourceMap(o, source, false);
+ }
+ for (std::string const& o : byproducts) {
+ this->UpdateOutputToSourceMap(o, source, true);
+ }
+}
+
+void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct,
+ cmTarget* target)
+{
+ SourceEntry entry;
+ entry.Sources.Target = target;
+
+ auto pr = this->OutputToSource.emplace(byproduct, entry);
+ if (!pr.second) {
+ SourceEntry& current = pr.first->second;
+ // Has the target already been set?
+ if (!current.Sources.Target) {
+ current.Sources.Target = target;
+ } else {
+ // Multiple custom commands/targets produce the same output (source file
+ // or target). See also comment in other UpdateOutputToSourceMap
+ // overload.
+ //
+ // TODO: Warn the user about this case.
+ }
+ }
+}
+
+void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
+ cmSourceFile* source, bool byproduct)
+{
+ SourceEntry entry;
+ entry.Sources.Source = source;
+ entry.Sources.SourceIsByproduct = byproduct;
+
+ auto pr = this->OutputToSource.emplace(output, entry);
+ if (!pr.second) {
+ SourceEntry& current = pr.first->second;
+ // Outputs take precedence over byproducts
+ if (!current.Sources.Source ||
+ (current.Sources.SourceIsByproduct && !byproduct)) {
+ current.Sources.Source = source;
+ current.Sources.SourceIsByproduct = false;
+ } else {
+ // Multiple custom commands produce the same output but may
+ // be attached to a different source file (MAIN_DEPENDENCY).
+ // LinearGetSourceFileWithOutput would return the first one,
+ // so keep the mapping for the first one.
+ //
+ // TODO: Warn the user about this case. However, the VS 8 generator
+ // triggers it for separate generate.stamp rules in ZERO_CHECK and
+ // individual targets.
+ }
+ }
+}
+
+#if !defined(CMAKE_BOOTSTRAP)
cmSourceGroup* cmMakefile::GetSourceGroup(
const std::vector<std::string>& name) const
{
@@ -2184,8 +2396,7 @@ cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name)
if (delimiter == nullptr) {
delimiter = "\\";
}
- return this->GetOrCreateSourceGroup(
- cmSystemTools::tokenize(name, delimiter));
+ return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter));
}
/**
@@ -2199,8 +2410,7 @@ cmSourceGroup* cmMakefile::FindSourceGroup(
const std::string& source, std::vector<cmSourceGroup>& groups) const
{
// First search for a group that lists the file explicitly.
- for (std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
- sg != groups.rend(); ++sg) {
+ for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
cmSourceGroup* result = sg->MatchChildrenFiles(source);
if (result) {
return result;
@@ -2208,8 +2418,7 @@ cmSourceGroup* cmMakefile::FindSourceGroup(
}
// Now search for a group whose regex matches the file.
- for (std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
- sg != groups.rend(); ++sg) {
+ for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
cmSourceGroup* result = sg->MatchChildrenRegex(source);
if (result) {
return result;
@@ -2290,11 +2499,9 @@ void cmMakefile::ExpandVariablesCMP0019()
}
if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs;
- cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs);
+ std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
- for (std::vector<std::string>::iterator l = linkLibs.begin();
- l != linkLibs.end(); ++l) {
+ for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
std::string libName = *l;
if (libName == "optimized") {
++l;
@@ -2334,7 +2541,7 @@ void cmMakefile::ExpandVariablesCMP0019()
bool cmMakefile::IsOn(const std::string& name) const
{
const char* value = this->GetDefinition(name);
- return cmSystemTools::IsOn(value);
+ return cmIsOn(value);
}
bool cmMakefile::IsSet(const std::string& name) const
@@ -2348,7 +2555,7 @@ bool cmMakefile::IsSet(const std::string& name) const
return false;
}
- if (cmSystemTools::IsNOTFOUND(value)) {
+ if (cmIsNOTFOUND(value)) {
return false;
}
@@ -2470,7 +2677,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (cmVariableWatch* vv = this->GetVariableWatch()) {
if (!def) {
vv->VariableAccessed(
@@ -2487,7 +2694,7 @@ const std::string* cmMakefile::GetDef(const std::string& name) const
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv && !this->SuppressSideEffects) {
bool const watch_function_executed =
@@ -2606,8 +2813,8 @@ const std::string& cmMakefile::ExpandVariablesInString(
}
// ...otherwise, see if there's a difference that needs to be warned about.
else if (compareResults && (newResult != source || newError != mtype)) {
- std::string msg = cmPolicies::GetPolicyWarning(cmPolicies::CMP0053);
- msg += "\n";
+ std::string msg =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0053), '\n');
std::string msg_input = original;
cmSystemTools::ReplaceString(msg_input, "\n", "\n ");
@@ -2677,7 +2884,7 @@ MessageType cmMakefile::ExpandVariablesInStringOld(
if (const char* val = this->GetDefinition(var)) {
// Store the value in the output escaping as requested.
if (escapeQuotes) {
- source.append(cmSystemTools::EscapeQuotes(val));
+ source.append(cmEscapeQuotes(val));
} else {
source.append(val);
}
@@ -2756,12 +2963,13 @@ MessageType cmMakefile::ExpandVariablesInStringOld(
return mtype;
}
-typedef enum
+enum t_domain
{
NORMAL,
ENVIRONMENT,
CACHE
-} t_domain;
+};
+
struct t_lookup
{
t_domain domain = NORMAL;
@@ -2822,9 +3030,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
switch (var.domain) {
case NORMAL:
if (filename && lookup == lineVar) {
- std::ostringstream ostr;
- ostr << line;
- varresult = ostr.str();
+ varresult = std::to_string(line);
} else {
value = this->GetDefinition(lookup);
}
@@ -2841,7 +3047,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
// Get the string we're meant to append to.
if (value) {
if (escapeQuotes) {
- varresult = cmSystemTools::EscapeQuotes(value);
+ varresult = cmEscapeQuotes(value);
} else {
varresult = value;
}
@@ -2967,7 +3173,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
}
if (escapeQuotes) {
- varresult = cmSystemTools::EscapeQuotes(varresult);
+ varresult = cmEscapeQuotes(varresult);
}
// Skip over the variable.
result.append(last, in - last);
@@ -3060,7 +3266,7 @@ std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs,
if (this->GetGlobalGenerator()->IsMultiConfig()) {
if (const char* configTypes =
this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
- cmSystemTools::ExpandListArgument(configTypes, configs);
+ cmExpandList(configTypes, configs);
}
return "";
}
@@ -3071,23 +3277,25 @@ std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs,
return buildType;
}
+std::vector<std::string> cmMakefile::GetGeneratorConfigs() const
+{
+ std::vector<std::string> configs;
+ GetConfigurations(configs);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
+ return configs;
+}
+
bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus& status)
{
// if there are no blockers get out of here
- if (this->FunctionBlockers.begin() == this->FunctionBlockers.end()) {
+ if (this->FunctionBlockers.empty()) {
return false;
}
- // loop over all function blockers to see if any block this command
- // evaluate in reverse, this is critical for balanced IF statements etc
- for (cmFunctionBlocker* pos : cmReverseRange(this->FunctionBlockers)) {
- if (pos->IsFunctionBlocked(lff, *this, status)) {
- return true;
- }
- }
-
- return false;
+ return this->FunctionBlockers.top()->IsFunctionBlocked(lff, status);
}
void cmMakefile::PushFunctionBlockerBarrier()
@@ -3101,8 +3309,9 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
FunctionBlockersType::size_type barrier =
this->FunctionBlockerBarriers.back();
while (this->FunctionBlockers.size() > barrier) {
- std::unique_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
- this->FunctionBlockers.pop_back();
+ std::unique_ptr<cmFunctionBlocker> fb(
+ std::move(this->FunctionBlockers.top()));
+ this->FunctionBlockers.pop();
if (reportError) {
// Report the context in which the unclosed block was opened.
cmListFileContext const& lfc = fb->GetStartingContext();
@@ -3184,7 +3393,7 @@ bool cmMakefile::ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
if (i.Delim == cmListFileArgument::Quoted) {
outArgs.push_back(value);
} else {
- cmSystemTools::ExpandListArgument(value, outArgs);
+ cmExpandList(value, outArgs);
}
}
return !cmSystemTools::GetFatalErrorOccured();
@@ -3216,8 +3425,7 @@ bool cmMakefile::ExpandArguments(
if (i.Delim == cmListFileArgument::Quoted) {
outArgs.emplace_back(value, true);
} else {
- std::vector<std::string> stringArgs;
- cmSystemTools::ExpandListArgument(value, stringArgs);
+ std::vector<std::string> stringArgs = cmExpandedList(value);
for (std::string const& stringArg : stringArgs) {
outArgs.emplace_back(stringArg, false);
}
@@ -3226,54 +3434,25 @@ bool cmMakefile::ExpandArguments(
return !cmSystemTools::GetFatalErrorOccured();
}
-void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
+void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
{
if (!this->ExecutionStatusStack.empty()) {
// Record the context in which the blocker is created.
fb->SetStartingContext(this->GetExecutionContext());
}
- this->FunctionBlockers.push_back(fb);
+ this->FunctionBlockers.push(std::move(fb));
}
-std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
- cmFunctionBlocker* fb, const cmListFileFunction& lff)
+std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker()
{
- // Find the function blocker stack barrier for the current scope.
- // We only remove a blocker whose index is not less than the barrier.
- FunctionBlockersType::size_type barrier = 0;
- if (!this->FunctionBlockerBarriers.empty()) {
- barrier = this->FunctionBlockerBarriers.back();
- }
-
- // Search for the function blocker whose scope this command ends.
- for (FunctionBlockersType::size_type i = this->FunctionBlockers.size();
- i > barrier; --i) {
- std::vector<cmFunctionBlocker*>::iterator pos =
- this->FunctionBlockers.begin() + (i - 1);
- if (*pos == fb) {
- // Warn if the arguments do not match, but always remove.
- if (!(*pos)->ShouldRemove(lff, *this)) {
- cmListFileContext const& lfc = fb->GetStartingContext();
- cmListFileContext closingContext =
- cmListFileContext::FromCommandContext(lff, lfc.FilePath);
- std::ostringstream e;
- /* clang-format off */
- e << "A logical block opening on the line\n"
- << " " << lfc << "\n"
- << "closes on the line\n"
- << " " << closingContext << "\n"
- << "with mis-matching arguments.";
- /* clang-format on */
- this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
- }
- cmFunctionBlocker* b = *pos;
- this->FunctionBlockers.erase(pos);
- return std::unique_ptr<cmFunctionBlocker>(b);
- }
- }
+ assert(!this->FunctionBlockers.empty());
+ assert(this->FunctionBlockerBarriers.empty() ||
+ this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
- return std::unique_ptr<cmFunctionBlocker>();
+ auto b = std::move(this->FunctionBlockers.top());
+ this->FunctionBlockers.pop();
+ return b;
}
std::string const& cmMakefile::GetHomeDirectory() const
@@ -3288,20 +3467,18 @@ std::string const& cmMakefile::GetHomeOutputDirectory() const
void cmMakefile::SetScriptModeFile(std::string const& scriptfile)
{
- this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile.c_str());
+ this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile);
}
void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
{
- std::ostringstream strStream;
- strStream << args.size();
- this->AddDefinition("CMAKE_ARGC", strStream.str().c_str());
+ this->AddDefinition("CMAKE_ARGC", std::to_string(args.size()));
// this->MarkVariableAsUsed("CMAKE_ARGC");
for (unsigned int t = 0; t < args.size(); ++t) {
std::ostringstream tmpStream;
tmpStream << "CMAKE_ARGV" << t;
- this->AddDefinition(tmpStream.str(), args[t].c_str());
+ this->AddDefinition(tmpStream.str(), args[t]);
// this->MarkVariableAsUsed(tmpStream.str().c_str());
}
}
@@ -3367,23 +3544,41 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
return this->CreateSource(sourceName, generated, kind);
}
+cmSourceFile* cmMakefile::GetOrCreateGeneratedSource(
+ const std::string& sourceName)
+{
+ cmSourceFile* sf =
+ this->GetOrCreateSource(sourceName, true, cmSourceFileLocationKind::Known);
+ sf->SetProperty("GENERATED", "1");
+ return sf;
+}
+
+void cmMakefile::CreateGeneratedSources(
+ const std::vector<std::string>& outputs)
+{
+ for (std::string const& output : outputs) {
+ this->GetOrCreateGeneratedSource(output);
+ }
+}
+
void cmMakefile::AddTargetObject(std::string const& tgtName,
std::string const& objFile)
{
cmSourceFile* sf = this->GetOrCreateSource(objFile, true);
sf->SetObjectLibrary(tgtName);
sf->SetProperty("EXTERNAL_OBJECT", "1");
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->SourceGroups[this->ObjectLibrariesSourceGroupIndex].AddGroupFile(
- sf->GetFullPath());
+ sf->ResolveFullPath());
#endif
}
void cmMakefile::EnableLanguage(std::vector<std::string> const& lang,
bool optional)
{
- this->AddDefinition("CMAKE_CFG_INTDIR",
- this->GetGlobalGenerator()->GetCMakeCFGIntDir());
+ if (const char* def = this->GetGlobalGenerator()->GetCMakeCFGIntDir()) {
+ this->AddDefinition("CMAKE_CFG_INTDIR", def);
+ }
// If RC is explicitly listed we need to do it after other languages.
// On some platforms we enable RC implicitly while enabling others.
// Do not let that look like recursive enable_language(RC).
@@ -3554,7 +3749,7 @@ cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const
return this->GlobalGenerator;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* cmMakefile::GetVariableWatch() const
{
if (this->GetCMakeInstance() &&
@@ -3602,8 +3797,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
// Always search in CMAKE_MODULE_PATH:
const char* cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
if (cmakeModulePath) {
- std::vector<std::string> modulePath;
- cmSystemTools::ExpandListArgument(cmakeModulePath, modulePath);
+ std::vector<std::string> modulePath = cmExpandedList(cmakeModulePath);
// Look through the possible module directories.
for (std::string itempl : modulePath) {
@@ -3618,9 +3812,8 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
}
// Always search in the standard modules location.
- moduleInCMakeRoot = cmSystemTools::GetCMakeRoot();
- moduleInCMakeRoot += "/Modules/";
- moduleInCMakeRoot += filename;
+ moduleInCMakeRoot =
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/", filename);
cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
if (!cmSystemTools::FileExists(moduleInCMakeRoot)) {
moduleInCMakeRoot.clear();
@@ -3695,7 +3888,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
// Replace #cmakedefine instances.
if (this->cmDefineRegex.find(line)) {
const char* def = this->GetDefinition(this->cmDefineRegex.match(2));
- if (!cmSystemTools::IsOff(def)) {
+ if (!cmIsOff(def)) {
const std::string indentation = this->cmDefineRegex.match(1);
cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine",
"#" + indentation + "define");
@@ -3711,7 +3904,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output,
cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01",
"#" + indentation + "define");
output += line;
- if (!cmSystemTools::IsOff(def)) {
+ if (!cmIsOff(def)) {
output += " 1";
} else {
output += " 0";
@@ -3786,8 +3979,7 @@ int cmMakefile::ConfigureFile(const std::string& infile,
} else {
newLineCharacters = "\n";
}
- std::string tempOutputFile = soutfile;
- tempOutputFile += ".tmp";
+ std::string tempOutputFile = cmStrCat(soutfile, ".tmp");
cmsys::ofstream fout(tempOutputFile.c_str(), omode);
if (!fout) {
cmSystemTools::Error("Could not open file for write in copy operation " +
@@ -3875,7 +4067,7 @@ const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const
bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
{
- return cmSystemTools::IsOn(this->GetProperty(prop));
+ return cmIsOn(this->GetProperty(prop));
}
std::vector<std::string> cmMakefile::GetPropertyKeys() const
@@ -3885,7 +4077,7 @@ std::vector<std::string> cmMakefile::GetPropertyKeys() const
cmTarget* cmMakefile::FindLocalNonAliasTarget(const std::string& name) const
{
- cmTargetMap::iterator i = this->Targets.find(name);
+ auto i = this->Targets.find(name);
if (i != this->Targets.end()) {
return &i->second;
}
@@ -3906,8 +4098,7 @@ cmTest* cmMakefile::CreateTest(const std::string& testName)
cmTest* cmMakefile::GetTest(const std::string& testName) const
{
- std::map<std::string, cmTest*>::const_iterator mi =
- this->Tests.find(testName);
+ auto mi = this->Tests.find(testName);
if (mi != this->Tests.end()) {
return mi->second;
}
@@ -3928,15 +4119,13 @@ void cmMakefile::AddCMakeDependFilesFromUser()
{
std::vector<std::string> deps;
if (const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
- cmSystemTools::ExpandListArgument(deps_str, deps);
+ cmExpandList(deps_str, deps);
}
for (std::string const& dep : deps) {
if (cmSystemTools::FileIsFullPath(dep)) {
this->AddCMakeDependFile(dep);
} else {
- std::string f = this->GetCurrentSourceDirectory();
- f += "/";
- f += dep;
+ std::string f = cmStrCat(this->GetCurrentSourceDirectory(), '/', dep);
this->AddCMakeDependFile(f);
}
}
@@ -3954,7 +4143,7 @@ std::string cmMakefile::FormatListFileStack() const
std::ostringstream tmp;
size_t depth = listFiles.size();
if (depth > 0) {
- std::vector<std::string>::const_iterator it = listFiles.end();
+ auto it = listFiles.end();
do {
if (depth != listFiles.size()) {
tmp << "\n ";
@@ -3976,14 +4165,14 @@ void cmMakefile::PushScope()
this->GetState()->CreateVariableScopeSnapshot(this->StateSnapshot);
this->PushLoopBlockBarrier();
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
#endif
}
void cmMakefile::PopScope()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
#endif
@@ -4007,7 +4196,7 @@ void cmMakefile::RaiseScope(const std::string& var, const char* varDef)
return;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(var, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
@@ -4041,7 +4230,7 @@ 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.
- TargetMap::const_iterator imported = this->ImportedTargets.find(name);
+ auto imported = this->ImportedTargets.find(name);
if (imported != this->ImportedTargets.end()) {
return imported->second;
}
@@ -4057,7 +4246,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
bool cmMakefile::IsAlias(const std::string& name) const
{
- if (this->AliasTargets.find(name) != this->AliasTargets.end()) {
+ if (cmContains(this->AliasTargets, name)) {
return true;
}
return this->GetGlobalGenerator()->IsAlias(name);
@@ -4235,7 +4424,7 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re)
std::string const& m = re.match(i);
if (!m.empty()) {
std::string const& var = matchVariables[i];
- this->AddDefinition(var, m.c_str());
+ this->AddDefinition(var, m);
this->MarkVariableAsUsed(var);
highest = static_cast<char>('0' + i);
}
@@ -4265,7 +4454,7 @@ bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
{
// Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting.
if (const char* val = this->GetDefinition(var)) {
- return cmSystemTools::IsOn(val);
+ return cmIsOn(val);
}
// Enable optional policy warnings with --debug-output, --trace,
// or --trace-expand.
@@ -4298,7 +4487,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::CMP0066 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0067 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4368,7 +4557,7 @@ bool cmMakefile::HasCMP0054AlreadyBeenReported(
void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
{
/* Record the setting of every policy. */
- typedef cmPolicies::PolicyID PolicyID;
+ using PolicyID = cmPolicies::PolicyID;
for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
pid = PolicyID(pid + 1)) {
pm.Set(pid, this->GetPolicyStatus(pid));
@@ -4422,10 +4611,8 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
return false;
}
- std::vector<std::string> availableFeatures;
- cmSystemTools::ExpandListArgument(features, availableFeatures);
- if (std::find(availableFeatures.begin(), availableFeatures.end(), feature) ==
- availableFeatures.end()) {
+ std::vector<std::string> availableFeatures = cmExpandedList(features);
+ if (!cmContains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
<< " compiler\n\""
@@ -4443,9 +4630,9 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
target->AppendProperty("COMPILE_FEATURES", feature.c_str());
- return lang == "C"
- ? this->AddRequiredTargetCFeature(target, feature, error)
- : this->AddRequiredTargetCxxFeature(target, feature, error);
+ return lang == "C" || lang == "OBJC"
+ ? this->AddRequiredTargetCFeature(target, feature, lang, error)
+ : this->AddRequiredTargetCxxFeature(target, feature, lang, error);
}
bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
@@ -4537,30 +4724,33 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
std::string const& lang,
const std::string& feature) const
{
- return lang == "C" ? this->HaveCStandardAvailable(target, feature)
- : this->HaveCxxStandardAvailable(target, feature);
+ return lang == "C" || lang == "OBJC"
+ ? this->HaveCStandardAvailable(target, feature, lang)
+ : this->HaveCxxStandardAvailable(target, feature, lang);
}
bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature) const
+ const std::string& feature,
+ std::string const& lang) const
{
const char* defaultCStandard =
- this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCStandard) {
- std::ostringstream e;
- e << "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ this->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("CMAKE_", lang,
+ "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler."));
// Return true so the caller does not try to lookup the default standard.
return true;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
- std::ostringstream e;
- e << "The CMAKE_C_STANDARD_DEFAULT variable contains an "
- "invalid value: \""
- << defaultCStandard << "\".";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ const std::string e = cmStrCat("The CMAKE_", lang,
+ "_STANDARD_DEFAULT variable contains an "
+ "invalid value: \"",
+ defaultCStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4568,19 +4758,20 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
bool needC99 = false;
bool needC11 = false;
- this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+ this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard = target->GetProperty("C_STANDARD");
+ const char* 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)) {
- std::ostringstream e;
- e << "The C_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCStandard << "\".";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4611,7 +4802,7 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
std::string const& lhs,
std::string const& rhs)
{
- if (lang == "C") {
+ if (lang == "C" || lang == "OBJC") {
const char* const* rhsIt = std::find_if(
cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
@@ -4626,25 +4817,26 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
}
bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature) const
+ const std::string& feature,
+ std::string const& lang) const
{
const char* defaultCxxStandard =
- this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCxxStandard) {
- std::ostringstream e;
- e << "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
- "not fully configured for this compiler.";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ this->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("CMAKE_", lang,
+ "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler."));
// Return true so the caller does not try to lookup the default standard.
return true;
}
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an "
- "invalid value: \""
- << defaultCxxStandard << "\".";
- this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+ const std::string e =
+ cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
+ "invalid value: \"", defaultCxxStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4653,10 +4845,11 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
bool needCxx14 = false;
bool needCxx17 = false;
bool needCxx20 = false;
- this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+ this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ const char* existingCxxStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCxxStandard) {
existingCxxStandard = defaultCxxStandard;
}
@@ -4665,10 +4858,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CXX_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4686,44 +4879,41 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
}
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
+ std::string const& lang,
bool& needCxx98, bool& needCxx11,
bool& needCxx14, bool& needCxx17,
bool& needCxx20) const
{
if (const char* propCxx98 =
- this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propCxx98, props);
- needCxx98 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCxx98);
+ needCxx98 = cmContains(props, feature);
}
if (const char* propCxx11 =
- this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propCxx11, props);
- needCxx11 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCxx11);
+ needCxx11 = cmContains(props, feature);
}
if (const char* propCxx14 =
- this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propCxx14, props);
- needCxx14 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCxx14);
+ needCxx14 = cmContains(props, feature);
}
if (const char* propCxx17 =
- this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propCxx17, props);
- needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCxx17);
+ needCxx17 = cmContains(props, feature);
}
if (const char* propCxx20 =
- this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propCxx20, props);
- needCxx20 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCxx20);
+ needCxx20 = cmContains(props, feature);
}
}
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error) const
{
bool needCxx98 = false;
@@ -4732,13 +4922,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool needCxx17 = false;
bool needCxx20 = false;
- this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+ this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ const char* existingCxxStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCxxStandard == nullptr) {
const char* defaultCxxStandard =
- this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (defaultCxxStandard && *defaultCxxStandard) {
existingCxxStandard = defaultCxxStandard;
}
@@ -4749,14 +4940,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
cmStrCmp(existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CXX_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCxxStandard, "\".");
if (error) {
- *error = e.str();
+ *error = e;
} else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
}
return false;
}
@@ -4797,7 +4988,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
// Ensure the C++ language level is high enough to support
// the needed C++ features.
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
- target->SetProperty("CXX_STANDARD", *needCxxLevel);
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
}
// Ensure the CUDA language level is high enough to support
@@ -4811,43 +5002,42 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
}
void cmMakefile::CheckNeededCLanguage(const std::string& feature,
- bool& needC90, bool& needC99,
- bool& needC11) const
+ std::string const& lang, bool& needC90,
+ bool& needC99, bool& needC11) const
{
if (const char* propC90 =
- this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propC90, props);
- needC90 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propC90);
+ needC90 = cmContains(props, feature);
}
if (const char* propC99 =
- this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propC99, props);
- needC99 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propC99);
+ needC99 = cmContains(props, feature);
}
if (const char* propC11 =
- this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(propC11, props);
- needC11 = std::find(props.begin(), props.end(), feature) != props.end();
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propC11);
+ needC11 = cmContains(props, feature);
}
}
bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error) const
{
bool needC90 = false;
bool needC99 = false;
bool needC11 = false;
- this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+ this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard = target->GetProperty("C_STANDARD");
+ const char* existingCStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCStandard == nullptr) {
const char* defaultCStandard =
- this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (defaultCStandard && *defaultCStandard) {
existingCStandard = defaultCStandard;
}
@@ -4855,14 +5045,14 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
if (existingCStandard) {
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
- std::ostringstream e;
- e << "The C_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCStandard << "\".";
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCStandard, "\".");
if (error) {
- *error = e.str();
+ *error = e;
} else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
}
return false;
}
@@ -4893,11 +5083,11 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
if (setC11) {
- target->SetProperty("C_STANDARD", "11");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
} else if (setC99) {
- target->SetProperty("C_STANDARD", "99");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
} else if (setC90) {
- target->SetProperty("C_STANDARD", "90");
+ target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
}
return true;
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d22334751..6e5949404 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -5,18 +5,23 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
+#include <cstddef>
#include <deque>
+#include <functional>
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <set>
#include <stack>
-#include <stddef.h>
#include <string>
#include <unordered_map>
#include <vector>
+#include <cm/string_view>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
+#include "cmCustomCommandTypes.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmNewLineStyle.h"
@@ -24,13 +29,16 @@
#include "cmSourceFileLocationKind.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmTarget.h"
+#include "cmStringAlgorithms.h"
+
+// IWYU does not see that 'std::unordered_map<std::string, cmTarget>'
+// will not compile without the complete type.
+#include "cmTarget.h" // IWYU pragma: keep
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmSourceGroup.h"
#endif
-class cmCommand;
class cmCompiledGeneratorExpression;
class cmCustomCommandLines;
class cmExecutionStatus;
@@ -39,6 +47,7 @@ class cmExportBuildFileGenerator;
class cmFunctionBlocker;
class cmGeneratorExpressionEvaluationFile;
class cmGlobalGenerator;
+class cmImplicitDependsList;
class cmInstallGenerator;
class cmMessenger;
class cmSourceFile;
@@ -48,6 +57,24 @@ class cmTestGenerator;
class cmVariableWatch;
class cmake;
+/** Flag if byproducts shall also be considered. */
+enum class cmSourceOutputKind
+{
+ OutputOnly,
+ OutputOrByproduct
+};
+
+/** Target and source file which have a specific output. */
+struct cmSourcesWithOutput
+{
+ /** Target with byproduct. */
+ cmTarget* Target = nullptr;
+
+ /** Source file with output or byproduct. */
+ cmSourceFile* Source = nullptr;
+ bool SourceIsByproduct = false;
+};
+
/** A type-safe wrapper for a string representing a directory id. */
class cmDirectoryId
{
@@ -95,7 +122,7 @@ public:
/**
* Add a function blocker to this makefile
*/
- void AddFunctionBlocker(cmFunctionBlocker* fb);
+ void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb);
/// @return whether we are processing the top CMakeLists.txt file.
bool IsRootMakefile() const;
@@ -104,8 +131,7 @@ public:
* Remove the function blocker whose scope ends with the given command.
* This returns ownership of the function blocker object.
*/
- std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(
- cmFunctionBlocker* fb, const cmListFileFunction& lff);
+ std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
/**
* Try running cmake and building a file. This is used for dynalically
@@ -125,6 +151,13 @@ public:
bool EnforceUniqueName(std::string const& name, std::string& msg,
bool isCustom = false) const;
+ using FinalAction = std::function<void(cmMakefile&)>;
+
+ /**
+ * Register an action that is executed during FinalPass
+ */
+ void AddFinalAction(FinalAction action);
+
/**
* Perform FinalPass, Library dependency analysis etc before output of the
* makefile.
@@ -132,38 +165,38 @@ public:
void ConfigureFinalPass();
/**
- * run the final pass on all commands.
+ * run all FinalActions.
*/
void FinalPass();
- /** How to handle custom commands for object libraries */
- enum ObjectLibraryCommands
- {
- RejectObjectLibraryCommands,
- AcceptObjectLibraryCommands
- };
+ /**
+ * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
+ */
+ cmTarget* GetCustomCommandTarget(
+ const std::string& target, cmObjectLibraryCommands objLibCommands) const;
/** Add a custom command to the build. */
- void AddCustomCommandToTarget(
+ cmTarget* AddCustomCommandToTarget(
const std::string& target, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type,
+ 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,
- ObjectLibraryCommands objLibraryCommands = RejectObjectLibraryCommands);
+ cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
cmSourceFile* AddCustomCommandToOutput(
- const std::vector<std::string>& outputs,
- const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
+ const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency,
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 = "");
cmSourceFile* AddCustomCommandToOutput(
- const std::string& output, const std::vector<std::string>& depends,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
@@ -174,6 +207,23 @@ public:
const std::string& source,
const cmCustomCommandLines& commandLines,
const char* comment);
+ bool AppendCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines);
+
+ /**
+ * Add target byproducts.
+ */
+ void AddTargetByproducts(cmTarget* target,
+ const std::vector<std::string>& byproducts);
+
+ /**
+ * Add source file outputs.
+ */
+ void AddSourceOutputs(cmSourceFile* source,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts);
/**
* Add a define flag to the build.
@@ -192,6 +242,10 @@ public:
cmTarget* AddNewTarget(cmStateEnums::TargetType type,
const std::string& name);
+ /** Create a target instance for the utility. */
+ cmTarget* AddNewUtilityTarget(const std::string& utilityName,
+ cmCommandOrigin origin, bool excludeFromAll);
+
/**
* Add an executable to the build.
*/
@@ -199,34 +253,19 @@ public:
const std::vector<std::string>& srcs,
bool excludeFromAll = false);
- /** Where the target originated from. */
- enum class TargetOrigin
- {
- Project,
- Generator
- };
+ /**
+ * Return the utility target output source file name and the CMP0049 name.
+ */
+ cmUtilityOutput GetUtilityOutput(cmTarget* target);
/**
* Add a utility to the build. A utility target is a command that
* is run every time the target is built.
*/
- cmTarget* AddUtilityCommand(const std::string& utilityName,
- TargetOrigin origin, bool excludeFromAll,
- const std::vector<std::string>& depends,
- const char* workingDirectory,
- const char* command, const char* arg1 = nullptr,
- const char* arg2 = nullptr,
- const char* arg3 = nullptr,
- const char* arg4 = nullptr);
- cmTarget* AddUtilityCommand(
- const std::string& utilityName, TargetOrigin origin, bool excludeFromAll,
- const char* workingDirectory, 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 = "");
cmTarget* AddUtilityCommand(
- const std::string& utilityName, TargetOrigin origin, bool excludeFromAll,
- const char* workingDirectory, const std::vector<std::string>& byproducts,
+ const std::string& utilityName, cmCommandOrigin origin,
+ bool excludeFromAll, const char* workingDirectory,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
const char* comment = nullptr, bool uses_terminal = false,
@@ -256,18 +295,17 @@ public:
* Add a variable definition to the build. This variable
* can be used in CMake to refer to lists, directories, etc.
*/
- void AddDefinition(const std::string& name, const char* value);
+ void AddDefinition(const std::string& name, cm::string_view value);
+ /**
+ * Add bool variable definition to the build.
+ */
+ void AddDefinitionBool(const std::string& name, bool);
//! Add a definition to this makefile and the global cmake cache.
void AddCacheDefinition(const std::string& name, const char* value,
const char* doc, cmStateEnums::CacheEntryType type,
bool force = false);
/**
- * Add bool variable definition to the build.
- */
- void AddDefinition(const std::string& name, bool);
-
- /**
* Remove a variable definition from the build. This is not valid
* for cache entries, and will only affect the current makefile.
*/
@@ -284,6 +322,9 @@ public:
std::string GetConfigurations(std::vector<std::string>& configs,
bool single = true) const;
+ /** Get the configurations for dependency checking. */
+ std::vector<std::string> GetGeneratorConfigs() const;
+
/**
* Set the name of the library.
*/
@@ -374,7 +415,7 @@ public:
}
// -- List of targets
- typedef std::unordered_map<std::string, cmTarget> cmTargetMap;
+ using cmTargetMap = std::unordered_map<std::string, cmTarget>;
/** Get the target map */
cmTargetMap& GetTargets() { return this->Targets; }
/** Get the target map - const version */
@@ -428,6 +469,12 @@ public:
const std::string& sourceName, bool generated = false,
cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
+ /** Get a cmSourceFile pointer for a given source name and always mark the
+ * file as generated, if the name is not found, then create the source file
+ * and return it.
+ */
+ cmSourceFile* GetOrCreateGeneratedSource(const std::string& sourceName);
+
void AddTargetObject(std::string const& tgtName, std::string const& objFile);
/**
@@ -495,7 +542,7 @@ public:
*/
bool CanIWriteThisFile(std::string const& fileName) const;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
/**
* Get the vector source groups.
*/
@@ -619,6 +666,11 @@ public:
void PrintCommandTrace(const cmListFileFunction& lff) const;
/**
+ * Set a callback that is invoked whenever ExecuteCommand is called.
+ */
+ void OnExecuteCommand(std::function<void()> callback);
+
+ /**
* Execute a single CMake command. Returns true if the command
* succeeded or false if it failed.
*/
@@ -636,7 +688,7 @@ public:
* Get the variable watch. This is used to determine when certain variables
* are accessed.
*/
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* GetVariableWatch() const;
#endif
@@ -671,10 +723,19 @@ public:
}
/**
- * Is there a source file that has the provided source file as an output?
- * if so then return it
+ * Return the target if the provided source name is a byproduct of a utility
+ * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
+ * Return the source file which has the provided source name as output.
+ */
+ cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
+
+ /**
+ * Is there a source file that has the provided source name as an output?
+ * If so then return it.
*/
- cmSourceFile* GetSourceFileWithOutput(const std::string& outName) const;
+ cmSourceFile* GetSourceFileWithOutput(
+ const std::string& name,
+ cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
//! Add a new cmTest to the list of tests for this makefile.
cmTest* CreateTest(const std::string& testName);
@@ -898,7 +959,10 @@ protected:
mutable cmTargetMap Targets;
std::map<std::string, std::string> AliasTargets;
- typedef std::vector<cmSourceFile*> SourceFileVec;
+ using TargetsVec = std::vector<cmTarget*>;
+ TargetsVec OrderedTargets;
+
+ using SourceFileVec = std::vector<cmSourceFile*>;
SourceFileVec SourceFiles;
// Because cmSourceFile names are compared in a fuzzy way (see
@@ -907,7 +971,7 @@ protected:
// Name portion of the cmSourceFileLocation and then compare on the list of
// cmSourceFiles that might match that name. Note that on platforms which
// have a case-insensitive filesystem we store the key in all lowercase.
- typedef std::unordered_map<std::string, SourceFileVec> SourceFileMap;
+ using SourceFileMap = std::unordered_map<std::string, SourceFileVec>;
SourceFileMap SourceFileSearchIndex;
// For "Known" paths we can store a direct filename to cmSourceFile map
@@ -932,12 +996,12 @@ protected:
// Track the value of the computed DEFINITIONS property.
std::string DefineFlagsOrig;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::vector<cmSourceGroup> SourceGroups;
size_t ObjectLibrariesSourceGroupIndex;
#endif
- std::vector<cmCommand*> FinalPassCommands;
+ std::vector<FinalAction> FinalActions;
cmGlobalGenerator* GlobalGenerator;
bool IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus& status);
@@ -955,7 +1019,10 @@ private:
bool EnforceUniqueDir(const std::string& srcPath,
const std::string& binPath) const;
- typedef std::vector<cmFunctionBlocker*> FunctionBlockersType;
+ std::function<void()> ExecuteCommandCallback;
+ using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
+ using FunctionBlockersType =
+ std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
FunctionBlockersType FunctionBlockers;
std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
void PushFunctionBlockerBarrier();
@@ -978,7 +1045,7 @@ private:
friend class cmParseFileScope;
std::vector<cmTarget*> ImportedTargetsOwned;
- typedef std::unordered_map<std::string, cmTarget*> TargetMap;
+ using TargetMap = std::unordered_map<std::string, cmTarget*>;
TargetMap ImportedTargets;
// Internal policy stack management.
@@ -986,15 +1053,15 @@ private:
cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
void PopPolicy();
void PopSnapshot(bool reportError = true);
- friend class cmCMakePolicyCommand;
+ friend bool cmCMakePolicyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
class IncludeScope;
-
friend class IncludeScope;
- class ListFileScope;
+ class ListFileScope;
friend class ListFileScope;
- class BuildsystemFileScope;
+ class BuildsystemFileScope;
friend class BuildsystemFileScope;
// CMP0053 == old
@@ -1010,40 +1077,98 @@ private:
bool escapeQuotes, bool noEscapes,
bool atOnly, const char* filename,
long line, bool replaceAt) const;
+
+ bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
+
+ void CreateGeneratedSources(const std::vector<std::string>& outputs);
+
+ void CommitCustomCommandToTarget(
+ cmTarget* target, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ 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);
+ cmSourceFile* CommitCustomCommandToOutput(
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ 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);
+ void CommitAppendCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines);
+
+ void CommitUtilityCommand(cmTarget* target, const cmUtilityOutput& force,
+ const char* workingDirectory,
+ const std::vector<std::string>& byproducts,
+ 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);
+
/**
- * Old version of GetSourceFileWithOutput(const std::string&) kept for
- * backward-compatibility. It implements a linear search and support
- * relative file paths. It is used as a fall back by
- * GetSourceFileWithOutput(const std::string&).
+ * See LinearGetSourceFileWithOutput for background information
*/
- cmSourceFile* LinearGetSourceFileWithOutput(const std::string& cname) const;
+ cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
+
+ /**
+ * Generalized old version of GetSourceFileWithOutput kept for
+ * backward-compatibility. It implements a linear search and supports
+ * relative file paths. It is used as a fall back by GetSourceFileWithOutput
+ * and GetSourcesWithOutput.
+ */
+ cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
+ cmSourceOutputKind kind,
+ bool& byproduct) const;
+
+ struct SourceEntry
+ {
+ cmSourcesWithOutput Sources;
+ };
// A map for fast output to input look up.
- typedef std::unordered_map<std::string, cmSourceFile*> OutputToSourceMap;
+ using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
OutputToSourceMap OutputToSource;
- void UpdateOutputToSourceMap(std::vector<std::string> const& outputs,
- cmSourceFile* source);
- void UpdateOutputToSourceMap(std::string const& output,
- cmSourceFile* source);
+ void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
+ void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
+ bool byproduct);
+
+ /**
+ * Return if the provided source file might have a custom command.
+ */
+ bool MightHaveCustomCommand(const std::string& name) const;
bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
+ std::string const& lang,
std::string* error = nullptr) const;
bool AddRequiredTargetCxxFeature(cmTarget* target,
const std::string& feature,
+ std::string const& lang,
std::string* error = nullptr) const;
- void CheckNeededCLanguage(const std::string& feature, bool& needC90,
+ void CheckNeededCLanguage(const std::string& feature,
+ std::string const& lang, bool& needC90,
bool& needC99, bool& needC11) const;
- void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
+ void CheckNeededCxxLanguage(const std::string& feature,
+ std::string const& lang, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
bool& needCxx17, bool& needCxx20) const;
bool HaveCStandardAvailable(cmTarget const* target,
- const std::string& feature) const;
+ const std::string& feature,
+ std::string const& lang) const;
bool HaveCxxStandardAvailable(cmTarget const* target,
- const std::string& feature) const;
+ const std::string& feature,
+ std::string const& lang) const;
void CheckForUnusedVariables() const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 6b9b9c7f1..40265ff65 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -2,13 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileExecutableTargetGenerator.h"
-#include <memory> // IWYU pragma: keep
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -25,6 +26,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
@@ -81,7 +83,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
bool relink)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
const bool requiresDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
if (!requiresDeviceLinking) {
@@ -109,14 +111,13 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
cmLocalUnixMakefileGenerator3::EchoProgress progress;
this->MakeEchoProgress(progress);
// Add the link message.
- std::string buildEcho = "Linking ";
- buildEcho += linkLanguage;
- buildEcho += " device code ";
- buildEcho += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(),
- this->DeviceLinkObject),
- cmOutputConverter::SHELL);
+ std::string buildEcho =
+ cmStrCat("Linking ", linkLanguage, " device code ",
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ this->DeviceLinkObject),
+ cmOutputConverter::SHELL));
this->LocalGenerator->AppendEcho(
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
}
@@ -128,11 +129,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
// Add flags to create an executable.
// Add symbol export flags if necessary.
if (this->GeneratorTarget->IsExecutableWithExports()) {
- std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
- export_flag_var += linkLanguage;
- export_flag_var += "_FLAG";
+ std::string export_flag_var =
+ cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG");
this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetDefinition(export_flag_var));
+ linkFlags, this->Makefile->GetSafeDefinition(export_flag_var));
}
this->LocalGenerator->AppendFlags(linkFlags,
@@ -163,7 +163,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
const std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE";
const std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ cmExpandList(linkRule, real_link_commands);
bool useResponseFileForObjects =
this->CheckUseResponseFileForObjects(linkLanguage);
@@ -232,8 +232,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -242,7 +241,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -295,14 +294,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
if (this->GeneratorTarget->IsAppBundleOnApple()) {
this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath);
}
- outpath += "/";
+ outpath += '/';
std::string outpathImp;
if (relink) {
- outpath = this->Makefile->GetCurrentBinaryDirectory();
- outpath += "/CMakeFiles";
- outpath += "/CMakeRelink.dir";
+ outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeRelink.dir");
cmSystemTools::MakeDirectory(outpath);
- outpath += "/";
+ outpath += '/';
if (!targetNames.ImportLibrary.empty()) {
outpathImp = outpath;
}
@@ -312,7 +310,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
outpathImp = this->GeneratorTarget->GetDirectory(
this->ConfigName, cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
- outpathImp += "/";
+ outpathImp += '/';
}
}
@@ -323,7 +321,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string pdbOutputPath =
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(pdbOutputPath);
- pdbOutputPath += "/";
+ pdbOutputPath += '/';
std::string targetFullPath = outpath + targetNames.Output;
std::string targetFullPathReal = outpath + targetNames.Real;
@@ -370,10 +368,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmLocalUnixMakefileGenerator3::EchoProgress progress;
this->MakeEchoProgress(progress);
// Add the link message.
- std::string buildEcho = "Linking ";
- buildEcho += linkLanguage;
- buildEcho += " executable ";
- buildEcho += targetOutPath;
+ std::string buildEcho =
+ cmStrCat("Linking ", linkLanguage, " executable ", targetOutPath);
this->LocalGenerator->AppendEcho(
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
}
@@ -388,19 +384,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE"));
+ linkFlags, this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"));
} else {
this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetDefinition("CMAKE_CREATE_CONSOLE_EXE"));
+ linkFlags,
+ this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"));
}
// Add symbol export flags if necessary.
if (this->GeneratorTarget->IsExecutableWithExports()) {
- std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
- export_flag_var += linkLanguage;
- export_flag_var += "_FLAG";
+ std::string export_flag_var =
+ cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG");
this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetDefinition(export_flag_var));
+ linkFlags, this->Makefile->GetSafeDefinition(export_flag_var));
}
this->LocalGenerator->AppendFlags(linkFlags,
@@ -482,20 +478,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Construct the main link rule.
std::vector<std::string> real_link_commands;
- std::string linkRuleVar = "CMAKE_";
- linkRuleVar += linkLanguage;
- linkRuleVar += "_LINK_EXECUTABLE";
+ std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
+ linkLanguage, this->ConfigName);
std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ cmExpandList(linkRule, real_link_commands);
if (this->GeneratorTarget->IsExecutableWithExports()) {
// If a separate rule for creating an import library is specified
// add it now.
- std::string implibRuleVar = "CMAKE_";
- implibRuleVar += linkLanguage;
- implibRuleVar += "_CREATE_IMPORT_LIBRARY";
+ std::string implibRuleVar =
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY");
if (const char* rule = this->Makefile->GetDefinition(implibRuleVar)) {
- cmSystemTools::ExpandListArgument(rule, real_link_commands);
+ cmExpandList(rule, real_link_commands);
}
}
@@ -590,10 +584,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Manifests = manifests.c_str();
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand = this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- cmakeCommand += " -E __run_co_compile --lwyu=";
- cmakeCommand += targetOutPathReal;
+ std::string cmakeCommand =
+ cmStrCat(this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=", targetOutPathReal);
real_link_commands.push_back(std::move(cmakeCommand));
}
@@ -602,8 +596,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -612,7 +605,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -639,10 +632,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add a rule to create necessary symlinks for the library.
if (targetOutPath != targetOutPathReal) {
- std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable ";
- symlink += targetOutPathReal;
- symlink += " ";
- symlink += targetOutPath;
+ std::string symlink =
+ cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_executable ",
+ targetOutPathReal, ' ', targetOutPath);
commands1.push_back(std::move(symlink));
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index b9f7c6d13..54a66065c 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -2,13 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileLibraryTargetGenerator.h"
-#include <memory> // IWYU pragma: keep
+#include <cstddef>
#include <set>
#include <sstream>
-#include <stddef.h>
#include <utility>
#include <vector>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -25,6 +26,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
@@ -161,9 +163,8 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
std::string linkLanguage =
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- std::string linkRuleVar = "CMAKE_";
- linkRuleVar += linkLanguage;
- linkRuleVar += "_CREATE_SHARED_LIBRARY";
+ std::string linkRuleVar =
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
@@ -196,9 +197,8 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
std::string linkLanguage =
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- std::string linkRuleVar = "CMAKE_";
- linkRuleVar += linkLanguage;
- linkRuleVar += "_CREATE_SHARED_MODULE";
+ std::string linkRuleVar =
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
@@ -219,9 +219,8 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
std::string linkLanguage =
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- std::string linkRuleVar = "CMAKE_";
- linkRuleVar += linkLanguage;
- linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
+ std::string linkRuleVar =
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
@@ -234,7 +233,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
const std::string& linkRuleVar, bool relink)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// TODO: Merge the methods that call this method to avoid
// code duplication.
std::vector<std::string> commands;
@@ -262,12 +261,13 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
cmLocalUnixMakefileGenerator3::EchoProgress progress;
this->MakeEchoProgress(progress);
// Add the link message.
- std::string buildEcho = "Linking " + linkLanguage + " device code ";
- buildEcho += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(),
- this->DeviceLinkObject),
- cmOutputConverter::SHELL);
+ std::string buildEcho =
+ cmStrCat("Linking ", linkLanguage, " device code ",
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ this->DeviceLinkObject),
+ cmOutputConverter::SHELL));
this->LocalGenerator->AppendEcho(
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
}
@@ -298,19 +298,16 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
// Collect up flags to link in needed libraries.
std::string linkLibs;
- if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ new cmLinkLineDeviceComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ linkLineComputer->SetForResponse(useResponseFileForLibs);
+ linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetRelink(relink);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
- new cmLinkLineDeviceComputer(
- this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
- linkLineComputer->SetForResponse(useResponseFileForLibs);
- linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
- linkLineComputer->SetRelink(relink);
-
- this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
- useResponseFileForLibs, depends);
- }
+ this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
+ useResponseFileForLibs, depends);
// Construct object file lists that may be needed to expand the
// rule.
@@ -358,8 +355,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -368,11 +364,11 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ cmExpandList(linkRule, real_link_commands);
// Expand placeholders.
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -463,30 +459,29 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
outpath);
- outpath += "/";
+ outpath += '/';
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
outpath);
- outpath += "/";
+ outpath += '/';
} else if (relink) {
- outpath = this->Makefile->GetCurrentBinaryDirectory();
- outpath += "/CMakeFiles";
- outpath += "/CMakeRelink.dir";
+ outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
+ "/CMakeFiles/CMakeRelink.dir");
cmSystemTools::MakeDirectory(outpath);
- outpath += "/";
+ outpath += '/';
if (!this->TargetNames.ImportLibrary.empty()) {
outpathImp = outpath;
}
} else {
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(outpath);
- outpath += "/";
+ outpath += '/';
if (!this->TargetNames.ImportLibrary.empty()) {
outpathImp = this->GeneratorTarget->GetDirectory(
this->ConfigName, cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
- outpathImp += "/";
+ outpathImp += '/';
}
}
@@ -535,8 +530,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmLocalUnixMakefileGenerator3::EchoProgress progress;
this->MakeEchoProgress(progress);
// Add the link message.
- std::string buildEcho = "Linking ";
- buildEcho += linkLanguage;
+ std::string buildEcho = cmStrCat("Linking ", linkLanguage);
switch (this->GeneratorTarget->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
buildEcho += " static library ";
@@ -640,35 +634,32 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string::size_type archiveCommandLimit = std::string::npos;
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
haveStaticLibraryRule = this->Makefile->IsDefinitionSet(linkRuleVar);
- std::string arCreateVar = "CMAKE_";
- arCreateVar += linkLanguage;
- arCreateVar += "_ARCHIVE_CREATE";
+ std::string arCreateVar =
+ cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arCreateVar, linkLanguage, this->ConfigName);
if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
- cmSystemTools::ExpandListArgument(rule, archiveCreateCommands);
+ cmExpandList(rule, archiveCreateCommands);
}
- std::string arAppendVar = "CMAKE_";
- arAppendVar += linkLanguage;
- arAppendVar += "_ARCHIVE_APPEND";
+ std::string arAppendVar =
+ cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arAppendVar, linkLanguage, this->ConfigName);
if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
- cmSystemTools::ExpandListArgument(rule, archiveAppendCommands);
+ cmExpandList(rule, archiveAppendCommands);
}
- std::string arFinishVar = "CMAKE_";
- arFinishVar += linkLanguage;
- arFinishVar += "_ARCHIVE_FINISH";
+ std::string arFinishVar =
+ cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arFinishVar, linkLanguage, this->ConfigName);
if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
- cmSystemTools::ExpandListArgument(rule, archiveFinishCommands);
+ cmExpandList(rule, archiveFinishCommands);
}
}
@@ -820,8 +811,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -844,7 +834,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Create the archive with the first set of objects.
- std::vector<std::string>::iterator osi = object_strings.begin();
+ auto osi = object_strings.begin();
{
vars.Objects = osi->c_str();
for (std::string const& acc : archiveCreateCommands) {
@@ -878,19 +868,19 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
} else {
// Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ cmExpandList(linkRule, real_link_commands);
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
(this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) {
- std::string cmakeCommand = this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- cmakeCommand += " -E __run_co_compile --lwyu=";
- cmakeCommand += targetOutPathReal;
+ std::string cmakeCommand = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=", targetOutPathReal);
real_link_commands.push_back(std::move(cmakeCommand));
}
// Expand placeholders.
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -920,12 +910,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Frameworks are handled by cmOSXBundleGenerator.
if (targetOutPath != targetOutPathReal &&
!this->GeneratorTarget->IsFrameworkOnApple()) {
- std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
- symlink += targetOutPathReal;
- symlink += " ";
- symlink += targetOutPathSO;
- symlink += " ";
- symlink += targetOutPath;
+ std::string symlink =
+ cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_library ", targetOutPathReal,
+ ' ', targetOutPathSO, ' ', targetOutPath);
commands1.push_back(std::move(symlink));
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 35e43277d..ca22b099d 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmMakefileTargetGenerator.h"
-
#include <string>
+#include "cmMakefileTargetGenerator.h"
+
class cmGeneratorTarget;
class cmMakefileLibraryTargetGenerator : public cmMakefileTargetGenerator
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index b3bab4b08..767f4e0aa 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileTargetGenerator.h"
-#include <memory> // IWYU pragma: keep
+#include <cstdio>
+#include <memory>
#include <sstream>
-#include <stdio.h>
#include <utility>
#include "cmAlgorithms.h"
@@ -15,6 +15,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalCommonGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmMakefileExecutableTargetGenerator.h"
@@ -28,6 +29,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -48,7 +50,7 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
this->NoRuleMessages = false;
if (const char* ruleStatus =
cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
- this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
+ this->NoRuleMessages = cmIsOff(ruleStatus);
}
MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
}
@@ -87,12 +89,12 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
std::string& flags, const std::string& linkLanguage)
{
this->LocalGenerator->AppendFlags(
- flags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
+ flags, this->GeneratorTarget->GetSafeProperty("LINK_FLAGS"));
- std::string linkFlagsConfig = "LINK_FLAGS_";
- linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ std::string linkFlagsConfig =
+ cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName));
this->LocalGenerator->AppendFlags(
- flags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+ flags, this->GeneratorTarget->GetSafeProperty(linkFlagsConfig));
std::vector<std::string> opts;
this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
@@ -113,14 +115,13 @@ void cmMakefileTargetGenerator::CreateRuleFile()
cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull);
// Construct the rule file name.
- this->BuildFileName = this->TargetBuildDirectory;
- this->BuildFileName += "/build.make";
- this->BuildFileNameFull = this->TargetBuildDirectoryFull;
- this->BuildFileNameFull += "/build.make";
+ this->BuildFileName = cmStrCat(this->TargetBuildDirectory, "/build.make");
+ this->BuildFileNameFull =
+ cmStrCat(this->TargetBuildDirectoryFull, "/build.make");
// Construct the rule file name.
- this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
- this->ProgressFileNameFull += "/progress.make";
+ this->ProgressFileNameFull =
+ cmStrCat(this->TargetBuildDirectoryFull, "/progress.make");
// reset the progress count
this->NumberOfProgressActions = 0;
@@ -130,10 +131,10 @@ void cmMakefileTargetGenerator::CreateRuleFile()
this->BuildFileStream =
new cmGeneratedFileStream(this->BuildFileNameFull, false,
this->GlobalGenerator->GetMakefileEncoding());
- this->BuildFileStream->SetCopyIfDifferent(true);
if (!this->BuildFileStream) {
return;
}
+ this->BuildFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
if (this->GlobalGenerator->AllowDeleteOnError()) {
std::vector<std::string> no_depends;
@@ -149,18 +150,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
// -- Write the custom commands for this target
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-
// Evaluates generator expressions and expands prop_value
auto evaluatedFiles =
- [this, &config](const char* prop_value) -> std::vector<std::string> {
+ [this](const char* prop_value) -> std::vector<std::string> {
std::vector<std::string> files;
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(this->LocalGenerator, config, false, this->GeneratorTarget,
- nullptr, nullptr),
+ cmExpandList(
+ cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator,
+ this->ConfigName, this->GeneratorTarget),
files);
return files;
};
@@ -186,12 +182,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// add custom commands to the clean rules?
const char* clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
- bool clean = cmSystemTools::IsOff(clean_no_custom);
+ bool clean = cmIsOff(clean_no_custom);
// First generate the object rule files. Save a list of all object
// files for this target.
std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (cmSourceFile const* sf : customCommands) {
@@ -224,7 +220,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->GeneratorTarget->GetPostBuildCommands());
for (const auto& be : buildEventCommands) {
- const std::vector<std::string>& byproducts = be.GetByproducts();
+ cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator);
+ const std::vector<std::string>& byproducts = beg.GetByproducts();
for (std::string const& byproduct : byproducts) {
this->CleanFiles.insert(
this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir,
@@ -233,20 +230,25 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, config);
+ this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
headerSources, this->MacOSXContentGenerator);
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, config);
+ this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
extraSources, this->MacOSXContentGenerator);
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects, config);
+ this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName);
for (cmSourceFile const* sf : externalObjects) {
- this->ExternalObjects.push_back(sf->GetFullPath());
+ auto const& objectFileName = sf->GetFullPath();
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ this->ExternalObjects.push_back(objectFileName);
+ }
}
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, config);
+ this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
for (cmSourceFile const* sf : objectSources) {
// Generate this object file's rule file.
this->WriteObjectRuleFiles(*sf);
@@ -260,8 +262,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
: "");
// Include the dependencies for the target.
- std::string dependFileNameFull = this->TargetBuildDirectoryFull;
- dependFileNameFull += "/depend.make";
+ std::string dependFileNameFull =
+ cmStrCat(this->TargetBuildDirectoryFull, "/depend.make");
*this->BuildFileStream
<< "# Include any dependencies generated for this target.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
@@ -295,15 +297,15 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// Open the flags file. This should be copy-if-different because the
// rules may depend on this file itself.
- this->FlagFileNameFull = this->TargetBuildDirectoryFull;
- this->FlagFileNameFull += "/flags.make";
+ this->FlagFileNameFull =
+ cmStrCat(this->TargetBuildDirectoryFull, "/flags.make");
this->FlagFileStream =
new cmGeneratedFileStream(this->FlagFileNameFull, false,
this->GlobalGenerator->GetMakefileEncoding());
- this->FlagFileStream->SetCopyIfDifferent(true);
if (!this->FlagFileStream) {
return;
}
+ this->FlagFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream);
// Include the flags for the target.
@@ -325,9 +327,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// put the compiler in the rules.make file so that if it changes
// things rebuild
for (std::string const& language : languages) {
- std::string compiler = "CMAKE_";
- compiler += language;
- compiler += "_COMPILER";
+ std::string compiler = cmStrCat("CMAKE_", language, "_COMPILER");
*this->FlagFileStream << "# compile " << language << " with "
<< this->Makefile->GetSafeDefinition(compiler)
<< "\n";
@@ -362,9 +362,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
std::string const& input = source.GetFullPath();
// Get the output file location.
- std::string output = macdir;
- output += "/";
- output += cmSystemTools::GetFilenameName(input);
+ std::string output =
+ cmStrCat(macdir, '/', cmSystemTools::GetFilenameName(input));
this->Generator->CleanFiles.insert(
this->Generator->LocalGenerator->MaybeConvertToRelativePath(
this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output));
@@ -375,16 +374,16 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
std::vector<std::string> depends;
std::vector<std::string> commands;
depends.push_back(input);
- std::string copyEcho = "Copying OS X content ";
- copyEcho += output;
+ std::string copyEcho = cmStrCat("Copying OS X content ", output);
this->Generator->LocalGenerator->AppendEcho(
commands, copyEcho, cmLocalUnixMakefileGenerator3::EchoBuild);
- std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
- copyCommand += this->Generator->LocalGenerator->ConvertToOutputFormat(
- input, cmOutputConverter::SHELL);
- copyCommand += " ";
- copyCommand += this->Generator->LocalGenerator->ConvertToOutputFormat(
- output, cmOutputConverter::SHELL);
+ std::string copyCommand =
+ cmStrCat("$(CMAKE_COMMAND) -E copy ",
+ this->Generator->LocalGenerator->ConvertToOutputFormat(
+ input, cmOutputConverter::SHELL),
+ ' ',
+ this->Generator->LocalGenerator->ConvertToOutputFormat(
+ output, cmOutputConverter::SHELL));
commands.push_back(std::move(copyCommand));
this->Generator->LocalGenerator->WriteMakeRule(
*this->Generator->BuildFileStream, nullptr, output, depends, commands,
@@ -407,9 +406,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string const& objectName =
this->GeneratorTarget->GetObjectName(&source);
std::string obj =
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- obj += "/";
- obj += objectName;
+ cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ '/', objectName);
// Avoid generating duplicate rules.
if (this->ObjectFiles.find(obj) == this->ObjectFiles.end()) {
@@ -425,40 +423,26 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Create the directory containing the object file. This may be a
// subdirectory under the target's directory.
- std::string dir = cmSystemTools::GetFilenamePath(obj);
- cmSystemTools::MakeDirectory(this->LocalGenerator->ConvertToFullPath(dir));
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(obj);
+ cmSystemTools::MakeDirectory(this->LocalGenerator->ConvertToFullPath(dir));
+ }
// Save this in the target's list of object files.
this->Objects.push_back(obj);
this->CleanFiles.insert(obj);
- // TODO: Remove
- // std::string relativeObj
- //= this->LocalGenerator->GetHomeRelativeOutputPath();
- // relativeObj += obj;
-
- // we compute some depends when writing the depend.make that we will also
- // use in the build.make, same with depMakeFile
std::vector<std::string> depends;
- // generate the build rule file
- this->WriteObjectBuildFile(obj, lang, source, depends);
-
// The object file should be checked for dependency integrity.
- std::string objFullPath = this->LocalGenerator->GetCurrentBinaryDirectory();
- objFullPath += "/";
- objFullPath += obj;
+ std::string objFullPath =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj);
objFullPath = cmSystemTools::CollapseFullPath(objFullPath);
std::string srcFullPath =
cmSystemTools::CollapseFullPath(source.GetFullPath());
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
objFullPath, srcFullPath);
-}
-void cmMakefileTargetGenerator::WriteObjectBuildFile(
- std::string& obj, const std::string& lang, cmSourceFile const& source,
- std::vector<std::string>& depends)
-{
this->LocalGenerator->AppendRuleDepend(depends,
this->FlagFileNameFull.c_str());
this->LocalGenerator->AppendRuleDepends(depends,
@@ -467,21 +451,34 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// generate the depend scanning rule
this->WriteObjectDependRules(source, depends);
- std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
- relativeObj += obj;
+ std::string config = this->LocalGenerator->GetConfigName();
+ 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));
+ }
+ this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
+ objFullPath, pchHeader);
+ }
+
+ std::string relativeObj =
+ cmStrCat(this->LocalGenerator->GetHomeRelativeOutputPath(), obj);
// Write the build rule.
// Build the set of compiler flags.
std::string flags;
// Add language-specific flags.
- std::string langFlags = "$(";
- langFlags += lang;
- langFlags += "_FLAGS)";
+ std::string langFlags = cmStrCat("$(", lang, "_FLAGS)");
this->LocalGenerator->AppendFlags(flags, langFlags);
- std::string config = this->LocalGenerator->GetConfigName();
- std::string configUpper = cmSystemTools::UpperCase(config);
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, config, this->GeneratorTarget, lang);
@@ -511,6 +508,26 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
<< "\n";
}
+ // Add precompile headers compile options.
+ if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ std::string pchOptions;
+ if (source.GetFullPath() == pchSource) {
+ pchOptions =
+ this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+ } else {
+ pchOptions =
+ this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
+ }
+
+ const std::string& evaluatedFlags =
+ genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS);
+
+ this->LocalGenerator->AppendCompileOptions(flags, evaluatedFlags);
+ *this->FlagFileStream << "# PCH options: " << relativeObj
+ << "_OPTIONS = " << evaluatedFlags << "\n"
+ << "\n";
+ }
+
// Add include directories from source file properties.
std::vector<std::string> includes;
@@ -539,8 +556,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
<< "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += configUpper;
+ std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
if (const char* config_compile_defs = source.GetProperty(defPropName)) {
const std::string& evaluatedDefs =
genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS);
@@ -564,10 +580,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
if (!this->NoRuleMessages) {
cmLocalUnixMakefileGenerator3::EchoProgress progress;
this->MakeEchoProgress(progress);
- std::string buildEcho = "Building ";
- buildEcho += lang;
- buildEcho += " object ";
- buildEcho += relativeObj;
+ std::string buildEcho =
+ cmStrCat("Building ", lang, " object ", relativeObj);
this->LocalGenerator->AppendEcho(commands, buildEcho,
cmLocalUnixMakefileGenerator3::EchoBuild,
&progress);
@@ -587,9 +601,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
targetFullPathReal = this->GeneratorTarget->GetFullPath(
this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true);
targetFullPathPDB =
- this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
- targetFullPathPDB += "/";
- targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
+ cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/',
+ this->GeneratorTarget->GetPDBName(this->ConfigName));
}
targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
@@ -638,9 +651,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
vars.ObjectFileDir = objectFileDir.c_str();
vars.Flags = flags.c_str();
- std::string definesString = "$(";
- definesString += lang;
- definesString += "_DEFINES)";
+ std::string definesString = cmStrCat("$(", lang, "_DEFINES)");
this->LocalGenerator->JoinDefines(defines, definesString, lang);
@@ -679,12 +690,12 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
}
const std::string& compileRule =
this->Makefile->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileRule, compileCommands);
+ cmExpandList(compileRule, compileCommands);
} else {
const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
const std::string& compileRule =
this->Makefile->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileRule, compileCommands);
+ cmExpandList(compileRule, compileCommands);
}
if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
@@ -781,8 +792,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCommands.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(compilerLauncher, args, true);
+ std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -798,14 +808,13 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_COMPILE");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
}
// Expand placeholders in the commands.
for (std::string& compileCommand : compileCommands) {
- compileCommand = launcher + compileCommand;
+ compileCommand = cmStrCat(launcher, compileCommand);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCommand, vars);
}
@@ -821,7 +830,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
std::vector<std::string> outputs(1, relativeObj);
if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
// Register these as extra files to clean.
- cmSystemTools::ExpandListArgument(extra_outputs_str, outputs);
+ cmExpandList(extra_outputs_str, outputs);
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
@@ -846,20 +855,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
std::string relativeObjI = relativeObjBase + ".i";
std::string objI = objBase + ".i";
- std::string preprocessEcho = "Preprocessing ";
- preprocessEcho += lang;
- preprocessEcho += " source to ";
- preprocessEcho += objI;
+ std::string preprocessEcho =
+ cmStrCat("Preprocessing ", lang, " source to ", objI);
this->LocalGenerator->AppendEcho(
commands, preprocessEcho, cmLocalUnixMakefileGenerator3::EchoBuild);
- std::string preprocessRuleVar = "CMAKE_";
- preprocessRuleVar += lang;
- preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
+ std::string preprocessRuleVar =
+ cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE");
if (const char* preprocessRule =
this->Makefile->GetDefinition(preprocessRuleVar)) {
- std::vector<std::string> preprocessCommands;
- cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
+ std::vector<std::string> preprocessCommands =
+ cmExpandedList(preprocessRule);
std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat(
objI, cmOutputConverter::SHELL);
@@ -878,8 +884,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
this->LocalGenerator->GetBinaryDirectory());
cmAppend(commands, preprocessCommands);
} else {
- std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
- cmd += preprocessRuleVar;
+ std::string cmd =
+ cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
+ preprocessRuleVar);
commands.push_back(std::move(cmd));
}
@@ -893,20 +900,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
std::string relativeObjS = relativeObjBase + ".s";
std::string objS = objBase + ".s";
- std::string assemblyEcho = "Compiling ";
- assemblyEcho += lang;
- assemblyEcho += " source to assembly ";
- assemblyEcho += objS;
+ std::string assemblyEcho =
+ cmStrCat("Compiling ", lang, " source to assembly ", objS);
this->LocalGenerator->AppendEcho(
commands, assemblyEcho, cmLocalUnixMakefileGenerator3::EchoBuild);
- std::string assemblyRuleVar = "CMAKE_";
- assemblyRuleVar += lang;
- assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
+ std::string assemblyRuleVar =
+ cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE");
if (const char* assemblyRule =
this->Makefile->GetDefinition(assemblyRuleVar)) {
- std::vector<std::string> assemblyCommands;
- cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
+ std::vector<std::string> assemblyCommands =
+ cmExpandedList(assemblyRule);
std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat(
objS, cmOutputConverter::SHELL);
@@ -924,8 +928,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
this->LocalGenerator->GetBinaryDirectory());
cmAppend(commands, assemblyCommands);
} else {
- std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
- cmd += assemblyRuleVar;
+ std::string cmd =
+ cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
+ assemblyRuleVar);
commands.push_back(std::move(cmd));
}
@@ -942,9 +947,9 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
std::vector<std::string> commands;
// Construct the clean target name.
- std::string cleanTarget =
- this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
- cleanTarget += "/clean";
+ std::string cleanTarget = cmStrCat(
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget),
+ "/clean");
// Construct the clean command.
this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles,
@@ -1028,15 +1033,14 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// must write the targets depend info file
std::string dir =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- this->InfoFileNameFull = dir;
- this->InfoFileNameFull += "/DependInfo.cmake";
+ this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake");
this->InfoFileNameFull =
this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull);
- this->InfoFileStream->SetCopyIfDifferent(true);
- if (!*this->InfoFileStream) {
+ if (!this->InfoFileStream) {
return;
}
+ this->InfoFileStream->SetCopyIfDifferent(true);
this->LocalGenerator->WriteDependLanguageInfo(*this->InfoFileStream,
this->GeneratorTarget);
@@ -1088,9 +1092,9 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
std::vector<std::string> commands;
// Construct the name of the dependency generation target.
- std::string depTarget =
- this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
- depTarget += "/depend";
+ std::string depTarget = cmStrCat(
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget),
+ "/depend");
// Add a command to call CMake to scan dependencies. CMake will
// touch the corresponding depends file after scanning dependencies.
@@ -1181,7 +1185,7 @@ void cmMakefileTargetGenerator::WriteObjectDependRules(
// shared between the object file and dependency scanning rule.
depends.push_back(source.GetFullPath());
if (const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
- cmSystemTools::ExpandListArgument(objectDeps, depends);
+ cmExpandList(objectDeps, depends);
}
}
@@ -1235,8 +1239,8 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
void cmMakefileTargetGenerator::MakeEchoProgress(
cmLocalUnixMakefileGenerator3::EchoProgress& progress) const
{
- progress.Dir = this->LocalGenerator->GetBinaryDirectory();
- progress.Dir += "/CMakeFiles";
+ progress.Dir =
+ cmStrCat(this->LocalGenerator->GetBinaryDirectory(), "/CMakeFiles");
std::ostringstream progressArg;
progressArg << "$(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
progress.Arg = progressArg.str();
@@ -1259,7 +1263,14 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
if (!lineContinue) {
lineContinue = "\\";
}
+
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
+
for (std::string const& obj : this->Objects) {
+ if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
+ continue;
+ }
*this->BuildFileStream << " " << lineContinue << "\n";
*this->BuildFileStream
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
@@ -1352,10 +1363,16 @@ private:
void cmMakefileTargetGenerator::WriteObjectsStrings(
std::vector<std::string>& objStrings, std::string::size_type limit)
{
+ const char* pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
+
cmMakefileTargetGeneratorObjectStrings helper(
objStrings, this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit);
for (std::string const& obj : this->Objects) {
+ if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
+ continue;
+ }
helper.Feed(obj);
}
for (std::string const& obj : this->ExternalObjects) {
@@ -1370,8 +1387,8 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
// Compute the name of the driver target.
std::string dir =
this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
- std::string buildTargetRuleName = dir;
- buildTargetRuleName += relink ? "/preinstall" : "/build";
+ std::string buildTargetRuleName =
+ cmStrCat(dir, relink ? "/preinstall" : "/build");
buildTargetRuleName = this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(), buildTargetRuleName);
@@ -1426,8 +1443,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends(
std::string const& relPath =
this->LocalGenerator->GetHomeRelativeOutputPath();
for (std::string const& obj : this->Objects) {
- std::string objTarget = relPath;
- objTarget += obj;
+ std::string objTarget = cmStrCat(relPath, obj);
depends.push_back(std::move(objTarget));
}
@@ -1473,9 +1489,9 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = "CMAKE_";
- ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- ruleVar += "_GNUtoMS_RULE";
+ std::string ruleVar = cmStrCat(
+ "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkRule += rule;
}
@@ -1496,9 +1512,8 @@ void cmMakefileTargetGenerator::CreateLinkScript(
std::vector<std::string>& makefile_depends)
{
// Create the link script file.
- std::string linkScriptName = this->TargetBuildDirectoryFull;
- linkScriptName += "/";
- linkScriptName += name;
+ std::string linkScriptName =
+ cmStrCat(this->TargetBuildDirectoryFull, '/', name);
cmGeneratedFileStream linkScriptStream(linkScriptName);
linkScriptStream.SetCopyIfDifferent(true);
for (std::string const& link_command : link_commands) {
@@ -1510,12 +1525,13 @@ void cmMakefileTargetGenerator::CreateLinkScript(
}
// Create the makefile command to invoke the link script.
- std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
- link_command += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName),
- cmOutputConverter::SHELL);
- link_command += " --verbose=$(VERBOSE)";
+ std::string link_command = cmStrCat(
+ "$(CMAKE_COMMAND) -E cmake_link_script ",
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName),
+ cmOutputConverter::SHELL),
+ " --verbose=$(VERBOSE)");
makefile_commands.push_back(std::move(link_command));
makefile_depends.push_back(std::move(linkScriptName));
}
@@ -1528,7 +1544,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
"CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_OBJECTS";
if (const char* val = this->Makefile->GetDefinition(responseVar)) {
if (*val) {
- return cmSystemTools::IsOn(val);
+ return cmIsOn(val);
}
}
@@ -1567,7 +1583,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries(
"CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES";
if (const char* val = this->Makefile->GetDefinition(responseVar)) {
if (*val) {
- return cmSystemTools::IsOn(val);
+ return cmIsOn(val);
}
}
@@ -1580,9 +1596,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
std::vector<std::string>& makefile_depends)
{
// Create the response file.
- std::string responseFileNameFull = this->TargetBuildDirectoryFull;
- responseFileNameFull += "/";
- responseFileNameFull += name;
+ std::string responseFileNameFull =
+ cmStrCat(this->TargetBuildDirectoryFull, '/', name);
cmGeneratedFileStream responseStream(responseFileNameFull);
responseStream.SetCopyIfDifferent(true);
responseStream << options << "\n";
@@ -1592,9 +1607,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
makefile_depends.push_back(std::move(responseFileNameFull));
// Construct the name to be used on the command line.
- std::string responseFileName = this->TargetBuildDirectory;
- responseFileName += "/";
- responseFileName += name;
+ std::string responseFileName =
+ cmStrCat(this->TargetBuildDirectory, '/', name);
return responseFileName;
}
@@ -1615,10 +1629,8 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
{
std::string frameworkPath;
std::string linkPath;
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmComputeLinkInformation* pcli =
- this->GeneratorTarget->GetLinkInformation(config);
+ this->GeneratorTarget->GetLinkInformation(this->ConfigName);
this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
linkLibs = frameworkPath + linkPath + linkLibs;
@@ -1626,10 +1638,9 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
if (useResponseFile &&
linkLibs.find_first_not_of(' ') != std::string::npos) {
// Lookup the response file reference flag.
- std::string responseFlagVar = "CMAKE_";
- responseFlagVar +=
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
+ std::string responseFlagVar = cmStrCat(
+ "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1640,9 +1651,9 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends);
// Reference the response file.
- linkLibs = responseFlag;
- linkLibs += this->LocalGenerator->ConvertToOutputFormat(
- link_rsp, cmOutputConverter::SHELL);
+ linkLibs = cmStrCat(responseFlag,
+ this->LocalGenerator->ConvertToOutputFormat(
+ link_rsp, cmOutputConverter::SHELL));
}
}
@@ -1664,10 +1675,9 @@ void cmMakefileTargetGenerator::CreateObjectLists(
this->WriteObjectsStrings(object_strings, responseFileLimit);
// Lookup the response file reference flag.
- std::string responseFlagVar = "CMAKE_";
- responseFlagVar +=
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
+ std::string responseFlagVar = cmStrCat(
+ "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1700,30 +1710,25 @@ void cmMakefileTargetGenerator::CreateObjectLists(
buildObjs = objStrings[0];
}
} else {
- buildObjs = "$(";
- buildObjs += variableName;
- buildObjs += ") $(";
- buildObjs += variableNameExternal;
- buildObjs += ")";
+ buildObjs =
+ cmStrCat("$(", variableName, ") $(", variableNameExternal, ')');
}
}
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
const std::string& lang)
{
- std::string responseVar = "CMAKE_";
- responseVar += lang;
- responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
+ std::string responseVar =
+ cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES");
bool useResponseFile = this->Makefile->IsOn(responseVar);
std::vector<std::string> includes;
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- lang, config);
+ lang, this->ConfigName);
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
- includes, this->GeneratorTarget, lang, false, useResponseFile, config);
+ includes, this->GeneratorTarget, lang, false, useResponseFile,
+ this->ConfigName);
if (includeFlags.empty()) {
return;
}
@@ -1736,9 +1741,7 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
if (responseFlag.empty()) {
responseFlag = "@";
}
- std::string name = "includes_";
- name += lang;
- name += ".rsp";
+ std::string name = cmStrCat("includes_", lang, ".rsp");
std::string arg = std::move(responseFlag) +
this->CreateResponseFile(name.c_str(), includeFlags,
this->FlagFileDepends[lang]);
@@ -1757,19 +1760,25 @@ void cmMakefileTargetGenerator::GenDefFile(
return;
}
std::string cmd = cmSystemTools::GetCMakeCommand();
- cmd =
- this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL);
- cmd += " -E __create_def ";
- cmd += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile),
- cmOutputConverter::SHELL);
- cmd += " ";
+ cmd = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL),
+ " -E __create_def ",
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile),
+ cmOutputConverter::SHELL),
+ ' ');
std::string objlist_file = mdi->DefFile + ".objs";
cmd += this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
cmOutputConverter::SHELL);
+ const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM");
+ if (nm_executable && *nm_executable) {
+ cmd += " --nm=";
+ cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
+ nm_executable, cmOutputConverter::SHELL);
+ }
real_link_commands.insert(real_link_commands.begin(), cmd);
// create a list of obj files for the -E __create_def to read
cmGeneratedFileStream fout(objlist_file);
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index c570a7ccf..7b9c7a5ff 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -7,6 +7,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -90,11 +91,6 @@ protected:
// write the rules for an object
void WriteObjectRuleFiles(cmSourceFile const& source);
- // write the build rule for an object
- void WriteObjectBuildFile(std::string& obj, const std::string& lang,
- cmSourceFile const& source,
- std::vector<std::string>& depends);
-
// write the depend.make file for an object
void WriteObjectDependRules(cmSourceFile const& source,
std::vector<std::string>& depends);
@@ -222,7 +218,7 @@ protected:
// Set of extra output files to be driven by the build.
std::set<std::string> ExtraFiles;
- typedef std::map<std::string, std::string> MultipleOutputPairsType;
+ using MultipleOutputPairsType = std::map<std::string, std::string>;
MultipleOutputPairsType MultipleOutputPairs;
bool WriteMakeRule(std::ostream& os, const char* comment,
const std::vector<std::string>& outputs,
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 42369954c..1625e4fdb 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -7,7 +7,8 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 45c59b999..ca46e14c2 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -2,20 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMarkAsAdvancedCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmake.h"
-class cmExecutionStatus;
-
// cmMarkAsAdvancedCommand
-bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -31,9 +30,9 @@ bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args,
}
for (; i < args.size(); ++i) {
std::string const& variable = args[i];
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
if (!state->GetCacheEntryValue(variable)) {
- this->Makefile->GetCMakeInstance()->AddCacheEntry(
+ status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
overwrite = true;
}
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index 5dd198f62..de7bf08b4 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmMarkAsAdvancedCommand
+/**
* \brief mark_as_advanced command
*
* cmMarkAsAdvancedCommand implements the mark_as_advanced CMake command
*/
-class cmMarkAsAdvancedCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmMarkAsAdvancedCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index 48b9a27ad..f11b906d4 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -2,35 +2,42 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMathCommand.h"
+#include <cstdio>
+
+#include "cm_kwiml.h"
+
+#include "cmExecutionStatus.h"
#include "cmExprParserHelper.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
-#include "cm_kwiml.h"
-#include <stdio.h>
-
-class cmExecutionStatus;
+namespace {
+bool HandleExprCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+}
-bool cmMathCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmMathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("must be called with at least one argument.");
+ status.SetError("must be called with at least one argument.");
return false;
}
const std::string& subCommand = args[0];
if (subCommand == "EXPR") {
- return this->HandleExprCommand(args);
+ return HandleExprCommand(args, status);
}
std::string e = "does not recognize sub-command " + subCommand;
- this->SetError(e);
+ status.SetError(e);
return false;
}
-bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
+namespace {
+bool HandleExprCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if ((args.size() != 3) && (args.size() != 5)) {
- this->SetError("EXPR called with incorrect arguments.");
+ status.SetError("EXPR called with incorrect arguments.");
return false;
}
@@ -46,7 +53,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
size_t argumentIndex = 3;
NumericFormat outputFormat = NumericFormat::UNINITIALIZED;
- this->Makefile->AddDefinition(outputVariable, "ERROR");
+ status.GetMakefile().AddDefinition(outputVariable, "ERROR");
if (argumentIndex < args.size()) {
const std::string messageHint = "sub-command EXPR ";
@@ -61,19 +68,19 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
} else {
std::string error = messageHint + "value \"" + argument +
"\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ status.SetError(error);
return false;
}
} else {
std::string error =
messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ status.SetError(error);
return false;
}
} else {
std::string error =
messageHint + "option \"" + option + "\" is unknown.";
- this->SetError(error);
+ status.SetError(error);
return false;
}
}
@@ -84,7 +91,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
cmExprParserHelper helper;
if (!helper.ParseString(expression.c_str(), 0)) {
- this->SetError(helper.GetError());
+ status.SetError(helper.GetError());
return false;
}
@@ -104,9 +111,10 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
std::string const& w = helper.GetWarning();
if (!w.empty()) {
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, w);
}
- this->Makefile->AddDefinition(outputVariable, buffer);
+ status.GetMakefile().AddDefinition(outputVariable, buffer);
return true;
}
+}
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index 0c6c76bb1..ac1957c24 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -8,28 +8,10 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
/// Mathematical expressions: math(EXPR ...) command.
-class cmMathCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmMathCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool HandleExprCommand(std::vector<std::string> const& args);
-};
+bool cmMathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 5320ec570..96a6386bf 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -2,30 +2,28 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessageCommand.h"
-#include "cmAlgorithms.h"
+#include <cassert>
+
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <cassert>
-
-class cmExecutionStatus;
-
// cmLibraryCommand
-bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmMessageCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
auto i = args.cbegin();
auto type = MessageType::MESSAGE;
- auto status = false;
auto fatal = false;
auto level = cmake::LogLevel::LOG_UNDEFINED;
if (*i == "SEND_ERROR") {
@@ -42,12 +40,13 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
level = cmake::LogLevel::LOG_WARNING;
++i;
} else if (*i == "AUTHOR_WARNING") {
- if (this->Makefile->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
- !this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
+ if (status.GetMakefile().IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+ !status.GetMakefile().IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
fatal = true;
type = MessageType::AUTHOR_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
+ } else if (!status.GetMakefile().IsOn(
+ "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
type = MessageType::AUTHOR_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
@@ -55,28 +54,24 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
}
++i;
} else if (*i == "STATUS") {
- status = true;
level = cmake::LogLevel::LOG_STATUS;
++i;
} else if (*i == "VERBOSE") {
- status = true;
level = cmake::LogLevel::LOG_VERBOSE;
++i;
} else if (*i == "DEBUG") {
- status = true;
level = cmake::LogLevel::LOG_DEBUG;
++i;
} else if (*i == "TRACE") {
- status = true;
level = cmake::LogLevel::LOG_TRACE;
++i;
} else if (*i == "DEPRECATION") {
- if (this->Makefile->IsOn("CMAKE_ERROR_DEPRECATED")) {
+ if (status.GetMakefile().IsOn("CMAKE_ERROR_DEPRECATED")) {
fatal = true;
type = MessageType::DEPRECATION_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if ((!this->Makefile->IsSet("CMAKE_WARN_DEPRECATED") ||
- this->Makefile->IsOn("CMAKE_WARN_DEPRECATED"))) {
+ } else if (!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
+ status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED")) {
type = MessageType::DEPRECATION_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
@@ -94,7 +89,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
assert("Message log level expected to be set" &&
level != cmake::LogLevel::LOG_UNDEFINED);
- auto desiredLevel = this->Makefile->GetCMakeInstance()->GetLogLevel();
+ auto desiredLevel = status.GetMakefile().GetCMakeInstance()->GetLogLevel();
assert("Expected a valid log level here" &&
desiredLevel != cmake::LogLevel::LOG_UNDEFINED);
@@ -105,17 +100,45 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
- if (type != MessageType::MESSAGE) {
- // we've overridden the message type, above, so display it directly
- cmMessenger* m = this->Makefile->GetMessenger();
- m->DisplayMessage(type, message, this->Makefile->GetBacktrace());
- } else {
- if (status) {
- this->Makefile->DisplayStatus(message, -1);
- } else {
+ if (cmake::LogLevel::LOG_NOTICE <= level) {
+ // Check if any indentation has requested:
+ // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
+ // to be joined and prepended to the message lines.
+ auto indent = cmJoin(cmExpandedList(status.GetMakefile().GetSafeDefinition(
+ "CMAKE_MESSAGE_INDENT")),
+ "");
+ // Make every line of the `message` indented
+ // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
+ // here cuz it appends `\n` to the EOM ;-(
+ cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
+ message = indent + message;
+ }
+
+ switch (level) {
+ case cmake::LogLevel::LOG_ERROR:
+ case cmake::LogLevel::LOG_WARNING:
+ // we've overridden the message type, above, so display it directly
+ status.GetMakefile().GetMessenger()->DisplayMessage(
+ type, message, status.GetMakefile().GetBacktrace());
+ break;
+
+ case cmake::LogLevel::LOG_NOTICE:
cmSystemTools::Message(message);
- }
+ break;
+
+ case cmake::LogLevel::LOG_STATUS:
+ case cmake::LogLevel::LOG_VERBOSE:
+ case cmake::LogLevel::LOG_DEBUG:
+ case cmake::LogLevel::LOG_TRACE:
+ status.GetMakefile().DisplayStatus(message, -1);
+ break;
+
+ default:
+ assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
+ false);
+ break;
}
+
if (fatal) {
cmSystemTools::SetFatalErrorOccured();
}
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index 819ebdacf..7d544c408 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -8,28 +8,13 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmMessageCommand
+/**
* \brief Displays a message to the user
*
*/
-class cmMessageCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmMessageCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmMessageCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 1d790e2e8..af83478a6 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessenger.h"
-#include "cmAlgorithms.h"
#include "cmDocumentationFormatter.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmsys/SystemInformation.hxx"
#endif
@@ -100,14 +100,13 @@ void displayMessage(MessageType t, std::ostringstream& msg)
"it.";
} else if (t == MessageType::AUTHOR_ERROR) {
msg << "This error is for project developers. Use -Wno-error=dev to "
- "suppress "
- "it.";
+ "suppress it.";
}
// Add a terminating blank line.
msg << "\n";
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Add a C++ stack trace to internal errors.
if (t == MessageType::INTERNAL_ERROR) {
std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0);
diff --git a/Source/cmMessenger.h b/Source/cmMessenger.h
index cf15adfc1..8c097827e 100644
--- a/Source/cmMessenger.h
+++ b/Source/cmMessenger.h
@@ -5,11 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmListFileCache.h"
#include "cmMessageType.h"
-#include <string>
-
class cmMessenger
{
public:
diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx
index 3f6523e09..a121332b2 100644
--- a/Source/cmNewLineStyle.cxx
+++ b/Source/cmNewLineStyle.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmNewLineStyle.h"
-#include <stddef.h>
+#include <cstddef>
cmNewLineStyle::cmNewLineStyle() = default;
@@ -41,7 +41,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
return true;
}
-const std::string cmNewLineStyle::GetCharacters() const
+std::string cmNewLineStyle::GetCharacters() const
{
switch (NewLineStyle) {
case Invalid:
diff --git a/Source/cmNewLineStyle.h b/Source/cmNewLineStyle.h
index f1a7bc6e0..ab9002e4d 100644
--- a/Source/cmNewLineStyle.h
+++ b/Source/cmNewLineStyle.h
@@ -30,7 +30,7 @@ public:
bool ReadFromArguments(const std::vector<std::string>& args,
std::string& errorString);
- const std::string GetCharacters() const;
+ std::string GetCharacters() const;
private:
Style NewLineStyle = Invalid;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index b7b822ab1..beedef4c2 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -3,15 +3,17 @@
#include "cmNinjaNormalTargetGenerator.h"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
#include <iterator>
#include <map>
-#include <memory> // IWYU pragma: keep
#include <set>
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
+#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -19,6 +21,7 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -32,6 +35,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
@@ -217,8 +221,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
const char* val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -227,7 +230,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
for (std::string& linkCmd : linkCmds) {
- linkCmd = launcher + linkCmd;
+ linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
linkCmd, vars);
}
@@ -238,16 +241,10 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = "Rule for linking ";
- rule.Comment += this->TargetLinkLanguage;
- rule.Comment += " ";
- rule.Comment += this->GetVisibleTypeName();
- rule.Comment += ".";
- rule.Description = "Linking ";
- rule.Description += this->TargetLinkLanguage;
- rule.Description += " ";
- rule.Description += this->GetVisibleTypeName();
- rule.Description += " $TARGET_FILE";
+ rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
@@ -281,8 +278,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::string responseFlag;
- std::string cmakeVarLang = "CMAKE_";
- cmakeVarLang += this->TargetLinkLanguage;
+ std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -356,8 +352,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
const char* val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -366,7 +361,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd();
for (std::string& linkCmd : linkCmds) {
- linkCmd = launcher + linkCmd;
+ linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
linkCmd, vars);
}
@@ -379,16 +374,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = "Rule for linking ";
- rule.Comment += this->TargetLinkLanguage;
- rule.Comment += " ";
- rule.Comment += this->GetVisibleTypeName();
- rule.Comment += ".";
- rule.Description = "Linking ";
- rule.Description += this->TargetLinkLanguage;
- rule.Description += " ";
- rule.Description += this->GetVisibleTypeName();
- rule.Description += " $TARGET_FILE";
+ rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
@@ -439,12 +428,12 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
case cmStateEnums::MODULE_LIBRARY: {
const std::string cudaLinkCmd(
this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY"));
- cmSystemTools::ExpandListArgument(cudaLinkCmd, linkCmds);
+ cmExpandList(cudaLinkCmd, linkCmds);
} break;
case cmStateEnums::EXECUTABLE: {
const std::string cudaLinkCmd(this->GetMakefile()->GetDefinition(
"CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"));
- cmSystemTools::ExpandListArgument(cudaLinkCmd, linkCmds);
+ cmExpandList(cudaLinkCmd, linkCmds);
} break;
default:
break;
@@ -466,19 +455,19 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
if (linkCmd) {
std::string linkCmdStr = linkCmd;
if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = "CMAKE_";
- ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
- ruleVar += "_GNUtoMS_RULE";
+ std::string ruleVar = cmStrCat(
+ "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkCmdStr += rule;
}
}
- cmSystemTools::ExpandListArgument(linkCmdStr, linkCmds);
+ cmExpandList(linkCmdStr, linkCmds);
if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand =
+ std::string cmakeCommand = cmStrCat(
this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- cmakeCommand += " -E __run_co_compile --lwyu=";
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
cmGeneratorTarget& gt = *this->GetGeneratorTarget();
const std::string cfgName = this->GetConfigName();
std::string targetOutputReal = this->ConvertToNinjaPath(
@@ -501,26 +490,24 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
}
// TODO: Use ARCHIVE_APPEND for archives over a certain size.
{
- std::string linkCmdVar = "CMAKE_";
- linkCmdVar += this->TargetLinkLanguage;
- linkCmdVar += "_ARCHIVE_CREATE";
+ std::string linkCmdVar =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
+ cmExpandList(linkCmd, linkCmds);
}
{
- std::string linkCmdVar = "CMAKE_";
- linkCmdVar += this->TargetLinkLanguage;
- linkCmdVar += "_ARCHIVE_FINISH";
+ std::string linkCmdVar =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
+ cmExpandList(linkCmd, linkCmds);
}
#ifdef __APPLE__
// On macOS ranlib truncates the fractional part of the static archive
@@ -589,10 +576,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// Compute the comment.
cmNinjaBuild build(this->LanguageLinkerDeviceRule());
- build.Comment = "Link the ";
- build.Comment += this->GetVisibleTypeName();
- build.Comment += " ";
- build.Comment += targetOutputReal;
+ build.Comment =
+ cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
cmNinjaVars& vars = build.Variables;
@@ -727,13 +712,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
outpath);
// Calculate the output path
- targetOutput = outpath;
- targetOutput += "/";
- targetOutput += this->TargetNames.Output;
+ targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output);
targetOutput = this->ConvertToNinjaPath(targetOutput);
- targetOutputReal = outpath;
- targetOutputReal += "/";
- targetOutputReal += this->TargetNames.Real;
+ targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real);
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
} else if (gt->IsFrameworkOnApple()) {
// Create the library framework.
@@ -756,10 +737,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaVars& vars = linkBuild.Variables;
// Compute the comment.
- linkBuild.Comment = "Link the ";
- linkBuild.Comment += this->GetVisibleTypeName();
- linkBuild.Comment += " ";
- linkBuild.Comment += targetOutputReal;
+ linkBuild.Comment =
+ cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
// Compute outputs.
linkBuild.Outputs.push_back(targetOutputReal);
@@ -966,7 +945,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
&gt->GetPostBuildCommands()
};
- std::vector<std::string> preLinkCmdLines, postBuildCmdLines;
+ std::vector<std::string> preLinkCmdLines;
+ std::vector<std::string> postBuildCmdLines;
std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
&preLinkCmdLines,
&postBuildCmdLines };
@@ -988,14 +968,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- std::string cmd = cmakeCommand;
- cmd += " -E __create_def ";
- cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
- mdi->DefFile, cmOutputConverter::SHELL);
- cmd += " ";
+ std::string cmd =
+ cmStrCat(cmakeCommand, " -E __create_def ",
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ mdi->DefFile, cmOutputConverter::SHELL),
+ ' ');
std::string obj_list_file = mdi->DefFile + ".objs";
cmd += this->GetLocalGenerator()->ConvertToOutputFormat(
obj_list_file, cmOutputConverter::SHELL);
+
+ const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
+ if (nm_executable && *nm_executable) {
+ cmd += " --nm=";
+ cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
+ nm_executable, cmOutputConverter::SHELL);
+ }
preLinkCmdLines.push_back(std::move(cmd));
// create a list of obj files for the -E __create_def to read
@@ -1037,8 +1024,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
symlinkVars["POST_BUILD"] = postBuildCmdLine;
}
- std::string cmakeVarLang = "CMAKE_";
- cmakeVarLang += this->TargetLinkLanguage;
+ std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -1061,6 +1047,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Gather order-only dependencies.
this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
+ // Add order-only dependencies on versioning symlinks of shared libs we link.
+ if (!this->GeneratorTarget->IsDLLPlatform()) {
+ if (cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
+ for (auto const& item : cli->GetItems()) {
+ if (item.Target &&
+ item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
+ !item.Target->IsFrameworkOnApple()) {
+ std::string const& lib = this->ConvertToNinjaPath(
+ item.Target->GetFullPath(this->GetConfigName()));
+ if (std::find(linkBuild.ImplicitDeps.begin(),
+ linkBuild.ImplicitDeps.end(),
+ lib) == linkBuild.ImplicitDeps.end()) {
+ linkBuild.OrderOnlyDeps.emplace_back(lib);
+ }
+ }
+ }
+ }
+ }
+
// Ninja should restat after linking if and only if there are byproducts.
vars["RESTAT"] = byproducts.empty() ? "" : "1";
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 14991a286..ebc126823 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGeneratorTarget.h"
-#include "cmNinjaTargetGenerator.h"
-
#include <string>
#include <vector>
+#include "cmGeneratorTarget.h"
+#include "cmNinjaTargetGenerator.h"
+
class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator
{
public:
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 2139a452d..919a5dbb3 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -2,16 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmNinjaTargetGenerator.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
#include <iterator>
#include <map>
-#include <memory> // IWYU pragma: keep
#include <ostream>
#include <utility>
+#include <cm/memory>
+
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
+
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
@@ -30,6 +32,7 @@
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -106,6 +109,13 @@ bool cmNinjaTargetGenerator::UsePreprocessedSource(
return lang == "Fortran";
}
+bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
+ std::string const& lang) const
+{
+ return this->Makefile->IsOn(
+ cmStrCat("CMAKE_", lang, "_COMPILE_WITH_DEFINES"));
+}
+
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
const std::string& lang) const
{
@@ -131,6 +141,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
cmSourceFile const* source, const std::string& language)
{
std::string flags = this->GetFlags(language);
+ const std::string configName = this->LocalGenerator->GetConfigName();
// Add Fortran format flags.
if (language == "Fortran") {
@@ -139,8 +150,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(
- this->LocalGenerator, this->LocalGenerator->GetConfigName(),
- this->GeneratorTarget, language);
+ this->LocalGenerator, configName, this->GeneratorTarget, language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
@@ -154,6 +164,24 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
}
+ // Add precompile headers compile options.
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(configName, language);
+
+ if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ std::string pchOptions;
+ if (source->GetFullPath() == pchSource) {
+ pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+ configName, language);
+ } else {
+ pchOptions =
+ this->GeneratorTarget->GetPchUseCompileOptions(configName, language);
+ }
+
+ this->LocalGenerator->AppendCompileOptions(
+ flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
+ }
+
return flags;
}
@@ -217,8 +245,8 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
}
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(config);
+ std::string defPropName =
+ cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
if (const char* config_compile_defs = source->GetProperty(defPropName)) {
this->LocalGenerator->AppendDefines(
defines,
@@ -372,10 +400,10 @@ std::string cmNinjaTargetGenerator::GetDyndepFilePath(
std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
std::string const& lang) const
{
- std::string path = this->Makefile->GetCurrentBinaryDirectory();
- path += "/";
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += "/" + lang + "DependInfo.json";
+ std::string path =
+ cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ '/', lang, "DependInfo.json");
return path;
}
@@ -414,9 +442,9 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
- pdbPath = this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
- pdbPath += "/";
- pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
+ pdbPath = cmStrCat(
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
+ this->GeneratorTarget->GetPDBName(this->GetConfigName()));
}
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -456,12 +484,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
vars.ObjectDir = "$OBJECT_DIR";
vars.ObjectFileDir = "$OBJECT_FILE_DIR";
+ cmMakefile* mf = this->GetMakefile();
+
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(lang);
+ bool const compilePPWithDefines = this->UsePreprocessedSource(lang) &&
+ this->CompilePreprocessedSourceWithDefines(lang);
bool const needDyndep = this->NeedDyndep(lang);
- cmMakefile* mf = this->GetMakefile();
-
std::string flags = "$FLAGS";
std::string responseFlag;
@@ -486,8 +516,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
const char* val = this->GetLocalGenerator()->GetRuleLauncher(
this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
if (val && *val) {
- launcher = val;
- launcher += " ";
+ launcher = cmStrCat(val, ' ');
}
std::string const cmakeCmd =
@@ -516,9 +545,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// Preprocessing and compilation use the same flags.
std::string ppFlags = flags;
- // Move preprocessor definitions to the preprocessor rule.
- ppVars.Defines = vars.Defines;
- vars.Defines = "";
+ if (!compilePPWithDefines) {
+ // Move preprocessor definitions to the preprocessor rule.
+ ppVars.Defines = vars.Defines;
+ 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.
@@ -527,12 +561,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
- rule.RspContent = " ";
- rule.RspContent += ppVars.Defines;
- rule.RspContent += " ";
- rule.RspContent += ppVars.Includes;
- rule.RspContent += " ";
- rule.RspContent += ppFlags;
+ rule.RspContent =
+ cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
ppFlags = responseFlag + rule.RspFile;
ppVars.Defines = "";
ppVars.Includes = "";
@@ -544,26 +574,21 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
std::vector<std::string> ppCmds;
{
// Lookup the explicit preprocessing rule.
- std::string ppVar = "CMAKE_" + lang;
- ppVar += "_PREPROCESS_SOURCE";
- cmSystemTools::ExpandListArgument(
- this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
+ std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
+ cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
}
for (std::string& i : ppCmds) {
- i = launcher + i;
+ i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
i, ppVars);
}
// Run CMake dependency scanner on preprocessed output.
{
- std::string ccmd = cmakeCmd;
- ccmd += " -E cmake_ninja_depends --tdi=";
- ccmd += tdi;
- ccmd += " --lang=";
- ccmd += lang;
- ccmd += " --pp=$out --dep=$DEP_FILE";
+ 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";
}
@@ -572,12 +597,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds);
// Write the rule for preprocessing file of the given language.
- rule.Comment = "Rule for preprocessing ";
- rule.Comment += lang;
- rule.Comment += " files.";
- rule.Description = "Building ";
- rule.Description += lang;
- rule.Description += " preprocessed $out";
+ rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
+ rule.Description = cmStrCat("Building ", lang, " preprocessed $out");
this->GetGlobalGenerator()->AddRule(rule);
}
@@ -594,24 +615,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
{
std::vector<std::string> ddCmds;
{
- std::string ccmd = cmakeCmd;
- ccmd += " -E cmake_ninja_dyndep --tdi=";
- ccmd += tdi;
- ccmd += " --lang=";
- ccmd += lang;
- ccmd += " --dd=$out ";
- ccmd += "@";
- ccmd += rule.RspFile;
+ std::string ccmd =
+ cmStrCat(cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi,
+ " --lang=", lang, " --dd=$out @", rule.RspFile);
ddCmds.emplace_back(std::move(ccmd));
}
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
}
- rule.Comment = "Rule to generate ninja dyndep files for ";
- rule.Comment += lang;
- rule.Comment += ".";
- rule.Description = "Generating ";
- rule.Description += lang;
- rule.Description += " dyndep file $out";
+ rule.Comment =
+ cmStrCat("Rule to generate ninja dyndep files for ", lang, '.');
+ rule.Description = cmStrCat("Generating ", lang, " dyndep file $out");
this->GetGlobalGenerator()->AddRule(rule);
}
@@ -619,12 +632,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
- rule.RspContent = " ";
- rule.RspContent += vars.Defines;
- rule.RspContent += " ";
- rule.RspContent += vars.Includes;
- rule.RspContent += " ";
- rule.RspContent += flags;
+ rule.RspContent =
+ cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags);
flags = responseFlag + rule.RspFile;
vars.Defines = "";
vars.Includes = "";
@@ -647,11 +656,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
? mf->GetSafeDefinition("CMAKE_C_COMPILER")
: mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
- cldeps = "\"";
- cldeps += cmSystemTools::GetCMClDepsCommand();
- cldeps += "\" " + lang + " " + vars.Source + " $DEP_FILE $out \"";
- cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
- cldeps += "\" \"" + cl + "\" ";
+ cldeps = cmStrCat('"', cmSystemTools::GetCMClDepsCommand(), "\" ", lang,
+ ' ', vars.Source, " $DEP_FILE $out \"",
+ mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"),
+ "\" \"", cl, "\" ");
}
} else {
rule.DepType = "gcc";
@@ -684,11 +692,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmdVar = "CMAKE_CUDA_COMPILE_WHOLE_COMPILATION";
}
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+ cmExpandList(compileCmd, compileCmds);
} else {
const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+ cmExpandList(compileCmd, compileCmds);
}
// See if we need to use a compiler launcher like ccache or distcc
@@ -714,8 +722,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
(cppcheck && *cppcheck)) {
- std::string run_iwyu = cmakeCmd;
- run_iwyu += " -E __run_co_compile";
+ 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
@@ -751,8 +758,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCmds.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(compilerLauncher, args, true);
+ std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -768,7 +774,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
}
for (std::string& i : compileCmds) {
- i = launcher + i;
+ i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
vars);
}
@@ -776,12 +782,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds);
// Write the rule for compiling file of the given language.
- rule.Comment = "Rule for compiling ";
- rule.Comment += lang;
- rule.Comment += " files.";
- rule.Description = "Building ";
- rule.Description += lang;
- rule.Description += " object $out";
+ rule.Comment = cmStrCat("Rule for compiling ", lang, " files.");
+ rule.Description = cmStrCat("Building ", lang, " object $out");
this->GetGlobalGenerator()->AddRule(rule);
}
@@ -794,11 +796,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target " << this->GetTargetName() << "\n\n";
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
{
std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
for (cmSourceFile const* sf : customCommands) {
cmCustomCommand const* cc = sf->GetCustomCommand();
this->GetLocalGenerator()->AddCustomCommandTarget(
@@ -810,21 +810,28 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
}
{
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, config);
+ this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
headerSources, this->MacOSXContentGenerator.get());
}
{
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, config);
+ this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
extraSources, this->MacOSXContentGenerator.get());
}
{
+ const char* pchExtension =
+ GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects, config);
+ this->GeneratorTarget->GetExternalObjects(externalObjects,
+ this->ConfigName);
for (cmSourceFile const* sf : externalObjects) {
- this->Objects.push_back(this->GetSourceFilePath(sf));
+ const auto objectFileName = this->GetSourceFilePath(sf);
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ this->Objects.push_back(objectFileName);
+ }
}
}
@@ -863,11 +870,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
if (orderOnlyDeps.empty()) {
// Any path that always exists will work here. It would be nice to
// use just "." but that is not supported by Ninja < 1.7.
- std::string tgtDir;
- tgtDir += this->LocalGenerator->GetCurrentBinaryDirectory();
- tgtDir += "/";
- tgtDir +=
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ std::string tgtDir = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
}
@@ -876,7 +881,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
{
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, config);
+ this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
for (cmSourceFile const* sf : objectSources) {
this->WriteObjectBuildStatement(sf);
}
@@ -909,8 +914,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
this->GetBuildFileStream() << "\n";
if (!this->SwiftOutputMap.empty()) {
- std::string const mapFilePath = this->ConvertToNinjaPath(
- this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json");
+ std::string const mapFilePath =
+ this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json";
std::string const targetSwiftDepsPath = [this]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
@@ -944,8 +949,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
- std::string cmakeVarLang = "CMAKE_";
- cmakeVarLang += language;
+ std::string cmakeVarLang = cmStrCat("CMAKE_", language);
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_FLAG";
@@ -966,9 +970,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (!this->NeedDepTypeMSVC(language)) {
bool replaceExt(false);
if (!language.empty()) {
- std::string repVar = "CMAKE_";
- repVar += language;
- repVar += "_DEPFILE_EXTENSION_REPLACE";
+ std::string repVar =
+ cmStrCat("CMAKE_", language, "_DEPFILE_EXTENSION_REPLACE");
replaceExt = this->Makefile->IsOn(repVar);
}
if (!replaceExt) {
@@ -990,14 +993,36 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
objBuild.Outputs.push_back(objectFileName);
- // Add this object to the list of object files.
- this->Objects.push_back(objectFileName);
+ const char* pchExtension =
+ this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ // Add this object to the list of object files.
+ this->Objects.push_back(objectFileName);
+ }
objBuild.ExplicitDeps.push_back(sourceFileName);
+ // Add precompile headers dependencies
+ std::vector<std::string> depList;
+
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(this->GetConfigName(), language);
+ if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ depList.push_back(
+ this->GeneratorTarget->GetPchHeader(this->GetConfigName(), language));
+ if (source->GetFullPath() != pchSource) {
+ depList.push_back(
+ this->GeneratorTarget->GetPchFile(this->GetConfigName(), language));
+ }
+ }
+
if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depList =
- cmSystemTools::ExpandedListArgument(objectDeps);
+ std::vector<std::string> objDepList = cmExpandedList(objectDeps);
+ std::copy(objDepList.begin(), objDepList.end(),
+ std::back_inserter(depList));
+ }
+
+ if (!depList.empty()) {
for (std::string& odi : depList) {
if (cmSystemTools::FileIsFullPath(odi)) {
odi = cmSystemTools::CollapseFullPath(odi);
@@ -1037,6 +1062,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
ppBuild.RspFile = ppFileName + ".rsp";
bool const compilePP = this->UsePreprocessedSource(language);
+ bool const compilePPWithDefines =
+ compilePP && this->CompilePreprocessedSourceWithDefines(language);
if (compilePP) {
// Move compilation dependencies to the preprocessing build statement.
std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
@@ -1065,7 +1092,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
}
- if (compilePP) {
+ if (compilePP && !compilePPWithDefines) {
// Move preprocessor definitions to the preprocessor build statement.
std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
} else {
@@ -1150,7 +1177,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
cmNinjaBuild build("phony");
build.Comment = "Additional output files.";
- build.Outputs = cmSystemTools::ExpandedListArgument(objectOutputs);
+ build.Outputs = cmExpandedList(objectOutputs);
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
@@ -1299,12 +1326,12 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
}
const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+ cmExpandList(compileCmd, compileCmds);
} else {
const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT";
const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+ cmExpandList(compileCmd, compileCmds);
}
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -1328,15 +1355,11 @@ void cmNinjaTargetGenerator::AdditionalCleanFiles()
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
std::vector<std::string> cleanFiles;
- {
- cmGeneratorExpression ge;
- auto cge = ge.Parse(prop_value);
- cmSystemTools::ExpandListArgument(
- cge->Evaluate(lg,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
- false, this->GeneratorTarget, nullptr, nullptr),
- cleanFiles);
- }
+ cmExpandList(cmGeneratorExpression::Evaluate(
+ prop_value, lg,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
+ this->GeneratorTarget),
+ cleanFiles);
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
for (std::string const& cleanFile : cleanFiles) {
@@ -1384,9 +1407,8 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
input = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(input);
// Get the output file location.
- std::string output = macdir;
- output += "/";
- output += cmSystemTools::GetFilenameName(input);
+ std::string output =
+ cmStrCat(macdir, '/', cmSystemTools::GetFilenameName(input));
output = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
// Write a build statement to copy the content into the bundle.
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 3055e18c3..4627bcdc6 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -5,6 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
#include "cm_jsoncpp_value.h"
#include "cmCommonTargetGenerator.h"
@@ -12,12 +18,6 @@
#include "cmNinjaTypes.h"
#include "cmOSXBundleGenerator.h"
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <set>
-#include <string>
-#include <vector>
-
class cmCustomCommand;
class cmGeneratedFileStream;
class cmGeneratorTarget;
@@ -70,6 +70,7 @@ protected:
std::string LanguageDyndepRule(std::string const& lang) const;
bool NeedDyndep(std::string const& lang) const;
bool UsePreprocessedSource(std::string const& lang) const;
+ bool CompilePreprocessedSourceWithDefines(std::string const& lang) const;
std::string OrderDependsTargetForTarget();
diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h
index 52c05b62c..bd0e83fa1 100644
--- a/Source/cmNinjaTypes.h
+++ b/Source/cmNinjaTypes.h
@@ -17,9 +17,9 @@ enum cmNinjaTargetDepends
DependOnTargetOrdering
};
-typedef std::vector<std::string> cmNinjaDeps;
-typedef std::set<std::string> cmNinjaOuts;
-typedef std::map<std::string, std::string> cmNinjaVars;
+using cmNinjaDeps = std::vector<std::string>;
+using cmNinjaOuts = std::set<std::string>;
+using cmNinjaVars = std::map<std::string, std::string>;
class cmNinjaRule
{
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index e774b53b5..5259037bf 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -2,6 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmNinjaUtilityTargetGenerator.h"
+#include <algorithm>
+#include <array>
+#include <iterator>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -13,15 +20,9 @@
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <algorithm>
-#include <array>
-#include <iterator>
-#include <string>
-#include <utility>
-#include <vector>
-
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmGeneratorTarget* target)
: cmNinjaTargetGenerator(target)
@@ -36,15 +37,15 @@ void cmNinjaUtilityTargetGenerator::Generate()
cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
- std::string utilCommandName = lg->GetCurrentBinaryDirectory();
- utilCommandName += "/CMakeFiles";
- utilCommandName += "/";
- utilCommandName += this->GetTargetName() + ".util";
+ std::string utilCommandName =
+ cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ this->GetTargetName(), ".util");
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
cmNinjaBuild phonyBuild("phony");
std::vector<std::string> commands;
- cmNinjaDeps deps, util_outputs(1, utilCommandName);
+ cmNinjaDeps deps;
+ cmNinjaDeps util_outputs(1, utilCommandName);
bool uses_terminal = false;
{
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 47a8df4ef..a6f4e512e 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -2,16 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmOSXBundleGenerator.h"
+#include <cassert>
+#include <utility>
+
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include <cassert>
-#include <utility>
-
class cmSourceFile;
cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
@@ -40,20 +41,20 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
}
// Compute bundle directory names.
- std::string out = outpath;
- out += "/";
- out += this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
+ std::string out =
+ cmStrCat(outpath, '/',
+ this->GT->GetAppBundleDirectory(this->ConfigName,
+ cmGeneratorTarget::FullLevel));
cmSystemTools::MakeDirectory(out);
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist = outpath;
- plist += "/";
- plist += this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- plist += "/Info.plist";
+ std::string plist =
+ cmStrCat(outpath, '/',
+ this->GT->GetAppBundleDirectory(this->ConfigName,
+ cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
this->Makefile->AddCMakeOutputFile(plist);
outpath = out;
@@ -69,10 +70,11 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
assert(this->MacContentFolders);
// Compute the location of the top-level foo.framework directory.
- std::string contentdir = outpath + "/" +
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- contentdir += "/";
+ std::string contentdir =
+ cmStrCat(outpath, '/',
+ this->GT->GetFrameworkDirectory(this->ConfigName,
+ cmGeneratorTarget::ContentLevel),
+ '/');
std::string newoutpath = outpath + "/" +
this->GT->GetFrameworkDirectory(this->ConfigName,
@@ -102,8 +104,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
std::string newName;
// Make foo.framework/Versions
- std::string versions = contentdir;
- versions += "Versions";
+ std::string versions = cmStrCat(contentdir, "Versions");
cmSystemTools::MakeDirectory(versions);
// Make foo.framework/Versions/version
@@ -111,17 +112,14 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
// Current -> version
oldName = frameworkVersion;
- newName = versions;
- newName += "/Current";
+ newName = cmStrCat(versions, "/Current");
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
// foo -> Versions/Current/foo
- oldName = "Versions/Current/";
- oldName += name;
- newName = contentdir;
- newName += name;
+ oldName = cmStrCat("Versions/Current/", name);
+ newName = cmStrCat(contentdir, name);
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
@@ -130,8 +128,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
if (this->MacContentFolders->find("Resources") !=
this->MacContentFolders->end()) {
oldName = "Versions/Current/Resources";
- newName = contentdir;
- newName += "Resources";
+ newName = cmStrCat(contentdir, "Resources");
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
@@ -141,8 +138,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
if (this->MacContentFolders->find("Headers") !=
this->MacContentFolders->end()) {
oldName = "Versions/Current/Headers";
- newName = contentdir;
- newName += "Headers";
+ newName = cmStrCat(contentdir, "Headers");
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
@@ -152,8 +148,7 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
if (this->MacContentFolders->find("PrivateHeaders") !=
this->MacContentFolders->end()) {
oldName = "Versions/Current/PrivateHeaders";
- newName = contentdir;
- newName += "PrivateHeaders";
+ newName = cmStrCat(contentdir, "PrivateHeaders");
cmSystemTools::RemoveFile(newName);
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
@@ -168,19 +163,20 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
}
// Compute bundle directory names.
- std::string out = root;
- out += "/";
- out += this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
+ std::string out =
+ cmStrCat(root, '/',
+ this->GT->GetCFBundleDirectory(this->ConfigName,
+ cmGeneratorTarget::FullLevel));
cmSystemTools::MakeDirectory(out);
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist = root + "/" +
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel);
- plist += "/Info.plist";
+ std::string plist =
+ cmStrCat(root, '/',
+ this->GT->GetCFBundleDirectory(this->ConfigName,
+ cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
std::string name = cmSystemTools::GetFilenameName(targetName);
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
this->Makefile->AddCMakeOutputFile(plist);
@@ -208,10 +204,10 @@ std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
{
// Construct the full path to the content subdirectory.
- std::string macdir = this->GT->GetMacContentDirectory(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact);
- macdir += "/";
- macdir += pkgloc;
+ std::string macdir =
+ cmStrCat(this->GT->GetMacContentDirectory(
+ this->ConfigName, cmStateEnums::RuntimeBinaryArtifact),
+ '/', pkgloc);
cmSystemTools::MakeDirectory(macdir);
// Record use of this content location. Only the first level
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 52f63a379..22e59ac43 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -2,38 +2,35 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmOptionCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
-
-class cmExecutionStatus;
+#include "cmStringAlgorithms.h"
// cmOptionCommand
-bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmOptionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
const bool argError = (args.size() < 2) || (args.size() > 3);
if (argError) {
- std::string m = "called with incorrect number of arguments: ";
- m += cmJoin(args, " ");
- this->SetError(m);
+ std::string m = cmStrCat("called with incorrect number of arguments: ",
+ cmJoin(args, " "));
+ status.SetError(m);
return false;
}
// Determine the state of the option policy
bool checkAndWarn = false;
{
- auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077);
+ auto policyStatus =
+ status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077);
const auto* existsBeforeSet =
- this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
- switch (status) {
+ status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
+ switch (policyStatus) {
case cmPolicies::WARN:
checkAndWarn = (existsBeforeSet != nullptr);
break;
@@ -54,7 +51,7 @@ bool cmOptionCommand::InitialPass(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 = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
const char* existingValue = state->GetCacheEntryValue(args[0]);
if (existingValue &&
(state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
@@ -67,21 +64,21 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args,
if (args.size() == 3) {
initialValue = args[2];
}
- bool init = cmSystemTools::IsOn(initialValue);
- this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF",
- args[1].c_str(), cmStateEnums::BOOL);
+ bool init = cmIsOn(initialValue);
+ status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF",
+ args[1].c_str(), cmStateEnums::BOOL);
if (checkAndWarn) {
const auto* existsAfterSet =
- this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
+ status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
if (!existsAfterSet) {
- std::ostringstream w;
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077)
- << "\n"
- "For compatibility with older versions of CMake, option "
- "is clearing the normal variable '"
- << args[0] << "'.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0077),
+ "\n"
+ "For compatibility with older versions of CMake, option "
+ "is clearing the normal variable '",
+ args[0], "'."));
}
}
return true;
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index 34e0e6f01..cbd1cb864 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -8,29 +8,13 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmOptionCommand
+/**
* \brief Provide an option to the user
*
* cmOptionCommand provides an option for the user to select
*/
-class cmOptionCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmOptionCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
-
+bool cmOptionCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 585db423e..073222cd8 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmOrderDirectories.h"
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <sstream>
+#include <vector>
+
#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <algorithm>
-#include <assert.h>
-#include <functional>
-#include <sstream>
-
/*
Directory ordering computation.
- Useful to compute a safe runtime library path order
@@ -116,9 +118,7 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir,
std::string const& name)
{
// Check if the file exists on disk.
- std::string file = dir;
- file += "/";
- file += name;
+ std::string file = cmStrCat(dir, '/', name);
if (cmSystemTools::FileExists(file, true)) {
// The file conflicts only if it is not the same as the original
// file due to a symlink or hardlink.
@@ -128,7 +128,7 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir,
// Check if the file will be built by cmake.
std::set<std::string> const& files =
(this->GlobalGenerator->GetDirectoryContent(dir, false));
- std::set<std::string>::const_iterator fi = files.find(name);
+ auto fi = files.find(name);
return fi != files.end();
}
@@ -186,9 +186,9 @@ bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir)
// know the soname just look at all files that start with the
// file name. Usually the soname starts with the library name.
std::string base = this->FileName;
- std::set<std::string>::const_iterator first = files.lower_bound(base);
+ auto first = files.lower_bound(base);
++base.back();
- std::set<std::string>::const_iterator last = files.upper_bound(base);
+ auto last = files.upper_bound(base);
if (first != last) {
return true;
}
@@ -228,8 +228,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
std::string ext = this->OD->RemoveLibraryExtension.match(2);
for (std::string const& LinkExtension : this->OD->LinkExtensions) {
if (LinkExtension != ext) {
- std::string fname = lib;
- fname += LinkExtension;
+ std::string fname = cmStrCat(lib, LinkExtension);
if (this->FileMayConflict(dir, fname)) {
return true;
}
@@ -381,7 +380,7 @@ void cmOrderDirectories::CollectOriginalDirectories()
int cmOrderDirectories::AddOriginalDirectory(std::string const& dir)
{
// Add the runtime directory with a unique index.
- std::map<std::string, int>::iterator i = this->DirectoryIndex.find(dir);
+ auto i = this->DirectoryIndex.find(dir);
if (i == this->DirectoryIndex.end()) {
std::map<std::string, int>::value_type entry(
dir, static_cast<int>(this->OriginalDirectories.size()));
@@ -413,7 +412,7 @@ void cmOrderDirectories::AddOriginalDirectories(
struct cmOrderDirectoriesCompare
{
- typedef std::pair<int, int> ConflictPair;
+ using ConflictPair = std::pair<int, int>;
// The conflict pair is unique based on just the directory
// (first). The second element is only used for displaying
@@ -442,8 +441,7 @@ void cmOrderDirectories::FindConflicts()
std::sort(cl.begin(), cl.end());
// Make the edge list unique so cycle detection will be reliable.
- ConflictList::iterator last =
- std::unique(cl.begin(), cl.end(), cmOrderDirectoriesCompare());
+ auto last = std::unique(cl.begin(), cl.end(), cmOrderDirectoriesCompare());
cl.erase(last, cl.end());
}
@@ -467,14 +465,14 @@ void cmOrderDirectories::FindImplicitConflicts()
}
// Warn about the conflicts.
- std::ostringstream w;
- w << "Cannot generate a safe " << this->Purpose << " for target "
- << this->Target->GetName()
- << " because files in some directories may conflict with "
- << " libraries in implicit directories:\n"
- << text << "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()->IssueMessage(
- MessageType::WARNING, w.str(), this->Target->GetBacktrace());
+ MessageType::WARNING,
+ cmStrCat("Cannot generate a safe ", this->Purpose, " for target ",
+ this->Target->GetName(),
+ " because files in some directories may "
+ "conflict with libraries in implicit directories:\n",
+ text, "Some of these libraries may not be found correctly."),
+ this->Target->GetBacktrace());
}
void cmOrderDirectories::OrderDirectories()
@@ -554,11 +552,10 @@ bool cmOrderDirectories::IsSameDirectory(std::string const& l,
std::string const& cmOrderDirectories::GetRealPath(std::string const& dir)
{
- std::map<std::string, std::string>::iterator i =
- this->RealPaths.lower_bound(dir);
+ auto i = this->RealPaths.lower_bound(dir);
if (i == this->RealPaths.end() ||
this->RealPaths.key_comp()(dir, i->first)) {
- typedef std::map<std::string, std::string>::value_type value_type;
+ using value_type = std::map<std::string, std::string>::value_type;
i = this->RealPaths.insert(
i, value_type(dir, cmSystemTools::GetRealPath(dir)));
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 23e61d678..23c514500 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -5,13 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmOrderDirectoriesConstraint;
@@ -75,7 +76,7 @@ private:
// the index of the directory that must come first. The second
// element is the index of the runtime library that added the
// constraint.
- typedef std::pair<int, int> ConflictPair;
+ using ConflictPair = std::pair<int, int>;
struct ConflictList : public std::vector<ConflictPair>
{
};
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 7d88b088e..e602a6d0a 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -3,13 +3,13 @@
#include "cmOutputConverter.h"
#include <algorithm>
-#include <assert.h>
-#include <ctype.h>
+#include <cassert>
+#include <cctype>
#include <set>
-#include <string.h>
#include <vector>
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
@@ -38,10 +38,10 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
return this->ConvertToOutputFormat(remote, format);
}
-std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
+std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
OutputFormat output) const
{
- std::string result = source;
+ std::string result(source);
// Convert it to an output path.
if (output == SHELL || output == WATCOMQUOTE) {
result = this->ConvertDirectorySeparatorsForShell(source);
@@ -53,9 +53,9 @@ std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
}
std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
- const std::string& source) const
+ cm::string_view source) const
{
- std::string result = source;
+ std::string result(source);
// For the MSYS shell convert drive letters to posix paths, so
// that c:/some/path becomes /c/some/path. This is needed to
// avoid problems with the shell path translation.
@@ -71,33 +71,21 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
return result;
}
-static bool cmOutputConverterIsShellOperator(const std::string& str)
+static bool cmOutputConverterIsShellOperator(cm::string_view str)
{
- static std::set<std::string> shellOperators;
- if (shellOperators.empty()) {
- shellOperators.insert("<");
- shellOperators.insert(">");
- shellOperators.insert("<<");
- shellOperators.insert(">>");
- shellOperators.insert("|");
- shellOperators.insert("||");
- shellOperators.insert("&&");
- shellOperators.insert("&>");
- shellOperators.insert("1>");
- shellOperators.insert("2>");
- shellOperators.insert("2>&1");
- shellOperators.insert("1>&2");
- }
- return shellOperators.count(str) > 0;
+ static std::set<cm::string_view> const shellOperators{
+ "<", ">", "<<", ">>", "|", "||", "&&", "&>", "1>", "2>", "2>&1", "1>&2"
+ };
+ return (shellOperators.count(str) != 0);
}
-std::string cmOutputConverter::EscapeForShell(const std::string& str,
+std::string cmOutputConverter::EscapeForShell(cm::string_view str,
bool makeVars, bool forEcho,
bool useWatcomQuote) const
{
// Do not escape shell operators.
if (cmOutputConverterIsShellOperator(str)) {
- return str;
+ return std::string(str);
}
// Compute the flags for the target shell environment.
@@ -129,46 +117,44 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str,
flags |= Shell_Flag_IsUnix;
}
- return Shell__GetArgument(str.c_str(), flags);
+ return Shell__GetArgument(str, flags);
}
-std::string cmOutputConverter::EscapeForCMake(const std::string& str)
+std::string cmOutputConverter::EscapeForCMake(cm::string_view str)
{
// Always double-quote the argument to take care of most escapes.
std::string result = "\"";
- for (const char* c = str.c_str(); *c; ++c) {
- if (*c == '"') {
+ for (const char c : str) {
+ if (c == '"') {
// Escape the double quote to avoid ending the argument.
result += "\\\"";
- } else if (*c == '$') {
+ } else if (c == '$') {
// Escape the dollar to avoid expanding variables.
result += "\\$";
- } else if (*c == '\\') {
+ } else if (c == '\\') {
// Escape the backslash to avoid other escapes.
result += "\\\\";
} else {
// Other characters will be parsed correctly.
- result += *c;
+ result += c;
}
}
result += "\"";
return result;
}
-std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
+std::string cmOutputConverter::EscapeWindowsShellArgument(cm::string_view arg,
int shell_flags)
{
return Shell__GetArgument(arg, shell_flags);
}
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
- const char* value)
+ cm::string_view value)
{
FortranFormat format = FortranFormatNone;
- if (value && *value) {
- std::vector<std::string> fmt;
- cmSystemTools::ExpandListArgument(value, fmt);
- for (std::string const& fi : fmt) {
+ if (!value.empty()) {
+ for (std::string const& fi : cmExpandedList(value)) {
if (fi == "FIXED") {
format = FortranFormatFixed;
}
@@ -180,6 +166,15 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
return format;
}
+cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
+ const char* value)
+{
+ if (!value) {
+ return FortranFormatNone;
+ }
+ return GetFortranFormat(cm::string_view(value));
+}
+
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
this->LinkScriptShell = linkScriptShell;
@@ -225,12 +220,12 @@ use the caret character itself (^), use two in a row (^^).
*/
/* Some helpers to identify character classes */
-static int Shell__CharIsWhitespace(char c)
+static bool Shell__CharIsWhitespace(char c)
{
return ((c == ' ') || (c == '\t'));
}
-static int Shell__CharNeedsQuotesOnUnix(char c)
+static bool Shell__CharNeedsQuotesOnUnix(char c)
{
return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
(c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
@@ -238,51 +233,52 @@ static int Shell__CharNeedsQuotesOnUnix(char c)
(c == '\\'));
}
-static int Shell__CharNeedsQuotesOnWindows(char c)
+static bool Shell__CharNeedsQuotesOnWindows(char c)
{
return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
(c == '>') || (c == '|') || (c == '^'));
}
-static int Shell__CharIsMakeVariableName(char c)
+static bool Shell__CharIsMakeVariableName(char c)
{
return c && (c == '_' || isalpha((static_cast<int>(c))));
}
-int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
+bool cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
{
/* On Windows the built-in command shell echo never needs quotes. */
if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
- return 0;
+ return false;
}
/* On all platforms quotes are needed to preserve whitespace. */
if (Shell__CharIsWhitespace(c)) {
- return 1;
+ return true;
}
if (flags & Shell_Flag_IsUnix) {
/* On UNIX several special characters need quotes to preserve them. */
if (Shell__CharNeedsQuotesOnUnix(c)) {
- return 1;
+ return true;
}
} else {
/* On Windows several special characters need quotes to preserve them. */
if (Shell__CharNeedsQuotesOnWindows(c)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
+cm::string_view::iterator cmOutputConverter::Shell__SkipMakeVariables(
+ cm::string_view::iterator c, cm::string_view::iterator end)
{
- while (*c == '$' && *(c + 1) == '(') {
- const char* skip = c + 2;
- while (Shell__CharIsMakeVariableName(*skip)) {
+ while ((c != end && (c + 1) != end) && (*c == '$' && *(c + 1) == '(')) {
+ cm::string_view::iterator skip = c + 2;
+ while ((skip != end) && Shell__CharIsMakeVariableName(*skip)) {
++skip;
}
- if (*skip == ')') {
+ if ((skip != end) && *skip == ')') {
c = skip + 1;
} else {
break;
@@ -314,63 +310,60 @@ flag later when we understand applications of this better.
*/
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags)
+bool cmOutputConverter::Shell__ArgumentNeedsQuotes(cm::string_view in,
+ int flags)
{
/* The empty string needs quotes. */
- if (!*in) {
- return 1;
+ if (in.empty()) {
+ return true;
}
/* Scan the string for characters that require quoting. */
- {
- const char* c;
- for (c = in; *c; ++c) {
- /* Look for $(MAKEVAR) syntax if requested. */
- if (flags & Shell_Flag_AllowMakeVariables) {
+ for (cm::string_view::iterator cit = in.begin(), cend = in.end();
+ cit != cend; ++cit) {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if (flags & Shell_Flag_AllowMakeVariables) {
#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
- /* We need to quote make variable references to preserve the
- string with contents substituted in its place. */
- return 1;
- }
+ cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
+ if (skip != cit) {
+ /* We need to quote make variable references to preserve the
+ string with contents substituted in its place. */
+ return true;
+ }
#else
- /* Skip over the make variable references if any are present. */
- c = Shell__SkipMakeVariables(c);
+ /* Skip over the make variable references if any are present. */
+ cit = Shell__SkipMakeVariables(cit, cend);
- /* Stop if we have reached the end of the string. */
- if (!*c) {
- break;
- }
-#endif
+ /* Stop if we have reached the end of the string. */
+ if (cit == cend) {
+ break;
}
+#endif
+ }
- /* Check whether this character needs quotes. */
- if (Shell__CharNeedsQuotes(*c, flags)) {
- return 1;
- }
+ /* Check whether this character needs quotes. */
+ if (Shell__CharNeedsQuotes(*cit, flags)) {
+ return true;
}
}
/* On Windows some single character arguments need quotes. */
- if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) {
- char c = *in;
+ if (flags & Shell_Flag_IsUnix && in.size() == 1) {
+ char c = in[0];
if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
+std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
+ int flags)
{
/* Output will be at least as long as input string. */
std::string out;
- out.reserve(strlen(in));
-
- /* String iterator. */
- const char* c;
+ out.reserve(in.size());
/* Keep track of how many backslashes have been encountered in a row. */
int windows_backslashes = 0;
@@ -390,14 +383,15 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
}
/* Scan the string for characters that require escaping or quoting. */
- for (c = in; *c; ++c) {
+ for (cm::string_view::iterator cit = in.begin(), cend = in.end();
+ cit != cend; ++cit) {
/* Look for $(MAKEVAR) syntax if requested. */
if (flags & Shell_Flag_AllowMakeVariables) {
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
+ cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
+ if (skip != cit) {
/* Copy to the end of the make variable references. */
- while (c != skip) {
- out += *c++;
+ while (cit != skip) {
+ out += *cit++;
}
/* The make variable reference eliminates any escaping needed
@@ -405,7 +399,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
windows_backslashes = 0;
/* Stop if we have reached the end of the string. */
- if (!*c) {
+ if (cit == cend) {
break;
}
}
@@ -415,7 +409,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
if (flags & Shell_Flag_IsUnix) {
/* On Unix a few special characters need escaping even inside a
quoted argument. */
- if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
+ if (*cit == '\\' || *cit == '"' || *cit == '`' || *cit == '$') {
/* This character needs a backslash to escape it. */
out += '\\';
}
@@ -423,10 +417,10 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
/* On Windows the built-in command shell echo never needs escaping. */
} else {
/* On Windows only backslashes and double-quotes need escaping. */
- if (*c == '\\') {
+ if (*cit == '\\') {
/* Found a backslash. It may need to be escaped later. */
++windows_backslashes;
- } else if (*c == '"') {
+ } else if (*cit == '"') {
/* Found a double-quote. Escape all immediately preceding
backslashes. */
while (windows_backslashes > 0) {
@@ -444,7 +438,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
}
/* Check whether this character needs escaping for a make tool. */
- if (*c == '$') {
+ if (*cit == '$') {
if (flags & Shell_Flag_Make) {
/* In Makefiles a dollar is written $$. The make tool will
replace it with just $ before passing it to the shell. */
@@ -461,7 +455,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
/* Otherwise a dollar is written just $. */
out += '$';
}
- } else if (*c == '#') {
+ } else if (*cit == '#') {
if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
/* In Watcom WMake makefiles a pound is written $#. The make
tool will replace it with just # before passing it to the
@@ -471,7 +465,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
/* Otherwise a pound is written just #. */
out += '#';
}
- } else if (*c == '%') {
+ } else if (*cit == '%') {
if ((flags & Shell_Flag_VSIDE) ||
((flags & Shell_Flag_Make) &&
((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
@@ -481,7 +475,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
/* Otherwise a percent is written just %. */
out += '%';
}
- } else if (*c == ';') {
+ } else if (*cit == ';') {
if (flags & Shell_Flag_VSIDE) {
/* In a VS IDE a semicolon is written ";". If this is written
in an un-quoted argument it starts a quoted segment,
@@ -495,7 +489,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
}
} else {
/* Store this character. */
- out += *c;
+ out += *cit;
}
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index deca767c6..349a069d6 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -7,6 +7,8 @@
#include <string>
+#include <cm/string_view>
+
#include "cmStateSnapshot.h"
class cmState;
@@ -22,10 +24,9 @@ public:
WATCOMQUOTE,
RESPONSE
};
- std::string ConvertToOutputFormat(const std::string& source,
+ std::string ConvertToOutputFormat(cm::string_view source,
OutputFormat output) const;
- std::string ConvertDirectorySeparatorsForShell(
- const std::string& source) const;
+ std::string ConvertDirectorySeparatorsForShell(cm::string_view source) const;
//! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const std::string& remote,
@@ -72,15 +73,15 @@ public:
Shell_Flag_IsUnix = (1 << 8)
};
- std::string EscapeForShell(const std::string& str, bool makeVars = false,
+ std::string EscapeForShell(cm::string_view str, bool makeVars = false,
bool forEcho = false,
bool useWatcomQuote = false) const;
- static std::string EscapeForCMake(const std::string& str);
+ static std::string EscapeForCMake(cm::string_view str);
/** Compute an escaped version of the given argument for use in a
windows shell. */
- static std::string EscapeWindowsShellArgument(const char* arg,
+ static std::string EscapeWindowsShellArgument(cm::string_view arg,
int shell_flags);
enum FortranFormat
@@ -89,15 +90,17 @@ public:
FortranFormatFixed,
FortranFormatFree
};
+ static FortranFormat GetFortranFormat(cm::string_view value);
static FortranFormat GetFortranFormat(const char* value);
private:
cmState* GetState() const;
- static int Shell__CharNeedsQuotes(char c, int flags);
- static const char* Shell__SkipMakeVariables(const char* c);
- static int Shell__ArgumentNeedsQuotes(const char* in, int flags);
- static std::string Shell__GetArgument(const char* in, int flags);
+ static bool Shell__CharNeedsQuotes(char c, int flags);
+ static cm::string_view::iterator Shell__SkipMakeVariables(
+ cm::string_view::iterator begin, cm::string_view::iterator end);
+ static bool Shell__ArgumentNeedsQuotes(cm::string_view in, int flags);
+ static std::string Shell__GetArgument(cm::string_view in, int flags);
private:
cmStateSnapshot StateSnapshot;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index f3276ecd6..e093be019 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -2,20 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmOutputRequiredFilesCommand.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
+#include <cstdio>
#include <map>
+#include <set>
#include <utility>
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
+namespace {
/** \class cmDependInformation
* \brief Store dependency information for a single source file.
*
@@ -33,7 +37,7 @@ public:
/**
* The set of files on which this one depends.
*/
- typedef std::set<cmDependInformation*> DependencySetType;
+ using DependencySetType = std::set<cmDependInformation*>;
DependencySetType DependencySet;
/**
@@ -121,8 +125,7 @@ public:
std::string incDirs = cmGeneratorExpression::Preprocess(
incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- std::vector<std::string> includes;
- cmSystemTools::ExpandListArgument(incDirs, includes);
+ std::vector<std::string> includes = cmExpandedList(incDirs);
for (std::string& path : includes) {
this->Makefile->ExpandVariablesInString(path);
@@ -192,10 +195,8 @@ protected:
// see if the include matches the regular expression
if (!this->IncludeFileRegularExpression.find(includeFile)) {
if (this->Verbose) {
- std::string message = "Skipping ";
- message += includeFile;
- message += " for file ";
- message += info->FullPath;
+ std::string message =
+ cmStrCat("Skipping ", includeFile, " for file ", info->FullPath);
cmSystemTools::Error(message);
}
continue;
@@ -214,10 +215,8 @@ protected:
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -226,10 +225,8 @@ protected:
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -239,10 +236,8 @@ protected:
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -252,10 +247,8 @@ protected:
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -333,16 +326,16 @@ protected:
cmSourceFile* srcFile = this->Makefile->GetSource(
cmSystemTools::GetFilenameWithoutExtension(path));
if (srcFile) {
- if (srcFile->GetFullPath() == path) {
+ if (srcFile->ResolveFullPath() == path) {
found = true;
} else {
// try to guess which include path to use
for (std::string incpath : this->IncludeDirectories) {
if (!incpath.empty() && incpath.back() != '/') {
- incpath = incpath + "/";
+ incpath += "/";
}
- incpath = incpath + path;
- if (srcFile->GetFullPath() == incpath) {
+ incpath += path;
+ if (srcFile->ResolveFullPath() == incpath) {
// set the path to the guessed path
info->FullPath = incpath;
found = true;
@@ -375,8 +368,7 @@ protected:
std::string fullPath = this->FullPath(file, extraPath);
// Try to find the file's instance of cmDependInformation.
- DependInformationMapType::const_iterator result =
- this->DependInformationMap.find(fullPath);
+ auto result = this->DependInformationMap.find(fullPath);
if (result != this->DependInformationMap.end()) {
// Found an instance, return it.
return result->second;
@@ -406,7 +398,7 @@ protected:
if (m != this->DirectoryToFileToPathMap.end()) {
FileToPathMapType& map = m->second;
- FileToPathMapType::iterator p = map.find(fname);
+ auto p = map.find(fname);
if (p != map.end()) {
return p->second;
}
@@ -420,9 +412,9 @@ protected:
for (std::string path : this->IncludeDirectories) {
if (!path.empty() && path.back() != '/') {
- path = path + "/";
+ path += "/";
}
- path = path + fname;
+ path += fname;
if (cmSystemTools::FileExists(path, true) &&
!cmSystemTools::FileIsDirectory(path)) {
std::string fp = cmSystemTools::CollapseFullPath(path);
@@ -454,53 +446,55 @@ protected:
cmsys::RegularExpression IncludeFileRegularExpression;
cmsys::RegularExpression ComplainFileRegularExpression;
std::vector<std::string> IncludeDirectories;
- typedef std::map<std::string, std::string> FileToPathMapType;
- typedef std::map<std::string, FileToPathMapType>
- DirectoryToFileToPathMapType;
- typedef std::map<std::string, cmDependInformation*> DependInformationMapType;
+ using FileToPathMapType = std::map<std::string, std::string>;
+ using DirectoryToFileToPathMapType =
+ std::map<std::string, FileToPathMapType>;
+ using DependInformationMapType = std::map<std::string, cmDependInformation*>;
DependInformationMapType DependInformationMap;
DirectoryToFileToPathMapType DirectoryToFileToPathMap;
};
+void ListDependencies(cmDependInformation const* info, FILE* fout,
+ std::set<cmDependInformation const*>* visited);
+}
+
// cmOutputRequiredFilesCommand
-bool cmOutputRequiredFilesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// store the arg for final pass
- this->File = args[0];
- this->OutputFile = args[1];
+ const std::string& file = args[0];
+ const std::string& outputFile = args[1];
// compute the list of files
cmLBDepend md;
- md.SetMakefile(this->Makefile);
- md.AddSearchPath(this->Makefile->GetCurrentSourceDirectory());
+ md.SetMakefile(&status.GetMakefile());
+ md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory());
// find the depends for a file
- const cmDependInformation* info = md.FindDependencies(this->File.c_str());
+ const cmDependInformation* info = md.FindDependencies(file.c_str());
if (info) {
// write them out
- FILE* fout = cmsys::SystemTools::Fopen(this->OutputFile, "w");
+ FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w");
if (!fout) {
- std::string err = "Can not open output file: ";
- err += this->OutputFile;
- this->SetError(err);
+ status.SetError(cmStrCat("Can not open output file: ", outputFile));
return false;
}
std::set<cmDependInformation const*> visited;
- this->ListDependencies(info, fout, &visited);
+ ListDependencies(info, fout, &visited);
fclose(fout);
}
return true;
}
-void cmOutputRequiredFilesCommand::ListDependencies(
- cmDependInformation const* info, FILE* fout,
- std::set<cmDependInformation const*>* visited)
+namespace {
+void ListDependencies(cmDependInformation const* info, FILE* fout,
+ std::set<cmDependInformation const*>* visited)
{
// add info to the visited set
visited->insert(info);
@@ -515,7 +509,8 @@ void cmOutputRequiredFilesCommand::ListDependencies(
fprintf(fout, "%s\n", d->FullPath.c_str());
}
}
- this->ListDependencies(d, fout, visited);
+ ListDependencies(d, fout, visited);
}
}
}
+}
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 09e622b41..4c1189457 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -5,29 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <set>
-#include <stdio.h>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
-class cmDependInformation;
class cmExecutionStatus;
-class cmOutputRequiredFilesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmOutputRequiredFilesCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- void ListDependencies(cmDependInformation const* info, FILE* fout,
- std::set<cmDependInformation const*>* visited);
-
-private:
- std::string File;
- std::string OutputFile;
-};
+bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 521343203..d712edb81 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -7,15 +7,15 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/string_view>
+
#include "cmArgumentParser.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cm_string_view.hxx"
-
-class cmExecutionStatus;
static std::string EscapeArg(const std::string& arg)
{
@@ -38,10 +38,10 @@ static std::string JoinList(std::vector<std::string> const& arg, bool escape)
namespace {
-typedef std::map<std::string, bool> options_map;
-typedef std::map<std::string, std::string> single_map;
-typedef std::map<std::string, std::vector<std::string>> multi_map;
-typedef std::set<std::string> options_set;
+using options_map = std::map<std::string, bool>;
+using single_map = std::map<std::string, std::string>;
+using multi_map = std::map<std::string, std::vector<std::string>>;
+using options_set = std::set<std::string>;
struct UserArgumentParser : public cmArgumentParser<void>
{
@@ -75,7 +75,7 @@ static void PassParsedArguments(
for (auto const& iter : singleValArgs) {
if (!iter.second.empty()) {
- makefile.AddDefinition(prefix + iter.first, iter.second.c_str());
+ makefile.AddDefinition(prefix + iter.first, iter.second);
} else {
makefile.RemoveDefinition(prefix + iter.first);
}
@@ -84,7 +84,7 @@ static void PassParsedArguments(
for (auto const& iter : multiValArgs) {
if (!iter.second.empty()) {
makefile.AddDefinition(prefix + iter.first,
- JoinList(iter.second, parseFromArgV).c_str());
+ JoinList(iter.second, parseFromArgV));
} else {
makefile.RemoveDefinition(prefix + iter.first);
}
@@ -92,39 +92,38 @@ static void PassParsedArguments(
if (!unparsed.empty()) {
makefile.AddDefinition(prefix + "UNPARSED_ARGUMENTS",
- JoinList(unparsed, parseFromArgV).c_str());
+ JoinList(unparsed, parseFromArgV));
} else {
makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
}
if (!keywordsMissingValues.empty()) {
- makefile.AddDefinition(
- prefix + "KEYWORDS_MISSING_VALUES",
- cmJoin(cmMakeRange(keywordsMissingValues), ";").c_str());
+ makefile.AddDefinition(prefix + "KEYWORDS_MISSING_VALUES",
+ cmJoin(cmMakeRange(keywordsMissingValues), ";"));
} else {
makefile.RemoveDefinition(prefix + "KEYWORDS_MISSING_VALUES");
}
}
-bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmParseArgumentsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// cmake_parse_arguments(prefix options single multi <ARGN>)
// 1 2 3 4
// or
// cmake_parse_arguments(PARSE_ARGV N prefix options single multi)
if (args.size() < 4) {
- this->SetError("must be called with at least 4 arguments.");
+ status.SetError("must be called with at least 4 arguments.");
return false;
}
- std::vector<std::string>::const_iterator argIter = args.begin(),
- argEnd = args.end();
+ auto argIter = args.begin();
+ auto argEnd = args.end();
bool parseFromArgV = false;
unsigned long argvStart = 0;
if (*argIter == "PARSE_ARGV") {
if (args.size() != 6) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"PARSE_ARGV must be called with exactly 6 arguments.");
cmSystemTools::SetFatalErrorOccured();
@@ -132,10 +131,10 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
}
parseFromArgV = true;
argIter++; // move past PARSE_ARGV
- if (!cmSystemTools::StringToULong(argIter->c_str(), &argvStart)) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "PARSE_ARGV index '" + *argIter +
- "' is not an unsigned integer");
+ if (!cmStrToULong(*argIter, &argvStart)) {
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+ "PARSE_ARGV index '" + *argIter +
+ "' is not an unsigned integer");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -155,24 +154,23 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
// anything else is put into a vector of unparsed strings
std::vector<std::string> unparsed;
- auto const duplicateKey = [this](std::string const& key) {
- this->GetMakefile()->IssueMessage(
+ auto const duplicateKey = [&status](std::string const& key) {
+ status.GetMakefile().IssueMessage(
MessageType::WARNING, "keyword defined more than once: " + key);
};
// the second argument is a (cmake) list of options without argument
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(*argIter++, list);
+ std::vector<std::string> list = cmExpandedList(*argIter++);
parser.Bind(list, options, duplicateKey);
// the third argument is a (cmake) list of single argument options
list.clear();
- cmSystemTools::ExpandListArgument(*argIter++, list);
+ cmExpandList(*argIter++, list);
parser.Bind(list, singleValArgs, duplicateKey);
// the fourth argument is a (cmake) list of multi argument options
list.clear();
- cmSystemTools::ExpandListArgument(*argIter++, list);
+ cmExpandList(*argIter++, list);
parser.Bind(list, multiValArgs, duplicateKey);
list.clear();
@@ -180,27 +178,28 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
// Flatten ;-lists in the arguments into a single list as was done
// by the original function(CMAKE_PARSE_ARGUMENTS).
for (; argIter != argEnd; ++argIter) {
- cmSystemTools::ExpandListArgument(*argIter, list);
+ cmExpandList(*argIter, list);
}
} else {
// in the PARSE_ARGV move read the arguments from ARGC and ARGV#
- std::string argc = this->Makefile->GetSafeDefinition("ARGC");
+ std::string argc = status.GetMakefile().GetSafeDefinition("ARGC");
unsigned long count;
- if (!cmSystemTools::StringToULong(argc.c_str(), &count)) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "PARSE_ARGV called with ARGC='" + argc +
- "' that is not an unsigned integer");
+ if (!cmStrToULong(argc, &count)) {
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+ "PARSE_ARGV called with ARGC='" +
+ argc +
+ "' that is not an unsigned integer");
cmSystemTools::SetFatalErrorOccured();
return true;
}
for (unsigned long i = argvStart; i < count; ++i) {
std::ostringstream argName;
argName << "ARGV" << i;
- const char* arg = this->Makefile->GetDefinition(argName.str());
+ const char* arg = status.GetMakefile().GetDefinition(argName.str());
if (!arg) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "PARSE_ARGV called with " +
- argName.str() + " not set");
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR,
+ "PARSE_ARGV called with " +
+ argName.str() + " not set");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -213,7 +212,8 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
parser.Parse(list, &unparsed, &keywordsMissingValues);
PassParsedArguments(
- prefix, *this->Makefile, options, singleValArgs, multiValArgs, unparsed,
+ prefix, status.GetMakefile(), options, singleValArgs, multiValArgs,
+ unparsed,
options_set(keywordsMissingValues.begin(), keywordsMissingValues.end()),
parseFromArgV);
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
index b8ba61d21..b2e436d89 100644
--- a/Source/cmParseArgumentsCommand.h
+++ b/Source/cmParseArgumentsCommand.h
@@ -8,27 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmParseArgumentsCommand
- *
- */
-class cmParseArgumentsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmParseArgumentsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmParseArgumentsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
index e67f15c57..81f8a49f6 100644
--- a/Source/cmPipeConnection.h
+++ b/Source/cmPipeConnection.h
@@ -4,12 +4,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmUVHandlePtr.h"
#include <string>
-#include "cmConnection.h"
#include "cm_uv.h"
+#include "cmConnection.h"
+#include "cmUVHandlePtr.h"
+
class cmPipeConnection : public cmEventBasedConnection
{
public:
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index ec4013629..5c8bc98b2 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -1,20 +1,20 @@
#include "cmPolicies.h"
-#include "cmAlgorithms.h"
+#include <cassert>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <vector>
+
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
-#include <assert.h>
-#include <ctype.h>
-#include <sstream>
-#include <stdio.h>
-#include <string.h>
-#include <vector>
-
static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
{
assert(input);
@@ -34,7 +34,7 @@ static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
}
}
long id;
- if (!cmSystemTools::StringToLong(input + 3, &id)) {
+ if (!cmStrToLong(input + 3, &id)) {
return false;
}
if (id >= cmPolicies::CMPCOUNT) {
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index b70511980..92c80bb4c 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -279,7 +279,18 @@ class cmMakefile;
SELECT(POLICY, CMP0094, \
"FindPython3, FindPython2 and FindPyton use " \
"LOCATION for lookup strategy.", \
- 3, 15, 0, cmPolicies::WARN)
+ 3, 15, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0095, \
+ "RPATH entries are properly escaped in the intermediary CMake " \
+ "install script.", \
+ 3, 16, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0096, \
+ "project() preserves leading zeros in version components.", 3, 16, \
+ 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0097, \
+ "ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \
+ "submodules.", \
+ 3, 16, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -307,7 +318,8 @@ class cmMakefile;
F(CMP0073) \
F(CMP0076) \
F(CMP0081) \
- F(CMP0083)
+ F(CMP0083) \
+ F(CMP0095)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProcessOutput.h b/Source/cmProcessOutput.h
index 400354c84..3db47a4b4 100644
--- a/Source/cmProcessOutput.h
+++ b/Source/cmProcessOutput.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <stddef.h>
+#include <cstddef>
#include <string>
#include <vector>
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index a2bc16ffb..9ebf5b771 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -1,11 +1,13 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProcessTools.h"
-#include "cmProcessOutput.h"
-#include "cmsys/Process.h"
#include <ostream>
+#include "cmsys/Process.h"
+
+#include "cmProcessOutput.h"
+
void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
OutputParser* err, Encoding encoding)
{
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 76163167a..21d59c463 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -4,12 +4,13 @@
#define cmProcessTools_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmProcessOutput.h"
+#include <cstring>
#include <iosfwd>
-#include <string.h>
#include <string>
+#include "cmProcessOutput.h"
+
/** \class cmProcessTools
* \brief Helper classes for process output parsing
*
@@ -17,7 +18,7 @@
class cmProcessTools
{
public:
- typedef cmProcessOutput::Encoding Encoding;
+ using Encoding = cmProcessOutput::Encoding;
/** Abstract interface for process output parsers. */
class OutputParser
{
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 8615ecc8d..7bb5209da 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -2,58 +2,56 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmProjectCommand.h"
-#include "cmsys/RegularExpression.hxx"
+#include <array>
+#include <cstddef>
+#include <cstdio>
#include <functional>
-#include <sstream>
-#include <stdio.h>
+#include <limits>
+#include <utility>
+
+#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+static bool IncludeByVariable(cmExecutionStatus& status,
+ const std::string& variable);
+static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
+ std::string const& value);
-// cmProjectCommand
-bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmProjectCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("PROJECT called with incorrect number of arguments");
+ status.SetError("PROJECT called with incorrect number of arguments");
return false;
}
- if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE_BEFORE")) {
+ cmMakefile& mf = status.GetMakefile();
+ if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) {
return false;
}
std::string const& projectName = args[0];
- this->Makefile->SetProjectName(projectName);
-
- std::string bindir = projectName;
- bindir += "_BINARY_DIR";
- std::string srcdir = projectName;
- srcdir += "_SOURCE_DIR";
-
- this->Makefile->AddCacheDefinition(
- bindir, this->Makefile->GetCurrentBinaryDirectory().c_str(),
- "Value Computed by CMake", cmStateEnums::STATIC);
- this->Makefile->AddCacheDefinition(
- srcdir, this->Makefile->GetCurrentSourceDirectory().c_str(),
- "Value Computed by CMake", cmStateEnums::STATIC);
+ mf.SetProjectName(projectName);
- bindir = "PROJECT_BINARY_DIR";
- srcdir = "PROJECT_SOURCE_DIR";
+ mf.AddCacheDefinition(projectName + "_BINARY_DIR",
+ mf.GetCurrentBinaryDirectory().c_str(),
+ "Value Computed by CMake", cmStateEnums::STATIC);
+ mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
+ mf.GetCurrentSourceDirectory().c_str(),
+ "Value Computed by CMake", cmStateEnums::STATIC);
- this->Makefile->AddDefinition(
- bindir, this->Makefile->GetCurrentBinaryDirectory().c_str());
- this->Makefile->AddDefinition(
- srcdir, this->Makefile->GetCurrentSourceDirectory().c_str());
+ mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
+ mf.AddDefinition("PROJECT_SOURCE_DIR", mf.GetCurrentSourceDirectory());
- this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str());
+ mf.AddDefinition("PROJECT_NAME", projectName);
// Set the CMAKE_PROJECT_NAME variable to be the highest-level
// project name in the tree. If there are two project commands
@@ -61,12 +59,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
// CMakeLists.txt file, then go with the last one, so that
// CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
// will work.
- if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") ||
- (this->Makefile->IsRootMakefile())) {
- this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str());
- this->Makefile->AddCacheDefinition(
- "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake",
- cmStateEnums::STATIC);
+ if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
+ mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
+ mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(),
+ "Value Computed by CMake", cmStateEnums::STATIC);
}
bool haveVersion = false;
@@ -93,9 +89,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
for (size_t i = 1; i < args.size(); ++i) {
if (args[i] == "LANGUAGES") {
if (haveLanguages) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "LANGUAGES may be specified at most once.");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "LANGUAGES may be specified at most once.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -105,17 +100,16 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
}
doing = DoingLanguages;
if (!languages.empty()) {
- std::string msg =
+ std::string msg = cmStrCat(
"the following parameters must be specified after LANGUAGES "
- "keyword: ";
- msg += cmJoin(languages, ", ");
- msg += '.';
- this->Makefile->IssueMessage(MessageType::WARNING, msg);
+ "keyword: ",
+ cmJoin(languages, ", "), '.');
+ mf.IssueMessage(MessageType::WARNING, msg);
}
} else if (args[i] == "VERSION") {
if (haveVersion) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "VERSION may be specified at most once.");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "VERSION may be specified at most once.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -124,8 +118,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
missedValueReporter();
}
doing = DoingVersion;
- missedValueReporter = [this, &resetReporter]() {
- this->Makefile->IssueMessage(
+ missedValueReporter = [&mf, &resetReporter]() {
+ mf.IssueMessage(
MessageType::WARNING,
"VERSION keyword not followed by a value or was followed by a "
"value that expanded to nothing.");
@@ -133,9 +127,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
};
} else if (args[i] == "DESCRIPTION") {
if (haveDescription) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "DESCRIPTION may be specified at most once.");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "DESCRIPTION may be specified at most once.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -144,8 +137,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
missedValueReporter();
}
doing = DoingDescription;
- missedValueReporter = [this, &resetReporter]() {
- this->Makefile->IssueMessage(
+ missedValueReporter = [&mf, &resetReporter]() {
+ mf.IssueMessage(
MessageType::WARNING,
"DESCRIPTION keyword not followed by a value or was followed "
"by a value that expanded to nothing.");
@@ -153,16 +146,15 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
};
} else if (args[i] == "HOMEPAGE_URL") {
if (haveHomepage) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "HOMEPAGE_URL may be specified at most once.");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "HOMEPAGE_URL may be specified at most once.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
haveHomepage = true;
doing = DoingHomepage;
- missedValueReporter = [this, &resetReporter]() {
- this->Makefile->IssueMessage(
+ missedValueReporter = [&mf, &resetReporter]() {
+ mf.IssueMessage(
MessageType::WARNING,
"HOMEPAGE_URL keyword not followed by a value or was followed "
"by a value that expanded to nothing.");
@@ -194,10 +186,9 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages &&
!languages.empty()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
- "use LANGUAGES before language names.");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
+ "use LANGUAGES before language names.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -205,14 +196,13 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
languages.emplace_back("NONE");
}
- cmPolicies::PolicyStatus cmp0048 =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
+ cmPolicies::PolicyStatus const cmp0048 =
+ mf.GetPolicyStatus(cmPolicies::CMP0048);
if (haveVersion) {
// Set project VERSION variables to given values
if (cmp0048 == cmPolicies::OLD || cmp0048 == cmPolicies::WARN) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "VERSION not allowed unless CMP0048 is set to NEW");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "VERSION not allowed unless CMP0048 is set to NEW");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -220,65 +210,85 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
cmsys::RegularExpression vx(
R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
if (!vx.find(version)) {
- std::string e = "VERSION \"" + version + "\" format invalid.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+ std::string e = R"(VERSION ")" + version + R"(" format invalid.)";
+ mf.IssueMessage(MessageType::FATAL_ERROR, e);
cmSystemTools::SetFatalErrorOccured();
return true;
}
- std::string vs;
- const char* sep = "";
- char vb[4][64];
- unsigned int v[4] = { 0, 0, 0, 0 };
- int vc =
- sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1], &v[2], &v[3]);
- for (int i = 0; i < 4; ++i) {
- if (i < vc) {
- sprintf(vb[i], "%u", v[i]);
- vs += sep;
- vs += vb[i];
- sep = ".";
- } else {
- vb[i][0] = 0;
+ cmPolicies::PolicyStatus const cmp0096 =
+ mf.GetPolicyStatus(cmPolicies::CMP0096);
+
+ constexpr std::size_t MAX_VERSION_COMPONENTS = 4u;
+ std::string version_string;
+ std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
+
+ if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) {
+ char vb[MAX_VERSION_COMPONENTS]
+ [std::numeric_limits<unsigned>::digits10 + 2];
+ unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 };
+ const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
+ &v[2], &v[3]);
+ for (auto i = 0u; i < MAX_VERSION_COMPONENTS; ++i) {
+ if (int(i) < vc) {
+ std::sprintf(vb[i], "%u", v[i]);
+ version_string += &"."[std::size_t(i == 0)];
+ version_string += vb[i];
+ version_components[i] = vb[i];
+ } else {
+ vb[i][0] = '\x00';
+ }
+ }
+ } else {
+ // The regex above verified that we have a .-separated string of
+ // non-negative integer components. Keep the original string.
+ version_string = std::move(version);
+ // Split the integer components.
+ auto components = cmSystemTools::SplitString(version_string, '.');
+ for (auto i = 0u; i < components.size(); ++i) {
+ version_components[i] = std::move(components[i]);
}
}
std::string vv;
vv = projectName + "_VERSION";
- this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
- this->Makefile->AddDefinition(vv, vs.c_str());
+ mf.AddDefinition("PROJECT_VERSION", version_string);
+ mf.AddDefinition(vv, version_string);
vv = projectName + "_VERSION_MAJOR";
- this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
- this->Makefile->AddDefinition(vv, vb[0]);
+ mf.AddDefinition("PROJECT_VERSION_MAJOR", version_components[0]);
+ mf.AddDefinition(vv, version_components[0]);
vv = projectName + "_VERSION_MINOR";
- this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
- this->Makefile->AddDefinition(vv, vb[1]);
+ mf.AddDefinition("PROJECT_VERSION_MINOR", version_components[1]);
+ mf.AddDefinition(vv, version_components[1]);
vv = projectName + "_VERSION_PATCH";
- this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
- this->Makefile->AddDefinition(vv, vb[2]);
+ mf.AddDefinition("PROJECT_VERSION_PATCH", version_components[2]);
+ mf.AddDefinition(vv, version_components[2]);
vv = projectName + "_VERSION_TWEAK";
- this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
- this->Makefile->AddDefinition(vv, vb[3]);
+ mf.AddDefinition("PROJECT_VERSION_TWEAK", version_components[3]);
+ mf.AddDefinition(vv, version_components[3]);
// Also, try set top level variables
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str());
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]);
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]);
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]);
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION", version_string);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MAJOR",
+ version_components[0]);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MINOR",
+ version_components[1]);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_PATCH",
+ version_components[2]);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_TWEAK",
+ version_components[3]);
} else if (cmp0048 != cmPolicies::OLD) {
// Set project VERSION variables to empty
- std::vector<std::string> vv;
- vv.emplace_back("PROJECT_VERSION");
- vv.emplace_back("PROJECT_VERSION_MAJOR");
- vv.emplace_back("PROJECT_VERSION_MINOR");
- vv.emplace_back("PROJECT_VERSION_PATCH");
- vv.emplace_back("PROJECT_VERSION_TWEAK");
- vv.push_back(projectName + "_VERSION");
- vv.push_back(projectName + "_VERSION_MAJOR");
- vv.push_back(projectName + "_VERSION_MINOR");
- vv.push_back(projectName + "_VERSION_PATCH");
- vv.push_back(projectName + "_VERSION_TWEAK");
- if (this->Makefile->IsRootMakefile()) {
+ std::vector<std::string> vv = { "PROJECT_VERSION",
+ "PROJECT_VERSION_MAJOR",
+ "PROJECT_VERSION_MINOR",
+ "PROJECT_VERSION_PATCH",
+ "PROJECT_VERSION_TWEAK",
+ projectName + "_VERSION",
+ projectName + "_VERSION_MAJOR",
+ projectName + "_VERSION_MINOR",
+ projectName + "_VERSION_PATCH",
+ projectName + "_VERSION_TWEAK" };
+ if (mf.IsRootMakefile()) {
vv.emplace_back("CMAKE_PROJECT_VERSION");
vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR");
vv.emplace_back("CMAKE_PROJECT_VERSION_MINOR");
@@ -287,7 +297,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
}
std::string vw;
for (std::string const& i : vv) {
- const char* v = this->Makefile->GetDefinition(i);
+ const char* const v = mf.GetDefinition(i);
if (v && *v) {
if (cmp0048 == cmPolicies::WARN) {
if (!injectedProjectCommand) {
@@ -295,54 +305,54 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
vw += i;
}
} else {
- this->Makefile->AddDefinition(i, "");
+ mf.AddDefinition(i, "");
}
}
}
if (!vw.empty()) {
- std::ostringstream w;
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0048)
- << "\nThe following variable(s) would be set to empty:" << vw;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0048),
+ "\nThe following variable(s) would be set to empty:", vw));
}
}
- this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
- this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
- description.c_str());
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str());
+ mf.AddDefinition("PROJECT_DESCRIPTION", description);
+ mf.AddDefinition(projectName + "_DESCRIPTION", description);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_DESCRIPTION", description);
- this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
- this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
- homepage.c_str());
- TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str());
+ mf.AddDefinition("PROJECT_HOMEPAGE_URL", homepage);
+ mf.AddDefinition(projectName + "_HOMEPAGE_URL", homepage);
+ TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_HOMEPAGE_URL", homepage);
if (languages.empty()) {
// if no language is specified do c and c++
- languages.emplace_back("C");
- languages.emplace_back("CXX");
+ languages = { "C", "CXX" };
}
- this->Makefile->EnableLanguage(languages, false);
+ mf.EnableLanguage(languages, false);
- if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE")) {
+ if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE")) {
return false;
}
- if (!this->IncludeByVariable("CMAKE_PROJECT_" + projectName + "_INCLUDE")) {
+ if (!IncludeByVariable(status,
+ "CMAKE_PROJECT_" + projectName + "_INCLUDE")) {
return false;
}
return true;
}
-bool cmProjectCommand::IncludeByVariable(const std::string& variable)
+static bool IncludeByVariable(cmExecutionStatus& status,
+ const std::string& variable)
{
- const char* include = this->Makefile->GetDefinition(variable);
+ cmMakefile& mf = status.GetMakefile();
+ const char* const include = mf.GetDefinition(variable);
if (!include) {
return true;
}
- const bool readit = this->Makefile->ReadDependentFile(include);
+ const bool readit = mf.ReadDependentFile(include);
if (readit) {
return true;
}
@@ -351,24 +361,20 @@ bool cmProjectCommand::IncludeByVariable(const std::string& variable)
return true;
}
- std::string m = "could not find file:\n"
- " ";
- m += include;
- this->SetError(m);
+ status.SetError(cmStrCat("could not find file:\n ", include));
return false;
}
-void cmProjectCommand::TopLevelCMakeVarCondSet(const char* const name,
- const char* const value)
+static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
+ std::string const& value)
{
// Set the CMAKE_PROJECT_XXX variable to be the highest-level
// project name in the tree. If there are two project commands
// in the same CMakeLists.txt file, and it is the top level
// CMakeLists.txt file, then go with the last one.
- if (!this->Makefile->GetDefinition(name) ||
- (this->Makefile->IsRootMakefile())) {
- this->Makefile->AddDefinition(name, value);
- this->Makefile->AddCacheDefinition(name, value, "Value Computed by CMake",
- cmStateEnums::STATIC);
+ if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
+ mf.AddDefinition(name, value);
+ mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake",
+ cmStateEnums::STATIC);
}
}
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
index f1d03e71d..c06b4594c 100644
--- a/Source/cmProjectCommand.h
+++ b/Source/cmProjectCommand.h
@@ -8,36 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmProjectCommand
- * \brief Specify the name for this build project.
- *
- * cmProjectCommand is used to specify a name for this build project.
- * It is defined once per set of CMakeList.txt files (including
- * all subdirectories). Currently it just sets the name of the workspace
- * file for Microsoft Visual C++
- */
-class cmProjectCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmProjectCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool IncludeByVariable(const std::string& variable);
- void TopLevelCMakeVarCondSet(const char* name, const char* value);
-};
+bool cmProjectCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
deleted file mode 100644
index 27f0ecd71..000000000
--- a/Source/cmProperty.cxx
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmProperty.h"
-
-void cmProperty::Set(const char* value)
-{
- this->Value = value;
- this->ValueHasBeenSet = true;
-}
-
-void cmProperty::Append(const char* value, bool asString)
-{
- if (!this->Value.empty() && *value && !asString) {
- this->Value += ";";
- }
- this->Value += value;
- this->ValueHasBeenSet = true;
-}
-
-const char* cmProperty::GetValue() const
-{
- if (this->ValueHasBeenSet) {
- return this->Value.c_str();
- }
- return nullptr;
-}
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index d11c5efbb..80f131a76 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -5,8 +5,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
-
class cmProperty
{
public:
@@ -22,22 +20,6 @@ public:
CACHED_VARIABLE,
INSTALL
};
-
- // set this property
- void Set(const char* value);
-
- // append to this property
- void Append(const char* value, bool asString = false);
-
- // get the value
- const char* GetValue() const;
-
- // construct with the value not set
- cmProperty() { this->ValueHasBeenSet = false; }
-
-protected:
- std::string Value;
- bool ValueHasBeenSet;
};
#endif
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 9adff4902..0d68c328b 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmProperty.h"
-
#include <string>
+#include "cmProperty.h"
+
/** \class cmPropertyDefinition
* \brief Property meta-information
*
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index 5daaf9ba3..f752ed7c6 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -10,7 +10,7 @@ void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
const char* FullDescription,
bool chain)
{
- cmPropertyDefinitionMap::iterator it = this->find(name);
+ auto it = this->find(name);
cmPropertyDefinition* prop;
if (it == this->end()) {
prop = &(*this)[name];
@@ -26,7 +26,7 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
{
- cmPropertyDefinitionMap::const_iterator it = this->find(name);
+ auto it = this->find(name);
if (it == this->end()) {
return false;
}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 97ba55391..8ec791033 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmProperty.h"
-#include "cmPropertyDefinition.h"
-
#include <map>
#include <string>
+#include "cmProperty.h"
+#include "cmPropertyDefinition.h"
+
class cmPropertyDefinitionMap
: public std::map<std::string, cmPropertyDefinition>
{
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 3f6d7c8a9..a3d49460b 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -3,40 +3,21 @@
#include "cmPropertyMap.h"
#include <algorithm>
-#include <assert.h>
#include <utility>
-cmProperty* cmPropertyMap::GetOrCreateProperty(const std::string& name)
+void cmPropertyMap::Clear()
{
- cmPropertyMap::iterator it = this->find(name);
- cmProperty* prop;
- if (it == this->end()) {
- prop = &(*this)[name];
- } else {
- prop = &(it->second);
- }
- return prop;
-}
-
-std::vector<std::string> cmPropertyMap::GetPropertyList() const
-{
- std::vector<std::string> keyList;
- for (auto const& i : *this) {
- keyList.push_back(i.first);
- }
- std::sort(keyList.begin(), keyList.end());
- return keyList;
+ Map_.clear();
}
void cmPropertyMap::SetProperty(const std::string& name, const char* value)
{
if (!value) {
- this->erase(name);
+ Map_.erase(name);
return;
}
- cmProperty* prop = this->GetOrCreateProperty(name);
- prop->Set(value);
+ Map_[name] = value;
}
void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
@@ -47,17 +28,53 @@ void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
return;
}
- cmProperty* prop = this->GetOrCreateProperty(name);
- prop->Append(value, asString);
+ {
+ std::string& pVal = Map_[name];
+ if (!pVal.empty() && !asString) {
+ pVal += ';';
+ }
+ pVal += value;
+ }
+}
+
+void cmPropertyMap::RemoveProperty(const std::string& name)
+{
+ Map_.erase(name);
}
const char* cmPropertyMap::GetPropertyValue(const std::string& name) const
{
- assert(!name.empty());
+ {
+ auto it = Map_.find(name);
+ if (it != Map_.end()) {
+ return it->second.c_str();
+ }
+ }
+ return nullptr;
+}
- cmPropertyMap::const_iterator it = this->find(name);
- if (it == this->end()) {
- return nullptr;
+std::vector<std::string> cmPropertyMap::GetKeys() const
+{
+ std::vector<std::string> keyList;
+ keyList.reserve(Map_.size());
+ for (auto const& item : Map_) {
+ keyList.push_back(item.first);
+ }
+ std::sort(keyList.begin(), keyList.end());
+ return keyList;
+}
+
+std::vector<std::pair<std::string, std::string>> cmPropertyMap::GetList() const
+{
+ using StringPair = std::pair<std::string, std::string>;
+ std::vector<StringPair> kvList;
+ kvList.reserve(Map_.size());
+ for (auto const& item : Map_) {
+ kvList.emplace_back(item.first, item.second);
}
- return it->second.GetValue();
+ std::sort(kvList.begin(), kvList.end(),
+ [](StringPair const& a, StringPair const& b) {
+ return a.first < b.first;
+ });
+ return kvList;
}
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 5a0515076..9aed34960 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -5,25 +5,47 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmProperty.h"
-
-#include <map>
#include <string>
+#include <unordered_map>
+#include <utility>
#include <vector>
-class cmPropertyMap : public std::map<std::string, cmProperty>
+/** \class cmPropertyMap
+ * \brief String property map.
+ */
+class cmPropertyMap
{
public:
- cmProperty* GetOrCreateProperty(const std::string& name);
+ // -- General
+
+ //! Clear property list
+ void Clear();
- std::vector<std::string> GetPropertyList() const;
+ // -- Properties
+ //! Set the property value
void SetProperty(const std::string& name, const char* value);
+ //! Append to the property value
void AppendProperty(const std::string& name, const char* value,
bool asString = false);
+ //! Get the property value
const char* GetPropertyValue(const std::string& name) const;
+
+ //! Remove the property @a name from the map
+ void RemoveProperty(const std::string& name);
+
+ // -- Lists
+
+ //! Get a sorted list of property keys
+ std::vector<std::string> GetKeys() const;
+
+ //! Get a sorted by key list of property key,value pairs
+ std::vector<std::pair<std::string, std::string>> GetList() const;
+
+private:
+ std::unordered_map<std::string, std::string> Map_;
};
#endif
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index 9a764c678..cc4df8f89 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -3,45 +3,41 @@
#include "cmQTWrapCPPCommand.h"
#include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <utility>
-
-class cmExecutionStatus;
-
-// cmQTWrapCPPCommand
-bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmQTWrapCPPCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Get the moc executable to run in the custom command.
- std::string const& moc_exe =
- this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
+ std::string const& moc_exe = mf.GetRequiredDefinition("QT_MOC_EXECUTABLE");
// Get the variable holding the list of sources.
std::string const& sourceList = args[1];
- std::string sourceListValue = this->Makefile->GetSafeDefinition(sourceList);
+ std::string sourceListValue = mf.GetSafeDefinition(sourceList);
// Create a rule for all sources listed.
for (std::string const& arg : cmMakeRange(args).advance(2)) {
- cmSourceFile* curr = this->Makefile->GetSource(arg);
+ cmSourceFile* curr = mf.GetSource(arg);
// if we should wrap the class
if (!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE"))) {
// Compute the name of the file to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(arg);
- std::string newName = this->Makefile->GetCurrentBinaryDirectory();
- newName += "/moc_";
- newName += srcName;
- newName += ".cxx";
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(newName, true);
+ std::string newName =
+ cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
+ cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
if (curr) {
sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
}
@@ -52,9 +48,9 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args,
hname = arg;
} else {
if (curr && curr->GetIsGenerated()) {
- hname = this->Makefile->GetCurrentBinaryDirectory();
+ hname = mf.GetCurrentBinaryDirectory();
} else {
- hname = this->Makefile->GetCurrentSourceDirectory();
+ hname = mf.GetCurrentSourceDirectory();
}
hname += "/";
hname += arg;
@@ -67,14 +63,8 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args,
sourceListValue += newName;
// Create the custom command to generate the file.
- cmCustomCommandLine commandLine;
- commandLine.push_back(moc_exe);
- commandLine.push_back("-o");
- commandLine.push_back(newName);
- commandLine.push_back(hname);
-
- cmCustomCommandLines commandLines;
- commandLines.push_back(std::move(commandLine));
+ cmCustomCommandLines commandLines =
+ cmMakeSingleCommandLine({ moc_exe, "-o", newName, hname });
std::vector<std::string> depends;
depends.push_back(moc_exe);
@@ -82,13 +72,13 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args,
std::string no_main_dependency;
const char* no_working_dir = nullptr;
- this->Makefile->AddCustomCommandToOutput(
- newName, depends, no_main_dependency, commandLines, "Qt Wrapped File",
- no_working_dir);
+ mf.AddCustomCommandToOutput(newName, depends, no_main_dependency,
+ commandLines, "Qt Wrapped File",
+ no_working_dir);
}
}
// Store the final list of source files.
- this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
+ mf.AddDefinition(sourceList, sourceListValue);
return true;
}
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
index c1dcd545e..75fa18028 100644
--- a/Source/cmQTWrapCPPCommand.h
+++ b/Source/cmQTWrapCPPCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmQTWrapCPPCommand
- * \brief Create moc file rules for Qt classes
- *
- * cmQTWrapCPPCommand is used to create wrappers for Qt classes into
- * normal C++
- */
-class cmQTWrapCPPCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmQTWrapCPPCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmQTWrapCPPCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx
index 2223e2d82..66c0228fc 100644
--- a/Source/cmQTWrapUICommand.cxx
+++ b/Source/cmQTWrapUICommand.cxx
@@ -3,56 +3,47 @@
#include "cmQTWrapUICommand.h"
#include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include <utility>
-
-class cmExecutionStatus;
-
-// cmQTWrapUICommand
-bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmQTWrapUICommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 4) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Get the uic and moc executables to run in the custom commands.
- std::string const& uic_exe =
- this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE");
- std::string const& moc_exe =
- this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
+ std::string const& uic_exe = mf.GetRequiredDefinition("QT_UIC_EXECUTABLE");
+ std::string const& moc_exe = mf.GetRequiredDefinition("QT_MOC_EXECUTABLE");
// Get the variable holding the list of sources.
std::string const& headerList = args[1];
std::string const& sourceList = args[2];
- std::string headerListValue = this->Makefile->GetSafeDefinition(headerList);
- std::string sourceListValue = this->Makefile->GetSafeDefinition(sourceList);
+ std::string headerListValue = mf.GetSafeDefinition(headerList);
+ std::string sourceListValue = mf.GetSafeDefinition(sourceList);
// Create rules for all sources listed.
for (std::string const& arg : cmMakeRange(args).advance(3)) {
- cmSourceFile* curr = this->Makefile->GetSource(arg);
+ cmSourceFile* curr = mf.GetSource(arg);
// if we should wrap the class
if (!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE"))) {
// Compute the name of the files to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(arg);
- std::string hName = this->Makefile->GetCurrentBinaryDirectory();
- hName += "/";
- hName += srcName;
- hName += ".h";
- std::string cxxName = this->Makefile->GetCurrentBinaryDirectory();
- cxxName += "/";
- cxxName += srcName;
- cxxName += ".cxx";
- std::string mocName = this->Makefile->GetCurrentBinaryDirectory();
- mocName += "/moc_";
- mocName += srcName;
- mocName += ".cxx";
+ std::string hName =
+ cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".h");
+ std::string cxxName =
+ cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".cxx");
+ std::string mocName =
+ cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
// Compute the name of the ui file from which to generate others.
std::string uiName;
@@ -60,9 +51,9 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args,
uiName = arg;
} else {
if (curr && curr->GetIsGenerated()) {
- uiName = this->Makefile->GetCurrentBinaryDirectory();
+ uiName = mf.GetCurrentBinaryDirectory();
} else {
- uiName = this->Makefile->GetCurrentSourceDirectory();
+ uiName = mf.GetCurrentSourceDirectory();
}
uiName += "/";
uiName += arg;
@@ -83,56 +74,34 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args,
sourceListValue += mocName;
// set up .ui to .h and .cxx command
- cmCustomCommandLine hCommand;
- hCommand.push_back(uic_exe);
- hCommand.push_back("-o");
- hCommand.push_back(hName);
- hCommand.push_back(uiName);
- cmCustomCommandLines hCommandLines;
- hCommandLines.push_back(std::move(hCommand));
-
- cmCustomCommandLine cxxCommand;
- cxxCommand.push_back(uic_exe);
- cxxCommand.push_back("-impl");
- cxxCommand.push_back(hName);
- cxxCommand.push_back("-o");
- cxxCommand.push_back(cxxName);
- cxxCommand.push_back(uiName);
- cmCustomCommandLines cxxCommandLines;
- cxxCommandLines.push_back(std::move(cxxCommand));
-
- cmCustomCommandLine mocCommand;
- mocCommand.push_back(moc_exe);
- mocCommand.push_back("-o");
- mocCommand.push_back(mocName);
- mocCommand.push_back(hName);
- cmCustomCommandLines mocCommandLines;
- mocCommandLines.push_back(std::move(mocCommand));
+ cmCustomCommandLines hCommandLines =
+ cmMakeSingleCommandLine({ uic_exe, "-o", hName, uiName });
+ cmCustomCommandLines cxxCommandLines = cmMakeSingleCommandLine(
+ { uic_exe, "-impl", hName, "-o", cxxName, uiName });
+ cmCustomCommandLines mocCommandLines =
+ cmMakeSingleCommandLine({ moc_exe, "-o", mocName, hName });
std::vector<std::string> depends;
depends.push_back(uiName);
std::string no_main_dependency;
const char* no_comment = nullptr;
const char* no_working_dir = nullptr;
- this->Makefile->AddCustomCommandToOutput(
- hName, depends, no_main_dependency, hCommandLines, no_comment,
- no_working_dir);
+ mf.AddCustomCommandToOutput(hName, depends, no_main_dependency,
+ hCommandLines, no_comment, no_working_dir);
depends.push_back(hName);
- this->Makefile->AddCustomCommandToOutput(
- cxxName, depends, no_main_dependency, cxxCommandLines, no_comment,
- no_working_dir);
+ mf.AddCustomCommandToOutput(cxxName, depends, no_main_dependency,
+ cxxCommandLines, no_comment, no_working_dir);
depends.clear();
depends.push_back(hName);
- this->Makefile->AddCustomCommandToOutput(
- mocName, depends, no_main_dependency, mocCommandLines, no_comment,
- no_working_dir);
+ mf.AddCustomCommandToOutput(mocName, depends, no_main_dependency,
+ mocCommandLines, no_comment, no_working_dir);
}
}
// Store the final list of source files and headers.
- this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
- this->Makefile->AddDefinition(headerList, headerListValue.c_str());
+ mf.AddDefinition(sourceList, sourceListValue);
+ mf.AddDefinition(headerList, headerListValue);
return true;
}
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
index 15cab406f..a17ef547d 100644
--- a/Source/cmQTWrapUICommand.h
+++ b/Source/cmQTWrapUICommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmQTWrapUICommand
- * \brief Create .h and .cxx files rules for Qt user interfaces files
- *
- * cmQTWrapUICommand is used to create wrappers for Qt classes into normal C++
- */
-class cmQTWrapUICommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmQTWrapUICommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmQTWrapUICommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 3683eddda..eb7c900c3 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -2,28 +2,29 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGen.h"
-#include "cmAlgorithms.h"
-#include "cmDuration.h"
-#include "cmProcessOutput.h"
-#include "cmSystemTools.h"
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
-
#include <algorithm>
#include <array>
+#include <initializer_list>
#include <sstream>
#include <utility>
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmAlgorithms.h"
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
// - Static functions
/// @brief Merges newOpts into baseOpts
/// @arg valueOpts list of options that accept a value
void MergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
- std::vector<std::string> const& valueOpts, bool isQt5)
+ std::initializer_list<cm::string_view> valueOpts, bool isQt5)
{
- typedef std::vector<std::string>::iterator Iter;
- typedef std::vector<std::string>::const_iterator CIter;
if (newOpts.empty()) {
return;
}
@@ -33,10 +34,10 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
std::vector<std::string> extraOpts;
- for (CIter fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd;
+ for (auto fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd;
++fit) {
std::string const& newOpt = *fit;
- Iter existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt);
+ auto existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt);
if (existIt != baseOpts.end()) {
if (newOpt.size() >= 2) {
// Acquire the option name
@@ -52,11 +53,9 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Test if this is a value option and change the existing value
- if (!optName.empty() &&
- (std::find(valueOpts.begin(), valueOpts.end(), optName) !=
- valueOpts.end())) {
- const Iter existItNext(existIt + 1);
- const CIter fitNext(fit + 1);
+ if (!optName.empty() && cmContains(valueOpts, optName)) {
+ const auto existItNext(existIt + 1);
+ const auto fitNext(fit + 1);
if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
*existItNext = *fitNext;
++fit;
@@ -74,104 +73,75 @@ void MergeOptions(std::vector<std::string>& baseOpts,
// - Class definitions
unsigned int const cmQtAutoGen::ParallelMax = 64;
-std::string const cmQtAutoGen::ListSep = "<<<S>>>";
-std::string const& cmQtAutoGen::GeneratorName(GenT genType)
+cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
- static const std::string AutoGen("AutoGen");
- static const std::string AutoMoc("AutoMoc");
- static const std::string AutoUic("AutoUic");
- static const std::string AutoRcc("AutoRcc");
-
switch (genType) {
case GenT::GEN:
- return AutoGen;
+ return "AutoGen";
case GenT::MOC:
- return AutoMoc;
+ return "AutoMoc";
case GenT::UIC:
- return AutoUic;
+ return "AutoUic";
case GenT::RCC:
- return AutoRcc;
+ return "AutoRcc";
}
- return AutoGen;
+ return "AutoGen";
}
-std::string const& cmQtAutoGen::GeneratorNameUpper(GenT genType)
+cm::string_view cmQtAutoGen::GeneratorNameUpper(GenT genType)
{
- static const std::string AUTOGEN("AUTOGEN");
- static const std::string AUTOMOC("AUTOMOC");
- static const std::string AUTOUIC("AUTOUIC");
- static const std::string AUTORCC("AUTORCC");
-
switch (genType) {
case GenT::GEN:
- return AUTOGEN;
+ return "AUTOGEN";
case GenT::MOC:
- return AUTOMOC;
+ return "AUTOMOC";
case GenT::UIC:
- return AUTOUIC;
+ return "AUTOUIC";
case GenT::RCC:
- return AUTORCC;
+ return "AUTORCC";
}
- return AUTOGEN;
+ return "AUTOGEN";
}
std::string cmQtAutoGen::Tools(bool moc, bool uic, bool rcc)
{
- std::string res;
- std::vector<std::string> lst;
+ std::array<cm::string_view, 3> lst;
+ decltype(lst)::size_type num = 0;
if (moc) {
- lst.emplace_back("AUTOMOC");
+ lst.at(num++) = "AUTOMOC";
}
if (uic) {
- lst.emplace_back("AUTOUIC");
+ lst.at(num++) = "AUTOUIC";
}
if (rcc) {
- lst.emplace_back("AUTORCC");
+ lst.at(num++) = "AUTORCC";
}
- switch (lst.size()) {
+ switch (num) {
case 1:
- res += lst.at(0);
- break;
+ return std::string(lst[0]);
case 2:
- res += lst.at(0);
- res += " and ";
- res += lst.at(1);
- break;
+ return cmStrCat(lst[0], " and ", lst[1]);
case 3:
- res += lst.at(0);
- res += ", ";
- res += lst.at(1);
- res += " and ";
- res += lst.at(2);
- break;
+ return cmStrCat(lst[0], ", ", lst[1], " and ", lst[2]);
default:
break;
}
- return res;
+ return std::string();
}
-std::string cmQtAutoGen::Quoted(std::string const& text)
+std::string cmQtAutoGen::Quoted(cm::string_view text)
{
- const std::array<std::pair<const char*, const char*>, 9> replaces = {
- { { "\\", "\\\\" },
- { "\"", "\\\"" },
- { "\a", "\\a" },
- { "\b", "\\b" },
- { "\f", "\\f" },
- { "\n", "\\n" },
- { "\r", "\\r" },
- { "\t", "\\t" },
- { "\v", "\\v" } }
- };
+ static std::initializer_list<std::pair<const char*, const char*>> const
+ replacements = { { "\\", "\\\\" }, { "\"", "\\\"" }, { "\a", "\\a" },
+ { "\b", "\\b" }, { "\f", "\\f" }, { "\n", "\\n" },
+ { "\r", "\\r" }, { "\t", "\\t" }, { "\v", "\\v" } };
- std::string res = text;
- for (auto const& pair : replaces) {
+ std::string res(text);
+ for (auto const& pair : replacements) {
cmSystemTools::ReplaceString(res, pair.first, pair.second);
}
- res = '"' + res;
- res += '"';
- return res;
+ return cmStrCat('"', res, '"');
}
std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
@@ -192,37 +162,50 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
return res;
}
-std::string cmQtAutoGen::SubDirPrefix(std::string const& filename)
+std::string cmQtAutoGen::FileNameWithoutLastExtension(cm::string_view filename)
+{
+ auto slashPos = filename.rfind('/');
+ if (slashPos != cm::string_view::npos) {
+ filename.remove_prefix(slashPos + 1);
+ }
+ auto dotPos = filename.rfind('.');
+ return std::string(filename.substr(0, dotPos));
+}
+
+std::string cmQtAutoGen::ParentDir(cm::string_view filename)
{
- std::string::size_type slash_pos = filename.rfind('/');
- if (slash_pos == std::string::npos) {
+ auto slashPos = filename.rfind('/');
+ if (slashPos == cm::string_view::npos) {
return std::string();
}
- return filename.substr(0, slash_pos + 1);
+ return std::string(filename.substr(0, slashPos));
}
-std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename,
- std::string const& suffix)
+std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename)
{
- std::string res;
- auto pos = filename.rfind('.');
- if (pos != std::string::npos) {
- const auto it_dot = filename.begin() + pos;
- res.assign(filename.begin(), it_dot);
- res.append(suffix);
- res.append(it_dot, filename.end());
- } else {
- res = filename;
- res.append(suffix);
+ auto slashPos = filename.rfind('/');
+ if (slashPos == cm::string_view::npos) {
+ return std::string();
}
- return res;
+ return std::string(filename.substr(0, slashPos + 1));
+}
+
+std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename,
+ cm::string_view suffix)
+{
+ auto dotPos = filename.rfind('.');
+ if (dotPos == cm::string_view::npos) {
+ return cmStrCat(filename, suffix);
+ }
+ return cmStrCat(filename.substr(0, dotPos), suffix,
+ filename.substr(dotPos, filename.size() - dotPos));
}
void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
- static std::vector<std::string> const valueOpts = {
+ static std::initializer_list<cm::string_view> const valueOpts = {
"tr", "translate", "postfix", "generator",
"include", // Since Qt 5.3
"g"
@@ -234,9 +217,9 @@ void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts,
std::vector<std::string> const& newOpts,
bool isQt5)
{
- static std::vector<std::string> const valueOpts = { "name", "root",
- "compress",
- "threshold" };
+ static std::initializer_list<cm::string_view> const valueOpts = {
+ "name", "root", "compress", "threshold"
+ };
MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
}
@@ -293,9 +276,8 @@ static bool RccListParseOutput(std::string const& rccStdOut,
std::string::size_type pos = eline.find(searchString);
if (pos == std::string::npos) {
- error = "rcc lists unparsable output:\n";
- error += cmQtAutoGen::Quoted(eline);
- error += "\n";
+ error = cmStrCat("rcc lists unparsable output:\n",
+ cmQtAutoGen::Quoted(eline), '\n');
return false;
}
pos += searchString.length();
@@ -324,9 +306,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
error.clear();
if (!cmSystemTools::FileExists(qrcFile, true)) {
- error = "The resource file ";
- error += Quoted(qrcFile);
- error += " does not exist.";
+ error =
+ cmStrCat("The resource file ", Quoted(qrcFile), " does not exist.");
return false;
}
@@ -352,10 +333,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
// Log command
if (verbose) {
- std::string msg = "Running command:\n";
- msg += QuotedCommand(cmd);
- msg += '\n';
- cmSystemTools::Stdout(msg);
+ cmSystemTools::Stdout(
+ cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'));
}
result = cmSystemTools::RunSingleCommand(
@@ -363,16 +342,13 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
}
if (!result || retVal) {
- error = "The rcc list process failed for ";
- error += Quoted(qrcFile);
- error += "\n";
+ error =
+ cmStrCat("The rcc list process failed for ", Quoted(qrcFile), '\n');
if (!rccStdOut.empty()) {
- error += rccStdOut;
- error += "\n";
+ error += cmStrCat(rccStdOut, '\n');
}
if (!rccStdErr.empty()) {
- error += rccStdErr;
- error += "\n";
+ error += cmStrCat(rccStdErr, '\n');
}
return false;
}
@@ -391,9 +367,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
osst << ifs.rdbuf();
qrcContents = osst.str();
} else {
- error = "The resource file ";
- error += Quoted(qrcFile);
- error += " is not readable\n";
+ error = cmStrCat("The resource file ", Quoted(qrcFile),
+ " is not readable\n");
return false;
}
}
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index 9c5212952..a740ba30a 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -5,17 +5,19 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
+#include <cm/string_view>
+
/** \class cmQtAutoGen
* \brief Common base class for QtAutoGen classes
*/
class cmQtAutoGen
{
public:
- /// @brief Integer version
+ /** Integer version. */
struct IntegerVersion
{
unsigned int Major = 0;
@@ -41,6 +43,7 @@ public:
}
};
+ /** Compiler features. */
class CompilerFeatures
{
public:
@@ -48,9 +51,9 @@ public:
std::string HelpOutput;
std::vector<std::string> ListOptions;
};
- typedef std::shared_ptr<CompilerFeatures> CompilerFeaturesHandle;
+ using CompilerFeaturesHandle = std::shared_ptr<CompilerFeatures>;
- /// @brief AutoGen generator type
+ /** AutoGen generator type. */
enum class GenT
{
GEN, // AUTOGEN
@@ -59,31 +62,35 @@ public:
RCC // AUTORCC
};
- /// @brief Nested lists separator
- static std::string const ListSep;
/// @brief Maximum number of parallel threads/processes in a generator
static unsigned int const ParallelMax;
public:
/// @brief Returns the generator name
- static std::string const& GeneratorName(GenT genType);
+ static cm::string_view GeneratorName(GenT genType);
/// @brief Returns the generator name in upper case
- static std::string const& GeneratorNameUpper(GenT genType);
+ static cm::string_view GeneratorNameUpper(GenT genType);
/// @brief Returns a string with the requested tool names
static std::string Tools(bool moc, bool uic, bool rcc);
/// @brief Returns the string escaped and enclosed in quotes
- static std::string Quoted(std::string const& text);
+ static std::string Quoted(cm::string_view text);
static std::string QuotedCommand(std::vector<std::string> const& command);
+ /// @brief Returns the file name without path and extension (thread safe)
+ static std::string FileNameWithoutLastExtension(cm::string_view filename);
+
+ /// @brief Returns the parent directory of the file (thread safe)
+ static std::string ParentDir(cm::string_view filename);
+
/// @brief Returns the parent directory of the file with a "/" suffix
- static std::string SubDirPrefix(std::string const& filename);
+ static std::string SubDirPrefix(cm::string_view filename);
/// @brief Appends the suffix to the filename before the last dot
- static std::string AppendFilenameSuffix(std::string const& filename,
- std::string const& suffix);
+ static std::string AppendFilenameSuffix(cm::string_view filename,
+ cm::string_view suffix);
/// @brief Merges newOpts into baseOpts
static void UicMergeOptions(std::vector<std::string>& baseOpts,
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index ef8a56b3b..ef6b88636 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -1,25 +1,27 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenGlobalInitializer.h"
-#include "cmQtAutoGen.h"
-#include "cmQtAutoGenInitializer.h"
-#include "cmAlgorithms.h"
+#include <utility>
+
+#include <cm/memory>
+
#include "cmCustomCommandLines.h"
+#include "cmCustomCommandTypes.h"
#include "cmDuration.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
+#include "cmQtAutoGen.h"
+#include "cmQtAutoGenInitializer.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include <memory>
-#include <utility>
-
cmQtAutoGenGlobalInitializer::Keywords::Keywords()
: AUTOMOC("AUTOMOC")
, AUTOUIC("AUTOUIC")
@@ -48,8 +50,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
{
cmMakefile* makefile = localGen->GetMakefile();
// Detect global autogen target name
- if (cmSystemTools::IsOn(
- makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
+ if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
std::string targetName =
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME");
if (targetName.empty()) {
@@ -60,8 +61,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
}
// Detect global autorcc target name
- if (cmSystemTools::IsOn(
- makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
+ if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
std::string targetName =
makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME");
if (targetName.empty()) {
@@ -119,23 +119,17 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
bool const uicDisabled = (uic && !uicAvailable);
bool const rccDisabled = (rcc && !rccAvailable);
if (mocDisabled || uicDisabled || rccDisabled) {
- std::string msg = "AUTOGEN: No valid Qt version found for target ";
- msg += target->GetName();
- msg += ". ";
- msg += cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled);
- msg += " disabled. Consider adding:\n";
- {
- std::string version = (qtVersion.second == 0)
- ? std::string("<QTVERSION>")
- : std::to_string(qtVersion.second);
- std::string comp = uicDisabled ? "Widgets" : "Core";
- msg += " find_package(Qt";
- msg += version;
- msg += " COMPONENTS ";
- msg += comp;
- msg += ")\n";
- }
- msg += "to your CMakeLists.txt file.";
+ cmAlphaNum version = (qtVersion.second == 0)
+ ? cmAlphaNum("<QTVERSION>")
+ : cmAlphaNum(qtVersion.second);
+ cmAlphaNum component = uicDisabled ? "Widgets" : "Core";
+
+ std::string const msg = cmStrCat(
+ "AUTOGEN: No valid Qt version found for target ",
+ target->GetName(), ". ",
+ cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled),
+ " disabled. Consider adding:\n", " find_package(Qt", version,
+ " COMPONENTS ", component, ")\n", "to your CMakeLists.txt file.");
target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
}
if (mocIsValid || uicIsValid || rccIsValid) {
@@ -161,7 +155,7 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
// Create utility target
cmTarget* target = makefile->AddUtilityCommand(
- name, cmMakefile::TargetOrigin::Generator, true,
+ name, cmCommandOrigin::Generator, true,
makefile->GetHomeOutputDirectory().c_str() /*work dir*/,
std::vector<std::string>() /*output*/,
std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
@@ -218,11 +212,8 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
// Check if the executable exists
if (!cmSystemTools::FileExists(executable, true)) {
- error = "The \"";
- error += generator;
- error += "\" executable ";
- error += cmQtAutoGen::Quoted(executable);
- error += " does not exist.";
+ error = cmStrCat("The \"", generator, "\" executable ",
+ cmQtAutoGen::Quoted(executable), " does not exist.");
return cmQtAutoGen::CompilerFeaturesHandle();
}
@@ -238,15 +229,10 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
command, &stdOut, &stdErr, &retVal, nullptr, cmSystemTools::OUTPUT_NONE,
cmDuration::zero(), cmProcessOutput::Auto);
if (!runResult) {
- error = "Test run of \"";
- error += generator;
- error += "\" executable ";
- error += cmQtAutoGen::Quoted(executable) + " failed.\n";
- error += cmQtAutoGen::QuotedCommand(command);
- error += "\n";
- error += stdOut;
- error += "\n";
- error += stdErr;
+ error = cmStrCat("Test run of \"", generator, "\" executable ",
+ cmQtAutoGen::Quoted(executable), " failed.\n",
+ cmQtAutoGen::QuotedCommand(command), '\n', stdOut, '\n',
+ stdErr);
return cmQtAutoGen::CompilerFeaturesHandle();
}
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index d56153ab7..806725a01 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -5,14 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmQtAutoGen.h"
-
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
+#include "cmQtAutoGen.h"
+
class cmLocalGenerator;
class cmQtAutoGenInitializer;
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 9985f93eb..a20f1060f 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1,13 +1,32 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenInitializer.h"
-#include "cmQtAutoGen.h"
-#include "cmQtAutoGenGlobalInitializer.h"
+
+#include <cstddef>
+#include <deque>
+#include <initializer_list>
+#include <map>
+#include <ostream>
+#include <set>
+#include <string>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <cm/algorithm>
+#include <cm/iterator>
+#include <cm/memory>
+
+#include "cmsys/SystemInformation.hxx"
+
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
-#include "cmFilePathChecksum.h"
+#include "cmCustomCommandTypes.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -16,44 +35,36 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
-#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmQtAutoGen.h"
+#include "cmQtAutoGenGlobalInitializer.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocationKind.h"
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
-#include "cmsys/SystemInformation.hxx"
-#include <algorithm>
-#include <array>
-#include <deque>
-#include <map>
-#include <set>
-#include <string>
-#include <unordered_set>
-#include <utility>
-#include <vector>
+namespace {
-static std::size_t GetParallelCPUCount()
+unsigned int GetParallelCPUCount()
{
- static std::size_t count = 0;
+ static unsigned int count = 0;
// Detect only on the first call
if (count == 0) {
cmsys::SystemInformation info;
info.RunCPUCheck();
- count = info.GetNumberOfPhysicalCPU();
- count = std::max<std::size_t>(count, 1);
- count = std::min<std::size_t>(count, cmQtAutoGen::ParallelMax);
+ count =
+ cm::clamp(info.GetNumberOfPhysicalCPU(), 1u, cmQtAutoGen::ParallelMax);
}
return count;
}
-static std::string FileProjectRelativePath(cmMakefile* makefile,
- std::string const& fileName)
+std::string FileProjectRelativePath(cmMakefile* makefile,
+ std::string const& fileName)
{
std::string res;
{
@@ -77,9 +88,9 @@ static std::string FileProjectRelativePath(cmMakefile* makefile,
* recursive STATIC_LIBRARY dependencies depends on targetOrigin
* (STATIC_LIBRARY cycle).
*/
-static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
- cmGeneratorTarget const* targetDepend,
- std::string const& config)
+bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
+ cmGeneratorTarget const* targetDepend,
+ std::string const& config)
{
bool cycle = false;
if ((targetOrigin->GetType() == cmStateEnums::STATIC_LIBRARY) &&
@@ -117,109 +128,180 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
return cycle;
}
-cmQtAutoGenInitializer::InfoWriter::InfoWriter(std::string const& filename)
+/** Sanitizes file search paths. */
+class SearchPathSanitizer
{
- Ofs_.SetCopyIfDifferent(true);
- Ofs_.Open(filename, false, true);
-}
+public:
+ SearchPathSanitizer(cmMakefile* makefile)
+ : SourcePath_(makefile->GetCurrentSourceDirectory())
+ {
+ }
+ std::vector<std::string> operator()(
+ std::vector<std::string> const& paths) const;
+
+private:
+ std::string SourcePath_;
+};
-template <class IT>
-std::string cmQtAutoGenInitializer::InfoWriter::ListJoin(IT it_begin,
- IT it_end)
+std::vector<std::string> SearchPathSanitizer::operator()(
+ std::vector<std::string> const& paths) const
{
- std::string res;
- for (IT it = it_begin; it != it_end; ++it) {
- if (it != it_begin) {
- res += ';';
- }
- for (const char* c = it->c_str(); *c; ++c) {
- if (*c == '"') {
- // Escape the double quote to avoid ending the argument.
- res += "\\\"";
- } else if (*c == '$') {
- // Escape the dollar to avoid expanding variables.
- res += "\\$";
- } else if (*c == '\\') {
- // Escape the backslash to avoid other escapes.
- res += "\\\\";
- } else if (*c == ';') {
- // Escape the semicolon to avoid list expansion.
- res += "\\;";
- } else {
- // Other characters will be parsed correctly.
- res += *c;
- }
+ std::vector<std::string> res;
+ res.reserve(paths.size());
+ for (std::string const& srcPath : paths) {
+ // Collapse relative paths
+ std::string path = cmSystemTools::CollapseFullPath(srcPath, SourcePath_);
+ // Remove suffix slashes
+ while (cmHasSuffix(path, '/')) {
+ path.pop_back();
+ }
+ // Accept only non empty paths
+ if (!path.empty()) {
+ res.emplace_back(std::move(path));
}
}
return res;
}
-std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey(
- const char* key, std::string const& config)
+/** @brief Writes a CMake info file. */
+class InfoWriter
+{
+public:
+ // -- Single value
+ void Set(std::string const& key, std::string const& value)
+ {
+ Value_[key] = value;
+ }
+ void SetConfig(std::string const& key,
+ cmQtAutoGenInitializer::ConfigString const& cfgStr);
+ void SetBool(std::string const& key, bool value) { Value_[key] = value; }
+ void SetUInt(std::string const& key, unsigned int value)
+ {
+ Value_[key] = value;
+ }
+
+ // -- Array utility
+ template <typename CONT>
+ static bool MakeArray(Json::Value& jval, CONT const& container);
+
+ template <typename CONT>
+ static void MakeStringArray(Json::Value& jval, CONT const& container);
+
+ // -- Array value
+ template <typename CONT>
+ void SetArray(std::string const& key, CONT const& container);
+ template <typename CONT>
+ void SetConfigArray(
+ std::string const& key,
+ cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr);
+
+ // -- Array of arrays
+ template <typename CONT, typename FUNC>
+ void SetArrayArray(std::string const& key, CONT const& container, FUNC func);
+
+ // -- Save to json file
+ bool Save(std::string const& filename);
+
+private:
+ Json::Value Value_;
+};
+
+void InfoWriter::SetConfig(std::string const& key,
+ cmQtAutoGenInitializer::ConfigString const& cfgStr)
{
- std::string ckey = key;
- ckey += '_';
- ckey += config;
- return ckey;
+ Set(key, cfgStr.Default);
+ for (auto const& item : cfgStr.Config) {
+ Set(cmStrCat(key, '_', item.first), item.second);
+ }
}
-void cmQtAutoGenInitializer::InfoWriter::Write(const char* key,
- std::string const& value)
+template <typename CONT>
+bool InfoWriter::MakeArray(Json::Value& jval, CONT const& container)
{
- Ofs_ << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value)
- << ")\n";
-};
+ jval = Json::arrayValue;
+ std::size_t const listSize = cm::size(container);
+ if (listSize == 0) {
+ return false;
+ }
+ jval.resize(static_cast<unsigned int>(listSize));
+ return true;
+}
-void cmQtAutoGenInitializer::InfoWriter::WriteUInt(const char* key,
- unsigned int value)
+template <typename CONT>
+void InfoWriter::MakeStringArray(Json::Value& jval, CONT const& container)
{
- Ofs_ << "set(" << key << " " << value << ")\n";
-};
+ if (MakeArray(jval, container)) {
+ Json::ArrayIndex ii = 0;
+ for (std::string const& item : container) {
+ jval[ii++] = item;
+ }
+ }
+}
-template <class C>
-void cmQtAutoGenInitializer::InfoWriter::WriteStrings(const char* key,
- C const& container)
+template <typename CONT>
+void InfoWriter::SetArray(std::string const& key, CONT const& container)
{
- Ofs_ << "set(" << key << " \""
- << ListJoin(container.begin(), container.end()) << "\")\n";
+ MakeStringArray(Value_[key], container);
}
-void cmQtAutoGenInitializer::InfoWriter::WriteConfig(
- const char* key, std::map<std::string, std::string> const& map)
+template <typename CONT, typename FUNC>
+void InfoWriter::SetArrayArray(std::string const& key, CONT const& container,
+ FUNC func)
{
- for (auto const& item : map) {
- Write(ConfigKey(key, item.first).c_str(), item.second);
+ Json::Value& jval = Value_[key];
+ if (MakeArray(jval, container)) {
+ Json::ArrayIndex ii = 0;
+ for (auto const& citem : container) {
+ Json::Value& aval = jval[ii++];
+ aval = Json::arrayValue;
+ func(aval, citem);
+ }
}
-};
+}
-template <class C>
-void cmQtAutoGenInitializer::InfoWriter::WriteConfigStrings(
- const char* key, std::map<std::string, C> const& map)
+template <typename CONT>
+void InfoWriter::SetConfigArray(
+ std::string const& key,
+ cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr)
{
- for (auto const& item : map) {
- WriteStrings(ConfigKey(key, item.first).c_str(), item.second);
+ SetArray(key, cfgStr.Default);
+ for (auto const& item : cfgStr.Config) {
+ SetArray(cmStrCat(key, '_', item.first), item.second);
}
}
-void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists(
- const char* key, std::vector<std::vector<std::string>> const& lists)
+bool InfoWriter::Save(std::string const& filename)
{
- std::vector<std::string> seplist;
- for (const std::vector<std::string>& list : lists) {
- std::string blist = "{";
- blist += ListJoin(list.begin(), list.end());
- blist += "}";
- seplist.push_back(std::move(blist));
+ cmGeneratedFileStream fileStream;
+ fileStream.SetCopyIfDifferent(true);
+ fileStream.Open(filename, false, true);
+ if (!fileStream) {
+ return false;
}
- Write(key, cmJoin(seplist, cmQtAutoGen::ListSep));
-};
+
+ Json::StyledStreamWriter jsonWriter;
+ try {
+ jsonWriter.write(fileStream, Value_);
+ } catch (...) {
+ return false;
+ }
+
+ return fileStream.Close();
+}
+
+} // End of unnamed namespace
cmQtAutoGenInitializer::cmQtAutoGenInitializer(
- cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target,
- IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled,
- bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget)
+ cmQtAutoGenGlobalInitializer* globalInitializer,
+ cmGeneratorTarget* genTarget, IntegerVersion const& qtVersion,
+ bool mocEnabled, bool uicEnabled, bool rccEnabled, bool globalAutogenTarget,
+ bool globalAutoRccTarget)
: GlobalInitializer(globalInitializer)
- , Target(target)
+ , GenTarget(genTarget)
+ , GlobalGen(genTarget->GetGlobalGenerator())
+ , LocalGen(genTarget->GetLocalGenerator())
+ , Makefile(genTarget->Makefile)
+ , PathCheckSum(genTarget->Makefile)
, QtVersion(qtVersion)
{
AutogenTarget.GlobalTarget = globalAutogenTarget;
@@ -231,38 +313,42 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer(
bool cmQtAutoGenInitializer::InitCustomTargets()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
- cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator();
-
// Configurations
- this->MultiConfig = globalGen->IsMultiConfig();
- this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList);
+ this->MultiConfig = this->GlobalGen->IsMultiConfig();
+ this->ConfigDefault = this->Makefile->GetConfigurations(this->ConfigsList);
if (this->ConfigsList.empty()) {
this->ConfigsList.push_back(this->ConfigDefault);
}
// Verbosity
- this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
- if (!this->Verbosity.empty()) {
- unsigned long iVerb = 0;
- if (!cmSystemTools::StringToULong(this->Verbosity.c_str(), &iVerb)) {
- // Non numeric verbosity
- this->Verbosity = cmSystemTools::IsOn(this->Verbosity) ? "1" : "0";
+ {
+ std::string def =
+ this->Makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
+ if (!def.empty()) {
+ unsigned long iVerb = 0;
+ if (cmStrToULong(def, &iVerb)) {
+ // Numeric verbosity
+ this->Verbosity = static_cast<unsigned int>(iVerb);
+ } else {
+ // Non numeric verbosity
+ if (cmIsOn(def)) {
+ this->Verbosity = 1;
+ }
+ }
}
}
// Targets FOLDER
{
const char* folder =
- makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
+ this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
if (folder == nullptr) {
- folder =
- makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
+ folder = this->Makefile->GetState()->GetGlobalProperty(
+ "AUTOGEN_TARGETS_FOLDER");
}
// Inherit FOLDER property from target (#13688)
if (folder == nullptr) {
- folder = this->Target->GetProperty("FOLDER");
+ folder = this->GenTarget->GetProperty("FOLDER");
}
if (folder != nullptr) {
this->TargetsFolder = folder;
@@ -272,7 +358,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Check status of policy CMP0071
{
cmPolicies::PolicyStatus const CMP0071_status =
- makefile->GetPolicyStatus(cmPolicies::CMP0071);
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0071);
switch (CMP0071_status) {
case cmPolicies::WARN:
this->CMP0071Warn = true;
@@ -293,24 +379,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
{
// Collapsed current binary directory
std::string const cbd = cmSystemTools::CollapseFullPath(
- std::string(), makefile->GetCurrentBinaryDirectory());
+ std::string(), this->Makefile->GetCurrentBinaryDirectory());
// Info directory
- this->Dir.Info = cbd;
- this->Dir.Info += "/CMakeFiles";
- this->Dir.Info += '/';
- this->Dir.Info += this->Target->GetName();
- this->Dir.Info += "_autogen";
- this->Dir.Info += ".dir";
+ this->Dir.Info = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(),
+ "_autogen.dir");
cmSystemTools::ConvertToUnixSlashes(this->Dir.Info);
// Build directory
- this->Dir.Build = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR");
+ this->Dir.Build = this->GenTarget->GetSafeProperty("AUTOGEN_BUILD_DIR");
if (this->Dir.Build.empty()) {
- this->Dir.Build = cbd;
- this->Dir.Build += '/';
- this->Dir.Build += this->Target->GetName();
- this->Dir.Build += "_autogen";
+ this->Dir.Build =
+ cmStrCat(cbd, '/', this->GenTarget->GetName(), "_autogen");
}
cmSystemTools::ConvertToUnixSlashes(this->Dir.Build);
// Cleanup build directory
@@ -321,19 +401,11 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
cmSystemTools::ConvertToUnixSlashes(this->Dir.Work);
// Include directory
- this->Dir.Include = this->Dir.Build;
- this->Dir.Include += "/include";
+ ConfigFileNames(this->Dir.Include, cmStrCat(this->Dir.Build, "/include"),
+ "");
+ this->Dir.IncludeGenExp = this->Dir.Include.Default;
if (this->MultiConfig) {
- this->Dir.Include += "_$<CONFIG>";
- }
- // Per config include directories
- if (this->MultiConfig) {
- for (std::string const& cfg : this->ConfigsList) {
- std::string& dir = this->Dir.ConfigInclude[cfg];
- dir = this->Dir.Build;
- dir += "/include_";
- dir += cfg;
- }
+ this->Dir.IncludeGenExp += "_$<CONFIG>";
}
}
@@ -350,55 +422,48 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
// Autogen target name
- this->AutogenTarget.Name = this->Target->GetName();
- this->AutogenTarget.Name += "_autogen";
+ this->AutogenTarget.Name =
+ cmStrCat(this->GenTarget->GetName(), "_autogen");
// Autogen target parallel processing
- this->AutogenTarget.Parallel =
- this->Target->GetSafeProperty("AUTOGEN_PARALLEL");
- if (this->AutogenTarget.Parallel.empty() ||
- (this->AutogenTarget.Parallel == "AUTO")) {
- // Autodetect number of CPUs
- this->AutogenTarget.Parallel = std::to_string(GetParallelCPUCount());
+ {
+ std::string prop = this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
+ if (prop.empty() || (prop == "AUTO")) {
+ // Autodetect number of CPUs
+ this->AutogenTarget.Parallel = GetParallelCPUCount();
+ } else {
+ this->AutogenTarget.Parallel = 1;
+ }
}
// Autogen target info and settings files
{
- this->AutogenTarget.InfoFile = this->Dir.Info;
- this->AutogenTarget.InfoFile += "/AutogenInfo.cmake";
-
- this->AutogenTarget.SettingsFile = this->Dir.Info;
- this->AutogenTarget.SettingsFile += "/AutogenOldSettings.txt";
-
- if (this->MultiConfig) {
- for (std::string const& cfg : this->ConfigsList) {
- std::string& filename = this->AutogenTarget.ConfigSettingsFile[cfg];
- filename =
- AppendFilenameSuffix(this->AutogenTarget.SettingsFile, "_" + cfg);
- this->AddCleanFile(filename);
- }
- } else {
- this->AddCleanFile(this->AutogenTarget.SettingsFile);
- }
+ // Info file
+ this->AutogenTarget.InfoFile =
+ cmStrCat(this->Dir.Info, "/AutogenInfo.json");
+
+ // Used settings file
+ ConfigFileNames(this->AutogenTarget.SettingsFile,
+ cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt");
+ ConfigFileClean(this->AutogenTarget.SettingsFile);
- this->AutogenTarget.ParseCacheFile = this->Dir.Info;
- this->AutogenTarget.ParseCacheFile += "/ParseCache.txt";
- this->AddCleanFile(this->AutogenTarget.ParseCacheFile);
+ // Parse cache file
+ ConfigFileNames(this->AutogenTarget.ParseCacheFile,
+ cmStrCat(this->Dir.Info, "/ParseCache"), ".txt");
+ ConfigFileClean(this->AutogenTarget.ParseCacheFile);
}
// Autogen target: Compute user defined dependencies
{
this->AutogenTarget.DependOrigin =
- this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
+ this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
std::string const deps =
- this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
+ this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
- std::vector<std::string> extraDeps;
- cmSystemTools::ExpandListArgument(deps, extraDeps);
- for (std::string const& depName : extraDeps) {
+ for (std::string const& depName : cmExpandedList(deps)) {
// Allow target and file dependencies
- auto* depTarget = makefile->FindTargetToUse(depName);
+ auto* depTarget = this->Makefile->FindTargetToUse(depName);
if (depTarget != nullptr) {
this->AutogenTarget.DependTargets.insert(depTarget);
} else {
@@ -408,16 +473,47 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
}
- // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning
if (this->Moc.Enabled) {
- if (cmSystemTools::IsOn(
- makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) {
- std::string msg = "AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
- "deprecated an will be removed in the future. ";
- msg += "Consider disabling it and converting the target ";
- msg += this->Target->GetName();
- msg += " to regular mode.";
- makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+ // Path prefix
+ if (cmIsOn(this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"))) {
+ this->Moc.PathPrefix = true;
+ }
+
+ // CMAKE_AUTOMOC_RELAXED_MODE
+ if (this->Makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
+ this->Moc.RelaxedMode = true;
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
+ "deprecated an will be removed in the future. Consider "
+ "disabling it and converting the target ",
+ this->GenTarget->GetName(), " to regular mode."));
+ }
+
+ // Options
+ cmExpandList(this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS"),
+ this->Moc.Options);
+ // Filters
+ cmExpandList(this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"),
+ this->Moc.MacroNames);
+ {
+ auto filterList = cmExpandedList(
+ this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
+ if ((filterList.size() % 2) != 0) {
+ cmSystemTools::Error(
+ cmStrCat("AutoMoc: AUTOMOC_DEPEND_FILTERS predefs size ",
+ filterList.size(), " is not a multiple of 2."));
+ return false;
+ }
+ this->Moc.DependFilters.reserve(1 + (filterList.size() / 2));
+ this->Moc.DependFilters.emplace_back(
+ "Q_PLUGIN_METADATA",
+ "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
+ "[^\\)]*FILE[ \t]*\"([^\"]+)\"");
+ for (std::size_t ii = 0; ii != filterList.size(); ii += 2) {
+ this->Moc.DependFilters.emplace_back(filterList[ii],
+ filterList[ii + 1]);
+ }
}
}
}
@@ -429,7 +525,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Add autogen include directory to the origin target INCLUDE_DIRECTORIES
if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) {
- this->Target->AddIncludeDirectory(this->Dir.Include, true);
+ this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, true);
}
// Scan files
@@ -452,54 +548,57 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
bool cmQtAutoGenInitializer::InitMoc()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-
// Mocs compilation file
- this->Moc.MocsCompilation = this->Dir.Build;
- this->Moc.MocsCompilation += "/mocs_compilation.cpp";
+ this->Moc.CompilationFile =
+ cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
- // Moc predefs command
- if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
+ // Moc predefs
+ if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
(this->QtVersion >= IntegerVersion(5, 8))) {
- this->Moc.PredefsCmd =
- makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
+ // Command
+ cmExpandList(this->Makefile->GetSafeDefinition(
+ "CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"),
+ this->Moc.PredefsCmd);
+ // Header
+ if (!this->Moc.PredefsCmd.empty()) {
+ ConfigFileNames(this->Moc.PredefsFile,
+ cmStrCat(this->Dir.Build, "/moc_predefs"), ".h");
+ }
}
// Moc includes
{
- bool const appendImplicit = (this->QtVersion.Major >= 5);
- auto GetIncludeDirs =
- [this, localGen,
- appendImplicit](std::string const& cfg) -> std::vector<std::string> {
+ SearchPathSanitizer sanitizer(this->Makefile);
+ auto getDirs =
+ [this, &sanitizer](std::string const& cfg) -> std::vector<std::string> {
// Get the include dirs for this target, without stripping the implicit
- // include dirs off, see
- // https://gitlab.kitware.com/cmake/cmake/issues/13667
+ // include dirs off, see issue #13667.
std::vector<std::string> dirs;
- localGen->GetIncludeDirectoriesImplicit(dirs, this->Target, "CXX", cfg,
- false, appendImplicit);
- return dirs;
+ bool const appendImplicit = (this->QtVersion.Major >= 5);
+ this->LocalGen->GetIncludeDirectoriesImplicit(
+ dirs, this->GenTarget, "CXX", cfg, false, appendImplicit);
+ return sanitizer(dirs);
};
// Default configuration include directories
- this->Moc.Includes = GetIncludeDirs(this->ConfigDefault);
+ this->Moc.Includes.Default = getDirs(this->ConfigDefault);
// Other configuration settings
if (this->MultiConfig) {
for (std::string const& cfg : this->ConfigsList) {
- std::vector<std::string> dirs = GetIncludeDirs(cfg);
- if (dirs != this->Moc.Includes) {
- this->Moc.ConfigIncludes[cfg] = std::move(dirs);
+ std::vector<std::string> dirs = getDirs(cfg);
+ if (dirs == this->Moc.Includes.Default) {
+ continue;
}
+ this->Moc.Includes.Config[cfg] = std::move(dirs);
}
}
}
// Moc compile definitions
{
- auto GetCompileDefinitions =
- [this, localGen](std::string const& cfg) -> std::set<std::string> {
+ auto getDefs = [this](std::string const& cfg) -> std::set<std::string> {
std::set<std::string> defines;
- localGen->GetTargetDefines(this->Target, cfg, "CXX", defines);
+ this->LocalGen->GetTargetDefines(this->GenTarget, cfg, "CXX", defines);
#ifdef _WIN32
if (this->Moc.PredefsCmd.empty()) {
// Add WIN32 definition if we don't have a moc_predefs.h
@@ -510,14 +609,15 @@ bool cmQtAutoGenInitializer::InitMoc()
};
// Default configuration defines
- this->Moc.Defines = GetCompileDefinitions(this->ConfigDefault);
+ this->Moc.Defines.Default = getDefs(this->ConfigDefault);
// Other configuration defines
if (this->MultiConfig) {
for (std::string const& cfg : this->ConfigsList) {
- std::set<std::string> defines = GetCompileDefinitions(cfg);
- if (defines != this->Moc.Defines) {
- this->Moc.ConfigDefines[cfg] = std::move(defines);
+ std::set<std::string> defines = getDefs(cfg);
+ if (defines == this->Moc.Defines.Default) {
+ continue;
}
+ this->Moc.Defines.Config[cfg] = std::move(defines);
}
}
}
@@ -539,39 +639,33 @@ bool cmQtAutoGenInitializer::InitMoc()
bool cmQtAutoGenInitializer::InitUic()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
-
// Uic search paths
{
std::string const usp =
- this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
+ this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
- cmSystemTools::ExpandListArgument(usp, this->Uic.SearchPaths);
- std::string const& srcDir = makefile->GetCurrentSourceDirectory();
- for (std::string& path : this->Uic.SearchPaths) {
- path = cmSystemTools::CollapseFullPath(path, srcDir);
- }
+ this->Uic.SearchPaths =
+ SearchPathSanitizer(this->Makefile)(cmExpandedList(usp));
}
}
// Uic target options
{
- auto UicGetOpts =
- [this](std::string const& cfg) -> std::vector<std::string> {
+ auto getOpts = [this](std::string const& cfg) -> std::vector<std::string> {
std::vector<std::string> opts;
- this->Target->GetAutoUicOptions(opts, cfg);
+ this->GenTarget->GetAutoUicOptions(opts, cfg);
return opts;
};
- // Default settings
- this->Uic.Options = UicGetOpts(this->ConfigDefault);
-
- // Configuration specific settings
+ // Default options
+ this->Uic.Options.Default = getOpts(this->ConfigDefault);
+ // Configuration specific options
if (this->MultiConfig) {
for (std::string const& cfg : this->ConfigsList) {
- std::vector<std::string> options = UicGetOpts(cfg);
- if (options != this->Uic.Options) {
- this->Uic.ConfigOptions[cfg] = std::move(options);
+ std::vector<std::string> options = getOpts(cfg);
+ if (options == this->Uic.Options.Default) {
+ continue;
}
+ this->Uic.Options.Config[cfg] = std::move(options);
}
}
}
@@ -619,13 +713,13 @@ bool cmQtAutoGenInitializer::InitRcc()
bool cmQtAutoGenInitializer::InitScanFiles()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
+ cmake const* cm = this->Makefile->GetCMakeInstance();
auto const& kw = this->GlobalInitializer->kw();
auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath,
bool muIt) -> MUFileHandle {
MUFileHandle muf = cm::make_unique<MUFile>();
- muf->RealPath = cmSystemTools::GetRealPath(fullPath);
+ muf->FullPath = fullPath;
muf->SF = sf;
muf->Generated = sf->GetIsGenerated();
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
@@ -655,39 +749,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
{
// Scan through target files
std::vector<cmSourceFile*> srcFiles;
- this->Target->GetConfigCommonSourceFiles(srcFiles);
+ this->GenTarget->GetConfigCommonSourceFiles(srcFiles);
for (cmSourceFile* sf : srcFiles) {
- // sf->GetExtension() is only valid after sf->GetFullPath() ...
+ // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
// Since we're iterating over source files that might be not in the
// target we need to check for path errors (not existing files).
std::string pathError;
- std::string const& fullPath = sf->GetFullPath(&pathError);
+ std::string const& fullPath = sf->ResolveFullPath(&pathError);
if (!pathError.empty() || fullPath.empty()) {
continue;
}
- std::string const& ext = sf->GetExtension();
+ std::string const& extLower =
+ cmSystemTools::LowerCase(sf->GetExtension());
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
- switch (cmSystemTools::GetFileFormat(ext)) {
- case cmSystemTools::HEADER_FILE_FORMAT:
- addMUFile(makeMUFile(sf, fullPath, true), true);
- break;
- case cmSystemTools::CXX_FILE_FORMAT:
- addMUFile(makeMUFile(sf, fullPath, true), false);
- break;
- default:
- break;
+ if (cm->IsHeaderExtension(extLower)) {
+ addMUFile(makeMUFile(sf, fullPath, true), true);
+ } else if (cm->IsSourceExtension(extLower)) {
+ addMUFile(makeMUFile(sf, fullPath, true), false);
}
}
// Register rcc enabled files
if (this->Rcc.Enabled) {
- if ((ext == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
+ if ((extLower == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) &&
!sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
// Register qrc file
Qrc qrc;
- qrc.QrcFile = cmSystemTools::GetRealPath(fullPath);
+ qrc.QrcFile = fullPath;
qrc.QrcName =
cmSystemTools::GetFilenameWithoutLastExtension(qrc.QrcFile);
qrc.Generated = sf->GetIsGenerated();
@@ -695,7 +785,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
{
std::string const opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS);
if (!opts.empty()) {
- cmSystemTools::ExpandListArgument(opts, qrc.Options);
+ cmExpandList(opts, qrc.Options);
}
}
this->Rcc.Qrcs.push_back(std::move(qrc));
@@ -707,36 +797,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// sources meta data cache. Clear it so that OBJECT library targets that
// are AUTOGEN initialized after this target get their added
// mocs_compilation.cpp source acknowledged by this target.
- this->Target->ClearSourcesCache();
+ this->GenTarget->ClearSourcesCache();
// For source files find additional headers and private headers
if (this->MocOrUicEnabled()) {
std::vector<MUFileHandle> extraHeaders;
extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2);
// Header search suffixes and extensions
- std::array<std::string, 2> const suffixes{ { "", "_p" } };
- auto const& exts = makefile->GetCMakeInstance()->GetHeaderExtensions();
+ static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
+ auto const& exts = cm->GetHeaderExtensions();
// Scan through sources
for (auto const& pair : this->AutogenTarget.Sources) {
MUFile const& muf = *pair.second;
if (muf.MocIt || muf.UicIt) {
// Search for the default header file and a private header
- std::string const& srcPath = muf.SF->GetFullPath();
- std::string basePath = cmQtAutoGen::SubDirPrefix(srcPath);
- basePath += cmSystemTools::GetFilenameWithoutLastExtension(srcPath);
+ std::string const& srcFullPath = muf.SF->ResolveFullPath();
+ std::string basePath = cmStrCat(
+ cmQtAutoGen::SubDirPrefix(srcFullPath),
+ cmSystemTools::GetFilenameWithoutLastExtension(srcFullPath));
for (auto const& suffix : suffixes) {
- std::string const suffixedPath = basePath + suffix;
+ std::string const suffixedPath = cmStrCat(basePath, suffix);
for (auto const& ext : exts) {
- std::string fullPath = suffixedPath;
- fullPath += '.';
- fullPath += ext;
+ std::string fullPath = cmStrCat(suffixedPath, '.', ext);
auto constexpr locationKind = cmSourceFileLocationKind::Known;
- cmSourceFile* sf = makefile->GetSource(fullPath, locationKind);
+ cmSourceFile* sf =
+ this->Makefile->GetSource(fullPath, locationKind);
if (sf != nullptr) {
// Check if we know about this header already
- if (this->AutogenTarget.Headers.find(sf) !=
- this->AutogenTarget.Headers.end()) {
+ if (cmContains(this->AutogenTarget.Headers, sf)) {
continue;
}
// We only accept not-GENERATED files that do exist.
@@ -746,7 +835,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
} else if (cmSystemTools::FileExists(fullPath)) {
// Create a new source file for the existing file
- sf = makefile->CreateSource(fullPath, false, locationKind);
+ sf = this->Makefile->CreateSource(fullPath, false, locationKind);
}
if (sf != nullptr) {
@@ -775,37 +864,34 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// The reason is that their file names might be discovered from source files
// at generation time.
if (this->MocOrUicEnabled()) {
- for (cmSourceFile* sf : makefile->GetSourceFiles()) {
- // sf->GetExtension() is only valid after sf->GetFullPath() ...
+ for (cmSourceFile* sf : this->Makefile->GetSourceFiles()) {
+ // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
// Since we're iterating over source files that might be not in the
// target we need to check for path errors (not existing files).
std::string pathError;
- std::string const& fullPath = sf->GetFullPath(&pathError);
+ std::string const& fullPath = sf->ResolveFullPath(&pathError);
if (!pathError.empty() || fullPath.empty()) {
continue;
}
- std::string const& ext = sf->GetExtension();
+ std::string const& extLower =
+ cmSystemTools::LowerCase(sf->GetExtension());
- auto const fileFormat = cmSystemTools::GetFileFormat(ext);
- if (fileFormat == cmSystemTools::HEADER_FILE_FORMAT) {
- if (this->AutogenTarget.Headers.find(sf) ==
- this->AutogenTarget.Headers.end()) {
+ if (cm->IsHeaderExtension(extLower)) {
+ if (!cmContains(this->AutogenTarget.Headers, sf)) {
auto muf = makeMUFile(sf, fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
this->AutogenTarget.Headers.emplace(sf, std::move(muf));
}
}
- } else if (fileFormat == cmSystemTools::CXX_FILE_FORMAT) {
- if (this->AutogenTarget.Sources.find(sf) ==
- this->AutogenTarget.Sources.end()) {
+ } else if (cm->IsSourceExtension(extLower)) {
+ if (!cmContains(this->AutogenTarget.Headers, sf)) {
auto muf = makeMUFile(sf, fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
this->AutogenTarget.Sources.emplace(sf, std::move(muf));
}
}
- } else if (this->Uic.Enabled && (ext == kw.ui)) {
+ } else if (this->Uic.Enabled && (extLower == kw.ui)) {
// .ui file
- std::string realPath = cmSystemTools::GetRealPath(fullPath);
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
bool const skipUic =
(skipAutogen || sf->GetPropertyAsBool(kw.SKIP_AUTOUIC));
@@ -813,14 +899,11 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Check if the .ui file has uic options
std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS);
if (!uicOpts.empty()) {
- this->Uic.FileFiles.push_back(std::move(realPath));
- std::vector<std::string> optsVec;
- cmSystemTools::ExpandListArgument(uicOpts, optsVec);
- this->Uic.FileOptions.push_back(std::move(optsVec));
+ this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts));
}
} else {
// Register skipped .ui file
- this->Uic.SkipUi.insert(std::move(realPath));
+ this->Uic.SkipUi.insert(fullPath);
}
}
}
@@ -831,37 +914,34 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (this->CMP0071Accept) {
// Let the autogen target depend on the GENERATED files
for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
- this->AutogenTarget.DependFiles.insert(muf->RealPath);
+ this->AutogenTarget.DependFiles.insert(muf->FullPath);
}
} else if (this->CMP0071Warn) {
- std::string msg;
- msg += cmPolicies::GetPolicyWarning(cmPolicies::CMP0071);
- msg += '\n';
- std::string property;
+ cm::string_view property;
if (this->Moc.Enabled && this->Uic.Enabled) {
- property = kw.SKIP_AUTOGEN;
+ property = "SKIP_AUTOGEN";
} else if (this->Moc.Enabled) {
- property = kw.SKIP_AUTOMOC;
+ property = "SKIP_AUTOMOC";
} else if (this->Uic.Enabled) {
- property = kw.SKIP_AUTOUIC;
+ property = "SKIP_AUTOUIC";
}
- msg += "For compatibility, CMake is excluding the GENERATED source "
- "file(s):\n";
+ std::string files;
for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
- msg += " ";
- msg += Quoted(muf->RealPath);
- msg += '\n';
+ files += cmStrCat(" ", Quoted(muf->FullPath), '\n');
}
- msg += "from processing by ";
- msg += cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false);
- msg += ". If any of the files should be processed, set CMP0071 to NEW. "
- "If any of the files should not be processed, "
- "explicitly exclude them by setting the source file property ";
- msg += property;
- msg += ":\n set_property(SOURCE file.h PROPERTY ";
- msg += property;
- msg += " ON)\n";
- makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n',
+ "For compatibility, CMake is excluding the GENERATED source "
+ "file(s):\n",
+ files, "from processing by ",
+ cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
+ ". If any of the files should be processed, set CMP0071 to NEW. "
+ "If any of the files should not be processed, "
+ "explicitly exclude them by setting the source file property ",
+ property, ":\n set_property(SOURCE file.h PROPERTY ", property,
+ " ON)\n"));
}
}
@@ -869,9 +949,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
// Target rcc options
- std::vector<std::string> optionsTarget;
- cmSystemTools::ExpandListArgument(
- this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS), optionsTarget);
+ std::vector<std::string> optionsTarget =
+ cmExpandedList(this->GenTarget->GetSafeProperty(kw.AUTORCC_OPTIONS));
// Check if file name is unique
for (Qrc& qrc : this->Rcc.Qrcs) {
@@ -884,46 +963,19 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
}
// Path checksum and file names
- {
- cmFilePathChecksum const fpathCheckSum(makefile);
- for (Qrc& qrc : this->Rcc.Qrcs) {
- qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
- // RCC output file name
- {
- std::string rccFile = this->Dir.Build + "/";
- rccFile += qrc.PathChecksum;
- rccFile += "/qrc_";
- rccFile += qrc.QrcName;
- rccFile += ".cpp";
- qrc.RccFile = std::move(rccFile);
- }
- {
- std::string base = this->Dir.Info;
- base += "/RCC";
- base += qrc.QrcName;
- if (!qrc.Unique) {
- base += qrc.PathChecksum;
- }
-
- qrc.LockFile = base;
- qrc.LockFile += ".lock";
-
- qrc.InfoFile = base;
- qrc.InfoFile += "Info.cmake";
-
- qrc.SettingsFile = base;
- qrc.SettingsFile += "Settings.txt";
-
- if (this->MultiConfig) {
- for (std::string const& cfg : this->ConfigsList) {
- qrc.ConfigSettingsFile[cfg] =
- AppendFilenameSuffix(qrc.SettingsFile, "_" + cfg);
- }
- }
- }
- }
- }
- // RCC options
+ for (Qrc& qrc : this->Rcc.Qrcs) {
+ // Path checksum
+ qrc.QrcPathChecksum = this->PathCheckSum.getPart(qrc.QrcFile);
+ // Output file name
+ qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
+ "/qrc_", qrc.QrcName, ".cpp");
+ std::string const base = cmStrCat(this->Dir.Info, "/AutoRcc_",
+ qrc.QrcName, '_', qrc.QrcPathChecksum);
+ qrc.LockFile = cmStrCat(base, "_Lock.lock");
+ qrc.InfoFile = cmStrCat(base, "_Info.json");
+ ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt");
+ }
+ // rcc options
for (Qrc& qrc : this->Rcc.Qrcs) {
// Target options
std::vector<std::string> opts = optionsTarget;
@@ -933,8 +985,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Replace '-' with '_'. The former is not valid for symbol names.
std::replace(name.begin(), name.end(), '-', '_');
if (!qrc.Unique) {
- name += "_";
- name += qrc.PathChecksum;
+ name += cmStrCat('_', qrc.QrcPathChecksum);
}
std::vector<std::string> nameOpts;
nameOpts.emplace_back("-name");
@@ -945,7 +996,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
RccMergeOptions(opts, qrc.Options, modernQt);
qrc.Options = std::move(opts);
}
- // RCC resources
+ // rcc resources
for (Qrc& qrc : this->Rcc.Qrcs) {
if (!qrc.Generated) {
std::string error;
@@ -964,18 +1015,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
bool cmQtAutoGenInitializer::InitAutogenTarget()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
- cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator();
-
// Register info file as generated by CMake
- makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
+ this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
// Files provided by the autogen target
std::vector<std::string> autogenProvides;
if (this->Moc.Enabled) {
- this->AddGeneratedSource(this->Moc.MocsCompilation, this->Moc, true);
- autogenProvides.push_back(this->Moc.MocsCompilation);
+ this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
+ autogenProvides.push_back(this->Moc.CompilationFile);
}
// Compose target comment
@@ -991,27 +1038,18 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
tools += "UIC";
}
- autogenComment = "Automatic ";
- autogenComment += tools;
- autogenComment += " for target ";
- autogenComment += this->Target->GetName();
+ autogenComment = cmStrCat("Automatic ", tools, " for target ",
+ this->GenTarget->GetName());
}
// Compose command lines
- cmCustomCommandLines commandLines;
- {
- cmCustomCommandLine currentLine;
- currentLine.push_back(cmSystemTools::GetCMakeCommand());
- currentLine.push_back("-E");
- currentLine.push_back("cmake_autogen");
- currentLine.push_back(this->AutogenTarget.InfoFile);
- currentLine.push_back("$<CONFIGURATION>");
- commandLines.push_back(std::move(currentLine));
- }
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
+ this->AutogenTarget.InfoFile, "$<CONFIGURATION>" });
// Use PRE_BUILD on demand
bool usePRE_BUILD = false;
- if (globalGen->GetName().find("Visual Studio") != std::string::npos) {
+ if (this->GlobalGen->GetName().find("Visual Studio") != std::string::npos) {
// Under VS use a PRE_BUILD event instead of a separate target to
// reduce the number of targets loaded into the IDE.
// This also works around a VS 11 bug that may skip updating the target:
@@ -1033,7 +1071,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (usePRE_BUILD) {
// Add additional autogen target dependencies to origin target
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- this->Target->Target->AddUtility(depTarget->GetName(), makefile);
+ this->GenTarget->Target->AddUtility(depTarget->GetName(),
+ this->Makefile);
}
// Add the pre-build command directly to bypass the OBJECT_LIBRARY
@@ -1043,12 +1082,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// PRE_BUILD does not support file dependencies!
const std::vector<std::string> no_output;
const std::vector<std::string> no_deps;
- cmCustomCommand cc(makefile, no_output, autogenProvides, no_deps,
+ cmCustomCommand cc(this->Makefile, no_output, autogenProvides, no_deps,
commandLines, autogenComment.c_str(),
this->Dir.Work.c_str());
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
- this->Target->Target->AddPreBuildCommand(cc);
+ this->GenTarget->Target->AddPreBuildCommand(std::move(cc));
} else {
// Add link library target dependencies to the autogen target
@@ -1059,12 +1098,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
std::map<cmGeneratorTarget const*, std::size_t> commonTargets;
for (std::string const& config : this->ConfigsList) {
cmLinkImplementationLibraries const* libs =
- this->Target->GetLinkImplementationLibraries(config);
+ this->GenTarget->GetLinkImplementationLibraries(config);
if (libs != nullptr) {
for (cmLinkItem const& item : libs->Libraries) {
cmGeneratorTarget const* libTarget = item.Target;
if ((libTarget != nullptr) &&
- !StaticLibraryCycle(this->Target, libTarget, config)) {
+ !StaticLibraryCycle(this->GenTarget, libTarget, config)) {
// Increment target config count
commonTargets[libTarget]++;
}
@@ -1079,25 +1118,25 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Create autogen target
- cmTarget* autogenTarget = makefile->AddUtilityCommand(
- this->AutogenTarget.Name, cmMakefile::TargetOrigin::Generator, true,
+ cmTarget* autogenTarget = this->Makefile->AddUtilityCommand(
+ this->AutogenTarget.Name, cmCommandOrigin::Generator, true,
this->Dir.Work.c_str(), /*byproducts=*/autogenProvides,
std::vector<std::string>(this->AutogenTarget.DependFiles.begin(),
this->AutogenTarget.DependFiles.end()),
commandLines, false, autogenComment.c_str());
// Create autogen generator target
- localGen->AddGeneratorTarget(
- new cmGeneratorTarget(autogenTarget, localGen));
+ this->LocalGen->AddGeneratorTarget(
+ new cmGeneratorTarget(autogenTarget, this->LocalGen));
// Forward origin utilities to autogen target
if (this->AutogenTarget.DependOrigin) {
- for (BT<std::string> const& depName : this->Target->GetUtilities()) {
- autogenTarget->AddUtility(depName.Value, makefile);
+ for (BT<std::string> const& depName : this->GenTarget->GetUtilities()) {
+ autogenTarget->AddUtility(depName.Value, this->Makefile);
}
}
// Add additional autogen target dependencies to autogen target
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- autogenTarget->AddUtility(depTarget->GetName(), makefile);
+ autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
}
// Set FOLDER property in autogen target
@@ -1106,11 +1145,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Add autogen target to the origin target dependencies
- this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile);
+ this->GenTarget->Target->AddUtility(this->AutogenTarget.Name,
+ this->Makefile);
// Add autogen target to the global autogen target dependencies
if (this->AutogenTarget.GlobalTarget) {
- this->GlobalInitializer->AddToGlobalAutoGen(localGen,
+ this->GlobalInitializer->AddToGlobalAutoGen(this->LocalGen,
this->AutogenTarget.Name);
}
}
@@ -1120,17 +1160,14 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
bool cmQtAutoGenInitializer::InitRccTargets()
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-
for (Qrc const& qrc : this->Rcc.Qrcs) {
// Register info file as generated by CMake
- makefile->AddCMakeOutputFile(qrc.InfoFile);
+ this->Makefile->AddCMakeOutputFile(qrc.InfoFile);
// Register file at target
- this->AddGeneratedSource(qrc.RccFile, this->Rcc);
+ this->AddGeneratedSource(qrc.OutputFile, this->Rcc);
std::vector<std::string> ccOutput;
- ccOutput.push_back(qrc.RccFile);
+ ccOutput.push_back(qrc.OutputFile);
std::vector<std::string> ccDepends;
// Add the .qrc and info file to the custom command dependencies
@@ -1141,61 +1178,51 @@ bool cmQtAutoGenInitializer::InitRccTargets()
if (this->MultiConfig) {
// Build for all configurations
for (std::string const& config : this->ConfigsList) {
- cmCustomCommandLine currentLine;
- currentLine.push_back(cmSystemTools::GetCMakeCommand());
- currentLine.push_back("-E");
- currentLine.push_back("cmake_autorcc");
- currentLine.push_back(qrc.InfoFile);
- currentLine.push_back(config);
- commandLines.push_back(std::move(currentLine));
+ commandLines.push_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
+ "cmake_autorcc", qrc.InfoFile, config }));
}
} else {
- cmCustomCommandLine currentLine;
- currentLine.push_back(cmSystemTools::GetCMakeCommand());
- currentLine.push_back("-E");
- currentLine.push_back("cmake_autorcc");
- currentLine.push_back(qrc.InfoFile);
- currentLine.push_back("$<CONFIG>");
- commandLines.push_back(std::move(currentLine));
+ commandLines.push_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
+ "cmake_autorcc", qrc.InfoFile, "$<CONFIG>" }));
}
- std::string ccComment = "Automatic RCC for ";
- ccComment += FileProjectRelativePath(makefile, qrc.QrcFile);
+ std::string ccComment =
+ cmStrCat("Automatic RCC for ",
+ FileProjectRelativePath(this->Makefile, qrc.QrcFile));
if (qrc.Generated || this->Rcc.GlobalTarget) {
// Create custom rcc target
std::string ccName;
{
- ccName = this->Target->GetName();
- ccName += "_arcc_";
- ccName += qrc.QrcName;
+ ccName = cmStrCat(this->GenTarget->GetName(), "_arcc_", qrc.QrcName);
if (!qrc.Unique) {
- ccName += "_";
- ccName += qrc.PathChecksum;
+ ccName += cmStrCat('_', qrc.QrcPathChecksum);
}
- cmTarget* autoRccTarget = makefile->AddUtilityCommand(
- ccName, cmMakefile::TargetOrigin::Generator, true,
- this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false,
- ccComment.c_str());
+ cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand(
+ ccName, cmCommandOrigin::Generator, true, this->Dir.Work.c_str(),
+ ccOutput, ccDepends, commandLines, false, ccComment.c_str());
// Create autogen generator target
- localGen->AddGeneratorTarget(
- new cmGeneratorTarget(autoRccTarget, localGen));
+ this->LocalGen->AddGeneratorTarget(
+ new cmGeneratorTarget(autoRccTarget, this->LocalGen));
// Set FOLDER property in autogen target
if (!this->TargetsFolder.empty()) {
autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
}
if (!this->Rcc.ExecutableTargetName.empty()) {
- autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, makefile);
+ autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName,
+ this->Makefile);
}
}
// Add autogen target to the origin target dependencies
- this->Target->Target->AddUtility(ccName, makefile);
+ this->GenTarget->Target->AddUtility(ccName, this->Makefile);
// Add autogen target to the global autogen target dependencies
if (this->Rcc.GlobalTarget) {
- this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName);
+ this->GlobalInitializer->AddToGlobalAutoRcc(this->LocalGen, ccName);
}
} else {
// Create custom rcc command
@@ -1210,13 +1237,15 @@ bool cmQtAutoGenInitializer::InitRccTargets()
if (!this->Rcc.ExecutableTargetName.empty()) {
ccDepends.push_back(this->Rcc.ExecutableTargetName);
}
- makefile->AddCustomCommandToOutput(ccOutput, ccByproducts, ccDepends,
- /*main_dependency*/ std::string(),
- commandLines, ccComment.c_str(),
- this->Dir.Work.c_str());
+ std::string no_main_dependency;
+ cmImplicitDependsList no_implicit_depends;
+ this->Makefile->AddCustomCommandToOutput(
+ ccOutput, ccByproducts, ccDepends, no_main_dependency,
+ no_implicit_depends, commandLines, ccComment.c_str(),
+ this->Dir.Work.c_str());
}
// Reconfigure when .qrc file changes
- makefile->AddCMakeDependFile(qrc.QrcFile);
+ this->Makefile->AddCMakeDependFile(qrc.QrcFile);
}
}
@@ -1227,9 +1256,8 @@ bool cmQtAutoGenInitializer::SetupCustomTargets()
{
// Create info directory on demand
if (!cmSystemTools::MakeDirectory(this->Dir.Info)) {
- std::string emsg = ("AutoGen: Could not create directory: ");
- emsg += Quoted(this->Dir.Info);
- cmSystemTools::Error(emsg);
+ cmSystemTools::Error(cmStrCat("AutoGen: Could not create directory: ",
+ Quoted(this->Dir.Info)));
return false;
}
@@ -1247,232 +1275,185 @@ bool cmQtAutoGenInitializer::SetupCustomTargets()
bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
{
- InfoWriter ofs(this->AutogenTarget.InfoFile);
- if (ofs) {
- // Utility lambdas
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- auto MfDef = [makefile](const char* key) {
- return makefile->GetSafeDefinition(key);
- };
+ // Utility lambdas
+ auto MfDef = [this](std::string const& key) {
+ return this->Makefile->GetSafeDefinition(key);
+ };
- // Write common settings
- ofs.Write("# Meta\n");
- ofs.Write("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE");
- ofs.Write("AM_PARALLEL", this->AutogenTarget.Parallel);
- ofs.Write("AM_VERBOSITY", this->Verbosity);
-
- ofs.Write("# Directories\n");
- ofs.Write("AM_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
- ofs.Write("AM_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
- ofs.Write("AM_CMAKE_CURRENT_SOURCE_DIR",
- MfDef("CMAKE_CURRENT_SOURCE_DIR"));
- ofs.Write("AM_CMAKE_CURRENT_BINARY_DIR",
- MfDef("CMAKE_CURRENT_BINARY_DIR"));
- ofs.Write("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE",
- MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"));
- ofs.Write("AM_BUILD_DIR", this->Dir.Build);
- ofs.Write("AM_INCLUDE_DIR", this->Dir.Include);
- ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude);
-
- std::vector<std::string> headers;
- std::vector<std::string> headersFlags;
- std::vector<std::string> headersBuildPaths;
- std::vector<std::string> sources;
- std::vector<std::string> sourcesFlags;
- std::set<std::string> moc_skip;
- std::set<std::string> uic_skip;
-
- // Filter headers
- {
- auto headerCount = this->AutogenTarget.Headers.size();
- headers.reserve(headerCount);
- headersFlags.reserve(headerCount);
+ // Filtered headers and sources
+ std::set<std::string> moc_skip;
+ std::set<std::string> uic_skip;
+ std::vector<MUFile const*> headers;
+ std::vector<MUFile const*> sources;
- std::vector<MUFile const*> sortedHeaders;
- {
- sortedHeaders.reserve(headerCount);
- for (auto const& pair : this->AutogenTarget.Headers) {
- sortedHeaders.emplace_back(pair.second.get());
- }
- std::sort(sortedHeaders.begin(), sortedHeaders.end(),
- [](MUFile const* a, MUFile const* b) {
- return (a->RealPath < b->RealPath);
- });
+ // Filter headers
+ {
+ headers.reserve(this->AutogenTarget.Headers.size());
+ for (auto const& pair : this->AutogenTarget.Headers) {
+ MUFile const* const muf = pair.second.get();
+ if (muf->Generated && !this->CMP0071Accept) {
+ continue;
}
-
- for (MUFile const* const muf : sortedHeaders) {
- if (muf->Generated && !this->CMP0071Accept) {
- continue;
- }
- if (muf->SkipMoc) {
- moc_skip.insert(muf->RealPath);
- }
- if (muf->SkipUic) {
- uic_skip.insert(muf->RealPath);
- }
- if (muf->MocIt || muf->UicIt) {
- headers.emplace_back(muf->RealPath);
- std::string flags;
- flags += muf->MocIt ? 'M' : 'm';
- flags += muf->UicIt ? 'U' : 'u';
- headersFlags.emplace_back(std::move(flags));
- }
+ if (muf->SkipMoc) {
+ moc_skip.insert(muf->FullPath);
}
- }
- // Header build paths
- {
- cmFilePathChecksum const fpathCheckSum(makefile);
- std::unordered_set<std::string> emitted;
- for (std::string const& hdr : headers) {
- std::string basePath = fpathCheckSum.getPart(hdr);
- basePath += "/moc_";
- basePath += cmSystemTools::GetFilenameWithoutLastExtension(hdr);
- for (unsigned int ii = 1; ii != 1024; ++ii) {
- std::string path = basePath;
- if (ii > 1) {
- path += '_';
- path += std::to_string(ii);
- }
- path += ".cpp";
- if (emitted.emplace(path).second) {
- headersBuildPaths.emplace_back(std::move(path));
- break;
- }
- }
+ if (muf->SkipUic) {
+ uic_skip.insert(muf->FullPath);
+ }
+ if (muf->MocIt || muf->UicIt) {
+ headers.emplace_back(muf);
}
}
+ std::sort(headers.begin(), headers.end(),
+ [](MUFile const* a, MUFile const* b) {
+ return (a->FullPath < b->FullPath);
+ });
+ }
- // Filter sources
- {
- auto sourcesCount = this->AutogenTarget.Sources.size();
- sources.reserve(sourcesCount);
- sourcesFlags.reserve(sourcesCount);
-
- std::vector<MUFile const*> sorted;
- sorted.reserve(sourcesCount);
- for (auto const& pair : this->AutogenTarget.Sources) {
- sorted.emplace_back(pair.second.get());
+ // Filter sources
+ {
+ sources.reserve(this->AutogenTarget.Sources.size());
+ for (auto const& pair : this->AutogenTarget.Sources) {
+ MUFile const* const muf = pair.second.get();
+ if (muf->Generated && !this->CMP0071Accept) {
+ continue;
}
- std::sort(sorted.begin(), sorted.end(),
- [](MUFile const* a, MUFile const* b) {
- return (a->RealPath < b->RealPath);
- });
-
- for (MUFile const* const muf : sorted) {
- if (muf->Generated && !this->CMP0071Accept) {
- continue;
- }
- if (muf->SkipMoc) {
- moc_skip.insert(muf->RealPath);
- }
- if (muf->SkipUic) {
- uic_skip.insert(muf->RealPath);
- }
- if (muf->MocIt || muf->UicIt) {
- sources.emplace_back(muf->RealPath);
- std::string flags;
- flags += muf->MocIt ? 'M' : 'm';
- flags += muf->UicIt ? 'U' : 'u';
- sourcesFlags.emplace_back(std::move(flags));
- }
+ if (muf->SkipMoc) {
+ moc_skip.insert(muf->FullPath);
+ }
+ if (muf->SkipUic) {
+ uic_skip.insert(muf->FullPath);
+ }
+ if (muf->MocIt || muf->UicIt) {
+ sources.emplace_back(muf);
}
}
+ std::sort(sources.begin(), sources.end(),
+ [](MUFile const* a, MUFile const* b) {
+ return (a->FullPath < b->FullPath);
+ });
+ }
- ofs.Write("# Qt\n");
- ofs.WriteUInt("AM_QT_VERSION_MAJOR", this->QtVersion.Major);
- ofs.Write("AM_QT_MOC_EXECUTABLE", this->Moc.Executable);
- ofs.Write("AM_QT_UIC_EXECUTABLE", this->Uic.Executable);
-
- ofs.Write("# Files\n");
- ofs.Write("AM_CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
- ofs.Write("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile);
- ofs.WriteConfig("AM_SETTINGS_FILE",
- this->AutogenTarget.ConfigSettingsFile);
- ofs.Write("AM_PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
- ofs.WriteStrings("AM_HEADERS", headers);
- ofs.WriteStrings("AM_HEADERS_FLAGS", headersFlags);
- ofs.WriteStrings("AM_HEADERS_BUILD_PATHS", headersBuildPaths);
- ofs.WriteStrings("AM_SOURCES", sources);
- ofs.WriteStrings("AM_SOURCES_FLAGS", sourcesFlags);
-
- // Write moc settings
- if (this->Moc.Enabled) {
- ofs.Write("# MOC settings\n");
- ofs.WriteStrings("AM_MOC_SKIP", moc_skip);
- ofs.WriteStrings("AM_MOC_DEFINITIONS", this->Moc.Defines);
- ofs.WriteConfigStrings("AM_MOC_DEFINITIONS", this->Moc.ConfigDefines);
- ofs.WriteStrings("AM_MOC_INCLUDES", this->Moc.Includes);
- ofs.WriteConfigStrings("AM_MOC_INCLUDES", this->Moc.ConfigIncludes);
- ofs.Write("AM_MOC_OPTIONS",
- this->Target->GetSafeProperty("AUTOMOC_MOC_OPTIONS"));
- ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE"));
- ofs.Write("AM_MOC_MACRO_NAMES",
- this->Target->GetSafeProperty("AUTOMOC_MACRO_NAMES"));
- ofs.Write("AM_MOC_DEPEND_FILTERS",
- this->Target->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
- ofs.Write("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
- }
-
- // Write uic settings
- if (this->Uic.Enabled) {
- // Add skipped .ui files
- uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end());
+ // Info writer
+ InfoWriter info;
+
+ // General
+ info.SetBool("MULTI_CONFIG", this->MultiConfig);
+ info.SetUInt("PARALLEL", this->AutogenTarget.Parallel);
+ info.SetUInt("VERBOSITY", this->Verbosity);
+
+ // Directories
+ info.Set("CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
+ info.Set("CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
+ info.Set("CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR"));
+ info.Set("CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR"));
+ info.Set("BUILD_DIR", this->Dir.Build);
+ info.SetConfig("INCLUDE_DIR", this->Dir.Include);
+
+ info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
+ info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
+ info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
+
+ info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
+ info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile);
+ info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
+ info.SetArray("HEADER_EXTENSIONS",
+ this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
+ info.SetArrayArray(
+ "HEADERS", headers, [this](Json::Value& jval, MUFile const* muf) {
+ jval.resize(3u);
+ jval[0u] = muf->FullPath;
+ jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
+ jval[2u] = this->GetMocBuildPath(*muf);
+ });
+ info.SetArrayArray(
+ "SOURCES", sources, [](Json::Value& jval, MUFile const* muf) {
+ jval.resize(2u);
+ jval[0u] = muf->FullPath;
+ jval[1u] = cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u');
+ });
+
+ // Write moc settings
+ if (this->Moc.Enabled) {
+ info.SetArray("MOC_SKIP", moc_skip);
+ info.SetConfigArray("MOC_DEFINITIONS", this->Moc.Defines);
+ info.SetConfigArray("MOC_INCLUDES", this->Moc.Includes);
+ info.SetArray("MOC_OPTIONS", this->Moc.Options);
+ info.SetBool("MOC_RELAXED_MODE", this->Moc.RelaxedMode);
+ info.SetBool("MOC_PATH_PREFIX", this->Moc.PathPrefix);
+ info.SetArray("MOC_MACRO_NAMES", this->Moc.MacroNames);
+ info.SetArrayArray(
+ "MOC_DEPEND_FILTERS", this->Moc.DependFilters,
+ [](Json::Value& jval, std::pair<std::string, std::string> const& pair) {
+ jval.resize(2u);
+ jval[0u] = pair.first;
+ jval[1u] = pair.second;
+ });
+ info.Set("MOC_COMPILATION_FILE", this->Moc.CompilationFile);
+ info.SetArray("MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
+ info.SetConfig("MOC_PREDEFS_FILE", this->Moc.PredefsFile);
+ }
- ofs.Write("# UIC settings\n");
- ofs.WriteStrings("AM_UIC_SKIP", uic_skip);
- ofs.WriteStrings("AM_UIC_TARGET_OPTIONS", this->Uic.Options);
- ofs.WriteConfigStrings("AM_UIC_TARGET_OPTIONS", this->Uic.ConfigOptions);
- ofs.WriteStrings("AM_UIC_OPTIONS_FILES", this->Uic.FileFiles);
- ofs.WriteNestedLists("AM_UIC_OPTIONS_OPTIONS", this->Uic.FileOptions);
- ofs.WriteStrings("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths);
- }
- } else {
- std::string err = "AutoGen: Could not write file ";
- err += this->AutogenTarget.InfoFile;
- cmSystemTools::Error(err);
- return false;
+ // Write uic settings
+ if (this->Uic.Enabled) {
+ // Add skipped .ui files
+ uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end());
+
+ info.SetArray("UIC_SKIP", uic_skip);
+ info.SetArrayArray("UIC_UI_FILES", this->Uic.UiFiles,
+ [](Json::Value& jval, UicT::UiFileT const& uiFile) {
+ jval.resize(2u);
+ jval[0u] = uiFile.first;
+ InfoWriter::MakeStringArray(jval[1u], uiFile.second);
+ });
+ info.SetConfigArray("UIC_OPTIONS", this->Uic.Options);
+ info.SetArray("UIC_SEARCH_PATHS", this->Uic.SearchPaths);
}
+ info.Save(this->AutogenTarget.InfoFile);
+
return true;
}
bool cmQtAutoGenInitializer::SetupWriteRccInfo()
{
for (Qrc const& qrc : this->Rcc.Qrcs) {
- InfoWriter ofs(qrc.InfoFile);
- if (ofs) {
- // Write
- ofs.Write("# Configurations\n");
- ofs.Write("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE");
- ofs.Write("ARCC_VERBOSITY", this->Verbosity);
- ofs.Write("# Settings file\n");
- ofs.Write("ARCC_SETTINGS_FILE", qrc.SettingsFile);
- ofs.WriteConfig("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile);
-
- ofs.Write("# Directories\n");
- ofs.Write("ARCC_BUILD_DIR", this->Dir.Build);
- ofs.Write("ARCC_INCLUDE_DIR", this->Dir.Include);
- ofs.WriteConfig("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude);
-
- ofs.Write("# Rcc executable\n");
- ofs.Write("ARCC_RCC_EXECUTABLE", this->Rcc.Executable);
- ofs.WriteStrings("ARCC_RCC_LIST_OPTIONS",
- this->Rcc.ExecutableFeatures->ListOptions);
-
- ofs.Write("# Rcc job\n");
- ofs.Write("ARCC_LOCK_FILE", qrc.LockFile);
- ofs.Write("ARCC_SOURCE", qrc.QrcFile);
- ofs.Write("ARCC_OUTPUT_CHECKSUM", qrc.PathChecksum);
- ofs.Write("ARCC_OUTPUT_NAME",
- cmSystemTools::GetFilenameName(qrc.RccFile));
- ofs.WriteStrings("ARCC_OPTIONS", qrc.Options);
- ofs.WriteStrings("ARCC_INPUTS", qrc.Resources);
- } else {
- std::string err = "AutoRcc: Could not write file ";
- err += qrc.InfoFile;
- cmSystemTools::Error(err);
- return false;
- }
+ // Utility lambdas
+ auto MfDef = [this](std::string const& key) {
+ return this->Makefile->GetSafeDefinition(key);
+ };
+
+ InfoWriter info;
+
+ // General
+ info.SetBool("MULTI_CONFIG", this->MultiConfig);
+ info.SetUInt("VERBOSITY", this->Verbosity);
+
+ // Files
+ info.Set("LOCK_FILE", qrc.LockFile);
+ info.SetConfig("SETTINGS_FILE", qrc.SettingsFile);
+
+ // Directories
+ info.Set("CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
+ info.Set("CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
+ info.Set("CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR"));
+ info.Set("CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR"));
+ info.Set("BUILD_DIR", this->Dir.Build);
+ info.SetConfig("INCLUDE_DIR", this->Dir.Include);
+
+ // rcc executable
+ info.Set("RCC_EXECUTABLE", this->Rcc.Executable);
+ info.SetArray("RCC_LIST_OPTIONS",
+ this->Rcc.ExecutableFeatures->ListOptions);
+
+ // qrc file
+ info.Set("SOURCE", qrc.QrcFile);
+ info.Set("OUTPUT_CHECKSUM", qrc.QrcPathChecksum);
+ info.Set("OUTPUT_NAME", cmSystemTools::GetFilenameName(qrc.OutputFile));
+ info.SetArray("OPTIONS", qrc.Options);
+ info.SetArray("INPUTS", qrc.Resources);
+
+ info.Save(qrc.InfoFile);
}
return true;
@@ -1481,8 +1462,7 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
void cmQtAutoGenInitializer::RegisterGeneratedSource(
std::string const& filename)
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
- cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true);
+ cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true);
gFile->SetProperty("GENERATED", "1");
gFile->SetProperty("SKIP_AUTOGEN", "1");
}
@@ -1494,15 +1474,14 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
// Register source at makefile
this->RegisterGeneratedSource(filename);
// Add source file to target
- this->Target->AddSource(filename, prepend);
+ this->GenTarget->AddSource(filename, prepend);
// Add source file to source group
return this->AddToSourceGroup(filename, genVars.GenNameUpper);
}
bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
- std::string const& genNameUpper)
+ cm::string_view genNameUpper)
{
- cmMakefile* makefile = this->Target->Target->GetMakefile();
cmSourceGroup* sourceGroup = nullptr;
// Acquire source group
{
@@ -1510,28 +1489,27 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
std::string groupName;
{
// Prefer generator specific source group name
- std::array<std::string, 2> props{ { genNameUpper + "_SOURCE_GROUP",
- "AUTOGEN_SOURCE_GROUP" } };
- for (std::string& prop : props) {
- const char* propName = makefile->GetState()->GetGlobalProperty(prop);
+ std::initializer_list<std::string> const props{
+ 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;
- property = std::move(prop);
+ property = prop;
break;
}
}
}
// Generate a source group on demand
if (!groupName.empty()) {
- sourceGroup = makefile->GetOrCreateSourceGroup(groupName);
+ sourceGroup = this->Makefile->GetOrCreateSourceGroup(groupName);
if (sourceGroup == nullptr) {
- std::string err;
- err += genNameUpper;
- err += " error in ";
- err += property;
- err += ": Could not find or create the source group ";
- err += cmQtAutoGen::Quoted(groupName);
- cmSystemTools::Error(err);
+ cmSystemTools::Error(
+ cmStrCat(genNameUpper, " error in ", property,
+ ": Could not find or create the source group ",
+ cmQtAutoGen::Quoted(groupName)));
return false;
}
}
@@ -1544,62 +1522,86 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
{
- Target->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName.c_str(),
- false);
+ this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES",
+ fileName.c_str(), false);
}
-static unsigned int CharPtrToUInt(const char* const input)
+void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString,
+ cm::string_view prefix,
+ cm::string_view suffix)
{
- unsigned long tmp = 0;
- if (input != nullptr && cmSystemTools::StringToULong(input, &tmp)) {
- return static_cast<unsigned int>(tmp);
+ configString.Default = cmStrCat(prefix, suffix);
+ if (this->MultiConfig) {
+ for (auto const& cfg : this->ConfigsList) {
+ configString.Config[cfg] = cmStrCat(prefix, '_', cfg, suffix);
+ }
}
- return 0;
}
-static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
- cmGeneratorTarget const* target)
+void cmQtAutoGenInitializer::ConfigFileClean(ConfigString& configString)
{
- // Qt version variable prefixes
- static std::array<std::string, 3> const prefixes{ { "Qt6Core", "Qt5Core",
- "QT" } };
-
- std::vector<cmQtAutoGen::IntegerVersion> result;
- result.reserve(prefixes.size() * 2);
- // Adds a version to the result (nullptr safe)
- auto addVersion = [&result](const char* major, const char* minor) {
- cmQtAutoGen::IntegerVersion ver(CharPtrToUInt(major),
- CharPtrToUInt(minor));
- if (ver.Major != 0) {
- result.emplace_back(ver);
+ this->AddCleanFile(configString.Default);
+ if (this->MultiConfig) {
+ for (auto const& pair : configString.Config) {
+ this->AddCleanFile(pair.second);
}
- };
- cmMakefile* makefile = target->Target->GetMakefile();
-
- // Read versions from variables
- for (const std::string& prefix : prefixes) {
- addVersion(makefile->GetDefinition(prefix + "_VERSION_MAJOR"),
- makefile->GetDefinition(prefix + "_VERSION_MINOR"));
}
-
- // Read versions from directory properties
- for (const std::string& prefix : prefixes) {
- addVersion(makefile->GetProperty(prefix + "_VERSION_MAJOR"),
- makefile->GetProperty(prefix + "_VERSION_MINOR"));
- }
-
- return result;
}
std::pair<cmQtAutoGen::IntegerVersion, unsigned int>
cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
{
+ // Converts a char ptr to an unsigned int value
+ auto toUInt = [](const char* const 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(
IntegerVersion(),
- CharPtrToUInt(target->GetLinkInterfaceDependentStringProperty(
- "QT_MAJOR_VERSION", "")));
+ toUInt(target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",
+ "")));
- auto knownQtVersions = GetKnownQtVersions(target);
+ // Acquire known Qt versions
+ std::vector<cmQtAutoGen::IntegerVersion> knownQtVersions;
+ {
+ // Qt version variable prefixes
+ static std::initializer_list<
+ std::pair<cm::string_view, cm::string_view>> const keys{
+ { "Qt6Core_VERSION_MAJOR", "Qt6Core_VERSION_MINOR" },
+ { "Qt5Core_VERSION_MAJOR", "Qt5Core_VERSION_MINOR" },
+ { "QT_VERSION_MAJOR", "QT_VERSION_MINOR" },
+ };
+
+ 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));
+ if (ver.Major != 0) {
+ knownQtVersions.emplace_back(ver);
+ }
+ };
+
+ // Read versions from variables
+ for (auto const& keyPair : keys) {
+ addVersion(target->Makefile->GetDefinition(std::string(keyPair.first)),
+ target->Makefile->GetDefinition(std::string(keyPair.second)));
+ }
+
+ // Read versions from directory properties
+ for (auto const& keyPair : keys) {
+ addVersion(target->Makefile->GetProperty(std::string(keyPair.first)),
+ target->Makefile->GetProperty(std::string(keyPair.second)));
+ }
+ }
+
+ // Evaluate known Qt versions
if (!knownQtVersions.empty()) {
if (res.second == 0) {
// No specific version was requested by the target:
@@ -1618,32 +1620,50 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
return res;
}
+std::string cmQtAutoGenInitializer::GetMocBuildPath(MUFile const& muf)
+{
+ std::string res;
+ if (!muf.MocIt) {
+ return res;
+ }
+ {
+ std::string const basePath =
+ cmStrCat(this->PathCheckSum.getPart(muf.FullPath), "/moc_",
+ FileNameWithoutLastExtension(muf.FullPath));
+ std::string suffix;
+ constexpr std::size_t num_tries_max = 256;
+ for (std::size_t ii = 0; ii != num_tries_max; ++ii) {
+ res = cmStrCat(basePath, suffix, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ break;
+ }
+ // Compute new suffix
+ suffix = cmStrCat('_', ii + 1);
+ }
+ }
+ return res;
+}
+
bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
const std::string& executable,
bool ignoreMissingTarget) const
{
auto print_err = [this, &genVars](std::string const& err) {
- std::string msg = genVars.GenNameUpper;
- msg += " for target ";
- msg += this->Target->GetName();
- msg += ": ";
- msg += err;
- cmSystemTools::Error(msg);
+ cmSystemTools::Error(cmStrCat(genVars.GenNameUpper, " for target ",
+ this->GenTarget->GetName(), ": ", err));
};
// Custom executable
{
- std::string const prop = genVars.GenNameUpper + "_EXECUTABLE";
- std::string const val = this->Target->Target->GetSafeProperty(prop);
+ std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
+ std::string const val = this->GenTarget->Target->GetSafeProperty(prop);
if (!val.empty()) {
// Evaluate generator expression
{
- cmListFileBacktrace lfbt =
- this->Target->Target->GetMakefile()->GetBacktrace();
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val);
- genVars.Executable =
- cge->Evaluate(this->Target->GetLocalGenerator(), "");
+ genVars.Executable = cge->Evaluate(this->LocalGen, "");
}
if (genVars.Executable.empty() && !ignoreMissingTarget) {
print_err(prop + " evaluates to an empty value");
@@ -1660,26 +1680,26 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Find executable target
{
// Find executable target name
- std::string targetName;
+ cm::string_view prefix;
if (this->QtVersion.Major == 4) {
- targetName = "Qt4::";
+ prefix = "Qt4::";
} else if (this->QtVersion.Major == 5) {
- targetName = "Qt5::";
+ prefix = "Qt5::";
} else if (this->QtVersion.Major == 6) {
- targetName = "Qt6::";
+ prefix = "Qt6::";
}
- targetName += executable;
+ std::string const targetName = cmStrCat(prefix, executable);
// Find target
- cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
- cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(targetName);
- if (target != nullptr) {
+ cmGeneratorTarget* genTarget =
+ this->LocalGen->FindGeneratorTargetToUse(targetName);
+ if (genTarget != nullptr) {
genVars.ExecutableTargetName = targetName;
- genVars.ExecutableTarget = target;
- if (target->IsImported()) {
- genVars.Executable = target->ImportedGetLocation("");
+ genVars.ExecutableTarget = genTarget;
+ if (genTarget->IsImported()) {
+ genVars.Executable = genTarget->ImportedGetLocation("");
} else {
- genVars.Executable = target->GetLocation("");
+ genVars.Executable = genTarget->GetLocation("");
}
} else {
if (ignoreMissingTarget) {
@@ -1688,11 +1708,8 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
std::make_shared<cmQtAutoGen::CompilerFeatures>();
return true;
}
- std::string err = "Could not find ";
- err += executable;
- err += " executable target ";
- err += targetName;
- print_err(err);
+ print_err(cmStrCat("Could not find ", executable, " executable target ",
+ targetName));
return false;
}
}
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index aa073d1fd..486dab71f 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -4,49 +4,72 @@
#define cmQtAutoGenInitializer_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmGeneratedFileStream.h"
-#include "cmQtAutoGen.h"
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <ostream>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
+#include <cm/string_view>
+
+#include "cmFilePathChecksum.h"
+#include "cmQtAutoGen.h"
+
class cmGeneratorTarget;
-class cmTarget;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
class cmQtAutoGenGlobalInitializer;
class cmSourceFile;
+class cmTarget;
-/// @brief Initializes the QtAutoGen generators
+/** \class cmQtAutoGenerator
+ * \brief Initializes the QtAutoGen generators
+ */
class cmQtAutoGenInitializer : public cmQtAutoGen
{
public:
- /// @brief Rcc job information
+ /** String value with per configuration variants. */
+ class ConfigString
+ {
+ public:
+ std::string Default;
+ std::unordered_map<std::string, std::string> Config;
+ };
+
+ /** String values with per configuration variants. */
+ template <typename C>
+ class ConfigStrings
+ {
+ public:
+ C Default;
+ std::unordered_map<std::string, C> Config;
+ };
+
+ /** rcc job. */
class Qrc
{
public:
std::string LockFile;
std::string QrcFile;
std::string QrcName;
- std::string PathChecksum;
+ std::string QrcPathChecksum;
std::string InfoFile;
- std::string SettingsFile;
- std::map<std::string, std::string> ConfigSettingsFile;
- std::string RccFile;
+ ConfigString SettingsFile;
+ std::string OutputFile;
bool Generated = false;
bool Unique = false;
std::vector<std::string> Options;
std::vector<std::string> Resources;
};
- /// @brief Moc/Uic file
+ /** moc and/or uic file. */
struct MUFile
{
- std::string RealPath;
+ std::string FullPath;
cmSourceFile* SF = nullptr;
bool Generated = false;
bool SkipMoc = false;
@@ -54,67 +77,33 @@ public:
bool MocIt = false;
bool UicIt = false;
};
- typedef std::unique_ptr<MUFile> MUFileHandle;
+ using MUFileHandle = std::unique_ptr<MUFile>;
- /// @brief Abstract moc/uic/rcc generator variables base class
+ /** Abstract moc/uic/rcc generator variables base class. */
struct GenVarsT
{
bool Enabled = false;
// Generator type/name
GenT Gen;
- std::string const& GenNameUpper;
+ cm::string_view GenNameUpper;
// Executable
std::string ExecutableTargetName;
cmGeneratorTarget* ExecutableTarget = nullptr;
std::string Executable;
CompilerFeaturesHandle ExecutableFeatures;
- /// @brief Constructor
GenVarsT(GenT gen)
: Gen(gen)
, GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){};
};
- /// @brief Writes a CMake info file
- class InfoWriter
- {
- public:
- /// @brief Open the given file
- InfoWriter(std::string const& filename);
-
- /// @return True if the file is open
- explicit operator bool() const { return static_cast<bool>(Ofs_); }
-
- void Write(const char* text) { Ofs_ << text; }
- void Write(const char* key, std::string const& value);
- void WriteUInt(const char* key, unsigned int value);
-
- template <class C>
- void WriteStrings(const char* key, C const& container);
- void WriteConfig(const char* key,
- std::map<std::string, std::string> const& map);
- template <class C>
- void WriteConfigStrings(const char* key,
- std::map<std::string, C> const& map);
- void WriteNestedLists(const char* key,
- std::vector<std::vector<std::string>> const& lists);
-
- private:
- template <class IT>
- static std::string ListJoin(IT it_begin, IT it_end);
- static std::string ConfigKey(const char* key, std::string const& config);
-
- private:
- cmGeneratedFileStream Ofs_;
- };
-
public:
- /// @return The detected Qt version and the required Qt major version
+ /** @return The detected Qt version and the required Qt major version. */
static std::pair<IntegerVersion, unsigned int> GetQtVersion(
- cmGeneratorTarget const* target);
+ cmGeneratorTarget const* genTarget);
cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
- cmGeneratorTarget* target,
+ cmGeneratorTarget* genTarget,
IntegerVersion const& qtVersion, bool mocEnabled,
bool uicEnabled, bool rccEnabled,
bool globalAutogenTarget, bool globalAutoRccTarget);
@@ -123,7 +112,7 @@ public:
bool SetupCustomTargets();
private:
- /// @brief If moc or uic is enabled, the autogen target will be generated
+ /** If moc or uic is enabled, the autogen target will be generated. */
bool MocOrUicEnabled() const
{
return (this->Moc.Enabled || this->Uic.Enabled);
@@ -144,48 +133,57 @@ private:
bool AddGeneratedSource(std::string const& filename, GenVarsT const& genVars,
bool prepend = false);
bool AddToSourceGroup(std::string const& fileName,
- std::string const& genNameUpper);
+ cm::string_view genNameUpper);
void AddCleanFile(std::string const& fileName);
+ void ConfigFileNames(ConfigString& configString, cm::string_view prefix,
+ cm::string_view suffix);
+ void ConfigFileClean(ConfigString& configString);
+
+ std::string GetMocBuildPath(MUFile const& muf);
+
bool GetQtExecutable(GenVarsT& genVars, const std::string& executable,
bool ignoreMissingTarget) const;
private:
- cmQtAutoGenGlobalInitializer* GlobalInitializer;
- cmGeneratorTarget* Target;
-
- // Configuration
+ cmQtAutoGenGlobalInitializer* GlobalInitializer = nullptr;
+ cmGeneratorTarget* GenTarget = nullptr;
+ cmGlobalGenerator* GlobalGen = nullptr;
+ cmLocalGenerator* LocalGen = nullptr;
+ cmMakefile* Makefile = nullptr;
+ cmFilePathChecksum const PathCheckSum;
+
+ // -- Configuration
IntegerVersion QtVersion;
+ unsigned int Verbosity = 0;
bool MultiConfig = false;
+ bool CMP0071Accept = false;
+ bool CMP0071Warn = false;
std::string ConfigDefault;
std::vector<std::string> ConfigsList;
- std::string Verbosity;
std::string TargetsFolder;
- bool CMP0071Accept = false;
- bool CMP0071Warn = false;
- /// @brief Common directories
+ /** Common directories. */
struct
{
std::string Info;
std::string Build;
std::string Work;
- std::string Include;
- std::map<std::string, std::string> ConfigInclude;
+ ConfigString Include;
+ std::string IncludeGenExp;
} Dir;
- /// @brief Autogen target variables
+ /** Autogen target variables. */
struct
{
std::string Name;
bool GlobalTarget = false;
// Settings
- std::string Parallel;
+ unsigned int Parallel = 1;
// Configuration files
std::string InfoFile;
- std::string SettingsFile;
- std::string ParseCacheFile;
- std::map<std::string, std::string> ConfigSettingsFile;
+ ConfigString SettingsFile;
+ ConfigString ParseCacheFile;
// Dependencies
bool DependOrigin = false;
std::set<std::string> DependFiles;
@@ -196,45 +194,53 @@ private:
std::vector<MUFile*> FilesGenerated;
} AutogenTarget;
- /// @brief Moc only variables
+ /** moc variables. */
struct MocT : public GenVarsT
{
- std::string PredefsCmd;
- std::vector<std::string> Includes;
- std::map<std::string, std::vector<std::string>> ConfigIncludes;
- std::set<std::string> Defines;
- std::map<std::string, std::set<std::string>> ConfigDefines;
- std::string MocsCompilation;
-
- /// @brief Constructor
MocT()
: GenVarsT(GenT::MOC){};
+
+ bool RelaxedMode = false;
+ bool PathPrefix = false;
+ std::string CompilationFile;
+ // Compiler implicit pre defines
+ std::vector<std::string> PredefsCmd;
+ ConfigString PredefsFile;
+ // Defines
+ ConfigStrings<std::set<std::string>> Defines;
+ // Includes
+ ConfigStrings<std::vector<std::string>> Includes;
+ // Options
+ std::vector<std::string> Options;
+ // Filters
+ std::vector<std::string> MacroNames;
+ std::vector<std::pair<std::string, std::string>> DependFilters;
+ // Utility
+ std::unordered_set<std::string> EmittedBuildPaths;
} Moc;
- /// @brief Uic only variables
+ /** uic variables. */
struct UicT : public GenVarsT
{
- std::set<std::string> SkipUi;
- std::vector<std::string> SearchPaths;
- std::vector<std::string> Options;
- std::map<std::string, std::vector<std::string>> ConfigOptions;
- std::vector<std::string> FileFiles;
- std::vector<std::vector<std::string>> FileOptions;
+ using UiFileT = std::pair<std::string, std::vector<std::string>>;
- /// @brief Constructor
UicT()
: GenVarsT(GenT::UIC){};
+
+ std::set<std::string> SkipUi;
+ std::vector<UiFileT> UiFiles;
+ ConfigStrings<std::vector<std::string>> Options;
+ std::vector<std::string> SearchPaths;
} Uic;
- /// @brief Rcc only variables
+ /** rcc variables. */
struct RccT : public GenVarsT
{
- bool GlobalTarget = false;
- std::vector<Qrc> Qrcs;
-
- /// @brief Constructor
RccT()
: GenVarsT(GenT::RCC){};
+
+ bool GlobalTarget = false;
+ std::vector<Qrc> Qrcs;
} Rcc;
};
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index e1c435be0..da963052f 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -1,18 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerator.h"
-#include "cmQtAutoGen.h"
#include "cmsys/FStream.hxx"
-#include "cmAlgorithms.h"
-#include "cmGlobalGenerator.h"
-#include "cmMakefile.h"
-#include "cmState.h"
-#include "cmStateDirectory.h"
-#include "cmStateSnapshot.h"
+#include "cm_jsoncpp_reader.h"
+
+#include "cmQtAutoGen.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmake.h"
cmQtAutoGenerator::Logger::Logger()
{
@@ -21,11 +17,11 @@ cmQtAutoGenerator::Logger::Logger()
std::string verbose;
if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) {
unsigned long iVerbose = 0;
- if (cmSystemTools::StringToULong(verbose.c_str(), &iVerbose)) {
+ if (cmStrToULong(verbose, &iVerbose)) {
SetVerbosity(static_cast<unsigned int>(iVerbose));
} else {
// Non numeric verbosity
- SetVerbose(cmSystemTools::IsOn(verbose));
+ SetVerbose(cmIsOn(verbose));
}
}
}
@@ -33,7 +29,7 @@ cmQtAutoGenerator::Logger::Logger()
std::string colorEnv;
cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
- SetColorOutput(cmSystemTools::IsOn(colorEnv));
+ SetColorOutput(cmIsOn(colorEnv));
} else {
SetColorOutput(true);
}
@@ -42,13 +38,10 @@ cmQtAutoGenerator::Logger::Logger()
cmQtAutoGenerator::Logger::~Logger() = default;
-void cmQtAutoGenerator::Logger::RaiseVerbosity(std::string const& value)
+void cmQtAutoGenerator::Logger::RaiseVerbosity(unsigned int value)
{
- unsigned long verbosity = 0;
- if (cmSystemTools::StringToULong(value.c_str(), &verbosity)) {
- if (this->Verbosity_ < verbosity) {
- this->Verbosity_ = static_cast<unsigned int>(verbosity);
- }
+ if (this->Verbosity_ < value) {
+ this->Verbosity_ = value;
}
}
@@ -57,24 +50,16 @@ void cmQtAutoGenerator::Logger::SetColorOutput(bool value)
ColorOutput_ = value;
}
-std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title)
+std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title)
{
- std::string head = title;
- head += '\n';
- head.append(head.size() - 1, '-');
- head += '\n';
- return head;
+ return cmStrCat(title, '\n', std::string(title.size(), '-'), '\n');
}
void cmQtAutoGenerator::Logger::Info(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
- std::string msg = GeneratorName(genType);
- msg += ": ";
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
+ std::string msg = cmStrCat(GeneratorName(genType), ": ", message,
+ cmHasSuffix(message, '\n') ? "" : "\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
@@ -82,94 +67,46 @@ void cmQtAutoGenerator::Logger::Info(GenT genType,
}
void cmQtAutoGenerator::Logger::Warning(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
std::string msg;
if (message.find('\n') == std::string::npos) {
// Single line message
- msg += GeneratorName(genType);
- msg += " warning: ";
+ msg = cmStrCat(GeneratorName(genType), " warning: ", message,
+ cmHasSuffix(message, '\n') ? "\n" : "\n\n");
} else {
// Multi line message
- msg += HeadLine(GeneratorName(genType) + " warning");
- }
- // Message
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
+ msg = cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " warning")),
+ message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
}
- msg.push_back('\n');
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stdout(msg);
}
}
-void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
- std::string const& filename,
- std::string const& message) const
-{
- std::string msg = " ";
- msg += Quoted(filename);
- msg.push_back('\n');
- // Message
- msg += message;
- Warning(genType, msg);
-}
-
void cmQtAutoGenerator::Logger::Error(GenT genType,
- std::string const& message) const
+ cm::string_view message) const
{
- std::string msg;
- msg += HeadLine(GeneratorName(genType) + " error");
- // Message
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
+ std::string msg =
+ cmStrCat('\n', HeadLine(cmStrCat(GeneratorName(genType), " error")),
+ message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);
}
}
-void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
- std::string const& filename,
- std::string const& message) const
-{
- std::string emsg = " ";
- emsg += Quoted(filename);
- emsg += '\n';
- // Message
- emsg += message;
- Error(genType, emsg);
-}
-
void cmQtAutoGenerator::Logger::ErrorCommand(
- GenT genType, std::string const& message,
+ GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
- std::string msg;
- msg.push_back('\n');
- msg += HeadLine(GeneratorName(genType) + " subprocess error");
- msg += message;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
- msg += HeadLine("Command");
- msg += QuotedCommand(command);
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
- msg += HeadLine("Output");
- msg += output;
- if (msg.back() != '\n') {
- msg.push_back('\n');
- }
- msg.push_back('\n');
+ std::string msg = cmStrCat(
+ '\n', HeadLine(cmStrCat(GeneratorName(genType), " subprocess error")),
+ message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
+ msg += cmStrCat(HeadLine("Command"), QuotedCommand(command), "\n\n");
+ msg += cmStrCat(HeadLine("Output"), output,
+ cmHasSuffix(output, '\n') ? "\n" : "\n\n");
{
std::lock_guard<std::mutex> lock(Mutex_);
cmSystemTools::Stderr(msg);
@@ -210,7 +147,7 @@ bool cmQtAutoGenerator::FileRead(std::string& content,
return false;
}
content.reserve(length);
- typedef std::istreambuf_iterator<char> IsIt;
+ using IsIt = std::istreambuf_iterator<char>;
content.assign(IsIt{ ifs }, IsIt{});
if (!ifs) {
content.clear();
@@ -268,65 +205,288 @@ bool cmQtAutoGenerator::FileDiffers(std::string const& filename,
return differs;
}
-cmQtAutoGenerator::cmQtAutoGenerator() = default;
+cmQtAutoGenerator::cmQtAutoGenerator(GenT genType)
+ : GenType_(genType)
+{
+}
cmQtAutoGenerator::~cmQtAutoGenerator() = default;
-bool cmQtAutoGenerator::Run(std::string const& infoFile,
- std::string const& config)
+bool cmQtAutoGenerator::InfoT::Read(std::istream& istr)
{
- // Info settings
- InfoFile_ = infoFile;
- cmSystemTools::ConvertToUnixSlashes(InfoFile_);
- if (!InfoFileTime_.Load(InfoFile_)) {
- std::string msg = "AutoGen: The info file ";
- msg += Quoted(InfoFile_);
- msg += " is not readable\n";
- cmSystemTools::Stderr(msg);
+ try {
+ istr >> Json_;
+ } catch (...) {
return false;
}
- InfoDir_ = cmSystemTools::GetFilenamePath(infoFile);
- InfoConfig_ = config;
+ return true;
+}
- bool success = false;
- {
- cmake cm(cmake::RoleScript, cmState::Unknown);
- cm.SetHomeOutputDirectory(InfoDir());
- cm.SetHomeDirectory(InfoDir());
- cm.GetCurrentSnapshot().SetDefaultDefinitions();
- cmGlobalGenerator gg(&cm);
-
- cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
- snapshot.GetDirectory().SetCurrentBinary(InfoDir());
- snapshot.GetDirectory().SetCurrentSource(InfoDir());
-
- auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
- // The OLD/WARN behavior for policy CMP0053 caused a speed regression.
- // https://gitlab.kitware.com/cmake/cmake/issues/17570
- makefile->SetPolicyVersion("3.9", std::string());
- gg.SetCurrentMakefile(makefile.get());
- success = this->Init(makefile.get());
+bool cmQtAutoGenerator::InfoT::GetJsonArray(std::vector<std::string>& list,
+ Json::Value const& jval)
+{
+ Json::ArrayIndex const arraySize = jval.size();
+ if (arraySize == 0) {
+ return false;
}
- if (success) {
- success = this->Process();
+
+ bool picked = false;
+ list.reserve(list.size() + arraySize);
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ Json::Value const& ival = jval[ii];
+ if (ival.isString()) {
+ list.emplace_back(ival.asString());
+ picked = true;
+ }
}
- return success;
+ return picked;
+}
+
+bool cmQtAutoGenerator::InfoT::GetJsonArray(
+ std::unordered_set<std::string>& list, Json::Value const& jval)
+{
+ Json::ArrayIndex const arraySize = jval.size();
+ if (arraySize == 0) {
+ return false;
+ }
+
+ bool picked = false;
+ list.reserve(list.size() + arraySize);
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ Json::Value const& ival = jval[ii];
+ if (ival.isString()) {
+ list.emplace(ival.asString());
+ picked = true;
+ }
+ }
+ return picked;
+}
+
+std::string cmQtAutoGenerator::InfoT::ConfigKey(cm::string_view key) const
+{
+ return cmStrCat(key, '_', Gen_.InfoConfig());
+}
+
+bool cmQtAutoGenerator::InfoT::GetString(std::string const& key,
+ std::string& value,
+ bool required) const
+{
+ Json::Value const& jval = Json_[key];
+ if (!jval.isString()) {
+ if (!jval.isNull() || required) {
+ return LogError(cmStrCat(key, " is not a string."));
+ }
+ } else {
+ value = jval.asString();
+ if (value.empty() && required) {
+ return LogError(cmStrCat(key, " is empty."));
+ }
+ }
+ return true;
+}
+
+bool cmQtAutoGenerator::InfoT::GetStringConfig(std::string const& key,
+ std::string& value,
+ bool required) const
+{
+ { // Try config
+ std::string const configKey = ConfigKey(key);
+ Json::Value const& jval = Json_[configKey];
+ if (!jval.isNull()) {
+ if (!jval.isString()) {
+ return LogError(cmStrCat(configKey, " is not a string."));
+ }
+ value = jval.asString();
+ if (required && value.empty()) {
+ return LogError(cmStrCat(configKey, " is empty."));
+ }
+ return true;
+ }
+ }
+ // Try plain
+ return GetString(key, value, required);
+}
+
+bool cmQtAutoGenerator::InfoT::GetBool(std::string const& key, bool& value,
+ bool required) const
+{
+ Json::Value const& jval = Json_[key];
+ if (jval.isBool()) {
+ value = jval.asBool();
+ } else {
+ if (!jval.isNull() || required) {
+ return LogError(cmStrCat(key, " is not a boolean."));
+ }
+ }
+ return true;
+}
+
+bool cmQtAutoGenerator::InfoT::GetUInt(std::string const& key,
+ unsigned int& value,
+ bool required) const
+{
+ Json::Value const& jval = Json_[key];
+ if (jval.isUInt()) {
+ value = jval.asUInt();
+ } else {
+ if (!jval.isNull() || required) {
+ return LogError(cmStrCat(key, " is not an unsigned integer."));
+ }
+ }
+ return true;
+}
+
+bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key,
+ std::vector<std::string>& list,
+ bool required) const
+{
+ Json::Value const& jval = Json_[key];
+ if (!jval.isArray()) {
+ if (!jval.isNull() || required) {
+ return LogError(cmStrCat(key, " is not an array."));
+ }
+ }
+ return GetJsonArray(list, jval) || !required;
+}
+
+bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key,
+ std::unordered_set<std::string>& list,
+ bool required) const
+{
+ Json::Value const& jval = Json_[key];
+ if (!jval.isArray()) {
+ if (!jval.isNull() || required) {
+ return LogError(cmStrCat(key, " is not an array."));
+ }
+ }
+ return GetJsonArray(list, jval) || !required;
+}
+
+bool cmQtAutoGenerator::InfoT::GetArrayConfig(std::string const& key,
+ std::vector<std::string>& list,
+ bool required) const
+{
+ { // Try config
+ std::string const configKey = ConfigKey(key);
+ Json::Value const& jval = Json_[configKey];
+ if (!jval.isNull()) {
+ if (!jval.isArray()) {
+ return LogError(cmStrCat(configKey, " is not an array string."));
+ }
+ if (!GetJsonArray(list, jval) && required) {
+ return LogError(cmStrCat(configKey, " is empty."));
+ }
+ return true;
+ }
+ }
+ // Try plain
+ return GetArray(key, list, required);
+}
+
+bool cmQtAutoGenerator::InfoT::LogError(GenT genType,
+ cm::string_view message) const
+{
+ Gen_.Log().Error(genType,
+ cmStrCat("Info error in info file\n",
+ Quoted(Gen_.InfoFile()), ":\n", message));
+ return false;
+}
+
+bool cmQtAutoGenerator::InfoT::LogError(cm::string_view message) const
+{
+ return LogError(Gen_.GenType_, message);
}
-std::string cmQtAutoGenerator::SettingsFind(std::string const& content,
- const char* key)
+std::string cmQtAutoGenerator::SettingsFind(cm::string_view content,
+ cm::string_view key)
{
- std::string prefix(key);
- prefix += ':';
- std::string::size_type pos = content.find(prefix);
- if (pos != std::string::npos) {
+ cm::string_view res;
+ std::string const prefix = cmStrCat(key, ':');
+ cm::string_view::size_type pos = content.find(prefix);
+ if (pos != cm::string_view::npos) {
pos += prefix.size();
if (pos < content.size()) {
- std::string::size_type posE = content.find('\n', pos);
- if ((posE != std::string::npos) && (posE != pos)) {
- return content.substr(pos, posE - pos);
+ cm::string_view::size_type posE = content.find('\n', pos);
+ if ((posE != cm::string_view::npos) && (posE != pos)) {
+ res = content.substr(pos, posE - pos);
}
}
}
- return std::string();
+ return std::string(res);
+}
+
+std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const
+{
+ std::string res;
+ if (cmHasPrefix(path, ProjectDirs().Source)) {
+ res = cmStrCat("SRC:", path.substr(ProjectDirs().Source.size()));
+ } else if (cmHasPrefix(path, ProjectDirs().Binary)) {
+ res = cmStrCat("BIN:", path.substr(ProjectDirs().Binary.size()));
+ } else {
+ res = std::string(path);
+ }
+ return cmQtAutoGen::Quoted(res);
+}
+
+bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config)
+{
+ // Info config
+ InfoConfig_ = std::string(config);
+
+ // Info file
+ InfoFile_ = std::string(infoFile);
+ cmSystemTools::CollapseFullPath(InfoFile_);
+ InfoDir_ = cmSystemTools::GetFilenamePath(InfoFile_);
+
+ // Load info file time
+ if (!InfoFileTime_.Load(InfoFile_)) {
+ cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ",
+ Quoted(InfoFile_), " is not readable\n"));
+ return false;
+ }
+
+ {
+ InfoT info(*this);
+
+ // Read info file
+ {
+ cmsys::ifstream ifs(InfoFile_.c_str(),
+ (std::ios::in | std::ios::binary));
+ if (!ifs) {
+ Log().Error(
+ GenType_,
+ cmStrCat("Could not to open info file ", Quoted(InfoFile_)));
+ return false;
+ }
+ if (!info.Read(ifs)) {
+ Log().Error(GenType_,
+ cmStrCat("Could not read info file ", Quoted(InfoFile_)));
+ return false;
+ }
+ }
+
+ // -- Read common info settings
+ {
+ unsigned int verbosity = 0;
+ // Info: setup project directories
+ if (!info.GetUInt("VERBOSITY", verbosity, false) ||
+ !info.GetString("CMAKE_SOURCE_DIR", ProjectDirs_.Source, true) ||
+ !info.GetString("CMAKE_BINARY_DIR", ProjectDirs_.Binary, true) ||
+ !info.GetString("CMAKE_CURRENT_SOURCE_DIR",
+ ProjectDirs_.CurrentSource, true) ||
+ !info.GetString("CMAKE_CURRENT_BINARY_DIR",
+ ProjectDirs_.CurrentBinary, true)) {
+ return false;
+ }
+ Logger_.RaiseVerbosity(verbosity);
+ }
+
+ // -- Call virtual init from info method.
+ if (!this->InitFromInfo(info)) {
+ return false;
+ }
+ }
+
+ // Call virtual process method.
+ return this->Process();
}
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index ff4c4c942..bbe6dd015 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -5,14 +5,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTime.h"
-#include "cmQtAutoGen.h"
-
+#include <istream>
#include <mutex>
#include <string>
+#include <unordered_set>
#include <vector>
-class cmMakefile;
+#include <cm/string_view>
+
+#include "cm_jsoncpp_value.h"
+
+#include "cmFileTime.h"
+#include "cmQtAutoGen.h"
/** \class cmQtAutoGenerator
* \brief Base class for QtAutoGen generators
@@ -22,9 +26,7 @@ class cmQtAutoGenerator : public cmQtAutoGen
public:
// -- Types
- /**
- * Thread safe logger
- */
+ /** Thread safe logger. */
class Logger
{
public:
@@ -34,28 +36,24 @@ public:
// -- Verbosity
unsigned int Verbosity() const { return this->Verbosity_; }
void SetVerbosity(unsigned int value) { this->Verbosity_ = value; }
- void RaiseVerbosity(std::string const& value);
+ void RaiseVerbosity(unsigned int value);
bool Verbose() const { return (this->Verbosity_ != 0); }
void SetVerbose(bool value) { this->Verbosity_ = value ? 1 : 0; }
// -- Color output
bool ColorOutput() const { return this->ColorOutput_; }
void SetColorOutput(bool value);
// -- Log info
- void Info(GenT genType, std::string const& message) const;
+ void Info(GenT genType, cm::string_view message) const;
// -- Log warning
- void Warning(GenT genType, std::string const& message) const;
- void WarningFile(GenT genType, std::string const& filename,
- std::string const& message) const;
+ void Warning(GenT genType, cm::string_view message) const;
// -- Log error
- void Error(GenT genType, std::string const& message) const;
- void ErrorFile(GenT genType, std::string const& filename,
- std::string const& message) const;
- void ErrorCommand(GenT genType, std::string const& message,
+ void Error(GenT genType, cm::string_view message) const;
+ void ErrorCommand(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
private:
- static std::string HeadLine(std::string const& title);
+ static std::string HeadLine(cm::string_view title);
private:
mutable std::mutex Mutex_;
@@ -63,6 +61,15 @@ public:
bool ColorOutput_ = false;
};
+ /** Project directories. */
+ struct ProjectDirsT
+ {
+ std::string Source;
+ std::string Binary;
+ std::string CurrentSource;
+ std::string CurrentBinary;
+ };
+
// -- File system methods
static bool MakeParentDirectory(std::string const& filename);
static bool FileRead(std::string& content, std::string const& filename,
@@ -75,35 +82,100 @@ public:
public:
// -- Constructors
- cmQtAutoGenerator();
+ cmQtAutoGenerator(GenT genType);
virtual ~cmQtAutoGenerator();
cmQtAutoGenerator(cmQtAutoGenerator const&) = delete;
cmQtAutoGenerator& operator=(cmQtAutoGenerator const&) = delete;
- // -- Run
- bool Run(std::string const& infoFile, std::string const& config);
-
- // -- InfoFile
+ // -- Info options
std::string const& InfoFile() const { return InfoFile_; }
- cmFileTime const& InfoFileTime() const { return InfoFileTime_; }
std::string const& InfoDir() const { return InfoDir_; }
+ cmFileTime const& InfoFileTime() const { return InfoFileTime_; }
std::string const& InfoConfig() const { return InfoConfig_; }
- // -- Utility
- static std::string SettingsFind(std::string const& content, const char* key);
+ // -- Info file parsing
+ /** Info file reader class. */
+ class InfoT
+ {
+ public:
+ InfoT(cmQtAutoGenerator& gen)
+ : Gen_(gen)
+ {
+ }
+
+ /** Read json data from a stream. */
+ bool Read(std::istream& istr);
+
+ /** Returns false if the JSON value isn't a string. */
+ bool GetString(std::string const& key, std::string& value,
+ bool required) const;
+ bool GetStringConfig(std::string const& key, std::string& value,
+ bool required) const;
+ bool GetBool(std::string const& key, bool& value, bool required) const;
+ bool GetUInt(std::string const& key, unsigned int& value,
+ bool required) const;
+ /** Returns false if the JSON value isn't an array. */
+ bool GetArray(std::string const& key, std::vector<std::string>& list,
+ bool required) const;
+ bool GetArray(std::string const& key,
+ std::unordered_set<std::string>& list, bool required) const;
+ bool GetArrayConfig(std::string const& key, std::vector<std::string>& list,
+ bool required) const;
+
+ Json::Value const& GetValue(std::string const& key) const
+ {
+ return Json_[key];
+ }
+
+ /** Returns true if strings were appended to the list. */
+ static bool GetJsonArray(std::vector<std::string>& list,
+ Json::Value const& jval);
+ /** Returns true if strings were found in the JSON array. */
+ static bool GetJsonArray(std::unordered_set<std::string>& list,
+ Json::Value const& jval);
+
+ bool LogError(GenT genType, cm::string_view message) const;
+ bool LogError(cm::string_view message) const;
+
+ private:
+ std::string ConfigKey(cm::string_view key) const;
+
+ private:
+ Json::Value Json_;
+ cmQtAutoGenerator& Gen_;
+ };
+
+ // -- Settings file
+ static std::string SettingsFind(cm::string_view content,
+ cm::string_view key);
+
+ // -- Directories
+ ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; }
+ std::string MessagePath(cm::string_view path) const;
+
+ // -- Run
+ bool Run(cm::string_view infoFile, cm::string_view config);
protected:
// -- Abstract processing interface
- virtual bool Init(cmMakefile* makefile) = 0;
+ virtual bool InitFromInfo(InfoT const& info) = 0;
virtual bool Process() = 0;
+ // - Utility classes
+ Logger const& Log() const { return Logger_; }
private:
- // -- Info settings
+ // -- Generator type
+ GenT GenType_;
+ // -- Logging
+ Logger Logger_;
+ // -- Info file
std::string InfoFile_;
- cmFileTime InfoFileTime_;
std::string InfoDir_;
+ cmFileTime InfoFileTime_;
std::string InfoConfig_;
+ // -- Directories
+ ProjectDirsT ProjectDirs_;
};
#endif
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 641d8aa3f..f8b898152 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -3,31 +3,571 @@
#include "cmQtAutoMocUic.h"
#include <algorithm>
-#include <array>
-#include <list>
-#include <memory>
+#include <atomic>
+#include <cstddef>
+#include <map>
+#include <mutex>
#include <set>
-#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
+#include <vector>
+
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_jsoncpp_value.h"
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
+#include "cmFileTime.h"
#include "cmGeneratedFileStream.h"
-#include "cmMakefile.h"
#include "cmQtAutoGen.h"
+#include "cmQtAutoGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmake.h"
-#include "cmsys/FStream.hxx"
+#include "cmWorkerPool.h"
#if defined(__APPLE__)
# include <unistd.h>
#endif
-static constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
-static constexpr std::size_t UiUnderscoreLength = 3; // Length of "ui_"
+namespace {
+
+constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
+constexpr std::size_t UiUnderscoreLength = 3; // Length of "ui_"
+
+/** \class cmQtAutoMocUicT
+ * \brief AUTOMOC and AUTOUIC generator
+ */
+class cmQtAutoMocUicT : public cmQtAutoGenerator
+{
+public:
+ cmQtAutoMocUicT();
+ ~cmQtAutoMocUicT() override;
+
+ cmQtAutoMocUicT(cmQtAutoMocUicT const&) = delete;
+ cmQtAutoMocUicT& operator=(cmQtAutoMocUicT const&) = delete;
+
+public:
+ // -- Types
+
+ /** Include string with sub parts. */
+ struct IncludeKeyT
+ {
+ IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
+
+ std::string Key; // Full include string
+ std::string Dir; // Include directory
+ std::string Base; // Base part of the include file name
+ };
+
+ /** Search key plus regular expression pair. */
+ struct KeyExpT
+ {
+ KeyExpT(std::string key, std::string const& exp)
+ : Key(std::move(key))
+ , Exp(exp)
+ {
+ }
+
+ std::string Key;
+ cmsys::RegularExpression Exp;
+ };
+
+ /** Source file parsing cache. */
+ class ParseCacheT
+ {
+ public:
+ // -- Types
+
+ /** Entry of the file parsing cache. */
+ struct FileT
+ {
+ void Clear();
+
+ struct MocT
+ {
+ std::string Macro;
+ struct IncludeT
+ {
+ std::vector<IncludeKeyT> Underscore;
+ std::vector<IncludeKeyT> Dot;
+ } Include;
+ std::vector<std::string> Depends;
+ } Moc;
+
+ struct UicT
+ {
+ std::vector<IncludeKeyT> Include;
+ std::vector<std::string> Depends;
+ } Uic;
+ };
+ using FileHandleT = std::shared_ptr<FileT>;
+ using GetOrInsertT = std::pair<FileHandleT, bool>;
+
+ public:
+ ParseCacheT();
+ ~ParseCacheT();
+
+ bool ReadFromFile(std::string const& fileName);
+ bool WriteToFile(std::string const& fileName);
+
+ //! Always returns a valid handle
+ GetOrInsertT GetOrInsert(std::string const& fileName);
+
+ private:
+ std::unordered_map<std::string, FileHandleT> Map_;
+ };
+
+ /** Source file data. */
+ class SourceFileT
+ {
+ public:
+ SourceFileT(std::string fileName)
+ : FileName(std::move(fileName))
+ {
+ }
+
+ public:
+ std::string FileName;
+ cmFileTime FileTime;
+ ParseCacheT::FileHandleT ParseData;
+ std::string BuildPath;
+ bool IsHeader = false;
+ bool Moc = false;
+ bool Uic = false;
+ };
+ using SourceFileHandleT = std::shared_ptr<SourceFileT>;
+ using SourceFileMapT = std::map<std::string, SourceFileHandleT>;
+
+ /** Meta compiler file mapping information. */
+ struct MappingT
+ {
+ SourceFileHandleT SourceFile;
+ std::string OutputFile;
+ std::string IncludeString;
+ std::vector<SourceFileHandleT> IncluderFiles;
+ };
+ using MappingHandleT = std::shared_ptr<MappingT>;
+ using MappingMapT = std::map<std::string, MappingHandleT>;
+
+ /** Common settings. */
+ class BaseSettingsT
+ {
+ public:
+ // -- Constructors
+ BaseSettingsT();
+ ~BaseSettingsT();
+
+ BaseSettingsT(BaseSettingsT const&) = delete;
+ BaseSettingsT& operator=(BaseSettingsT const&) = delete;
+
+ // -- Attributes
+ // - Config
+ bool MultiConfig = false;
+ unsigned int QtVersionMajor = 4;
+ unsigned int ThreadCount = 0;
+ // - Directories
+ std::string AutogenBuildDir;
+ std::string AutogenIncludeDir;
+ // - Files
+ std::string CMakeExecutable;
+ cmFileTime CMakeExecutableTime;
+ std::string ParseCacheFile;
+ std::vector<std::string> HeaderExtensions;
+ };
+
+ /** Shared common variables. */
+ class BaseEvalT
+ {
+ public:
+ // -- Parse Cache
+ bool ParseCacheChanged = false;
+ cmFileTime ParseCacheTime;
+ ParseCacheT ParseCache;
+
+ // -- Sources
+ SourceFileMapT Headers;
+ SourceFileMapT Sources;
+ };
+
+ /** Moc settings. */
+ class MocSettingsT
+ {
+ public:
+ // -- Constructors
+ MocSettingsT();
+ ~MocSettingsT();
+
+ MocSettingsT(MocSettingsT const&) = delete;
+ MocSettingsT& operator=(MocSettingsT const&) = delete;
+
+ // -- Const methods
+ bool skipped(std::string const& fileName) const;
+ std::string MacrosString() const;
+
+ // -- Attributes
+ bool Enabled = false;
+ bool SettingsChanged = false;
+ bool RelaxedMode = false;
+ bool PathPrefix = false;
+ cmFileTime ExecutableTime;
+ std::string Executable;
+ std::string CompFileAbs;
+ std::string PredefsFileAbs;
+ std::unordered_set<std::string> SkipList;
+ std::vector<std::string> IncludePaths;
+ std::vector<std::string> Definitions;
+ std::vector<std::string> OptionsIncludes;
+ std::vector<std::string> OptionsDefinitions;
+ std::vector<std::string> OptionsExtra;
+ std::vector<std::string> PredefsCmd;
+ std::vector<KeyExpT> DependFilters;
+ std::vector<KeyExpT> MacroFilters;
+ cmsys::RegularExpression RegExpInclude;
+ };
+
+ /** Moc shared variables. */
+ class MocEvalT
+ {
+ public:
+ // -- predefines file
+ cmFileTime PredefsTime;
+ // -- Mappings
+ MappingMapT HeaderMappings;
+ MappingMapT SourceMappings;
+ MappingMapT Includes;
+ // -- Discovered files
+ SourceFileMapT HeadersDiscovered;
+ // -- Output directories
+ std::unordered_set<std::string> OutputDirs;
+ // -- Mocs compilation
+ bool CompUpdated = false;
+ std::vector<std::string> CompFiles;
+ };
+
+ /** Uic settings. */
+ class UicSettingsT
+ {
+ public:
+ struct UiFile
+ {
+ std::vector<std::string> Options;
+ };
+
+ public:
+ UicSettingsT();
+ ~UicSettingsT();
+
+ UicSettingsT(UicSettingsT const&) = delete;
+ UicSettingsT& operator=(UicSettingsT const&) = delete;
+
+ // -- Const methods
+ bool skipped(std::string const& fileName) const;
+
+ // -- Attributes
+ bool Enabled = false;
+ bool SettingsChanged = false;
+ cmFileTime ExecutableTime;
+ std::string Executable;
+ std::unordered_set<std::string> SkipList;
+ std::vector<std::string> Options;
+ std::unordered_map<std::string, UiFile> UiFiles;
+ std::vector<std::string> SearchPaths;
+ cmsys::RegularExpression RegExpInclude;
+ };
+
+ /** Uic shared variables. */
+ class UicEvalT
+ {
+ public:
+ // -- Discovered files
+ SourceFileMapT UiFiles;
+ // -- Mappings
+ MappingMapT Includes;
+ // -- Output directories
+ std::unordered_set<std::string> OutputDirs;
+ };
+
+ /** Abstract job class for concurrent job processing. */
+ class JobT : public cmWorkerPool::JobT
+ {
+ protected:
+ /** Protected default constructor. */
+ JobT(bool fence = false)
+ : cmWorkerPool::JobT(fence)
+ {
+ }
+
+ //! Get the generator. Only valid during Process() call!
+ cmQtAutoMocUicT* Gen() const
+ {
+ return static_cast<cmQtAutoMocUicT*>(UserData());
+ };
+
+ // -- Accessors. Only valid during Process() call!
+ Logger const& Log() const { return Gen()->Log(); }
+ BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); }
+ BaseEvalT& BaseEval() const { return Gen()->BaseEval(); }
+ MocSettingsT const& MocConst() const { return Gen()->MocConst(); }
+ MocEvalT& MocEval() const { return Gen()->MocEval(); }
+ UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
+ UicEvalT& UicEval() const { return Gen()->UicEval(); }
+
+ // -- Logging
+ std::string MessagePath(cm::string_view path) const
+ {
+ return Gen()->MessagePath(path);
+ }
+ // - Error logging with automatic abort
+ void LogError(GenT genType, cm::string_view message) const;
+ void LogCommandError(GenT genType, cm::string_view message,
+ std::vector<std::string> const& command,
+ std::string const& output) const;
+
+ /** @brief Run an external process. Use only during Process() call! */
+ bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
+ std::vector<std::string> const& command,
+ std::string* infoMessage = nullptr);
+ };
+
+ /** Fence job utility class. */
+ class JobFenceT : public JobT
+ {
+ public:
+ JobFenceT()
+ : JobT(true)
+ {
+ }
+ void Process() override{};
+ };
+
+ /** Generate moc_predefs.h. */
+ class JobMocPredefsT : public JobFenceT
+ {
+ void Process() override;
+ bool Update(std::string* reason) const;
+ };
+
+ /** File parse job base class. */
+ class JobParseT : public JobT
+ {
+ public:
+ JobParseT(SourceFileHandleT fileHandle)
+ : FileHandle(std::move(fileHandle))
+ {
+ }
+
+ protected:
+ bool ReadFile();
+ void CreateKeys(std::vector<IncludeKeyT>& container,
+ std::set<std::string> const& source,
+ std::size_t basePrefixLength);
+ void MocMacro();
+ void MocDependecies();
+ void MocIncludes();
+ void UicIncludes();
+
+ protected:
+ SourceFileHandleT FileHandle;
+ std::string Content;
+ };
+
+ /** Header file parse job. */
+ class JobParseHeaderT : public JobParseT
+ {
+ public:
+ using JobParseT::JobParseT;
+ void Process() override;
+ };
+
+ /** Source file parse job. */
+ class JobParseSourceT : public JobParseT
+ {
+ public:
+ using JobParseT::JobParseT;
+ void Process() override;
+ };
+
+ /** Evaluate cached file parse data - moc. */
+ class JobEvalCacheT : public JobT
+ {
+ protected:
+ std::string MessageSearchLocations() const;
+ std::vector<std::string> SearchLocations;
+ };
+
+ /** Evaluate cached file parse data - moc. */
+ class JobEvalCacheMocT : public JobEvalCacheT
+ {
+ void Process() override;
+ bool EvalHeader(SourceFileHandleT source);
+ bool EvalSource(SourceFileHandleT const& source);
+ bool FindIncludedHeader(SourceFileHandleT& headerHandle,
+ cm::string_view includerDir,
+ cm::string_view includeBase);
+ bool RegisterIncluded(std::string const& includeString,
+ SourceFileHandleT includerFileHandle,
+ SourceFileHandleT sourceFileHandle) const;
+ void RegisterMapping(MappingHandleT mappingHandle) const;
+ std::string MessageHeader(cm::string_view headerBase) const;
+ };
+
+ /** Evaluate cached file parse data - uic. */
+ class JobEvalCacheUicT : public JobEvalCacheT
+ {
+ void Process() override;
+ bool EvalFile(SourceFileHandleT const& sourceFileHandle);
+ bool FindIncludedUi(cm::string_view sourceDirPrefix,
+ cm::string_view includePrefix);
+ bool RegisterMapping(std::string const& includeString,
+ SourceFileHandleT includerFileHandle);
+
+ std::string UiName;
+ SourceFileHandleT UiFileHandle;
+ };
+
+ /** Evaluate cached file parse data - finish */
+ class JobEvalCacheFinishT : public JobFenceT
+ {
+ void Process() override;
+ };
+
+ /** Dependency probing base job. */
+ class JobProbeDepsT : public JobT
+ {
+ };
+
+ /** Probes file dependencies and generates moc compile jobs. */
+ class JobProbeDepsMocT : public JobProbeDepsT
+ {
+ void Process() override;
+ bool Generate(MappingHandleT const& mapping, bool compFile) const;
+ bool Probe(MappingT const& mapping, std::string* reason) const;
+ std::pair<std::string, cmFileTime> FindDependency(
+ std::string const& sourceDir, std::string const& includeString) const;
+ };
+
+ /** Probes file dependencies and generates uic compile jobs. */
+ class JobProbeDepsUicT : public JobProbeDepsT
+ {
+ void Process() override;
+ bool Probe(MappingT const& mapping, std::string* reason) const;
+ };
+
+ /** Dependency probing finish job. */
+ class JobProbeDepsFinishT : public JobFenceT
+ {
+ void Process() override;
+ };
+
+ /** Meta compiler base job. */
+ class JobCompileT : public JobT
+ {
+ public:
+ JobCompileT(MappingHandleT uicMapping, std::unique_ptr<std::string> reason)
+ : Mapping(std::move(uicMapping))
+ , Reason(std::move(reason))
+ {
+ }
+
+ protected:
+ MappingHandleT Mapping;
+ std::unique_ptr<std::string> Reason;
+ };
+
+ /** moc compiles a file. */
+ class JobCompileMocT : public JobCompileT
+ {
+ public:
+ using JobCompileT::JobCompileT;
+ void Process() override;
+ };
+
+ /** uic compiles a file. */
+ class JobCompileUicT : public JobCompileT
+ {
+ public:
+ using JobCompileT::JobCompileT;
+ void Process() override;
+ };
+
+ /** Generate mocs_compilation.cpp. */
+ class JobMocsCompilationT : public JobFenceT
+ {
+ private:
+ void Process() override;
+ };
+
+ /** @brief The last job. */
+ class JobFinishT : public JobFenceT
+ {
+ private:
+ void Process() override;
+ };
-cmQtAutoMocUic::IncludeKeyT::IncludeKeyT(std::string const& key,
- std::size_t basePrefixLength)
+ // -- Const settings interface
+ BaseSettingsT const& BaseConst() const { return this->BaseConst_; }
+ BaseEvalT& BaseEval() { return this->BaseEval_; }
+ MocSettingsT const& MocConst() const { return this->MocConst_; }
+ MocEvalT& MocEval() { return this->MocEval_; }
+ UicSettingsT const& UicConst() const { return this->UicConst_; }
+ UicEvalT& UicEval() { return this->UicEval_; }
+
+ // -- Parallel job processing interface
+ cmWorkerPool& WorkerPool() { return WorkerPool_; }
+ void AbortError() { Abort(true); }
+ void AbortSuccess() { Abort(false); }
+
+ // -- Utility
+ std::string AbsoluteBuildPath(cm::string_view relativePath) const;
+ std::string AbsoluteIncludePath(cm::string_view relativePath) const;
+ template <class JOBTYPE>
+ void CreateParseJobs(SourceFileMapT const& sourceMap);
+ std::string CollapseFullPathTS(std::string const& path) const;
+
+private:
+ // -- Abstract processing interface
+ bool InitFromInfo(InfoT const& info) override;
+ void InitJobs();
+ bool Process() override;
+ // -- Settings file
+ void SettingsFileRead();
+ bool SettingsFileWrite();
+ // -- Parse cache
+ void ParseCacheRead();
+ bool ParseCacheWrite();
+ // -- Thread processing
+ void Abort(bool error);
+ // -- Generation
+ bool CreateDirectories();
+
+private:
+ // -- Settings
+ BaseSettingsT BaseConst_;
+ BaseEvalT BaseEval_;
+ MocSettingsT MocConst_;
+ MocEvalT MocEval_;
+ UicSettingsT UicConst_;
+ UicEvalT UicEval_;
+ // -- Settings file
+ std::string SettingsFile_;
+ std::string SettingsStringMoc_;
+ std::string SettingsStringUic_;
+ // -- Worker thread pool
+ std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
+ cmWorkerPool WorkerPool_;
+ // -- Concurrent processing
+ mutable std::mutex CMakeLibMutex_;
+};
+
+cmQtAutoMocUicT::IncludeKeyT::IncludeKeyT(std::string const& key,
+ std::size_t basePrefixLength)
: Key(key)
, Dir(SubDirPrefix(key))
, Base(cmSystemTools::GetFilenameWithoutLastExtension(key))
@@ -37,7 +577,7 @@ cmQtAutoMocUic::IncludeKeyT::IncludeKeyT(std::string const& key,
}
}
-void cmQtAutoMocUic::ParseCacheT::FileT::Clear()
+void cmQtAutoMocUicT::ParseCacheT::FileT::Clear()
{
Moc.Macro.clear();
Moc.Include.Underscore.clear();
@@ -48,18 +588,8 @@ void cmQtAutoMocUic::ParseCacheT::FileT::Clear()
Uic.Depends.clear();
}
-cmQtAutoMocUic::ParseCacheT::FileHandleT cmQtAutoMocUic::ParseCacheT::Get(
- std::string const& fileName) const
-{
- auto it = Map_.find(fileName);
- if (it != Map_.end()) {
- return it->second;
- }
- return FileHandleT();
-}
-
-cmQtAutoMocUic::ParseCacheT::GetOrInsertT
-cmQtAutoMocUic::ParseCacheT::GetOrInsert(std::string const& fileName)
+cmQtAutoMocUicT::ParseCacheT::GetOrInsertT
+cmQtAutoMocUicT::ParseCacheT::GetOrInsert(std::string const& fileName)
{
// Find existing entry
{
@@ -75,15 +605,10 @@ cmQtAutoMocUic::ParseCacheT::GetOrInsert(std::string const& fileName)
};
}
-cmQtAutoMocUic::ParseCacheT::ParseCacheT() = default;
-cmQtAutoMocUic::ParseCacheT::~ParseCacheT() = default;
+cmQtAutoMocUicT::ParseCacheT::ParseCacheT() = default;
+cmQtAutoMocUicT::ParseCacheT::~ParseCacheT() = default;
-void cmQtAutoMocUic::ParseCacheT::Clear()
-{
- Map_.clear();
-}
-
-bool cmQtAutoMocUic::ParseCacheT::ReadFromFile(std::string const& fileName)
+bool cmQtAutoMocUicT::ParseCacheT::ReadFromFile(std::string const& fileName)
{
cmsys::ifstream fin(fileName.c_str());
if (!fin) {
@@ -146,7 +671,7 @@ bool cmQtAutoMocUic::ParseCacheT::ReadFromFile(std::string const& fileName)
return true;
}
-bool cmQtAutoMocUic::ParseCacheT::WriteToFile(std::string const& fileName)
+bool cmQtAutoMocUicT::ParseCacheT::WriteToFile(std::string const& fileName)
{
cmGeneratedFileStream ofs(fileName);
if (!ofs) {
@@ -178,24 +703,24 @@ bool cmQtAutoMocUic::ParseCacheT::WriteToFile(std::string const& fileName)
return ofs.Close();
}
-cmQtAutoMocUic::BaseSettingsT::BaseSettingsT() = default;
-cmQtAutoMocUic::BaseSettingsT::~BaseSettingsT() = default;
+cmQtAutoMocUicT::BaseSettingsT::BaseSettingsT() = default;
+cmQtAutoMocUicT::BaseSettingsT::~BaseSettingsT() = default;
-cmQtAutoMocUic::MocSettingsT::MocSettingsT()
+cmQtAutoMocUicT::MocSettingsT::MocSettingsT()
{
RegExpInclude.compile(
"(^|\n)[ \t]*#[ \t]*include[ \t]+"
"[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
}
-cmQtAutoMocUic::MocSettingsT::~MocSettingsT() = default;
+cmQtAutoMocUicT::MocSettingsT::~MocSettingsT() = default;
-bool cmQtAutoMocUic::MocSettingsT::skipped(std::string const& fileName) const
+bool cmQtAutoMocUicT::MocSettingsT::skipped(std::string const& fileName) const
{
return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
}
-std::string cmQtAutoMocUic::MocSettingsT::MacrosString() const
+std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const
{
std::string res;
const auto itB = MacroFilters.cbegin();
@@ -217,65 +742,56 @@ std::string cmQtAutoMocUic::MocSettingsT::MacrosString() const
return res;
}
-cmQtAutoMocUic::UicSettingsT::UicSettingsT()
+cmQtAutoMocUicT::UicSettingsT::UicSettingsT()
{
RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
"[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
}
-cmQtAutoMocUic::UicSettingsT::~UicSettingsT() = default;
+cmQtAutoMocUicT::UicSettingsT::~UicSettingsT() = default;
-bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const
+bool cmQtAutoMocUicT::UicSettingsT::skipped(std::string const& fileName) const
{
return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
}
-void cmQtAutoMocUic::JobT::LogError(GenT genType,
- std::string const& message) const
+void cmQtAutoMocUicT::JobT::LogError(GenT genType,
+ cm::string_view message) const
{
Gen()->AbortError();
Gen()->Log().Error(genType, message);
}
-void cmQtAutoMocUic::JobT::LogFileError(GenT genType,
- std::string const& filename,
- std::string const& message) const
-{
- Gen()->AbortError();
- Gen()->Log().ErrorFile(genType, filename, message);
-}
-
-void cmQtAutoMocUic::JobT::LogCommandError(
- GenT genType, std::string const& message,
+void cmQtAutoMocUicT::JobT::LogCommandError(
+ GenT genType, cm::string_view message,
std::vector<std::string> const& command, std::string const& output) const
{
Gen()->AbortError();
Gen()->Log().ErrorCommand(genType, message, command, output);
}
-bool cmQtAutoMocUic::JobT::RunProcess(GenT genType,
- cmWorkerPool::ProcessResultT& result,
- std::vector<std::string> const& command,
- std::string* infoMessage)
+bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType,
+ cmWorkerPool::ProcessResultT& result,
+ std::vector<std::string> const& command,
+ std::string* infoMessage)
{
// Log command
if (Log().Verbose()) {
- std::string msg;
- if ((infoMessage != nullptr) && !infoMessage->empty()) {
- msg = *infoMessage;
- if (msg.back() != '\n') {
- msg += '\n';
- }
+ cm::string_view info;
+ if (infoMessage != nullptr) {
+ info = *infoMessage;
}
- msg += QuotedCommand(command);
- msg += '\n';
- Log().Info(genType, msg);
+ Log().Info(genType,
+ cmStrCat(info,
+ info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
+ QuotedCommand(command), '\n'));
}
+ // Run command
return cmWorkerPool::JobT::RunProcess(result, command,
BaseConst().AutogenBuildDir);
}
-void cmQtAutoMocUic::JobMocPredefsT::Process()
+void cmQtAutoMocUicT::JobMocPredefsT::Process()
{
// (Re)generate moc_predefs.h on demand
std::unique_ptr<std::string> reason;
@@ -285,26 +801,23 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
if (!Update(reason.get())) {
return;
}
- std::string const& predefsFileRel = MocConst().PredefsFileRel;
std::string const& predefsFileAbs = MocConst().PredefsFileAbs;
{
cmWorkerPool::ProcessResultT result;
{
// Compose command
std::vector<std::string> cmd = MocConst().PredefsCmd;
- // Add includes
- cmAppend(cmd, MocConst().Includes);
// Add definitions
- for (std::string const& def : MocConst().Definitions) {
- cmd.emplace_back("-D" + def);
- }
+ cmAppend(cmd, MocConst().OptionsDefinitions);
+ // Add includes
+ cmAppend(cmd, MocConst().OptionsIncludes);
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
- std::string msg = "The content generation command for ";
- msg += Quoted(predefsFileRel);
- msg += " failed.\n";
- msg += result.ErrorMessage;
- LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::MOC,
+ cmStrCat("The content generation command for ",
+ MessagePath(predefsFileAbs), " failed.\n",
+ result.ErrorMessage),
+ cmd, result.StdOut);
return;
}
}
@@ -312,22 +825,20 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
// (Re)write predefs file only on demand
if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
- std::string msg = "Writing ";
- msg += Quoted(predefsFileRel);
- msg += " failed.";
- LogFileError(GenT::MOC, predefsFileAbs, msg);
+ LogError(
+ GenT::MOC,
+ cmStrCat("Writing ", MessagePath(predefsFileAbs), " failed."));
return;
}
} else {
// Touch to update the time stamp
if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
+ Log().Info(GenT::MOC, "Touching " + MessagePath(predefsFileAbs));
}
if (!cmSystemTools::Touch(predefsFileAbs, false)) {
- std::string msg = "Touching ";
- msg += Quoted(predefsFileAbs);
- msg += " failed.";
- LogFileError(GenT::MOC, predefsFileAbs, msg);
+ LogError(
+ GenT::MOC,
+ cmStrCat("Touching ", MessagePath(predefsFileAbs), " failed."));
return;
}
}
@@ -335,19 +846,20 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
// Read file time afterwards
if (!MocEval().PredefsTime.Load(predefsFileAbs)) {
- LogFileError(GenT::MOC, predefsFileAbs, "File time reading failed.");
+ LogError(GenT::MOC,
+ cmStrCat("Reading the file time of ", MessagePath(predefsFileAbs),
+ " failed."));
return;
}
}
-bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
+bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const
{
// Test if the file exists
if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(MocConst().PredefsFileRel);
- *reason += ", because it doesn't exist.";
+ *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
+ ", because it doesn't exist.");
}
return true;
}
@@ -355,9 +867,8 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
// Test if the settings changed
if (MocConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(MocConst().PredefsFileRel);
- *reason += ", because the moc settings changed.";
+ *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
+ ", because the moc settings changed.");
}
return true;
}
@@ -369,11 +880,9 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
if (execTime.Load(exec)) {
if (MocEval().PredefsTime.Older(execTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(MocConst().PredefsFileRel);
- *reason += " because it is older than ";
- *reason += Quoted(exec);
- *reason += ".";
+ *reason =
+ cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs),
+ " because it is older than ", MessagePath(exec), '.');
}
return true;
}
@@ -383,34 +892,36 @@ bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
return false;
}
-bool cmQtAutoMocUic::JobParseT::ReadFile()
+bool cmQtAutoMocUicT::JobParseT::ReadFile()
{
// Clear old parse information
FileHandle->ParseData->Clear();
std::string const& fileName = FileHandle->FileName;
// Write info
if (Log().Verbose()) {
- Log().Info(GenT::GEN, "Parsing " + Quoted(fileName));
+ Log().Info(GenT::GEN, cmStrCat("Parsing ", MessagePath(fileName)));
}
// Read file content
{
std::string error;
if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) {
- LogFileError(GenT::GEN, fileName, "Could not read the file: " + error);
+ LogError(
+ GenT::GEN,
+ cmStrCat("Could not read ", MessagePath(fileName), ".\n", error));
return false;
}
}
// Warn if empty
if (Content.empty()) {
- Log().WarningFile(GenT::GEN, fileName, "The file is empty.");
+ Log().Warning(GenT::GEN, cmStrCat(MessagePath(fileName), " is empty."));
return false;
}
return true;
}
-void cmQtAutoMocUic::JobParseT::CreateKeys(std::vector<IncludeKeyT>& container,
- std::set<std::string> const& source,
- std::size_t basePrefixLength)
+void cmQtAutoMocUicT::JobParseT::CreateKeys(
+ std::vector<IncludeKeyT>& container, std::set<std::string> const& source,
+ std::size_t basePrefixLength)
{
if (source.empty()) {
return;
@@ -421,7 +932,7 @@ void cmQtAutoMocUic::JobParseT::CreateKeys(std::vector<IncludeKeyT>& container,
}
}
-void cmQtAutoMocUic::JobParseT::MocMacro()
+void cmQtAutoMocUicT::JobParseT::MocMacro()
{
for (KeyExpT const& filter : MocConst().MacroFilters) {
// Run a simple find string check
@@ -438,7 +949,7 @@ void cmQtAutoMocUic::JobParseT::MocMacro()
}
}
-void cmQtAutoMocUic::JobParseT::MocDependecies()
+void cmQtAutoMocUicT::JobParseT::MocDependecies()
{
if (MocConst().DependFilters.empty()) {
return;
@@ -479,7 +990,7 @@ void cmQtAutoMocUic::JobParseT::MocDependecies()
}
}
-void cmQtAutoMocUic::JobParseT::MocIncludes()
+void cmQtAutoMocUicT::JobParseT::MocIncludes()
{
if (Content.find("moc") == std::string::npos) {
return;
@@ -512,7 +1023,7 @@ void cmQtAutoMocUic::JobParseT::MocIncludes()
CreateKeys(Include.Dot, dot, 0);
}
-void cmQtAutoMocUic::JobParseT::UicIncludes()
+void cmQtAutoMocUicT::JobParseT::UicIncludes()
{
if (Content.find("ui_") == std::string::npos) {
return;
@@ -532,7 +1043,7 @@ void cmQtAutoMocUic::JobParseT::UicIncludes()
CreateKeys(FileHandle->ParseData->Uic.Include, includes, UiUnderscoreLength);
}
-void cmQtAutoMocUic::JobParseHeaderT::Process()
+void cmQtAutoMocUicT::JobParseHeaderT::Process()
{
if (!ReadFile()) {
return;
@@ -548,7 +1059,7 @@ void cmQtAutoMocUic::JobParseHeaderT::Process()
}
}
-void cmQtAutoMocUic::JobParseSourceT::Process()
+void cmQtAutoMocUicT::JobParseSourceT::Process()
{
if (!ReadFile()) {
return;
@@ -565,37 +1076,35 @@ void cmQtAutoMocUic::JobParseSourceT::Process()
}
}
-void cmQtAutoMocUic::JobEvaluateT::Process()
+std::string cmQtAutoMocUicT::JobEvalCacheT::MessageSearchLocations() const
{
- // Evaluate for moc
- if (MocConst().Enabled) {
- // Evaluate headers
- for (auto const& pair : BaseEval().Headers) {
- if (!MocEvalHeader(pair.second)) {
- return;
- }
- }
- // Evaluate sources
- for (auto const& pair : BaseEval().Sources) {
- if (!MocEvalSource(pair.second)) {
- return;
- }
+ std::string res;
+ res.reserve(512);
+ for (std::string const& path : SearchLocations) {
+ res += " ";
+ res += MessagePath(path);
+ res += '\n';
+ }
+ return res;
+}
+
+void cmQtAutoMocUicT::JobEvalCacheMocT::Process()
+{
+ // Evaluate headers
+ for (auto const& pair : BaseEval().Headers) {
+ if (!EvalHeader(pair.second)) {
+ return;
}
}
- // Evaluate for uic
- if (UicConst().Enabled) {
- if (!UicEval(BaseEval().Headers) || !UicEval(BaseEval().Sources)) {
+ // Evaluate sources
+ for (auto const& pair : BaseEval().Sources) {
+ if (!EvalSource(pair.second)) {
return;
}
}
-
- // Add discovered header parse jobs
- Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered);
- // Add generate job after
- Gen()->WorkerPool().EmplaceJob<JobGenerateT>();
}
-bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source)
+bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalHeader(SourceFileHandleT source)
{
SourceFileT const& sourceFile = *source;
auto const& parseData = sourceFile.ParseData->Moc;
@@ -616,13 +1125,13 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source)
}
// Register mapping in headers map
- MocRegisterMapping(handle, true);
+ RegisterMapping(handle);
}
return true;
}
-bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
+bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource(
SourceFileHandleT const& source)
{
SourceFileT const& sourceFile = *source;
@@ -633,7 +1142,7 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
return true;
}
- std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
+ std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName);
std::string const sourceBase =
cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName);
@@ -660,33 +1169,30 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// Check if this source needs to be moc processed but doesn't.
if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
!(relaxedMode && sourceIncludesMocUnderscore)) {
- {
- std::string emsg = "The file contains a ";
- emsg += Quoted(parseData.Macro);
- emsg += " macro, but does not include ";
- emsg += Quoted(sourceBase + ".moc");
- emsg += "!\nConsider to\n - add #include \"";
- emsg += sourceBase;
- emsg += ".moc\"\n - enable SKIP_AUTOMOC for this file";
- LogFileError(GenT::MOC, sourceFile.FileName, emsg);
- }
+ LogError(GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ",
+ Quoted(parseData.Macro), " macro, but does not include ",
+ MessagePath(sourceBase + ".moc"),
+ "!\nConsider to\n - add #include \"", sourceBase,
+ ".moc\"\n - enable SKIP_AUTOMOC for this file"));
return false;
}
// Evaluate "moc_" includes
for (IncludeKeyT const& incKey : parseData.Include.Underscore) {
- std::string const headerBase = incKey.Dir + incKey.Base;
- SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
- if (!header) {
- {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ",\nbut the header could not be found "
- "in the following locations\n";
- msg += MocMessageTestHeaders(headerBase);
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
+ SourceFileHandleT headerHandle;
+ {
+ std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base);
+ if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) {
+ LogError(GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", MessagePath(incKey.Key),
+ ",\nbut a header ", MessageHeader(headerBase),
+ "\ncould not be found "
+ "in the following directories\n",
+ MessageSearchLocations()));
+ return false;
}
- return false;
}
// The include might be handled differently in relaxed mode
if (relaxedMode && !sourceIncludesDotMoc && !parseData.Macro.empty() &&
@@ -696,35 +1202,32 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
// be generated from <BASE>.cpp instead of <BASE>.h, because otherwise
// it won't build. But warn, since this is not how it is supposed to be
// used. This is for KDE4 compatibility.
- {
- // Issue a warning
- std::string msg = "The file contains a ";
- msg += Quoted(parseData.Macro);
- msg += " macro, but does not include ";
- msg += Quoted(sourceBase + ".moc");
- msg += ".\nInstead it includes ";
- msg += Quoted(incKey.Key);
- msg += ".\nRunning moc on the source\n ";
- msg += Quoted(sourceFile.FileName);
- msg += "!\nBetter include ";
- msg += Quoted(sourceBase + ".moc");
- msg += " for compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
- }
+
+ // Issue a warning
+ Log().Warning(
+ GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ",
+ Quoted(parseData.Macro), " macro, but does not include ",
+ MessagePath(sourceBase + ".moc"), ".\nInstead it includes ",
+ MessagePath(incKey.Key), ".\nRunning moc on the source\n ",
+ MessagePath(sourceFile.FileName), "!\nBetter include ",
+ MessagePath(sourceBase + ".moc"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
+
// Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
+ if (!RegisterIncluded(incKey.Key, source, source)) {
return false;
}
continue;
}
// Check if header is skipped
- if (MocConst().skipped(header->FileName)) {
+ if (MocConst().skipped(headerHandle->FileName)) {
continue;
}
// Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
+ if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) {
return false;
}
}
@@ -737,57 +1240,60 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (ownMoc && !parseData.Macro.empty()) {
// Create mapping for the regular use case
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
+ if (!RegisterIncluded(incKey.Key, source, source)) {
return false;
}
continue;
}
// Try to find a header instead but issue a warning.
// This is for KDE4 compatibility.
- std::string const headerBase = incKey.Dir + incKey.Base;
- SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
- if (!header) {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ",\nwhich seems to be the moc file from a different source "
- "file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header"
- "could not be found in the following locations\n";
- msg += MocMessageTestHeaders(headerBase);
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
- return false;
+ SourceFileHandleT headerHandle;
+ {
+ std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base);
+ if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) {
+ LogError(
+ GenT::MOC,
+ cmStrCat(
+ MessagePath(sourceFile.FileName), "\nincludes the moc file ",
+ MessagePath(incKey.Key),
+ ",\nwhich seems to be the moc file from a different source "
+ "file.\nCMAKE_AUTOMOC_RELAXED_MODE:\nAlso a matching header ",
+ MessageHeader(headerBase),
+ "\ncould not be found in the following directories\n",
+ MessageSearchLocations()));
+ return false;
+ }
}
// Check if header is skipped
- if (MocConst().skipped(header->FileName)) {
+ if (MocConst().skipped(headerHandle->FileName)) {
continue;
}
// Issue a warning
if (ownMoc && parseData.Macro.empty()) {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ", but does not contain a\n";
- msg += MocConst().MacrosString();
- msg += " macro.\nRunning moc on the header\n ";
- msg += Quoted(header->FileName);
- msg += "!\nBetter include ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += " for a compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().Warning(
+ GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", MessagePath(incKey.Key),
+ ", but does not contain a\n", MocConst().MacrosString(),
+ " macro.\nRunning moc on the header\n ",
+ MessagePath(headerHandle->FileName), "!\nBetter include ",
+ MessagePath("moc_" + incKey.Base + ".cpp"),
+ " for a compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
} else {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += " instead of ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += ".\nRunning moc on the header\n ";
- msg += Quoted(header->FileName);
- msg += "!\nBetter include ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += " for compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().Warning(
+ GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", MessagePath(incKey.Key),
+ " instead of ", MessagePath("moc_" + incKey.Base + ".cpp"),
+ ".\nRunning moc on the header\n ",
+ MessagePath(headerHandle->FileName), "!\nBetter include ",
+ MessagePath("moc_" + incKey.Base + ".cpp"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
}
// Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
+ if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) {
return false;
}
}
@@ -798,26 +1304,26 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
bool const ownMoc = (incKey.Base == sourceBase);
if (!ownMoc) {
// Don't allow <BASE>.moc include other than own in regular mode
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ",\nwhich seems to be the moc file from a different "
- "source file.\nThis is not supported. Include ";
- msg += Quoted(sourceBase + ".moc");
- msg += " to run moc on this source file.";
- LogFileError(GenT::MOC, sourceFile.FileName, msg);
+ LogError(GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ", MessagePath(incKey.Key),
+ ",\nwhich seems to be the moc file from a different "
+ "source file.\nThis is not supported. Include ",
+ MessagePath(sourceBase + ".moc"),
+ " to run moc on this source file."));
return false;
}
// Accept but issue a warning if moc isn't required
if (parseData.Macro.empty()) {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ", but does not contain a ";
- msg += MocConst().MacrosString();
- msg += " macro.";
- Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
+ Log().Warning(GenT::MOC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the moc file ",
+ MessagePath(incKey.Key),
+ ", but does not contain a ",
+ MocConst().MacrosString(), " macro."));
}
// Create mapping
- if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
+ if (!RegisterIncluded(incKey.Key, source, source)) {
return false;
}
}
@@ -826,113 +1332,97 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
return true;
}
-cmQtAutoMocUic::SourceFileHandleT
-cmQtAutoMocUic::JobEvaluateT::MocFindIncludedHeader(
- std::string const& includerDir, std::string const& includeBase) const
+bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader(
+ SourceFileHandleT& headerHandle, cm::string_view includerDir,
+ cm::string_view includeBase)
{
- // Search in vicinity of the source
- {
- SourceFileHandleT res = MocFindHeader(includerDir + includeBase);
- if (res) {
- return res;
- }
- }
- // Search in include directories
- for (std::string const& path : MocConst().IncludePaths) {
- std::string testPath = path;
- testPath += '/';
- testPath += includeBase;
- SourceFileHandleT res = MocFindHeader(testPath);
- if (res) {
- return res;
- }
- }
- // Return without success
- return SourceFileHandleT();
-}
+ // Clear search locations
+ SearchLocations.clear();
+
+ auto findHeader = [this,
+ &headerHandle](std::string const& basePath) -> bool {
+ bool found = false;
+ for (std::string const& ext : this->BaseConst().HeaderExtensions) {
+ std::string const testPath =
+ this->Gen()->CollapseFullPathTS(cmStrCat(basePath, '.', ext));
+ cmFileTime fileTime;
+ if (!fileTime.Load(testPath)) {
+ // File not found
+ continue;
+ }
-cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader(
- std::string const& basePath) const
-{
- std::string testPath;
- testPath.reserve(basePath.size() + 8);
- for (std::string const& ext : BaseConst().HeaderExtensions) {
- testPath.clear();
- testPath += basePath;
- testPath += '.';
- testPath += ext;
- cmFileTime fileTime;
- if (fileTime.Load(testPath)) {
- // Compute real path of the file
- testPath = cmSystemTools::GetRealPath(testPath);
// Return a known file if it exists already
{
auto it = BaseEval().Headers.find(testPath);
if (it != BaseEval().Headers.end()) {
- return it->second;
+ headerHandle = it->second;
+ found = true;
+ break;
}
}
+
// Created and return discovered file entry
- SourceFileHandleT& res = MocEval().HeadersDiscovered[testPath];
- if (!res) {
- res = std::make_shared<SourceFileT>(testPath);
- res->FileTime = fileTime;
- res->Moc = true;
+ {
+ SourceFileHandleT& handle = MocEval().HeadersDiscovered[testPath];
+ if (!handle) {
+ handle = std::make_shared<SourceFileT>(testPath);
+ handle->FileTime = fileTime;
+ handle->IsHeader = true;
+ handle->Moc = true;
+ }
+ headerHandle = handle;
+ found = true;
+ break;
}
- return res;
}
- }
- // Return without success
- return SourceFileHandleT();
-}
+ if (!found) {
+ this->SearchLocations.emplace_back(cmQtAutoGen::ParentDir(basePath));
+ }
+ return found;
+ };
-std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders(
- std::string const& fileBase) const
-{
- std::ostringstream res;
- {
- std::string exts = ".{";
- exts += cmJoin(BaseConst().HeaderExtensions, ",");
- exts += '}';
- // Compose result string
- res << " " << fileBase << exts << '\n';
- for (std::string const& path : MocConst().IncludePaths) {
- res << " " << path << '/' << fileBase << exts << '\n';
+ // Search in vicinity of the source
+ if (findHeader(cmStrCat(includerDir, includeBase))) {
+ return true;
+ }
+ // Search in include directories
+ for (std::string const& path : MocConst().IncludePaths) {
+ if (findHeader(cmStrCat(path, '/', includeBase))) {
+ return true;
}
}
- return res.str();
+ // Return without success
+ return false;
}
-bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
+bool cmQtAutoMocUicT::JobEvalCacheMocT::RegisterIncluded(
std::string const& includeString, SourceFileHandleT includerFileHandle,
- SourceFileHandleT sourceFileHandle, bool sourceIsHeader) const
+ SourceFileHandleT sourceFileHandle) const
{
// Check if this file is already included
MappingHandleT& handle = MocEval().Includes[includeString];
if (handle) {
// Check if the output file would be generated from different source files
if (handle->SourceFile != sourceFileHandle) {
- std::string msg = "The source files\n ";
- msg += Quoted(includerFileHandle->FileName);
- msg += '\n';
+ std::string files =
+ cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
- }
- msg += "contain the same include string ";
- msg += Quoted(includeString);
- msg += ", but\nthe moc file would be generated from different "
- "source files\n ";
- msg += Quoted(sourceFileHandle->FileName);
- msg += " and\n ";
- msg += Quoted(handle->SourceFile->FileName);
- msg += ".\nConsider to\n"
- " - not include the \"moc_<NAME>.cpp\" file\n"
- " - add a directory prefix to a \"<NAME>.moc\" include "
- "(e.g \"sub/<NAME>.moc\")\n"
- " - rename the source file(s)\n";
- LogError(GenT::MOC, msg);
+ files += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ }
+ LogError(
+ GenT::MOC,
+ cmStrCat("The source files\n", files,
+ "contain the same include string ",
+ MessagePath(includeString),
+ ", but\nthe moc file would be generated from different "
+ "source files\n ",
+ MessagePath(sourceFileHandle->FileName), " and\n ",
+ MessagePath(handle->SourceFile->FileName),
+ ".\nConsider to\n"
+ " - not include the \"moc_<NAME>.cpp\" file\n"
+ " - add a directory prefix to a \"<NAME>.moc\" include "
+ "(e.g \"sub/<NAME>.moc\")\n"
+ " - rename the source file(s)\n"));
return false;
}
@@ -946,18 +1436,19 @@ bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
handle->SourceFile = std::move(sourceFileHandle);
- handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
+ handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping in sources/headers map
- MocRegisterMapping(handle, sourceIsHeader);
+ RegisterMapping(handle);
return true;
}
-void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping(
- MappingHandleT mappingHandle, bool sourceIsHeader) const
+void cmQtAutoMocUicT::JobEvalCacheMocT::RegisterMapping(
+ MappingHandleT mappingHandle) const
{
- auto& regMap =
- sourceIsHeader ? MocEval().HeaderMappings : MocEval().SourceMappings;
+ auto& regMap = mappingHandle->SourceFile->IsHeader
+ ? MocEval().HeaderMappings
+ : MocEval().SourceMappings;
// Check if source file already gets mapped
auto& regHandle = regMap[mappingHandle->SourceFile->FileName];
if (!regHandle) {
@@ -971,17 +1462,33 @@ void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping(
}
}
-bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap)
+std::string cmQtAutoMocUicT::JobEvalCacheMocT::MessageHeader(
+ cm::string_view headerBase) const
{
- for (auto const& pair : fileMap) {
- if (!UicEvalFile(pair.second)) {
- return false;
+ return MessagePath(cmStrCat(
+ headerBase, ".{", cmJoin(this->BaseConst().HeaderExtensions, ","), '}'));
+}
+
+void cmQtAutoMocUicT::JobEvalCacheUicT::Process()
+{
+ // Prepare buffers
+ SearchLocations.reserve((UicConst().SearchPaths.size() + 1) * 2);
+
+ // Evaluate headers
+ for (auto const& pair : BaseEval().Headers) {
+ if (!EvalFile(pair.second)) {
+ return;
+ }
+ }
+ // Evaluate sources
+ for (auto const& pair : BaseEval().Sources) {
+ if (!EvalFile(pair.second)) {
+ return;
}
}
- return true;
}
-bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
+bool cmQtAutoMocUicT::JobEvalCacheUicT::EvalFile(
SourceFileHandleT const& sourceFileHandle)
{
SourceFileT const& sourceFile = *sourceFileHandle;
@@ -990,17 +1497,25 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
return true;
}
- std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
+ std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName);
for (IncludeKeyT const& incKey : Include) {
- // Find .ui file name
- SourceFileHandleT uiFileHandle =
- UicFindIncludedUi(sourceFile.FileName, sourceDir, incKey);
- if (!uiFileHandle || UicConst().skipped(uiFileHandle->FileName)) {
+ // Find .ui file
+ UiName = cmStrCat(incKey.Base, ".ui");
+ if (!FindIncludedUi(sourceDirPrefix, incKey.Dir)) {
+ LogError(GenT::UIC,
+ cmStrCat(MessagePath(sourceFile.FileName),
+ "\nincludes the uic file ", MessagePath(incKey.Key),
+ ",\nbut the user interface file ", MessagePath(UiName),
+ "\ncould not be found in the following directories\n",
+ MessageSearchLocations()));
+ return false;
+ }
+ // Check if the file is skipped
+ if (UicConst().skipped(UiFileHandle->FileName)) {
continue;
}
// Register mapping
- if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle),
- sourceFileHandle)) {
+ if (!RegisterMapping(incKey.Key, sourceFileHandle)) {
return false;
}
}
@@ -1008,37 +1523,88 @@ bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
return true;
}
-bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
- std::string const& includeString, SourceFileHandleT uiFileHandle,
- SourceFileHandleT includerFileHandle)
+bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi(
+ cm::string_view sourceDirPrefix, cm::string_view includePrefix)
+{
+ // Clear locations buffer
+ SearchLocations.clear();
+
+ auto findUi = [this](std::string const& testPath) -> bool {
+ std::string const fullPath = this->Gen()->CollapseFullPathTS(testPath);
+ cmFileTime fileTime;
+ if (!fileTime.Load(fullPath)) {
+ this->SearchLocations.emplace_back(cmQtAutoGen::ParentDir(fullPath));
+ return false;
+ }
+ // .ui file found in files system!
+ // Get or create .ui file handle
+ SourceFileHandleT& handle = this->UicEval().UiFiles[fullPath];
+ if (!handle) {
+ // The file wasn't registered, yet
+ handle = std::make_shared<SourceFileT>(fullPath);
+ handle->FileTime = fileTime;
+ }
+ this->UiFileHandle = handle;
+ return true;
+ };
+
+ // Vicinity of the source
+ if (findUi(cmStrCat(sourceDirPrefix, UiName))) {
+ return true;
+ }
+ if (!includePrefix.empty()) {
+ if (findUi(cmStrCat(sourceDirPrefix, includePrefix, UiName))) {
+ return true;
+ }
+ }
+ // Additional AUTOUIC search paths
+ auto const& searchPaths = UicConst().SearchPaths;
+ if (!searchPaths.empty()) {
+ for (std::string const& sPath : searchPaths) {
+ if (findUi(cmStrCat(sPath, '/', UiName))) {
+ return true;
+ }
+ }
+ if (!includePrefix.empty()) {
+ for (std::string const& sPath : searchPaths) {
+ if (findUi(cmStrCat(sPath, '/', includePrefix, UiName))) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping(
+ std::string const& includeString, SourceFileHandleT includerFileHandle)
{
auto& Includes = Gen()->UicEval().Includes;
auto it = Includes.find(includeString);
if (it != Includes.end()) {
MappingHandleT const& handle = it->second;
- if (handle->SourceFile != uiFileHandle) {
+ if (handle->SourceFile != UiFileHandle) {
// The output file already gets generated - from a different .ui file!
- std::string msg = "The source files\n ";
- msg += Quoted(includerFileHandle->FileName);
- msg += '\n';
+ std::string files =
+ cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
- }
- msg += "contain the same include string ";
- msg += Quoted(includeString);
- msg += ", but\nthe uic file would be generated from different "
- "user interface files\n ";
- msg += Quoted(uiFileHandle->FileName);
- msg += " and\n ";
- msg += Quoted(handle->SourceFile->FileName);
- msg += ".\nConsider to\n"
- " - add a directory prefix to a \"ui_<NAME>.h\" include "
- "(e.g \"sub/ui_<NAME>.h\")\n"
- " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
- "include(s)\n";
- LogError(GenT::UIC, msg);
+ files += cmStrCat(" ", MessagePath(item->FileName), '\n');
+ }
+ LogError(
+ GenT::UIC,
+ cmStrCat(
+ "The source files\n", files, "contain the same include string ",
+ Quoted(includeString),
+ ", but\nthe uic file would be generated from different "
+ "user interface files\n ",
+ MessagePath(UiFileHandle->FileName), " and\n ",
+ MessagePath(handle->SourceFile->FileName),
+ ".\nConsider to\n"
+ " - add a directory prefix to a \"ui_<NAME>.h\" include "
+ "(e.g \"sub/ui_<NAME>.h\")\n"
+ " - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
+ "include(s)\n"));
return false;
}
// Add includer file to existing mapping
@@ -1048,143 +1614,68 @@ bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
MappingHandleT handle = std::make_shared<MappingT>();
handle->IncludeString = includeString;
handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
- handle->SourceFile = std::move(uiFileHandle);
- handle->OutputFile += Gen()->AbsoluteIncludePath(includeString);
+ handle->SourceFile = UiFileHandle;
+ handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
// Register mapping
Includes.emplace(includeString, std::move(handle));
}
return true;
}
-cmQtAutoMocUic::SourceFileHandleT
-cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi(
- std::string const& sourceFile, std::string const& sourceDir,
- IncludeKeyT const& incKey) const
+void cmQtAutoMocUicT::JobEvalCacheFinishT::Process()
{
- std::string searchFileName = incKey.Base;
- searchFileName += ".ui";
- // Collect search paths list
- std::vector<std::string> testFiles;
- {
- auto& searchPaths = UicConst().SearchPaths;
- testFiles.reserve((searchPaths.size() + 1) * 2);
-
- // Vicinity of the source
- testFiles.emplace_back(sourceDir + searchFileName);
- if (!incKey.Dir.empty()) {
- std::string path = sourceDir;
- path += incKey.Dir;
- path += searchFileName;
- testFiles.emplace_back(path);
- }
- // AUTOUIC search paths
- if (!searchPaths.empty()) {
- for (std::string const& sPath : searchPaths) {
- std::string path = sPath;
- path += '/';
- path += searchFileName;
- testFiles.emplace_back(std::move(path));
- }
- if (!incKey.Dir.empty()) {
- for (std::string const& sPath : searchPaths) {
- std::string path = sPath;
- path += '/';
- path += incKey.Dir;
- path += searchFileName;
- testFiles.emplace_back(std::move(path));
- }
- }
- }
- }
-
- // Search for the .ui file!
- for (std::string const& testFile : testFiles) {
- cmFileTime fileTime;
- if (fileTime.Load(testFile)) {
- // .ui file found in files system!
- std::string realPath = cmSystemTools::GetRealPath(testFile);
- // Get or create .ui file handle
- SourceFileHandleT& handle = Gen()->UicEval().UiFiles[realPath];
- if (!handle) {
- // The file wasn't registered, yet
- handle = std::make_shared<SourceFileT>(realPath);
- handle->FileTime = fileTime;
- }
- return handle;
- }
- }
+ // Add discovered header parse jobs
+ Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered);
- // Log error
+ // Add dependency probing jobs
{
- std::string msg = "The file includes the uic file ";
- msg += Quoted(incKey.Key);
- msg += ",\nbut the user interface file ";
- msg += Quoted(searchFileName);
- msg += "\ncould not be found in the following locations\n";
- for (std::string const& testFile : testFiles) {
- msg += " ";
- msg += Quoted(testFile);
- msg += '\n';
+ // Add fence job to ensure all parsing has finished
+ Gen()->WorkerPool().EmplaceJob<JobFenceT>();
+ if (MocConst().Enabled) {
+ Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>();
+ }
+ if (UicConst().Enabled) {
+ Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>();
}
- LogFileError(GenT::UIC, sourceFile, msg);
+ // Add probe finish job
+ Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>();
}
-
- return SourceFileHandleT();
}
-void cmQtAutoMocUic::JobGenerateT::Process()
+void cmQtAutoMocUicT::JobProbeDepsMocT::Process()
{
- // Add moc compile jobs
- if (MocConst().Enabled) {
- for (auto const& pair : MocEval().HeaderMappings) {
- // Register if this mapping is a candidate for mocs_compilation.cpp
- bool const compFile = pair.second->IncludeString.empty();
- if (compFile) {
- MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath);
- }
- if (!MocGenerate(pair.second, compFile)) {
- return;
- }
+ // Create moc header jobs
+ for (auto const& pair : MocEval().HeaderMappings) {
+ // Register if this mapping is a candidate for mocs_compilation.cpp
+ bool const compFile = pair.second->IncludeString.empty();
+ if (compFile) {
+ MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath);
}
- for (auto const& pair : MocEval().SourceMappings) {
- if (!MocGenerate(pair.second, false)) {
- return;
- }
+ if (!Generate(pair.second, compFile)) {
+ return;
}
-
- // Add mocs compilations job on demand
- Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
}
- // Add uic compile jobs
- if (UicConst().Enabled) {
- for (auto const& pair : Gen()->UicEval().Includes) {
- if (!UicGenerate(pair.second)) {
- return;
- }
+ // Create moc source jobs
+ for (auto const& pair : MocEval().SourceMappings) {
+ if (!Generate(pair.second, false)) {
+ return;
}
}
-
- // Add finish job
- Gen()->WorkerPool().EmplaceJob<JobFinishT>();
}
-bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping,
- bool compFile) const
+bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
+ bool compFile) const
{
std::unique_ptr<std::string> reason;
if (Log().Verbose()) {
reason = cm::make_unique<std::string>();
}
- if (MocUpdate(*mapping, reason.get())) {
- // Create the parent directory
- if (!MakeParentDirectory(mapping->OutputFile)) {
- LogFileError(GenT::MOC, mapping->OutputFile,
- "Could not create parent directory.");
- return false;
- }
+ if (Probe(*mapping, reason.get())) {
+ // Register the parent directory for creation
+ MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
// Add moc job
- Gen()->WorkerPool().EmplaceJob<JobMocT>(mapping, std::move(reason));
+ Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason));
// Check if a moc job for a mocs_compilation.cpp entry was generated
if (compFile) {
MocEval().CompUpdated = true;
@@ -1193,8 +1684,8 @@ bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping,
return true;
}
-bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
- std::string* reason) const
+bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping,
+ std::string* reason) const
{
std::string const& sourceFile = mapping.SourceFile->FileName;
std::string const& outputFile = mapping.OutputFile;
@@ -1203,10 +1694,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
cmFileTime outputFileTime;
if (!outputFileTime.Load(outputFile)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it doesn't exist, from ";
- *reason += Quoted(sourceFile);
+ *reason =
+ cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it doesn't exist, from ", MessagePath(sourceFile));
}
return true;
}
@@ -1214,10 +1704,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
// Test if any setting changed
if (MocConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because the uic settings changed, from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because the uic settings changed, from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1225,10 +1714,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
// Test if the source file is newer
if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it's older than its source file, from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it's older than its source file, from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1237,12 +1725,10 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
if (!MocConst().PredefsFileAbs.empty()) {
if (outputFileTime.Older(MocEval().PredefsTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it's older than ";
- *reason += Quoted(MocConst().PredefsFileAbs);
- *reason += ", from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it's older than ",
+ MessagePath(MocConst().PredefsFileAbs), ", from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1251,10 +1737,9 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
// Test if the moc executable is newer
if (outputFileTime.Older(MocConst().ExecutableTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it's older than the moc executable, from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it's older than the moc executable, from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1265,21 +1750,21 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
std::string const sourceDir = SubDirPrefix(sourceFile);
for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) {
// Find dependency file
- auto const depMatch = MocFindDependency(sourceDir, dep);
+ auto const depMatch = FindDependency(sourceDir, dep);
if (depMatch.first.empty()) {
- Log().WarningFile(GenT::MOC, sourceFile,
- "Could not find dependency file " + Quoted(dep));
+ Log().Warning(GenT::MOC,
+ cmStrCat(MessagePath(sourceFile), " depends on ",
+ MessagePath(dep),
+ " but the file does not exist."));
continue;
}
// Test if dependency file is older
if (outputFileTime.Older(depMatch.second)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it's older than its dependency file ";
- *reason += Quoted(depMatch.first);
- *reason += ", from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it's older than its dependency file ",
+ MessagePath(depMatch.first), ", from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1290,10 +1775,10 @@ bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
}
std::pair<std::string, cmFileTime>
-cmQtAutoMocUic::JobGenerateT::MocFindDependency(
+cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
std::string const& sourceDir, std::string const& includeString) const
{
- typedef std::pair<std::string, cmFileTime> ResPair;
+ using ResPair = std::pair<std::string, cmFileTime>;
// Search in vicinity of the source
{
ResPair res{ sourceDir + includeString, {} };
@@ -1303,9 +1788,7 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency(
}
// Search in include directories
for (std::string const& includePath : MocConst().IncludePaths) {
- ResPair res{ includePath, {} };
- res.first += '/';
- res.first += includeString;
+ ResPair res{ cmStrCat(includePath, '/', includeString), {} };
if (res.second.Load(res.first)) {
return res;
}
@@ -1314,28 +1797,27 @@ cmQtAutoMocUic::JobGenerateT::MocFindDependency(
return ResPair();
}
-bool cmQtAutoMocUic::JobGenerateT::UicGenerate(
- MappingHandleT const& mapping) const
+void cmQtAutoMocUicT::JobProbeDepsUicT::Process()
{
- std::unique_ptr<std::string> reason;
- if (Log().Verbose()) {
- reason = cm::make_unique<std::string>();
- }
- if (UicUpdate(*mapping, reason.get())) {
- // Create the parent directory
- if (!MakeParentDirectory(mapping->OutputFile)) {
- LogFileError(GenT::UIC, mapping->OutputFile,
- "Could not create parent directory.");
- return false;
+ for (auto const& pair : Gen()->UicEval().Includes) {
+ MappingHandleT const& mapping = pair.second;
+ std::unique_ptr<std::string> reason;
+ if (Log().Verbose()) {
+ reason = cm::make_unique<std::string>();
}
+ if (!Probe(*mapping, reason.get())) {
+ continue;
+ }
+
+ // Register the parent directory for creation
+ UicEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
// Add uic job
- Gen()->WorkerPool().EmplaceJob<JobUicT>(mapping, std::move(reason));
+ Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping, std::move(reason));
}
- return true;
}
-bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
- std::string* reason) const
+bool cmQtAutoMocUicT::JobProbeDepsUicT::Probe(MappingT const& mapping,
+ std::string* reason) const
{
std::string const& sourceFile = mapping.SourceFile->FileName;
std::string const& outputFile = mapping.OutputFile;
@@ -1344,10 +1826,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
cmFileTime outputFileTime;
if (!outputFileTime.Load(outputFile)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it doesn't exist, from ";
- *reason += Quoted(sourceFile);
+ *reason =
+ cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it doesn't exist, from ", MessagePath(sourceFile));
}
return true;
}
@@ -1355,10 +1836,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
// Test if the uic settings changed
if (UicConst().SettingsChanged) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because the uic settings changed, from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because the uic settings changed, from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1366,10 +1846,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
// Test if the source file is newer
if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += " because it's older than the source file ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ " because it's older than the source file ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1377,10 +1856,9 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
// Test if the uic executable is newer
if (outputFileTime.Older(UicConst().ExecutableTime)) {
if (reason != nullptr) {
- *reason = "Generating ";
- *reason += Quoted(outputFile);
- *reason += ", because it's older than the uic executable, from ";
- *reason += Quoted(sourceFile);
+ *reason = cmStrCat("Generating ", MessagePath(outputFile),
+ ", because it's older than the uic executable, from ",
+ MessagePath(sourceFile));
}
return true;
}
@@ -1388,24 +1866,93 @@ bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
return false;
}
-void cmQtAutoMocUic::JobMocT::Process()
+void cmQtAutoMocUicT::JobProbeDepsFinishT::Process()
+{
+ // Create output directories
+ {
+ using StringSet = std::unordered_set<std::string>;
+ auto createDirs = [this](GenT genType, StringSet const& dirSet) {
+ for (std::string const& dirName : dirSet) {
+ if (!cmSystemTools::MakeDirectory(dirName)) {
+ this->LogError(
+ genType,
+ cmStrCat("Creating directory ", MessagePath(dirName), " failed."));
+ return;
+ }
+ }
+ };
+ if (MocConst().Enabled && UicConst().Enabled) {
+ StringSet outputDirs = MocEval().OutputDirs;
+ outputDirs.insert(UicEval().OutputDirs.begin(),
+ UicEval().OutputDirs.end());
+ createDirs(GenT::GEN, outputDirs);
+ } else if (MocConst().Enabled) {
+ createDirs(GenT::MOC, MocEval().OutputDirs);
+ } else if (UicConst().Enabled) {
+ createDirs(GenT::UIC, UicEval().OutputDirs);
+ }
+ }
+
+ if (MocConst().Enabled) {
+ // Add mocs compilations job
+ Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
+ }
+
+ // Add finish job
+ Gen()->WorkerPool().EmplaceJob<JobFinishT>();
+}
+
+void cmQtAutoMocUicT::JobCompileMocT::Process()
{
std::string const& sourceFile = Mapping->SourceFile->FileName;
std::string const& outputFile = Mapping->OutputFile;
// Compose moc command
std::vector<std::string> cmd;
- cmd.push_back(MocConst().Executable);
- // Add options
- cmAppend(cmd, MocConst().AllOptions);
- // Add predefs include
- if (!MocConst().PredefsFileAbs.empty()) {
- cmd.emplace_back("--include");
- cmd.push_back(MocConst().PredefsFileAbs);
+ {
+ // Reserve large enough
+ cmd.reserve(MocConst().OptionsDefinitions.size() +
+ MocConst().OptionsIncludes.size() +
+ MocConst().OptionsExtra.size() + 16);
+ cmd.push_back(MocConst().Executable);
+ // Add definitions
+ cmAppend(cmd, MocConst().OptionsDefinitions);
+ // Add includes
+ cmAppend(cmd, MocConst().OptionsIncludes);
+ // Add predefs include
+ if (!MocConst().PredefsFileAbs.empty()) {
+ cmd.emplace_back("--include");
+ cmd.push_back(MocConst().PredefsFileAbs);
+ }
+ // Add path prefix on demand
+ if (MocConst().PathPrefix && Mapping->SourceFile->IsHeader) {
+ for (std::string const& dir : MocConst().IncludePaths) {
+ cm::string_view prefix = sourceFile;
+ if (cmHasPrefix(prefix, dir)) {
+ prefix.remove_prefix(dir.size());
+ if (cmHasPrefix(prefix, '/')) {
+ prefix.remove_prefix(1);
+ auto slashPos = prefix.rfind('/');
+ if (slashPos != cm::string_view::npos) {
+ cmd.emplace_back("-p");
+ cmd.emplace_back(prefix.substr(0, slashPos));
+ } else {
+ cmd.emplace_back("-p");
+ cmd.emplace_back("./");
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Add extra options
+ cmAppend(cmd, MocConst().OptionsExtra);
+ // Add output file
+ cmd.emplace_back("-o");
+ cmd.push_back(outputFile);
+ // Add source file
+ cmd.push_back(sourceFile);
}
- cmd.emplace_back("-o");
- cmd.push_back(outputFile);
- cmd.push_back(sourceFile);
// Execute moc command
cmWorkerPool::ProcessResultT result;
@@ -1416,26 +1963,23 @@ void cmQtAutoMocUic::JobMocT::Process()
}
} else {
// Moc command failed
- std::string msg = "The moc process failed to compile\n ";
- msg += Quoted(sourceFile);
- msg += "\ninto\n ";
- msg += Quoted(outputFile);
- if (Mapping->IncluderFiles.empty()) {
- msg += ".\n";
- } else {
- msg += "\nincluded by\n";
+ std::string includers;
+ if (!Mapping->IncluderFiles.empty()) {
+ includers = "included by\n";
for (auto const& item : Mapping->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
+ includers += cmStrCat(" ", MessagePath(item->FileName), '\n');
}
}
- msg += result.ErrorMessage;
- LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::MOC,
+ cmStrCat("The moc process failed to compile\n ",
+ MessagePath(sourceFile), "\ninto\n ",
+ MessagePath(outputFile), '\n', includers,
+ result.ErrorMessage),
+ cmd, result.StdOut);
}
}
-void cmQtAutoMocUic::JobUicT::Process()
+void cmQtAutoMocUicT::JobCompileUicT::Process()
{
std::string const& sourceFile = Mapping->SourceFile->FileName;
std::string const& outputFile = Mapping->OutputFile;
@@ -1444,10 +1988,10 @@ void cmQtAutoMocUic::JobUicT::Process()
std::vector<std::string> cmd;
cmd.push_back(UicConst().Executable);
{
- std::vector<std::string> allOpts = UicConst().TargetOptions;
- auto optionIt = UicConst().Options.find(sourceFile);
- if (optionIt != UicConst().Options.end()) {
- UicMergeOptions(allOpts, optionIt->second,
+ std::vector<std::string> allOpts = UicConst().Options;
+ auto optionIt = UicConst().UiFiles.find(sourceFile);
+ if (optionIt != UicConst().UiFiles.end()) {
+ UicMergeOptions(allOpts, optionIt->second.Options,
(BaseConst().QtVersionMajor == 5));
}
cmAppend(cmd, allOpts);
@@ -1465,22 +2009,20 @@ void cmQtAutoMocUic::JobUicT::Process()
}
} else {
// Uic command failed
- std::string msg = "The uic process failed to compile\n ";
- msg += Quoted(sourceFile);
- msg += "\ninto\n ";
- msg += Quoted(outputFile);
- msg += "\nincluded by\n";
+ std::string includers;
for (auto const& item : Mapping->IncluderFiles) {
- msg += " ";
- msg += Quoted(item->FileName);
- msg += '\n';
+ includers += cmStrCat(" ", MessagePath(item->FileName), '\n');
}
- msg += result.ErrorMessage;
- LogCommandError(GenT::UIC, msg, cmd, result.StdOut);
+ LogCommandError(GenT::UIC,
+ cmStrCat("The uic process failed to compile\n ",
+ MessagePath(sourceFile), "\ninto\n ",
+ MessagePath(outputFile), "\nincluded by\n",
+ includers, result.ErrorMessage),
+ cmd, result.StdOut);
}
}
-void cmQtAutoMocUic::JobMocsCompilationT::Process()
+void cmQtAutoMocUicT::JobMocsCompilationT::Process()
{
// Compose mocs compilation file content
std::string content =
@@ -1489,427 +2031,354 @@ void cmQtAutoMocUic::JobMocsCompilationT::Process()
if (MocEval().CompFiles.empty()) {
// Placeholder content
content += "// No files found that require moc or the moc files are "
- "included\n";
- content += "enum some_compilers { need_more_than_nothing };\n";
+ "included\n"
+ "enum some_compilers { need_more_than_nothing };\n";
} else {
// Valid content
- char const clampB = BaseConst().MultiConfig ? '<' : '"';
- char const clampE = BaseConst().MultiConfig ? '>' : '"';
- for (std::string const& mocfile : MocEval().CompFiles) {
- content += "#include ";
- content += clampB;
- content += mocfile;
- content += clampE;
- content += '\n';
- }
+ const bool mc = BaseConst().MultiConfig;
+ cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
+ cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
+ content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
}
std::string const& compAbs = MocConst().CompFileAbs;
if (cmQtAutoGenerator::FileDiffers(compAbs, content)) {
// Actually write mocs compilation file
if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Generating MOC compilation " + compAbs);
+ Log().Info(GenT::MOC,
+ "Generating MOC compilation " + MessagePath(compAbs));
}
if (!FileWrite(compAbs, content)) {
- LogFileError(GenT::MOC, compAbs,
- "mocs compilation file writing failed.");
+ LogError(GenT::MOC,
+ cmStrCat("Writing MOC compilation ", MessagePath(compAbs),
+ " failed."));
}
} else if (MocEval().CompUpdated) {
// Only touch mocs compilation file
if (Log().Verbose()) {
- Log().Info(GenT::MOC, "Touching mocs compilation " + compAbs);
+ Log().Info(GenT::MOC,
+ "Touching MOC compilation " + MessagePath(compAbs));
}
if (!cmSystemTools::Touch(compAbs, false)) {
- LogFileError(GenT::MOC, compAbs,
- "mocs compilation file touching failed.");
+ LogError(GenT::MOC,
+ cmStrCat("Touching MOC compilation ", MessagePath(compAbs),
+ " failed."));
}
}
}
-void cmQtAutoMocUic::JobFinishT::Process()
+void cmQtAutoMocUicT::JobFinishT::Process()
{
Gen()->AbortSuccess();
}
-cmQtAutoMocUic::cmQtAutoMocUic() = default;
-cmQtAutoMocUic::~cmQtAutoMocUic() = default;
+cmQtAutoMocUicT::cmQtAutoMocUicT()
+ : cmQtAutoGenerator(GenT::GEN)
+{
+}
+cmQtAutoMocUicT::~cmQtAutoMocUicT() = default;
-bool cmQtAutoMocUic::Init(cmMakefile* makefile)
+bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
- // Utility lambdas
- auto InfoGet = [makefile](const char* key) {
- return makefile->GetSafeDefinition(key);
- };
- auto InfoGetBool = [makefile](const char* key) {
- return makefile->IsOn(key);
- };
- auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
- return list;
- };
- auto InfoGetLists =
- [makefile](const char* key) -> std::vector<std::vector<std::string>> {
- std::vector<std::vector<std::string>> lists;
- {
- std::string const value = makefile->GetSafeDefinition(key);
- std::string::size_type pos = 0;
- while (pos < value.size()) {
- std::string::size_type next = value.find(ListSep, pos);
- std::string::size_type length =
- (next != std::string::npos) ? next - pos : value.size() - pos;
- // Remove enclosing braces
- if (length >= 2) {
- std::string::const_iterator itBeg = value.begin() + (pos + 1);
- std::string::const_iterator itEnd = itBeg + (length - 2);
- {
- std::string subValue(itBeg, itEnd);
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(subValue, list);
- lists.push_back(std::move(list));
- }
- }
- pos += length;
- pos += ListSep.size();
- }
- }
- return lists;
- };
- auto InfoGetConfig = [makefile, this](const char* key) -> std::string {
- const char* valueConf = nullptr;
- {
- std::string keyConf = key;
- keyConf += '_';
- keyConf += InfoConfig();
- valueConf = makefile->GetDefinition(keyConf);
- }
- if (valueConf == nullptr) {
- return makefile->GetSafeDefinition(key);
- }
- return std::string(valueConf);
- };
- auto InfoGetConfigList =
- [&InfoGetConfig](const char* key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
- return list;
- };
- auto LogInfoError = [this](std::string const& msg) -> bool {
- std::ostringstream err;
- err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
- this->Log().Error(GenT::GEN, err.str());
+ // -- Required settings
+ if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
+ !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
+ !info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
+ !info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
+ !info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
+ true) ||
+ !info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
+ !info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile,
+ true) ||
+ !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
+ !info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
+ !info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
+ !info.GetString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) {
return false;
- };
- auto MatchSizes = [&LogInfoError](const char* keyA, const char* keyB,
- std::size_t sizeA,
- std::size_t sizeB) -> bool {
- if (sizeA == sizeB) {
- return true;
- }
- std::ostringstream err;
- err << "Lists sizes mismatch " << keyA << '(' << sizeA << ") " << keyB
- << '(' << sizeB << ')';
- return LogInfoError(err.str());
- };
-
- // -- Read info file
- if (!makefile->ReadListFile(InfoFile())) {
- return LogInfoError("File processing failed");
}
- // -- Meta
- Logger_.RaiseVerbosity(InfoGet("AM_VERBOSITY"));
- BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
- {
- unsigned long num = 1;
- if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL").c_str(), &num)) {
- num = std::max<unsigned long>(num, 1);
- num = std::min<unsigned long>(num, ParallelMax);
- }
- WorkerPool_.SetThreadCount(static_cast<unsigned int>(num));
- }
- BaseConst_.HeaderExtensions =
- makefile->GetCMakeInstance()->GetHeaderExtensions();
-
- // - Files and directories
- BaseConst_.IncludeProjectDirsBefore =
- InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
- BaseConst_.ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR");
- BaseConst_.ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR");
- BaseConst_.CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
- BaseConst_.CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
- BaseConst_.AutogenBuildDir = InfoGet("AM_BUILD_DIR");
- if (BaseConst_.AutogenBuildDir.empty()) {
- return LogInfoError("Autogen build directory missing.");
- }
- BaseConst_.AutogenIncludeDir = InfoGetConfig("AM_INCLUDE_DIR");
- if (BaseConst_.AutogenIncludeDir.empty()) {
- return LogInfoError("Autogen include directory missing.");
- }
- BaseConst_.CMakeExecutable = InfoGetConfig("AM_CMAKE_EXECUTABLE");
- if (BaseConst_.CMakeExecutable.empty()) {
- return LogInfoError("CMake executable file name missing.");
- }
+ // -- Checks
if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
- std::string error = "The CMake executable ";
- error += Quoted(BaseConst_.CMakeExecutable);
- error += " does not exist.";
- return LogInfoError(error);
- }
- BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
- if (BaseConst_.ParseCacheFile.empty()) {
- return LogInfoError("Parse cache file name missing.");
+ return info.LogError(cmStrCat("The CMake executable ",
+ MessagePath(BaseConst_.CMakeExecutable),
+ " does not exist."));
}
- // - Settings file
- SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE");
- if (SettingsFile_.empty()) {
- return LogInfoError("Settings file name missing.");
- }
+ // -- Evaluate values
+ BaseConst_.ThreadCount = std::min(BaseConst_.ThreadCount, ParallelMax);
+ WorkerPool_.SetThreadCount(BaseConst_.ThreadCount);
- // - Qt environment
- {
- unsigned long qtv = BaseConst_.QtVersionMajor;
- if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR").c_str(),
- &qtv)) {
- BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
+ // -- Moc
+ if (!MocConst_.Executable.empty()) {
+ // -- Moc is enabled
+ MocConst_.Enabled = true;
+
+ // -- Temporary buffers
+ struct
+ {
+ std::vector<std::string> MacroNames;
+ std::vector<std::string> DependFilters;
+ } tmp;
+
+ // -- Required settings
+ if (!info.GetBool("MOC_RELAXED_MODE", MocConst_.RelaxedMode, false) ||
+ !info.GetBool("MOC_PATH_PREFIX", MocConst_.PathPrefix, true) ||
+ !info.GetArray("MOC_SKIP", MocConst_.SkipList, false) ||
+ !info.GetArrayConfig("MOC_DEFINITIONS", MocConst_.Definitions,
+ false) ||
+ !info.GetArrayConfig("MOC_INCLUDES", MocConst_.IncludePaths, false) ||
+ !info.GetArray("MOC_OPTIONS", MocConst_.OptionsExtra, false) ||
+ !info.GetStringConfig("MOC_COMPILATION_FILE", MocConst_.CompFileAbs,
+ true) ||
+ !info.GetArray("MOC_PREDEFS_CMD", MocConst_.PredefsCmd, false) ||
+ !info.GetStringConfig("MOC_PREDEFS_FILE", MocConst_.PredefsFileAbs,
+ !MocConst_.PredefsCmd.empty()) ||
+ !info.GetArray("MOC_MACRO_NAMES", tmp.MacroNames, true) ||
+ !info.GetArray("MOC_DEPEND_FILTERS", tmp.DependFilters, false)) {
+ return false;
}
- }
- // - Moc
- MocConst_.Executable = InfoGet("AM_QT_MOC_EXECUTABLE");
- if (!MocConst().Executable.empty()) {
- MocConst_.Enabled = true;
- // Load the executable file time
- if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
- std::string error = "The moc executable ";
- error += Quoted(MocConst_.Executable);
- error += " does not exist.";
- return LogInfoError(error);
- }
- for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
- MocConst_.SkipList.insert(std::move(sfl));
- }
- MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
- MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
- MocConst_.Options = InfoGetList("AM_MOC_OPTIONS");
- MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
- for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) {
+ // -- Evaluate settings
+ for (std::string const& item : tmp.MacroNames) {
MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
+ // Dependency filters
{
- auto addFilter = [this, &LogInfoError](std::string const& key,
- std::string const& exp) -> bool {
- auto filterErr = [&LogInfoError, &key, &exp](const char* err) -> bool {
- std::ostringstream ferr;
- ferr << "AUTOMOC_DEPEND_FILTERS: " << err << '\n';
- ferr << " Key: " << Quoted(key) << '\n';
- ferr << " Exp: " << Quoted(exp) << '\n';
- return LogInfoError(ferr.str());
+ Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
+ if (!val.isArray()) {
+ return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array.");
+ }
+ Json::ArrayIndex const arraySize = val.size();
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ // Test entry closure
+ auto testEntry = [&info, ii](bool test, cm::string_view msg) -> bool {
+ if (!test) {
+ info.LogError(
+ cmStrCat("MOC_DEPEND_FILTERS filter ", ii, ": ", msg));
+ }
+ return !test;
};
- if (key.empty()) {
- return filterErr("Key is empty");
- }
- if (exp.empty()) {
- return filterErr("Regular expression is empty");
+
+ Json::Value const& pairVal = val[ii];
+
+ if (testEntry(pairVal.isArray(), "JSON value is not an array.") ||
+ testEntry(pairVal.size() == 2, "JSON array size invalid.")) {
+ return false;
}
- this->MocConst_.DependFilters.emplace_back(key, exp);
- if (!this->MocConst_.DependFilters.back().Exp.is_valid()) {
- return filterErr("Regular expression compiling failed");
+
+ Json::Value const& keyVal = pairVal[0u];
+ Json::Value const& expVal = pairVal[1u];
+ if (testEntry(keyVal.isString(),
+ "JSON value for keyword is not a string.") ||
+ testEntry(expVal.isString(),
+ "JSON value for regular expression is not a string.")) {
+ return false;
}
- return true;
- };
- // Insert default filter for Q_PLUGIN_METADATA
- if (BaseConst().QtVersionMajor != 4) {
- if (!addFilter("Q_PLUGIN_METADATA",
- "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
- "[^\\)]*FILE[ \t]*\"([^\"]+)\"")) {
+ std::string const key = keyVal.asString();
+ std::string const exp = expVal.asString();
+ if (testEntry(!key.empty(), "Keyword is empty.") ||
+ testEntry(!exp.empty(), "Regular expression is empty.")) {
return false;
}
- }
- // Insert user defined dependency filters
- std::vector<std::string> flts = InfoGetList("AM_MOC_DEPEND_FILTERS");
- if ((flts.size() % 2) != 0) {
- return LogInfoError(
- "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
- }
- for (auto itC = flts.begin(), itE = flts.end(); itC != itE; itC += 2) {
- if (!addFilter(*itC, *(itC + 1))) {
+
+ this->MocConst_.DependFilters.emplace_back(key, exp);
+ if (testEntry(
+ this->MocConst_.DependFilters.back().Exp.is_valid(),
+ cmStrCat("Regular expression compilation failed.\nKeyword: ",
+ Quoted(key), "\nExpression: ", Quoted(exp)))) {
return false;
}
}
}
- MocConst_.PredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
+ // Check if moc executable exists (by reading the file time)
+ if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
+ return info.LogError(cmStrCat("The moc executable ",
+ MessagePath(MocConst_.Executable),
+ " does not exist."));
+ }
}
- // - Uic
- UicConst_.Executable = InfoGet("AM_QT_UIC_EXECUTABLE");
- if (!UicConst().Executable.empty()) {
+ // -- Uic
+ if (!UicConst_.Executable.empty()) {
+ // Uic is enabled
UicConst_.Enabled = true;
- // Load the executable file time
- if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
- std::string error = "The uic executable ";
- error += Quoted(UicConst_.Executable);
- error += " does not exist.";
- return LogInfoError(error);
- }
- for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
- UicConst_.SkipList.insert(std::move(sfl));
+
+ // -- Required settings
+ if (!info.GetArray("UIC_SKIP", UicConst_.SkipList, false) ||
+ !info.GetArray("UIC_SEARCH_PATHS", UicConst_.SearchPaths, false) ||
+ !info.GetArrayConfig("UIC_OPTIONS", UicConst_.Options, false)) {
+ return false;
}
- UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
- UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
+ // .ui files
{
- const char* keyFiles = "AM_UIC_OPTIONS_FILES";
- const char* keyOpts = "AM_UIC_OPTIONS_OPTIONS";
- auto sources = InfoGetList(keyFiles);
- auto options = InfoGetLists(keyOpts);
- if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) {
- return false;
- }
- auto fitEnd = sources.cend();
- auto fit = sources.begin();
- auto oit = options.begin();
- while (fit != fitEnd) {
- UicConst_.Options[*fit] = std::move(*oit);
- ++fit;
- ++oit;
+ Json::Value const& val = info.GetValue("UIC_UI_FILES");
+ if (!val.isArray()) {
+ return info.LogError("UIC_UI_FILES JSON value is not an array.");
+ }
+ Json::ArrayIndex const arraySize = val.size();
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ // Test entry closure
+ auto testEntry = [&info, ii](bool test, cm::string_view msg) -> bool {
+ if (!test) {
+ info.LogError(cmStrCat("UIC_UI_FILES entry ", ii, ": ", msg));
+ }
+ return !test;
+ };
+
+ Json::Value const& entry = val[ii];
+ if (testEntry(entry.isArray(), "JSON value is not an array.") ||
+ testEntry(entry.size() == 2, "JSON array size invalid.")) {
+ return false;
+ }
+
+ Json::Value const& entryName = entry[0u];
+ Json::Value const& entryOptions = entry[1u];
+ if (testEntry(entryName.isString(),
+ "JSON value for name is not a string.") ||
+ testEntry(entryOptions.isArray(),
+ "JSON value for options is not an array.")) {
+ return false;
+ }
+
+ auto& uiFile = UicConst_.UiFiles[entryName.asString()];
+ InfoT::GetJsonArray(uiFile.Options, entryOptions);
}
}
+
+ // -- Evaluate settings
+ // Check if uic executable exists (by reading the file time)
+ if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
+ return info.LogError(cmStrCat("The uic executable ",
+ MessagePath(UicConst_.Executable),
+ " does not exist."));
+ }
}
- // - Headers and sources
+ // -- Headers
{
- auto makeSource =
- [&LogInfoError](std::string const& fileName,
- std::string const& fileFlags) -> SourceFileHandleT {
- if (fileFlags.size() != 2) {
- LogInfoError("Invalid file flags string size");
- return SourceFileHandleT();
+ Json::Value const& val = info.GetValue("HEADERS");
+ if (!val.isArray()) {
+ return info.LogError("HEADERS JSON value is not an array.");
+ }
+ Json::ArrayIndex const arraySize = val.size();
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ // Test entry closure
+ auto testEntry = [&info, ii](bool test, cm::string_view msg) -> bool {
+ if (!test) {
+ info.LogError(cmStrCat("HEADERS entry ", ii, ": ", msg));
+ }
+ return !test;
+ };
+
+ Json::Value const& entry = val[ii];
+ if (testEntry(entry.isArray(), "JSON value is not an array.") ||
+ testEntry(entry.size() == 3, "JSON array size invalid.")) {
+ return false;
}
- cmFileTime fileTime;
- if (!fileTime.Load(fileName)) {
- LogInfoError("The source file " + cmQtAutoGen::Quoted(fileName) +
- " does not exist.");
- return SourceFileHandleT();
+
+ Json::Value const& entryName = entry[0u];
+ Json::Value const& entryFlags = entry[1u];
+ Json::Value const& entryBuild = entry[2u];
+ if (testEntry(entryName.isString(),
+ "JSON value for name is not a string.") ||
+ testEntry(entryFlags.isString(),
+ "JSON value for flags is not a string.") ||
+ testEntry(entryBuild.isString(),
+ "JSON value for build path is not a string.")) {
+ return false;
}
- SourceFileHandleT sfh = std::make_shared<SourceFileT>(fileName);
- sfh->FileTime = fileTime;
- sfh->Moc = (fileFlags[0] == 'M');
- sfh->Uic = (fileFlags[1] == 'U');
- return sfh;
- };
- // Headers
- {
- // Get file lists
- const char *keyFiles = "AM_HEADERS", *keyFlags = "AM_HEADERS_FLAGS";
- std::vector<std::string> files = InfoGetList(keyFiles);
- std::vector<std::string> flags = InfoGetList(keyFlags);
- std::vector<std::string> builds;
- if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
+ std::string name = entryName.asString();
+ std::string flags = entryFlags.asString();
+ std::string build = entryBuild.asString();
+ if (testEntry(flags.size() == 2, "Invalid flags string size")) {
return false;
}
- if (MocConst().Enabled) {
- const char* keyPaths = "AM_HEADERS_BUILD_PATHS";
- builds = InfoGetList(keyPaths);
- if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
- return false;
+
+ cmFileTime fileTime;
+ if (!fileTime.Load(name)) {
+ return info.LogError(cmStrCat(
+ "The header file ", this->MessagePath(name), " does not exist."));
+ }
+
+ SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(name);
+ sourceHandle->FileTime = fileTime;
+ sourceHandle->IsHeader = true;
+ sourceHandle->Moc = (flags[0] == 'M');
+ sourceHandle->Uic = (flags[1] == 'U');
+ if (sourceHandle->Moc && MocConst().Enabled) {
+ if (build.empty()) {
+ return info.LogError(
+ cmStrCat("Header file ", ii, " build path is empty"));
}
+ sourceHandle->BuildPath = std::move(build);
}
- // Process file lists
- for (std::size_t ii = 0; ii != files.size(); ++ii) {
- std::string& fileName(files[ii]);
- SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
- if (!sfh) {
- return false;
- }
- if (MocConst().Enabled) {
- sfh->BuildPath = std::move(builds[ii]);
- if (sfh->BuildPath.empty()) {
- Log().ErrorFile(GenT::GEN, this->InfoFile(),
- "Header file build path is empty");
- return false;
- }
+ BaseEval().Headers.emplace(std::move(name), std::move(sourceHandle));
+ }
+ }
+
+ // -- Sources
+ {
+ Json::Value const& val = info.GetValue("SOURCES");
+ if (!val.isArray()) {
+ return info.LogError("SOURCES JSON value is not an array.");
+ }
+ Json::ArrayIndex const arraySize = val.size();
+ for (Json::ArrayIndex ii = 0; ii != arraySize; ++ii) {
+ // Test entry closure
+ auto testEntry = [&info, ii](bool test, cm::string_view msg) -> bool {
+ if (!test) {
+ info.LogError(cmStrCat("SOURCES entry ", ii, ": ", msg));
}
- BaseEval().Headers.emplace(std::move(fileName), std::move(sfh));
+ return !test;
+ };
+
+ Json::Value const& entry = val[ii];
+ if (testEntry(entry.isArray(), "JSON value is not an array.") ||
+ testEntry(entry.size() == 2, "JSON array size invalid.")) {
+ return false;
}
- }
- // Sources
- {
- const char *keyFiles = "AM_SOURCES", *keyFlags = "AM_SOURCES_FLAGS";
- std::vector<std::string> files = InfoGetList(keyFiles);
- std::vector<std::string> flags = InfoGetList(keyFlags);
- if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
+ Json::Value const& entryName = entry[0u];
+ Json::Value const& entryFlags = entry[1u];
+ if (testEntry(entryName.isString(),
+ "JSON value for name is not a string.") ||
+ testEntry(entryFlags.isString(),
+ "JSON value for flags is not a string.")) {
return false;
}
- // Process file lists
- for (std::size_t ii = 0; ii != files.size(); ++ii) {
- std::string& fileName(files[ii]);
- SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
- if (!sfh) {
- return false;
- }
- BaseEval().Sources.emplace(std::move(fileName), std::move(sfh));
+
+ std::string name = entryName.asString();
+ std::string flags = entryFlags.asString();
+ if (testEntry(flags.size() == 2, "Invalid flags string size")) {
+ return false;
+ }
+
+ cmFileTime fileTime;
+ if (!fileTime.Load(name)) {
+ return info.LogError(cmStrCat(
+ "The source file ", this->MessagePath(name), " does not exist."));
}
+
+ SourceFileHandleT sourceHandle = std::make_shared<SourceFileT>(name);
+ sourceHandle->FileTime = fileTime;
+ sourceHandle->IsHeader = false;
+ sourceHandle->Moc = (flags[0] == 'M');
+ sourceHandle->Uic = (flags[1] == 'U');
+ BaseEval().Sources.emplace(std::move(name), std::move(sourceHandle));
}
}
- // Init derived information
- // ------------------------
-
+ // -- Init derived information
// Moc variables
if (MocConst().Enabled) {
- // Mocs compilation file
- MocConst_.CompFileAbs = AbsoluteBuildPath("mocs_compilation.cpp");
-
- // Moc predefs file
- if (!MocConst_.PredefsCmd.empty()) {
- MocConst_.PredefsFileRel = "moc_predefs";
- if (BaseConst_.MultiConfig) {
- MocConst_.PredefsFileRel += '_';
- MocConst_.PredefsFileRel += InfoConfig();
- }
- MocConst_.PredefsFileRel += ".h";
- MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel);
- }
-
- // Sort include directories on demand
- if (BaseConst().IncludeProjectDirsBefore) {
- // Move strings to temporary list
- std::list<std::string> includes(MocConst().IncludePaths.begin(),
- MocConst().IncludePaths.end());
- MocConst_.IncludePaths.clear();
- MocConst_.IncludePaths.reserve(includes.size());
- // Append project directories only
- {
- std::array<std::string const*, 2> const movePaths = {
- { &BaseConst().ProjectBinaryDir, &BaseConst().ProjectSourceDir }
- };
- for (std::string const* ppath : movePaths) {
- std::list<std::string>::iterator it = includes.begin();
- while (it != includes.end()) {
- std::string const& path = *it;
- if (cmSystemTools::StringStartsWith(path, ppath->c_str())) {
- MocConst_.IncludePaths.push_back(path);
- it = includes.erase(it);
- } else {
- ++it;
- }
- }
- }
- }
- // Append remaining directories
- MocConst_.IncludePaths.insert(MocConst_.IncludePaths.end(),
- includes.begin(), includes.end());
- }
// Compose moc includes list
{
+ // Compute framework paths
std::set<std::string> frameworkPaths;
for (std::string const& path : MocConst().IncludePaths) {
- MocConst_.Includes.push_back("-I" + path);
// Extract framework path
if (cmHasLiteralSuffix(path, ".framework/Headers")) {
// Go up twice to get to the framework root
@@ -1919,26 +2388,26 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
pathComponents.begin(), pathComponents.end() - 2));
}
}
+ // Reserve options
+ MocConst_.OptionsIncludes.reserve(MocConst().IncludePaths.size() +
+ frameworkPaths.size() * 2);
+ // Append includes
+ for (std::string const& path : MocConst().IncludePaths) {
+ MocConst_.OptionsIncludes.emplace_back("-I" + path);
+ }
// Append framework includes
for (std::string const& path : frameworkPaths) {
- MocConst_.Includes.emplace_back("-F");
- MocConst_.Includes.push_back(path);
+ MocConst_.OptionsIncludes.emplace_back("-F");
+ MocConst_.OptionsIncludes.push_back(path);
}
}
- // Setup single list with all options
+
+ // Compose moc definitions list
{
- // Add includes
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Includes.begin(),
- MocConst().Includes.end());
- // Add definitions
+ MocConst_.OptionsDefinitions.reserve(MocConst().Definitions.size());
for (std::string const& def : MocConst().Definitions) {
- MocConst_.AllOptions.push_back("-D" + def);
+ MocConst_.OptionsDefinitions.emplace_back("-D" + def);
}
- // Add options
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Options.begin(),
- MocConst().Options.end());
}
}
@@ -1946,7 +2415,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
}
template <class JOBTYPE>
-void cmQtAutoMocUic::CreateParseJobs(SourceFileMapT const& sourceMap)
+void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap)
{
cmFileTime const parseCacheTime = BaseEval().ParseCacheTime;
ParseCacheT& parseCache = BaseEval().ParseCache;
@@ -1962,21 +2431,41 @@ void cmQtAutoMocUic::CreateParseJobs(SourceFileMapT const& sourceMap)
}
}
-void cmQtAutoMocUic::InitJobs()
+/** Concurrently callable implementation of cmSystemTools::CollapseFullPath */
+std::string cmQtAutoMocUicT::CollapseFullPathTS(std::string const& path) const
+{
+ std::lock_guard<std::mutex> guard(CMakeLibMutex_);
+ return cmSystemTools::CollapseFullPath(path, ProjectDirs().CurrentSource);
+}
+
+void cmQtAutoMocUicT::InitJobs()
{
// Add moc_predefs.h job
if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) {
WorkerPool().EmplaceJob<JobMocPredefsT>();
}
+
// Add header parse jobs
CreateParseJobs<JobParseHeaderT>(BaseEval().Headers);
// Add source parse jobs
CreateParseJobs<JobParseSourceT>(BaseEval().Sources);
- // Add evaluate job
- WorkerPool().EmplaceJob<JobEvaluateT>();
+
+ // Add parse cache evaluations jobs
+ {
+ // Add a fence job to ensure all parsing has finished
+ WorkerPool().EmplaceJob<JobFenceT>();
+ if (MocConst().Enabled) {
+ WorkerPool().EmplaceJob<JobEvalCacheMocT>();
+ }
+ if (UicConst().Enabled) {
+ WorkerPool().EmplaceJob<JobEvalCacheUicT>();
+ }
+ // Add evaluate job
+ WorkerPool().EmplaceJob<JobEvalCacheFinishT>();
+ }
}
-bool cmQtAutoMocUic::Process()
+bool cmQtAutoMocUicT::Process()
{
SettingsFileRead();
ParseCacheRead();
@@ -1999,26 +2488,30 @@ bool cmQtAutoMocUic::Process()
return true;
}
-void cmQtAutoMocUic::SettingsFileRead()
+void cmQtAutoMocUicT::SettingsFileRead()
{
// Compose current settings strings
{
cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
- std::string const sep(";");
- auto cha = [&cryptoHash, &sep](std::string const& value) {
+ auto cha = [&cryptoHash](cm::string_view value) {
cryptoHash.Append(value);
- cryptoHash.Append(sep);
+ cryptoHash.Append(";");
};
if (MocConst_.Enabled) {
cryptoHash.Initialize();
cha(MocConst().Executable);
- for (auto const& value : MocConst().AllOptions) {
- cha(value);
+ for (auto const& item : MocConst().OptionsDefinitions) {
+ cha(item);
}
- cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE");
- for (auto const& value : MocConst().PredefsCmd) {
- cha(value);
+ for (auto const& item : MocConst().OptionsIncludes) {
+ cha(item);
+ }
+ for (auto const& item : MocConst().OptionsExtra) {
+ cha(item);
+ }
+ for (auto const& item : MocConst().PredefsCmd) {
+ cha(item);
}
for (auto const& filter : MocConst().DependFilters) {
cha(filter.Key);
@@ -2032,14 +2525,11 @@ void cmQtAutoMocUic::SettingsFileRead()
if (UicConst().Enabled) {
cryptoHash.Initialize();
cha(UicConst().Executable);
- for (auto const& value : UicConst().TargetOptions) {
- cha(value);
- }
- for (const auto& item : UicConst().Options) {
+ std::for_each(UicConst().Options.begin(), UicConst().Options.end(), cha);
+ for (const auto& item : UicConst().UiFiles) {
cha(item.first);
- for (auto const& svalue : item.second) {
- cha(svalue);
- }
+ auto const& opts = item.second.Options;
+ std::for_each(opts.begin(), opts.end(), cha);
}
SettingsStringUic_ = cryptoHash.FinalizeHex();
}
@@ -2077,23 +2567,22 @@ void cmQtAutoMocUic::SettingsFileRead()
}
}
-bool cmQtAutoMocUic::SettingsFileWrite()
+bool cmQtAutoMocUicT::SettingsFileWrite()
{
// Only write if any setting changed
if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
if (Log().Verbose()) {
- Log().Info(GenT::GEN, "Writing settings file " + Quoted(SettingsFile_));
+ Log().Info(
+ GenT::GEN,
+ cmStrCat("Writing the settings file ", MessagePath(SettingsFile_)));
}
// Compose settings file content
std::string content;
{
- auto SettingAppend = [&content](const char* key,
- std::string const& value) {
+ auto SettingAppend = [&content](cm::string_view key,
+ cm::string_view value) {
if (!value.empty()) {
- content += key;
- content += ':';
- content += value;
- content += '\n';
+ content += cmStrCat(key, ':', value, '\n');
}
};
SettingAppend("moc", SettingsStringMoc_);
@@ -2102,8 +2591,9 @@ bool cmQtAutoMocUic::SettingsFileWrite()
// Write settings file
std::string error;
if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) {
- Log().ErrorFile(GenT::GEN, SettingsFile_,
- "Settings file writing failed. " + error);
+ Log().Error(GenT::GEN,
+ cmStrCat("Writing the settings file ",
+ MessagePath(SettingsFile_), " failed.\n", error));
// Remove old settings file to trigger a full rebuild on the next run
cmSystemTools::RemoveFile(SettingsFile_);
return false;
@@ -2112,9 +2602,9 @@ bool cmQtAutoMocUic::SettingsFileWrite()
return true;
}
-void cmQtAutoMocUic::ParseCacheRead()
+void cmQtAutoMocUicT::ParseCacheRead()
{
- const char* reason = nullptr;
+ cm::string_view reason;
// Don't read the cache if it is invalid
if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
reason = "Refreshing parse cache because it doesn't exist.";
@@ -2126,7 +2616,7 @@ void cmQtAutoMocUic::ParseCacheRead()
"Refreshing parse cache because it is older than the CMake executable.";
}
- if (reason != nullptr) {
+ if (!reason.empty()) {
// Don't read but refresh the complete parse cache
if (Log().Verbose()) {
Log().Info(GenT::GEN, reason);
@@ -2138,35 +2628,39 @@ void cmQtAutoMocUic::ParseCacheRead()
}
}
-bool cmQtAutoMocUic::ParseCacheWrite()
+bool cmQtAutoMocUicT::ParseCacheWrite()
{
if (BaseEval().ParseCacheChanged) {
if (Log().Verbose()) {
Log().Info(GenT::GEN,
- "Writing parse cache file " +
- Quoted(BaseConst().ParseCacheFile));
+ cmStrCat("Writing the parse cache file ",
+ MessagePath(BaseConst().ParseCacheFile)));
}
if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) {
- Log().ErrorFile(GenT::GEN, BaseConst().ParseCacheFile,
- "Parse cache file writing failed.");
+ Log().Error(GenT::GEN,
+ cmStrCat("Writing the parse cache file ",
+ MessagePath(BaseConst().ParseCacheFile),
+ " failed."));
return false;
}
}
return true;
}
-bool cmQtAutoMocUic::CreateDirectories()
+bool cmQtAutoMocUicT::CreateDirectories()
{
// Create AUTOGEN include directory
if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) {
- Log().ErrorFile(GenT::GEN, BaseConst().AutogenIncludeDir,
- "Could not create directory.");
+ Log().Error(GenT::GEN,
+ cmStrCat("Creating the AUTOGEN include directory ",
+ MessagePath(BaseConst().AutogenIncludeDir),
+ " failed."));
return false;
}
return true;
}
-void cmQtAutoMocUic::Abort(bool error)
+void cmQtAutoMocUicT::Abort(bool error)
{
if (error) {
JobError_.store(true);
@@ -2174,20 +2668,21 @@ void cmQtAutoMocUic::Abort(bool error)
WorkerPool_.Abort();
}
-std::string cmQtAutoMocUic::AbsoluteBuildPath(
- std::string const& relativePath) const
+std::string cmQtAutoMocUicT::AbsoluteBuildPath(
+ cm::string_view relativePath) const
{
- std::string res(BaseConst().AutogenBuildDir);
- res += '/';
- res += relativePath;
- return res;
+ return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
}
-std::string cmQtAutoMocUic::AbsoluteIncludePath(
- std::string const& relativePath) const
+std::string cmQtAutoMocUicT::AbsoluteIncludePath(
+ cm::string_view relativePath) const
{
- std::string res(BaseConst().AutogenIncludeDir);
- res += '/';
- res += relativePath;
- return res;
+ return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
+}
+
+} // End of unnamed namespace
+
+bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config)
+{
+ return cmQtAutoMocUicT().Run(infoFile, config);
}
diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h
index 81546cc18..ffcc2db70 100644
--- a/Source/cmQtAutoMocUic.h
+++ b/Source/cmQtAutoMocUic.h
@@ -5,572 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileTime.h"
-#include "cmQtAutoGen.h"
-#include "cmQtAutoGenerator.h"
-#include "cmWorkerPool.h"
-#include "cmsys/RegularExpression.hxx"
+#include <cm/string_view>
-#include <atomic>
-#include <cstddef>
-#include <map>
-#include <memory> // IWYU pragma: keep
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-class cmMakefile;
-
-/** \class cmQtAutoMocUic
- * \brief AUTOMOC and AUTOUIC generator
+/**
+ * Process AUTOMOC and AUTOUIC
+ * @return true on success
*/
-class cmQtAutoMocUic : public cmQtAutoGenerator
-{
-public:
- cmQtAutoMocUic();
- ~cmQtAutoMocUic() override;
-
- cmQtAutoMocUic(cmQtAutoMocUic const&) = delete;
- cmQtAutoMocUic& operator=(cmQtAutoMocUic const&) = delete;
-
-public:
- // -- Types
-
- /**
- * Search key plus regular expression pair
- */
- struct KeyExpT
- {
- KeyExpT() = default;
-
- KeyExpT(const char* key, const char* exp)
- : Key(key)
- , Exp(exp)
- {
- }
-
- KeyExpT(std::string key, std::string const& exp)
- : Key(std::move(key))
- , Exp(exp)
- {
- }
-
- std::string Key;
- cmsys::RegularExpression Exp;
- };
-
- /**
- * Include string with sub parts
- */
- struct IncludeKeyT
- {
- IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
-
- std::string Key; // Full include string
- std::string Dir; // Include directory
- std::string Base; // Base part of the include file name
- };
-
- /**
- * Source file parsing cache
- */
- class ParseCacheT
- {
- public:
- // -- Types
- /**
- * Entry of the file parsing cache
- */
- struct FileT
- {
- void Clear();
-
- struct MocT
- {
- std::string Macro;
- struct IncludeT
- {
- std::vector<IncludeKeyT> Underscore;
- std::vector<IncludeKeyT> Dot;
- } Include;
- std::vector<std::string> Depends;
- } Moc;
-
- struct UicT
- {
- std::vector<IncludeKeyT> Include;
- std::vector<std::string> Depends;
- } Uic;
- };
- typedef std::shared_ptr<FileT> FileHandleT;
- typedef std::pair<FileHandleT, bool> GetOrInsertT;
-
- public:
- ParseCacheT();
- ~ParseCacheT();
-
- void Clear();
-
- bool ReadFromFile(std::string const& fileName);
- bool WriteToFile(std::string const& fileName);
-
- //! Might return an invalid handle
- FileHandleT Get(std::string const& fileName) const;
- //! Always returns a valid handle
- GetOrInsertT GetOrInsert(std::string const& fileName);
-
- private:
- std::unordered_map<std::string, FileHandleT> Map_;
- };
-
- /**
- * Source file data
- */
- class SourceFileT
- {
- public:
- SourceFileT(std::string fileName)
- : FileName(std::move(fileName))
- {
- }
-
- public:
- std::string FileName;
- cmFileTime FileTime;
- ParseCacheT::FileHandleT ParseData;
- std::string BuildPath;
- bool Moc = false;
- bool Uic = false;
- };
- typedef std::shared_ptr<SourceFileT> SourceFileHandleT;
- typedef std::map<std::string, SourceFileHandleT> SourceFileMapT;
-
- /**
- * Meta compiler file mapping information
- */
- struct MappingT
- {
- SourceFileHandleT SourceFile;
- std::string OutputFile;
- std::string IncludeString;
- std::vector<SourceFileHandleT> IncluderFiles;
- };
- typedef std::shared_ptr<MappingT> MappingHandleT;
- typedef std::map<std::string, MappingHandleT> MappingMapT;
-
- /**
- * Common settings
- */
- class BaseSettingsT
- {
- public:
- // -- Constructors
- BaseSettingsT();
- ~BaseSettingsT();
-
- BaseSettingsT(BaseSettingsT const&) = delete;
- BaseSettingsT& operator=(BaseSettingsT const&) = delete;
-
- // -- Attributes
- // - Config
- bool MultiConfig = false;
- bool IncludeProjectDirsBefore = false;
- unsigned int QtVersionMajor = 4;
- // - Directories
- std::string ProjectSourceDir;
- std::string ProjectBinaryDir;
- std::string CurrentSourceDir;
- std::string CurrentBinaryDir;
- std::string AutogenBuildDir;
- std::string AutogenIncludeDir;
- // - Files
- std::string CMakeExecutable;
- cmFileTime CMakeExecutableTime;
- std::string ParseCacheFile;
- std::vector<std::string> HeaderExtensions;
- };
-
- /**
- * Shared common variables
- */
- class BaseEvalT
- {
- public:
- // -- Parse Cache
- bool ParseCacheChanged = false;
- cmFileTime ParseCacheTime;
- ParseCacheT ParseCache;
-
- // -- Sources
- SourceFileMapT Headers;
- SourceFileMapT Sources;
- };
-
- /**
- * Moc settings
- */
- class MocSettingsT
- {
- public:
- // -- Constructors
- MocSettingsT();
- ~MocSettingsT();
-
- MocSettingsT(MocSettingsT const&) = delete;
- MocSettingsT& operator=(MocSettingsT const&) = delete;
-
- // -- Const methods
- bool skipped(std::string const& fileName) const;
- std::string MacrosString() const;
-
- // -- Attributes
- bool Enabled = false;
- bool SettingsChanged = false;
- bool RelaxedMode = false;
- cmFileTime ExecutableTime;
- std::string Executable;
- std::string CompFileAbs;
- std::string PredefsFileRel;
- std::string PredefsFileAbs;
- std::unordered_set<std::string> SkipList;
- std::vector<std::string> IncludePaths;
- std::vector<std::string> Includes;
- std::vector<std::string> Definitions;
- std::vector<std::string> Options;
- std::vector<std::string> AllOptions;
- std::vector<std::string> PredefsCmd;
- std::vector<KeyExpT> DependFilters;
- std::vector<KeyExpT> MacroFilters;
- cmsys::RegularExpression RegExpInclude;
- };
-
- /**
- * Moc shared variables
- */
- class MocEvalT
- {
- public:
- // -- predefines file
- cmFileTime PredefsTime;
- // -- Mappings
- MappingMapT HeaderMappings;
- MappingMapT SourceMappings;
- MappingMapT Includes;
- // -- Discovered files
- SourceFileMapT HeadersDiscovered;
- // -- Mocs compilation
- bool CompUpdated = false;
- std::vector<std::string> CompFiles;
- };
-
- /**
- * Uic settings
- */
- class UicSettingsT
- {
- public:
- UicSettingsT();
- ~UicSettingsT();
-
- UicSettingsT(UicSettingsT const&) = delete;
- UicSettingsT& operator=(UicSettingsT const&) = delete;
-
- // -- Const methods
- bool skipped(std::string const& fileName) const;
-
- // -- Attributes
- bool Enabled = false;
- bool SettingsChanged = false;
- cmFileTime ExecutableTime;
- std::string Executable;
- std::unordered_set<std::string> SkipList;
- std::vector<std::string> TargetOptions;
- std::map<std::string, std::vector<std::string>> Options;
- std::vector<std::string> SearchPaths;
- cmsys::RegularExpression RegExpInclude;
- };
-
- /**
- * Uic shared variables
- */
- class UicEvalT
- {
- public:
- SourceFileMapT UiFiles;
- MappingMapT Includes;
- };
-
- /**
- * Abstract job class for concurrent job processing
- */
- class JobT : public cmWorkerPool::JobT
- {
- protected:
- /**
- * @brief Protected default constructor
- */
- JobT(bool fence = false)
- : cmWorkerPool::JobT(fence)
- {
- }
-
- //! Get the generator. Only valid during Process() call!
- cmQtAutoMocUic* Gen() const
- {
- return static_cast<cmQtAutoMocUic*>(UserData());
- };
-
- // -- Accessors. Only valid during Process() call!
- Logger const& Log() const { return Gen()->Log(); }
- BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); }
- BaseEvalT& BaseEval() const { return Gen()->BaseEval(); }
- MocSettingsT const& MocConst() const { return Gen()->MocConst(); }
- MocEvalT& MocEval() const { return Gen()->MocEval(); }
- UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
- UicEvalT& UicEval() const { return Gen()->UicEval(); }
-
- // -- Error logging with automatic abort
- void LogError(GenT genType, std::string const& message) const;
- void LogFileError(GenT genType, std::string const& filename,
- std::string const& message) const;
- void LogCommandError(GenT genType, std::string const& message,
- std::vector<std::string> const& command,
- std::string const& output) const;
-
- /**
- * @brief Run an external process. Use only during Process() call!
- */
- bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
- std::vector<std::string> const& command,
- std::string* infoMessage = nullptr);
- };
-
- /**
- * Fence job utility class
- */
- class JobFenceT : public JobT
- {
- public:
- JobFenceT()
- : JobT(true)
- {
- }
- void Process() override{};
- };
-
- /**
- * Generate moc_predefs.h
- */
- class JobMocPredefsT : public JobFenceT
- {
- void Process() override;
- bool Update(std::string* reason) const;
- };
-
- /**
- * File parse job base class
- */
- class JobParseT : public JobT
- {
- public:
- JobParseT(SourceFileHandleT fileHandle)
- : FileHandle(std::move(fileHandle))
- {
- }
-
- protected:
- bool ReadFile();
- void CreateKeys(std::vector<IncludeKeyT>& container,
- std::set<std::string> const& source,
- std::size_t basePrefixLength);
- void MocMacro();
- void MocDependecies();
- void MocIncludes();
- void UicIncludes();
-
- protected:
- SourceFileHandleT FileHandle;
- std::string Content;
- };
-
- /**
- * Header file parse job
- */
- class JobParseHeaderT : public JobParseT
- {
- public:
- using JobParseT::JobParseT;
- void Process() override;
- };
-
- /**
- * Source file parse job
- */
- class JobParseSourceT : public JobParseT
- {
- public:
- using JobParseT::JobParseT;
- void Process() override;
- };
-
- /**
- * Evaluate parsed files
- */
- class JobEvaluateT : public JobFenceT
- {
- void Process() override;
-
- // -- Moc
- bool MocEvalHeader(SourceFileHandleT source);
- bool MocEvalSource(SourceFileHandleT const& source);
- SourceFileHandleT MocFindIncludedHeader(
- std::string const& includerDir, std::string const& includeBase) const;
- SourceFileHandleT MocFindHeader(std::string const& basePath) const;
- std::string MocMessageTestHeaders(std::string const& fileBase) const;
- bool MocRegisterIncluded(std::string const& includeString,
- SourceFileHandleT includerFileHandle,
- SourceFileHandleT sourceFileHandle,
- bool sourceIsHeader) const;
- void MocRegisterMapping(MappingHandleT mappingHandle,
- bool sourceIsHeader) const;
-
- // -- Uic
- bool UicEval(SourceFileMapT const& fileMap);
- bool UicEvalFile(SourceFileHandleT const& sourceFileHandle);
- SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile,
- std::string const& sourceDir,
- IncludeKeyT const& incKey) const;
- bool UicRegisterMapping(std::string const& includeString,
- SourceFileHandleT uiFileHandle,
- SourceFileHandleT includerFileHandle);
- };
-
- /**
- * Generates moc/uic jobs
- */
- class JobGenerateT : public JobFenceT
- {
- void Process() override;
- // -- Moc
- bool MocGenerate(MappingHandleT const& mapping, bool compFile) const;
- bool MocUpdate(MappingT const& mapping, std::string* reason) const;
- std::pair<std::string, cmFileTime> MocFindDependency(
- std::string const& sourceDir, std::string const& includeString) const;
- // -- Uic
- bool UicGenerate(MappingHandleT const& mapping) const;
- bool UicUpdate(MappingT const& mapping, std::string* reason) const;
- };
-
- /**
- * File compiling base job
- */
- class JobCompileT : public JobT
- {
- public:
- JobCompileT(MappingHandleT uicMapping, std::unique_ptr<std::string> reason)
- : Mapping(std::move(uicMapping))
- , Reason(std::move(reason))
- {
- }
-
- protected:
- MappingHandleT Mapping;
- std::unique_ptr<std::string> Reason;
- };
-
- /**
- * moc compiles a file
- */
- class JobMocT : public JobCompileT
- {
- public:
- using JobCompileT::JobCompileT;
- void Process() override;
- };
-
- /**
- * uic compiles a file
- */
- class JobUicT : public JobCompileT
- {
- public:
- using JobCompileT::JobCompileT;
- void Process() override;
- };
-
- /// @brief Generate mocs_compilation.cpp
- ///
- class JobMocsCompilationT : public JobFenceT
- {
- private:
- void Process() override;
- };
-
- /// @brief The last job
- ///
- class JobFinishT : public JobFenceT
- {
- private:
- void Process() override;
- };
-
- // -- Const settings interface
- BaseSettingsT const& BaseConst() const { return this->BaseConst_; }
- BaseEvalT& BaseEval() { return this->BaseEval_; }
- MocSettingsT const& MocConst() const { return this->MocConst_; }
- MocEvalT& MocEval() { return this->MocEval_; }
- UicSettingsT const& UicConst() const { return this->UicConst_; }
- UicEvalT& UicEval() { return this->UicEval_; }
-
- // -- Parallel job processing interface
- cmWorkerPool& WorkerPool() { return WorkerPool_; }
- void AbortError() { Abort(true); }
- void AbortSuccess() { Abort(false); }
-
- // -- Utility
- std::string AbsoluteBuildPath(std::string const& relativePath) const;
- std::string AbsoluteIncludePath(std::string const& relativePath) const;
- template <class JOBTYPE>
- void CreateParseJobs(SourceFileMapT const& sourceMap);
-
-private:
- // -- Utility accessors
- Logger const& Log() const { return Logger_; }
- // -- Abstract processing interface
- bool Init(cmMakefile* makefile) override;
- void InitJobs();
- bool Process() override;
- // -- Settings file
- void SettingsFileRead();
- bool SettingsFileWrite();
- // -- Parse cache
- void ParseCacheRead();
- bool ParseCacheWrite();
- // -- Thread processing
- void Abort(bool error);
- // -- Generation
- bool CreateDirectories();
-
-private:
- // -- Utility
- Logger Logger_;
- // -- Settings
- BaseSettingsT BaseConst_;
- BaseEvalT BaseEval_;
- MocSettingsT MocConst_;
- MocEvalT MocEval_;
- UicSettingsT UicConst_;
- UicEvalT UicEval_;
- // -- Settings file
- std::string SettingsFile_;
- std::string SettingsStringMoc_;
- std::string SettingsStringUic_;
- // -- Worker thread pool
- std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
- cmWorkerPool WorkerPool_;
-};
+bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config);
#endif
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 20885df93..3af81ad38 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -1,148 +1,135 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoRcc.h"
-#include "cmQtAutoGen.h"
-#include <sstream>
+#include <algorithm>
+#include <string>
+#include <vector>
#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmDuration.h"
+#include "cmFileLock.h"
#include "cmFileLockResult.h"
-#include "cmMakefile.h"
+#include "cmFileTime.h"
#include "cmProcessOutput.h"
+#include "cmQtAutoGen.h"
+#include "cmQtAutoGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-// -- Class methods
-
-cmQtAutoRcc::cmQtAutoRcc() = default;
+namespace {
-cmQtAutoRcc::~cmQtAutoRcc() = default;
+/** \class cmQtAutoRccT
+ * \brief AUTORCC generator
+ */
+class cmQtAutoRccT : public cmQtAutoGenerator
+{
+public:
+ cmQtAutoRccT();
+ ~cmQtAutoRccT() override;
+
+ cmQtAutoRccT(cmQtAutoRccT const&) = delete;
+ cmQtAutoRccT& operator=(cmQtAutoRccT const&) = delete;
+
+private:
+ // -- Utility
+ bool IsMultiConfig() const { return MultiConfig_; }
+ std::string MultiConfigOutput() const;
+
+ // -- Abstract processing interface
+ bool InitFromInfo(InfoT const& info) override;
+ bool Process() override;
+ // -- Settings file
+ bool SettingsFileRead();
+ bool SettingsFileWrite();
+ // -- Tests
+ bool TestQrcRccFiles(bool& generate);
+ bool TestResources(bool& generate);
+ bool TestInfoFile();
+ // -- Generation
+ bool GenerateRcc();
+ bool GenerateWrapper();
+
+private:
+ // -- Config settings
+ bool MultiConfig_ = false;
+ // -- Directories
+ std::string AutogenBuildDir_;
+ std::string IncludeDir_;
+ // -- Qt environment
+ std::string RccExecutable_;
+ cmFileTime RccExecutableTime_;
+ std::vector<std::string> RccListOptions_;
+ // -- Job
+ std::string LockFile_;
+ cmFileLock LockFileLock_;
+ std::string QrcFile_;
+ std::string QrcFileName_;
+ std::string QrcFileDir_;
+ cmFileTime QrcFileTime_;
+ std::string RccPathChecksum_;
+ std::string RccFileName_;
+ std::string RccFileOutput_;
+ std::string RccFilePublic_;
+ cmFileTime RccFileTime_;
+ std::string Reason;
+ std::vector<std::string> Options_;
+ std::vector<std::string> Inputs_;
+ // -- Settings file
+ std::string SettingsFile_;
+ std::string SettingsString_;
+ bool SettingsChanged_ = false;
+ bool BuildFileChanged_ = false;
+};
+
+cmQtAutoRccT::cmQtAutoRccT()
+ : cmQtAutoGenerator(GenT::RCC)
+{
+}
+cmQtAutoRccT::~cmQtAutoRccT() = default;
-bool cmQtAutoRcc::Init(cmMakefile* makefile)
+bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
{
- // -- Utility lambdas
- auto InfoGet = [makefile](std::string const& key) {
- return makefile->GetSafeDefinition(key);
- };
- auto InfoGetList =
- [makefile](std::string const& key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
- return list;
- };
- auto InfoGetConfig = [makefile,
- this](std::string const& key) -> std::string {
- const char* valueConf = nullptr;
- {
- std::string keyConf = key;
- keyConf += '_';
- keyConf += InfoConfig();
- valueConf = makefile->GetDefinition(keyConf);
- }
- if (valueConf == nullptr) {
- return makefile->GetSafeDefinition(key);
- }
- return std::string(valueConf);
- };
- auto InfoGetConfigList =
- [&InfoGetConfig](std::string const& key) -> std::vector<std::string> {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
- return list;
- };
- auto LogInfoError = [this](std::string const& msg) -> bool {
- std::ostringstream err;
- err << "In " << Quoted(this->InfoFile()) << ":\n" << msg;
- this->Log().Error(GenT::RCC, err.str());
+ // -- Required settings
+ if (!info.GetBool("MULTI_CONFIG", MultiConfig_, true) ||
+ !info.GetString("BUILD_DIR", AutogenBuildDir_, true) ||
+ !info.GetStringConfig("INCLUDE_DIR", IncludeDir_, true) ||
+ !info.GetString("RCC_EXECUTABLE", RccExecutable_, true) ||
+ !info.GetArray("RCC_LIST_OPTIONS", RccListOptions_, false) ||
+ !info.GetString("LOCK_FILE", LockFile_, true) ||
+ !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
+ !info.GetString("SOURCE", QrcFile_, true) ||
+ !info.GetString("OUTPUT_CHECKSUM", RccPathChecksum_, true) ||
+ !info.GetString("OUTPUT_NAME", RccFileName_, true) ||
+ !info.GetArray("OPTIONS", Options_, false) ||
+ !info.GetArray("INPUTS", Inputs_, false)) {
return false;
- };
-
- // -- Read info file
- if (!makefile->ReadListFile(InfoFile())) {
- return LogInfoError("File processing failed.");
- }
-
- // - Configurations
- Logger_.RaiseVerbosity(InfoGet("ARCC_VERBOSITY"));
- MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG");
-
- // - Directories
- AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR");
- if (AutogenBuildDir_.empty()) {
- return LogInfoError("Build directory empty.");
- }
-
- IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR");
- if (IncludeDir_.empty()) {
- return LogInfoError("Include directory empty.");
}
- // - Rcc executable
- RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
- if (!RccExecutableTime_.Load(RccExecutable_)) {
- std::string error = "The rcc executable ";
- error += Quoted(RccExecutable_);
- error += " does not exist.";
- return LogInfoError(error);
- }
- RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
-
- // - Job
- LockFile_ = InfoGet("ARCC_LOCK_FILE");
- QrcFile_ = InfoGet("ARCC_SOURCE");
+ // -- Derive information
QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_);
QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_);
- RccPathChecksum_ = InfoGet("ARCC_OUTPUT_CHECKSUM");
- RccFileName_ = InfoGet("ARCC_OUTPUT_NAME");
- Options_ = InfoGetConfigList("ARCC_OPTIONS");
- Inputs_ = InfoGetList("ARCC_INPUTS");
-
- // - Settings file
- SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE");
+ RccFilePublic_ =
+ cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_);
- // - Validity checks
- if (LockFile_.empty()) {
- return LogInfoError("Lock file name missing.");
- }
- if (SettingsFile_.empty()) {
- return LogInfoError("Settings file name missing.");
- }
- if (AutogenBuildDir_.empty()) {
- return LogInfoError("Autogen build directory missing.");
- }
- if (RccExecutable_.empty()) {
- return LogInfoError("rcc executable missing.");
- }
- if (QrcFile_.empty()) {
- return LogInfoError("rcc input file missing.");
- }
- if (RccFileName_.empty()) {
- return LogInfoError("rcc output file missing.");
- }
-
- // Init derived information
- // ------------------------
-
- RccFilePublic_ = AutogenBuildDir_;
- RccFilePublic_ += '/';
- RccFilePublic_ += RccPathChecksum_;
- RccFilePublic_ += '/';
- RccFilePublic_ += RccFileName_;
-
- // Compute rcc output file name
+ // rcc output file name
if (IsMultiConfig()) {
- RccFileOutput_ = IncludeDir_;
- RccFileOutput_ += '/';
- RccFileOutput_ += MultiConfigOutput();
+ RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput());
} else {
RccFileOutput_ = RccFilePublic_;
}
+ // -- Checks
+ if (!RccExecutableTime_.Load(RccExecutable_)) {
+ return info.LogError(cmStrCat(
+ "The rcc executable ", MessagePath(RccExecutable_), " does not exist."));
+ }
+
return true;
}
-bool cmQtAutoRcc::Process()
+bool cmQtAutoRccT::Process()
{
if (!SettingsFileRead()) {
return false;
@@ -175,48 +162,38 @@ bool cmQtAutoRcc::Process()
return SettingsFileWrite();
}
-std::string cmQtAutoRcc::MultiConfigOutput() const
+std::string cmQtAutoRccT::MultiConfigOutput() const
{
- static std::string const suffix = "_CMAKE_";
- std::string res;
- res += RccPathChecksum_;
- res += '/';
- res += AppendFilenameSuffix(RccFileName_, suffix);
- return res;
+ return cmStrCat(RccPathChecksum_, '/',
+ AppendFilenameSuffix(RccFileName_, "_CMAKE_"));
}
-bool cmQtAutoRcc::SettingsFileRead()
+bool cmQtAutoRccT::SettingsFileRead()
{
// Compose current settings strings
{
- cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
- std::string const sep(" ~~~ ");
- {
- std::string str;
- str += RccExecutable_;
- str += sep;
- str += cmJoin(RccListOptions_, ";");
- str += sep;
- str += QrcFile_;
- str += sep;
- str += RccPathChecksum_;
- str += sep;
- str += RccFileName_;
- str += sep;
- str += cmJoin(Options_, ";");
- str += sep;
- str += cmJoin(Inputs_, ";");
- str += sep;
- SettingsString_ = crypt.HashString(str);
- }
+ cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
+ auto cha = [&cryptoHash](cm::string_view value) {
+ cryptoHash.Append(value);
+ cryptoHash.Append(";");
+ };
+ cha(RccExecutable_);
+ std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha);
+ cha(QrcFile_);
+ cha(RccPathChecksum_);
+ cha(RccFileName_);
+ std::for_each(Options_.begin(), Options_.end(), cha);
+ std::for_each(Inputs_.begin(), Inputs_.end(), cha);
+ SettingsString_ = cryptoHash.FinalizeHex();
}
// Make sure the settings file exists
if (!cmSystemTools::FileExists(SettingsFile_, true)) {
// Touch the settings file to make sure it exists
if (!cmSystemTools::Touch(SettingsFile_, true)) {
- Log().ErrorFile(GenT::RCC, SettingsFile_,
- "Settings file creation failed.");
+ Log().Error(GenT::RCC,
+ cmStrCat("Touching the settings file ",
+ MessagePath(SettingsFile_), " failed."));
return false;
}
}
@@ -226,7 +203,9 @@ bool cmQtAutoRcc::SettingsFileRead()
// Make sure the lock file exists
if (!cmSystemTools::FileExists(LockFile_, true)) {
if (!cmSystemTools::Touch(LockFile_, true)) {
- Log().ErrorFile(GenT::RCC, LockFile_, "Lock file creation failed.");
+ Log().Error(GenT::RCC,
+ cmStrCat("Touching the lock file ", MessagePath(LockFile_),
+ " failed."));
return false;
}
}
@@ -234,8 +213,9 @@ bool cmQtAutoRcc::SettingsFileRead()
cmFileLockResult lockResult =
LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1));
if (!lockResult.IsOk()) {
- Log().ErrorFile(GenT::RCC, LockFile_,
- "File lock failed: " + lockResult.GetOutputMessage());
+ Log().Error(GenT::RCC,
+ cmStrCat("Locking of the lock file ", MessagePath(LockFile_),
+ " failed.\n", lockResult.GetOutputMessage()));
return false;
}
}
@@ -251,8 +231,10 @@ bool cmQtAutoRcc::SettingsFileRead()
if (SettingsChanged_) {
std::string error;
if (!FileWrite(SettingsFile_, "", &error)) {
- Log().ErrorFile(GenT::RCC, SettingsFile_,
- "Settings file clearing failed. " + error);
+ Log().Error(GenT::RCC,
+ cmStrCat("Clearing of the settings file ",
+ MessagePath(SettingsFile_), " failed.\n",
+ error));
return false;
}
}
@@ -264,21 +246,21 @@ bool cmQtAutoRcc::SettingsFileRead()
return true;
}
-bool cmQtAutoRcc::SettingsFileWrite()
+bool cmQtAutoRccT::SettingsFileWrite()
{
// Only write if any setting changed
if (SettingsChanged_) {
if (Log().Verbose()) {
- Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_));
+ Log().Info(GenT::RCC,
+ "Writing settings file " + MessagePath(SettingsFile_));
}
// Write settings file
- std::string content = "rcc:";
- content += SettingsString_;
- content += '\n';
+ std::string content = cmStrCat("rcc:", SettingsString_, '\n');
std::string error;
if (!FileWrite(SettingsFile_, content, &error)) {
- Log().ErrorFile(GenT::RCC, SettingsFile_,
- "Settings file writing failed. " + error);
+ Log().Error(GenT::RCC,
+ cmStrCat("Writing of the settings file ",
+ MessagePath(SettingsFile_), " failed.\n", error));
// Remove old settings file to trigger a full rebuild on the next run
cmSystemTools::RemoveFile(SettingsFile_);
return false;
@@ -291,25 +273,22 @@ bool cmQtAutoRcc::SettingsFileWrite()
}
/// Do basic checks if rcc generation is required
-bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
+bool cmQtAutoRccT::TestQrcRccFiles(bool& generate)
{
// Test if the rcc input file exists
if (!QrcFileTime_.Load(QrcFile_)) {
- std::string error;
- error = "The resources file ";
- error += Quoted(QrcFile_);
- error += " does not exist";
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
+ Log().Error(GenT::RCC,
+ cmStrCat("The resources file ", MessagePath(QrcFile_),
+ " does not exist"));
return false;
}
// Test if the rcc output file exists
if (!RccFileTime_.Load(RccFileOutput_)) {
if (Log().Verbose()) {
- Reason = "Generating ";
- Reason += Quoted(RccFileOutput_);
- Reason += ", because it doesn't exist, from ";
- Reason += Quoted(QrcFile_);
+ Reason =
+ cmStrCat("Generating ", MessagePath(RccFileOutput_),
+ ", because it doesn't exist, from ", MessagePath(QrcFile_));
}
generate = true;
return true;
@@ -318,10 +297,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the settings changed
if (SettingsChanged_) {
if (Log().Verbose()) {
- Reason = "Generating ";
- Reason += Quoted(RccFileOutput_);
- Reason += ", because the rcc settings changed, from ";
- Reason += Quoted(QrcFile_);
+ Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+ ", because the rcc settings changed, from ",
+ MessagePath(QrcFile_));
}
generate = true;
return true;
@@ -330,12 +308,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the rcc output file is older than the .qrc file
if (RccFileTime_.Older(QrcFileTime_)) {
if (Log().Verbose()) {
- Reason = "Generating ";
- Reason += Quoted(RccFileOutput_);
- Reason += ", because it is older than ";
- Reason += Quoted(QrcFile_);
- Reason += ", from ";
- Reason += Quoted(QrcFile_);
+ Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+ ", because it is older than ", MessagePath(QrcFile_),
+ ", from ", MessagePath(QrcFile_));
}
generate = true;
return true;
@@ -344,10 +319,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
// Test if the rcc output file is older than the rcc executable
if (RccFileTime_.Older(RccExecutableTime_)) {
if (Log().Verbose()) {
- Reason = "Generating ";
- Reason += Quoted(RccFileOutput_);
- Reason += ", because it is older than the rcc executable, from ";
- Reason += Quoted(QrcFile_);
+ Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+ ", because it is older than the rcc executable, from ",
+ MessagePath(QrcFile_));
}
generate = true;
return true;
@@ -356,14 +330,16 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
return true;
}
-bool cmQtAutoRcc::TestResources(bool& generate)
+bool cmQtAutoRccT::TestResources(bool& generate)
{
// Read resource files list
if (Inputs_.empty()) {
std::string error;
RccLister const lister(RccExecutable_, RccListOptions_);
if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) {
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
+ Log().Error(
+ GenT::RCC,
+ cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error));
return false;
}
}
@@ -373,22 +349,18 @@ bool cmQtAutoRcc::TestResources(bool& generate)
// Check if the resource file exists
cmFileTime fileTime;
if (!fileTime.Load(resFile)) {
- std::string error;
- error = "Could not find the resource file\n ";
- error += Quoted(resFile);
- error += '\n';
- Log().ErrorFile(GenT::RCC, QrcFile_, error);
+ Log().Error(GenT::RCC,
+ cmStrCat("The resource file ", MessagePath(resFile),
+ " listed in ", MessagePath(QrcFile_),
+ " does not exist."));
return false;
}
// Check if the resource file is newer than the rcc output file
if (RccFileTime_.Older(fileTime)) {
if (Log().Verbose()) {
- Reason = "Generating ";
- Reason += Quoted(RccFileOutput_);
- Reason += ", because it is older than ";
- Reason += Quoted(resFile);
- Reason += ", from ";
- Reason += Quoted(QrcFile_);
+ Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+ ", because it is older than ", MessagePath(resFile),
+ ", from ", MessagePath(QrcFile_));
}
generate = true;
break;
@@ -397,20 +369,21 @@ bool cmQtAutoRcc::TestResources(bool& generate)
return true;
}
-bool cmQtAutoRcc::TestInfoFile()
+bool cmQtAutoRccT::TestInfoFile()
{
// Test if the rcc output file is older than the info file
if (RccFileTime_.Older(InfoFileTime())) {
if (Log().Verbose()) {
- std::string reason = "Touching ";
- reason += Quoted(RccFileOutput_);
- reason += " because it is older than ";
- reason += Quoted(InfoFile());
- Log().Info(GenT::RCC, reason);
+ Log().Info(GenT::RCC,
+ cmStrCat("Touching ", MessagePath(RccFileOutput_),
+ " because it is older than ",
+ MessagePath(InfoFile())));
}
// Touch build file
if (!cmSystemTools::Touch(RccFileOutput_, false)) {
- Log().ErrorFile(GenT::RCC, RccFileOutput_, "Build file touch failed");
+ Log().Error(
+ GenT::RCC,
+ cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed."));
return false;
}
BuildFileChanged_ = true;
@@ -419,12 +392,13 @@ bool cmQtAutoRcc::TestInfoFile()
return true;
}
-bool cmQtAutoRcc::GenerateRcc()
+bool cmQtAutoRccT::GenerateRcc()
{
// Make parent directory
if (!MakeParentDirectory(RccFileOutput_)) {
- Log().ErrorFile(GenT::RCC, RccFileOutput_,
- "Could not create parent directory");
+ Log().Error(GenT::RCC,
+ cmStrCat("Could not create parent directory of ",
+ MessagePath(RccFileOutput_)));
return false;
}
@@ -438,13 +412,9 @@ bool cmQtAutoRcc::GenerateRcc()
// Log reason and command
if (Log().Verbose()) {
- std::string msg = Reason;
- if (!msg.empty() && (msg.back() != '\n')) {
- msg += '\n';
- }
- msg += QuotedCommand(cmd);
- msg += '\n';
- Log().Info(GenT::RCC, msg);
+ Log().Info(GenT::RCC,
+ cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n",
+ QuotedCommand(cmd), '\n'));
}
std::string rccStdOut;
@@ -455,13 +425,11 @@ bool cmQtAutoRcc::GenerateRcc()
cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
if (!result || (retVal != 0)) {
// rcc process failed
- {
- std::string err = "The rcc process failed to compile\n ";
- err += Quoted(QrcFile_);
- err += "\ninto\n ";
- err += Quoted(RccFileOutput_);
- Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr);
- }
+ Log().ErrorCommand(GenT::RCC,
+ cmStrCat("The rcc process failed to compile\n ",
+ MessagePath(QrcFile_), "\ninto\n ",
+ MessagePath(RccFileOutput_)),
+ cmd, rccStdOut + rccStdErr);
cmSystemTools::RemoveFile(RccFileOutput_);
return false;
}
@@ -476,17 +444,15 @@ bool cmQtAutoRcc::GenerateRcc()
return true;
}
-bool cmQtAutoRcc::GenerateWrapper()
+bool cmQtAutoRccT::GenerateWrapper()
{
// Generate a wrapper source file on demand
if (IsMultiConfig()) {
// Wrapper file content
- std::string content;
- content += "// This is an autogenerated configuration wrapper file.\n";
- content += "// Changes will be overwritten.\n";
- content += "#include <";
- content += MultiConfigOutput();
- content += ">\n";
+ std::string content =
+ cmStrCat("// This is an autogenerated configuration wrapper file.\n",
+ "// Changes will be overwritten.\n", "#include <",
+ MultiConfigOutput(), ">\n");
// Compare with existing file content
bool fileDiffers = true;
@@ -499,25 +465,39 @@ bool cmQtAutoRcc::GenerateWrapper()
if (fileDiffers) {
// Write new wrapper file
if (Log().Verbose()) {
- Log().Info(GenT::RCC, "Generating RCC wrapper file " + RccFilePublic_);
+ Log().Info(GenT::RCC,
+ cmStrCat("Generating RCC wrapper file ",
+ MessagePath(RccFilePublic_)));
}
std::string error;
if (!FileWrite(RccFilePublic_, content, &error)) {
- Log().ErrorFile(GenT::RCC, RccFilePublic_,
- "RCC wrapper file writing failed. " + error);
+ Log().Error(GenT::RCC,
+ cmStrCat("Generating RCC wrapper file ",
+ MessagePath(RccFilePublic_), " failed.\n",
+ error));
return false;
}
} else if (BuildFileChanged_) {
// Just touch the wrapper file
if (Log().Verbose()) {
- Log().Info(GenT::RCC, "Touching RCC wrapper file " + RccFilePublic_);
+ Log().Info(
+ GenT::RCC,
+ cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_)));
}
if (!cmSystemTools::Touch(RccFilePublic_, false)) {
- Log().ErrorFile(GenT::RCC, RccFilePublic_,
- "RCC wrapper file touch failed.");
+ Log().Error(GenT::RCC,
+ cmStrCat("Touching RCC wrapper file ",
+ MessagePath(RccFilePublic_), " failed."));
return false;
}
}
}
return true;
}
+
+} // End of unnamed namespace
+
+bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config)
+{
+ return cmQtAutoRccT().Run(infoFile, config);
+}
diff --git a/Source/cmQtAutoRcc.h b/Source/cmQtAutoRcc.h
index 636a6672d..a74b33ae4 100644
--- a/Source/cmQtAutoRcc.h
+++ b/Source/cmQtAutoRcc.h
@@ -5,77 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFileLock.h"
-#include "cmFileTime.h"
-#include "cmQtAutoGenerator.h"
+#include <cm/string_view>
-#include <string>
-#include <vector>
-
-class cmMakefile;
-
-// @brief AUTORCC generator
-class cmQtAutoRcc : public cmQtAutoGenerator
-{
-public:
- cmQtAutoRcc();
- ~cmQtAutoRcc() override;
-
- cmQtAutoRcc(cmQtAutoRcc const&) = delete;
- cmQtAutoRcc& operator=(cmQtAutoRcc const&) = delete;
-
-private:
- // -- Utility
- Logger const& Log() const { return Logger_; }
- bool IsMultiConfig() const { return MultiConfig_; }
- std::string MultiConfigOutput() const;
-
- // -- Abstract processing interface
- bool Init(cmMakefile* makefile) override;
- bool Process() override;
- // -- Settings file
- bool SettingsFileRead();
- bool SettingsFileWrite();
- // -- Tests
- bool TestQrcRccFiles(bool& generate);
- bool TestResources(bool& generate);
- bool TestInfoFile();
- // -- Generation
- bool GenerateRcc();
- bool GenerateWrapper();
-
-private:
- // -- Logging
- Logger Logger_;
- // -- Config settings
- bool MultiConfig_ = false;
- // -- Directories
- std::string AutogenBuildDir_;
- std::string IncludeDir_;
- // -- Qt environment
- std::string RccExecutable_;
- cmFileTime RccExecutableTime_;
- std::vector<std::string> RccListOptions_;
- // -- Job
- std::string LockFile_;
- cmFileLock LockFileLock_;
- std::string QrcFile_;
- std::string QrcFileName_;
- std::string QrcFileDir_;
- cmFileTime QrcFileTime_;
- std::string RccPathChecksum_;
- std::string RccFileName_;
- std::string RccFileOutput_;
- std::string RccFilePublic_;
- cmFileTime RccFileTime_;
- std::string Reason;
- std::vector<std::string> Options_;
- std::vector<std::string> Inputs_;
- // -- Settings file
- std::string SettingsFile_;
- std::string SettingsString_;
- bool SettingsChanged_ = false;
- bool BuildFileChanged_ = false;
-};
+/**
+ * Process AUTORCC
+ * @return true on success
+ */
+bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config);
#endif
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 2064275e7..7f4abf904 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRST.h"
+#include <algorithm>
+#include <cctype>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+
+#include "cmsys/FStream.hxx"
+
#include "cmAlgorithms.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
-#include "cmsys/FStream.hxx"
-#include <algorithm>
-#include <ctype.h>
-#include <iterator>
-#include <stddef.h>
-#include <utility>
-
cmRST::cmRST(std::ostream& os, std::string docroot)
: OS(os)
, DocRoot(std::move(docroot))
@@ -319,8 +321,7 @@ std::string cmRST::ReplaceSubstitutions(std::string const& line)
std::string::size_type start = this->Substitution.start(2);
std::string::size_type end = this->Substitution.end(2);
std::string substitute = this->Substitution.match(3);
- std::map<std::string, std::string>::iterator replace =
- this->Replace.find(substitute);
+ auto replace = this->Replace.find(substitute);
if (replace != this->Replace.end()) {
std::pair<std::set<std::string>::iterator, bool> replaced =
this->Replaced.insert(substitute);
@@ -341,7 +342,7 @@ void cmRST::OutputMarkupLines(bool inlineMarkup)
{
for (auto line : this->MarkupLines) {
if (!line.empty()) {
- line = " " + line;
+ line = cmStrCat(" ", line);
}
this->OutputLine(line, inlineMarkup);
}
@@ -450,10 +451,10 @@ void cmRST::UnindentLines(std::vector<std::string>& lines)
}
}
- std::vector<std::string>::const_iterator it = lines.begin();
+ auto it = lines.cbegin();
size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string()));
- std::vector<std::string>::const_reverse_iterator rit = lines.rbegin();
+ auto rit = lines.crbegin();
size_t trailingEmpty =
std::distance(rit, cmFindNot(cmReverseRange(lines), std::string()));
@@ -463,7 +464,7 @@ void cmRST::UnindentLines(std::vector<std::string>& lines)
return;
}
- std::vector<std::string>::iterator contentEnd = cmRotate(
- lines.begin(), lines.begin() + leadingEmpty, lines.end() - trailingEmpty);
+ auto contentEnd = cmRotate(lines.begin(), lines.begin() + leadingEmpty,
+ lines.end() - trailingEmpty);
lines.erase(contentEnd, lines.end());
}
diff --git a/Source/cmRST.h b/Source/cmRST.h
index d8d2a0bab..6b5d416d8 100644
--- a/Source/cmRST.h
+++ b/Source/cmRST.h
@@ -5,13 +5,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
/** \class cmRST
* \brief Perform basic .rst processing for command-line help
*
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index a64ad8c7d..457b70848 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -2,14 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRemoveCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-#include "cmSystemTools.h"
-
-class cmExecutionStatus;
+#include "cmStringAlgorithms.h"
// cmRemoveCommand
-bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmRemoveCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
return true;
@@ -17,7 +16,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
std::string const& variable = args[0]; // VAR is always first
// get the old value
- const char* cacheValue = this->Makefile->GetDefinition(variable);
+ const char* cacheValue = status.GetMakefile().GetDefinition(variable);
// if there is no old value then return
if (!cacheValue) {
@@ -25,13 +24,12 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
}
// expand the variable
- std::vector<std::string> const varArgsExpanded =
- cmSystemTools::ExpandedListArgument(cacheValue);
+ std::vector<std::string> const varArgsExpanded = cmExpandedList(cacheValue);
// expand the args
// check for REMOVE(VAR v1 v2 ... vn)
std::vector<std::string> const argsExpanded =
- cmSystemTools::ExpandedLists(args.begin() + 1, args.end());
+ cmExpandedLists(args.begin() + 1, args.end());
// now create the new value
std::string value;
@@ -52,7 +50,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
}
// add the definition
- this->Makefile->AddDefinition(variable, value.c_str());
+ status.GetMakefile().AddDefinition(variable, value);
return true;
}
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 7b118497b..fb72ab5f7 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmRemoveCommand
+/**
* \brief remove command
*
* cmRemoveCommand implements the remove CMake command
*/
-class cmRemoveCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmRemoveCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmRemoveCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmRemoveDefinitionsCommand.cxx b/Source/cmRemoveDefinitionsCommand.cxx
index 8d3f6889e..339ff9d35 100644
--- a/Source/cmRemoveDefinitionsCommand.cxx
+++ b/Source/cmRemoveDefinitionsCommand.cxx
@@ -2,21 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRemoveDefinitionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmRemoveDefinitionsCommand
-bool cmRemoveDefinitionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmRemoveDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- // it is OK to have no arguments
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->RemoveDefineFlag(i);
+ mf.RemoveDefineFlag(i);
}
return true;
}
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
index a5cb2044d..868416bc1 100644
--- a/Source/cmRemoveDefinitionsCommand.h
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmRemoveDefinitionsCommand
- * \brief Specify a list of compiler defines
- *
- * cmRemoveDefinitionsCommand specifies a list of compiler defines.
- * These defines will
- * be removed from the compile command.
- */
-class cmRemoveDefinitionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmRemoveDefinitionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmRemoveDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
index ceea8b4d9..59056690c 100644
--- a/Source/cmReturnCommand.cxx
+++ b/Source/cmReturnCommand.cxx
@@ -5,8 +5,8 @@
#include "cmExecutionStatus.h"
// cmReturnCommand
-bool cmReturnCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus& status)
+bool cmReturnCommand(std::vector<std::string> const&,
+ cmExecutionStatus& status)
{
status.SetReturnInvoked();
return true;
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index ef3961459..2404a363d 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -8,29 +8,10 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmReturnCommand
- * \brief Return from a directory or function
- *
- * cmReturnCommand returns from a directory or function
- */
-class cmReturnCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmReturnCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+/// Return from a directory or function
+bool cmReturnCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 33389cad5..0a1d109d5 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -2,8 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRulePlaceholderExpander.h"
-#include <ctype.h>
-#include <string.h>
+#include <cctype>
+#include <cstring>
#include <utility>
#include "cmOutputConverter.h"
@@ -235,8 +235,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
cmOutputConverter::SHELL);
}
- std::map<std::string, std::string>::iterator compIt =
- this->Compilers.find(variable);
+ auto compIt = this->Compilers.find(variable);
if (compIt != this->Compilers.end()) {
std::string ret = outputConverter->ConvertToOutputForExisting(
@@ -292,8 +291,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return ret;
}
- std::map<std::string, std::string>::iterator mapIt =
- this->VariableMappings.find(variable);
+ auto mapIt = this->VariableMappings.find(variable);
if (mapIt != this->VariableMappings.end()) {
if (variable.find("_FLAG") == std::string::npos) {
return outputConverter->ConvertToOutputForExisting(mapIt->second);
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
new file mode 100644
index 000000000..7a987c27e
--- /dev/null
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -0,0 +1,378 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmRuntimeDependencyArchive.h"
+
+#include "cmBinUtilsLinuxELFLinker.h"
+#include "cmBinUtilsMacOSMachOLinker.h"
+#include "cmBinUtilsWindowsPELinker.h"
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+#if defined(_WIN32)
+# include "cmGlobalGenerator.h"
+# ifndef CMAKE_BOOTSTRAP
+# include "cmGlobalVisualStudioVersionedGenerator.h"
+# endif
+# include "cmsys/Glob.hxx"
+
+# include "cmVSSetupHelper.h"
+#endif
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#if defined(_WIN32)
+static void AddVisualStudioPath(std::vector<std::string>& paths,
+ const std::string& prefix,
+ unsigned int version, cmGlobalGenerator* gg)
+{
+ // If generating for the VS IDE, use the same instance.
+ std::string vsloc;
+ bool found = false;
+# ifndef CMAKE_BOOTSTRAP
+ if (gg->GetName().find(prefix) == 0) {
+ cmGlobalVisualStudioVersionedGenerator* vsgen =
+ static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
+ if (vsgen->GetVSInstance(vsloc)) {
+ found = true;
+ }
+ }
+# endif
+
+ // Otherwise, find a VS instance ourselves.
+ if (!found) {
+ cmVSSetupAPIHelper vsSetupAPIHelper(version);
+ if (vsSetupAPIHelper.GetVSInstanceInfo(vsloc)) {
+ cmSystemTools::ConvertToUnixSlashes(vsloc);
+ found = true;
+ }
+ }
+
+ if (found) {
+ cmsys::Glob glob;
+ glob.SetListDirs(true);
+ glob.FindFiles(vsloc + "/VC/Tools/MSVC/*");
+ for (auto const& vcdir : glob.GetFiles()) {
+ paths.push_back(vcdir + "/bin/Hostx64/x64");
+ paths.push_back(vcdir + "/bin/Hostx86/x64");
+ paths.push_back(vcdir + "/bin/Hostx64/x86");
+ paths.push_back(vcdir + "/bin/Hostx86/x86");
+ }
+ }
+}
+
+static void AddRegistryPath(std::vector<std::string>& paths,
+ const std::string& path, cmMakefile* mf)
+{
+ // We should view the registry as the target application would view
+ // it.
+ cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
+ cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
+ if (mf->PlatformIs64Bit()) {
+ view = cmSystemTools::KeyWOW64_64;
+ other_view = cmSystemTools::KeyWOW64_32;
+ }
+
+ // Expand using the view of the target application.
+ std::string expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, view);
+ cmSystemTools::GlobDirs(expanded, paths);
+
+ // Executables can be either 32-bit or 64-bit, so expand using the
+ // alternative view.
+ expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, other_view);
+ cmSystemTools::GlobDirs(expanded, paths);
+}
+
+static void AddEnvPath(std::vector<std::string>& paths, const std::string& var,
+ const std::string& suffix)
+{
+ std::string value;
+ if (cmSystemTools::GetEnv(var, value)) {
+ paths.push_back(value + suffix);
+ }
+}
+#endif
+
+static cmsys::RegularExpression TransformCompile(const std::string& str)
+{
+ return cmsys::RegularExpression(str);
+}
+
+cmRuntimeDependencyArchive::cmRuntimeDependencyArchive(
+ cmExecutionStatus& status, std::vector<std::string> searchDirectories,
+ std::string bundleExecutable,
+ const std::vector<std::string>& preIncludeRegexes,
+ const std::vector<std::string>& preExcludeRegexes,
+ const std::vector<std::string>& postIncludeRegexes,
+ const std::vector<std::string>& postExcludeRegexes)
+ : Status(status)
+ , SearchDirectories(std::move(searchDirectories))
+ , BundleExecutable(std::move(bundleExecutable))
+ , PreIncludeRegexes(preIncludeRegexes.size())
+ , PreExcludeRegexes(preExcludeRegexes.size())
+ , PostIncludeRegexes(postIncludeRegexes.size())
+ , PostExcludeRegexes(postExcludeRegexes.size())
+{
+ std::transform(preIncludeRegexes.begin(), preIncludeRegexes.end(),
+ this->PreIncludeRegexes.begin(), TransformCompile);
+ std::transform(preExcludeRegexes.begin(), preExcludeRegexes.end(),
+ this->PreExcludeRegexes.begin(), TransformCompile);
+ std::transform(postIncludeRegexes.begin(), postIncludeRegexes.end(),
+ this->PostIncludeRegexes.begin(), TransformCompile);
+ std::transform(postExcludeRegexes.begin(), postExcludeRegexes.end(),
+ this->PostExcludeRegexes.begin(), TransformCompile);
+}
+
+bool cmRuntimeDependencyArchive::Prepare()
+{
+ std::string platform = this->GetMakefile()->GetSafeDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM");
+ if (platform.empty()) {
+ std::string systemName =
+ this->GetMakefile()->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
+ if (systemName == "Windows") {
+ platform = "windows+pe";
+ } else if (systemName == "Darwin") {
+ platform = "macos+macho";
+ } else if (systemName == "Linux") {
+ platform = "linux+elf";
+ }
+ }
+ if (platform == "linux+elf") {
+ this->Linker = cm::make_unique<cmBinUtilsLinuxELFLinker>(this);
+ } else if (platform == "windows+pe") {
+ this->Linker = cm::make_unique<cmBinUtilsWindowsPELinker>(this);
+ } else if (platform == "macos+macho") {
+ this->Linker = cm::make_unique<cmBinUtilsMacOSMachOLinker>(this);
+ } else {
+ std::ostringstream e;
+ e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: "
+ << platform;
+ this->SetError(e.str());
+ return false;
+ }
+
+ return this->Linker->Prepare();
+}
+
+bool cmRuntimeDependencyArchive::GetRuntimeDependencies(
+ const std::vector<std::string>& executables,
+ const std::vector<std::string>& libraries,
+ const std::vector<std::string>& modules)
+{
+ for (auto const& exe : executables) {
+ if (!this->Linker->ScanDependencies(exe, cmStateEnums::EXECUTABLE)) {
+ return false;
+ }
+ }
+ for (auto const& lib : libraries) {
+ if (!this->Linker->ScanDependencies(lib, cmStateEnums::SHARED_LIBRARY)) {
+ return false;
+ }
+ }
+ for (auto const& mod : modules) {
+ if (!this->Linker->ScanDependencies(mod, cmStateEnums::MODULE_LIBRARY)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void cmRuntimeDependencyArchive::SetError(const std::string& e)
+{
+ this->Status.SetError(e);
+}
+
+std::string cmRuntimeDependencyArchive::GetBundleExecutable()
+{
+ return this->BundleExecutable;
+}
+
+const std::vector<std::string>&
+cmRuntimeDependencyArchive::GetSearchDirectories()
+{
+ return this->SearchDirectories;
+}
+
+std::string cmRuntimeDependencyArchive::GetGetRuntimeDependenciesTool()
+{
+ return this->GetMakefile()->GetSafeDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL");
+}
+
+bool cmRuntimeDependencyArchive::GetGetRuntimeDependenciesCommand(
+ const std::string& search, std::vector<std::string>& command)
+{
+ // First see if it was supplied by the user
+ std::string toolCommand = this->GetMakefile()->GetSafeDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND");
+ if (!toolCommand.empty()) {
+ cmExpandList(toolCommand, command);
+ return true;
+ }
+
+ // Now go searching for it
+ std::vector<std::string> paths;
+#ifdef _WIN32
+ cmGlobalGenerator* gg = this->GetMakefile()->GetGlobalGenerator();
+
+ // Add newer Visual Studio paths
+ AddVisualStudioPath(paths, "Visual Studio 16 ", 16, gg);
+ AddVisualStudioPath(paths, "Visual Studio 15 ", 15, gg);
+
+ // Add older Visual Studio paths
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS140COMNTOOLS", "/../../VC/bin");
+ paths.push_back(
+ "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS120COMNTOOLS", "/../../VC/bin");
+ paths.push_back(
+ "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS110COMNTOOLS", "/../../VC/bin");
+ paths.push_back(
+ "C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS100COMNTOOLS", "/../../VC/bin");
+ paths.push_back(
+ "C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS90COMNTOOLS", "/../../VC/bin");
+ paths.push_back("C:/Program Files/Microsoft Visual Studio 9.0/VC/bin");
+ paths.push_back("C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]/"
+ "../../VC/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS80COMNTOOLS", "/../../VC/bin");
+ paths.push_back("C:/Program Files/Microsoft Visual Studio 8/VC/BIN");
+ paths.push_back("C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN");
+ AddRegistryPath(
+ paths,
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1;InstallDir]/"
+ "../../VC7/bin",
+ this->GetMakefile());
+ AddEnvPath(paths, "VS71COMNTOOLS", "/../../VC7/bin");
+ paths.push_back(
+ "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN");
+ paths.push_back(
+ "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN");
+#endif
+
+ std::string program = cmSystemTools::FindProgram(search, paths);
+ if (!program.empty()) {
+ command = { program };
+ return true;
+ }
+
+ // Couldn't find it
+ return false;
+}
+
+bool cmRuntimeDependencyArchive::IsPreExcluded(const std::string& name)
+{
+ cmsys::RegularExpressionMatch match;
+
+ for (auto const& regex : this->PreIncludeRegexes) {
+ if (regex.find(name.c_str(), match)) {
+ return false;
+ }
+ }
+
+ for (auto const& regex : this->PreExcludeRegexes) {
+ if (regex.find(name.c_str(), match)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool cmRuntimeDependencyArchive::IsPostExcluded(const std::string& name)
+{
+ cmsys::RegularExpressionMatch match;
+
+ for (auto const& regex : this->PostIncludeRegexes) {
+ if (regex.find(name.c_str(), match)) {
+ return false;
+ }
+ }
+
+ for (auto const& regex : this->PostExcludeRegexes) {
+ if (regex.find(name.c_str(), match)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name,
+ const std::string& path,
+ bool& unique)
+{
+ auto it = this->ResolvedPaths.emplace(name, std::set<std::string>{}).first;
+ unique = true;
+ for (auto const& other : it->second) {
+ if (cmSystemTools::SameFile(path, other)) {
+ unique = false;
+ break;
+ }
+ }
+ it->second.insert(path);
+}
+
+void cmRuntimeDependencyArchive::AddUnresolvedPath(const std::string& name)
+{
+ this->UnresolvedPaths.insert(name);
+}
+
+cmMakefile* cmRuntimeDependencyArchive::GetMakefile()
+{
+ return &this->Status.GetMakefile();
+}
+
+const std::map<std::string, std::set<std::string>>&
+cmRuntimeDependencyArchive::GetResolvedPaths()
+{
+ return this->ResolvedPaths;
+}
+
+const std::set<std::string>& cmRuntimeDependencyArchive::GetUnresolvedPaths()
+{
+ return this->UnresolvedPaths;
+}
diff --git a/Source/cmRuntimeDependencyArchive.h b/Source/cmRuntimeDependencyArchive.h
new file mode 100644
index 000000000..9e2dfb6c2
--- /dev/null
+++ b/Source/cmRuntimeDependencyArchive.h
@@ -0,0 +1,70 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmRuntimeDependencyArchive_h
+#define cmRuntimeDependencyArchive_h
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmBinUtilsLinker.h"
+
+class cmExecutionStatus;
+class cmMakefile;
+
+class cmRuntimeDependencyArchive
+{
+public:
+ explicit cmRuntimeDependencyArchive(
+ cmExecutionStatus& status, std::vector<std::string> searchDirectories,
+ std::string bundleExecutable,
+ const std::vector<std::string>& preIncludeRegexes,
+ const std::vector<std::string>& preExcludeRegexes,
+ const std::vector<std::string>& postIncludeRegexes,
+ const std::vector<std::string>& postExcludeRegexes);
+ bool Prepare();
+ bool GetRuntimeDependencies(const std::vector<std::string>& executables,
+ const std::vector<std::string>& libraries,
+ const std::vector<std::string>& modules);
+
+ void SetError(const std::string& e);
+
+ std::string GetBundleExecutable();
+ const std::vector<std::string>& GetSearchDirectories();
+ std::string GetGetRuntimeDependenciesTool();
+ bool GetGetRuntimeDependenciesCommand(const std::string& search,
+ std::vector<std::string>& command);
+ bool IsPreExcluded(const std::string& name);
+ bool IsPostExcluded(const std::string& name);
+
+ void AddResolvedPath(const std::string& name, const std::string& path,
+ bool& unique);
+ void AddUnresolvedPath(const std::string& name);
+
+ cmMakefile* GetMakefile();
+ const std::map<std::string, std::set<std::string>>& GetResolvedPaths();
+ const std::set<std::string>& GetUnresolvedPaths();
+
+private:
+ cmExecutionStatus& Status;
+ std::unique_ptr<cmBinUtilsLinker> Linker;
+
+ std::string GetRuntimeDependenciesTool;
+ std::vector<std::string> GetRuntimeDependenciesCommand;
+
+ std::vector<std::string> SearchDirectories;
+ std::string BundleExecutable;
+ std::vector<cmsys::RegularExpression> PreIncludeRegexes;
+ std::vector<cmsys::RegularExpression> PreExcludeRegexes;
+ std::vector<cmsys::RegularExpression> PostIncludeRegexes;
+ std::vector<cmsys::RegularExpression> PostExcludeRegexes;
+ std::map<std::string, std::set<std::string>> ResolvedPaths;
+ std::set<std::string> UnresolvedPaths;
+};
+
+#endif // cmRuntimeDependencyArchive_h
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 9182b4165..adc06792d 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -2,10 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmScriptGenerator.h"
-#include "cmSystemTools.h"
-
#include <utility>
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
cmScriptGenerator::cmScriptGenerator(std::string config_var,
std::vector<std::string> configurations)
: RuntimeConfigVariable(std::move(config_var))
@@ -51,9 +52,8 @@ static void cmScriptGeneratorEncodeConfig(const std::string& config,
std::string cmScriptGenerator::CreateConfigTest(const std::string& config)
{
- std::string result = "\"${";
- result += this->RuntimeConfigVariable;
- result += "}\" MATCHES \"^(";
+ std::string result =
+ cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^(");
if (!config.empty()) {
cmScriptGeneratorEncodeConfig(config, result);
}
@@ -64,9 +64,8 @@ std::string cmScriptGenerator::CreateConfigTest(const std::string& config)
std::string cmScriptGenerator::CreateConfigTest(
std::vector<std::string> const& configs)
{
- std::string result = "\"${";
- result += this->RuntimeConfigVariable;
- result += "}\" MATCHES \"^(";
+ std::string result =
+ cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^(");
const char* sep = "";
for (std::string const& config : configs) {
result += sep;
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index e334d5bad..c8bb1ab15 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -25,7 +25,7 @@ public:
}
cmScriptGeneratorIndent Next(int step = 2) const
{
- return cmScriptGeneratorIndent(this->Level + step);
+ return { this->Level + step };
}
private:
@@ -56,7 +56,7 @@ public:
std::vector<std::string> const& configurationTypes);
protected:
- typedef cmScriptGeneratorIndent Indent;
+ using Indent = cmScriptGeneratorIndent;
virtual void GenerateScript(std::ostream& os);
virtual void GenerateScriptConfigs(std::ostream& os, Indent indent);
virtual void GenerateScriptActions(std::ostream& os, Indent indent);
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index f98984ed6..d15ce5749 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -6,9 +6,9 @@
#include <cassert>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmFindCommon.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
@@ -78,8 +78,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable)
// Get a path from a CMake variable.
if (const char* value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded;
- cmSystemTools::ExpandListArgument(value, expanded);
+ std::vector<std::string> expanded = cmExpandedList(value);
for (std::string const& p : expanded) {
this->AddPathInternal(
@@ -103,8 +102,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
// Get a path from a CMake variable.
if (const char* value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded;
- cmSystemTools::ExpandListArgument(value, expanded);
+ std::vector<std::string> expanded = cmExpandedList(value);
this->AddPrefixPaths(
expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 28cbdc0ad..52bde7c5c 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -3,19 +3,18 @@
#include "cmSeparateArgumentsCommand.h"
#include <algorithm>
-#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmSeparateArgumentsCommand
-bool cmSeparateArgumentsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("must be given at least one argument.");
+ status.SetError("must be given at least one argument.");
return false;
}
@@ -57,19 +56,17 @@ bool cmSeparateArgumentsCommand::InitialPass(
command = arg;
doing = DoingNone;
} else {
- std::ostringstream e;
- e << "given unknown argument " << arg;
- this->SetError(e.str());
+ status.SetError(cmStrCat("given unknown argument ", arg));
return false;
}
}
if (mode == ModeOld) {
// Original space-replacement version of command.
- if (const char* def = this->Makefile->GetDefinition(var)) {
+ if (const char* def = status.GetMakefile().GetDefinition(var)) {
std::string value = def;
std::replace(value.begin(), value.end(), ' ', ';');
- this->Makefile->AddDefinition(var, value.c_str());
+ status.GetMakefile().AddDefinition(var, value);
}
} else {
// Parse the command line.
@@ -97,7 +94,7 @@ bool cmSeparateArgumentsCommand::InitialPass(
value += si;
}
}
- this->Makefile->AddDefinition(var, value.c_str());
+ status.GetMakefile().AddDefinition(var, value);
}
return true;
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index 988ad23ae..e000c511d 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmSeparateArgumentsCommand
+/**
* \brief separate_arguments command
*
* cmSeparateArgumentsCommand implements the separate_arguments CMake command
*/
-class cmSeparateArgumentsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmSeparateArgumentsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 1903fd917..3b2e5f322 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -2,25 +2,28 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmServer.h"
-#include "cmAlgorithms.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <mutex>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/shared_mutex>
+
+#include "cmsys/FStream.hxx"
+
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_writer.h"
+
#include "cmConnection.h"
#include "cmFileMonitor.h"
#include "cmJsonObjectDictionary.h"
#include "cmServerDictionary.h"
#include "cmServerProtocol.h"
#include "cmSystemTools.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_writer.h"
#include "cmake.h"
-#include "cmsys/FStream.hxx"
-
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <iostream>
-#include <memory>
-#include <mutex>
-#include <utility>
void on_signal(uv_signal_t* signal, int signum)
{
diff --git a/Source/cmServer.h b/Source/cmServer.h
index aba4924c9..3d7027b39 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -4,16 +4,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/shared_mutex>
+
#include "cm_jsoncpp_value.h"
-#include "cm_thread.hxx"
#include "cm_uv.h"
#include "cmUVHandlePtr.h"
-#include <memory> // IWYU pragma: keep
-#include <string>
-#include <vector>
-
class cmConnection;
class cmFileMonitor;
class cmServerProtocol;
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index a878890da..279197214 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -1,11 +1,13 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h"
+
#include "cmServerConnection.h"
-#include "cmConfigure.h"
+#include "cm_uv.h"
+
#include "cmServer.h"
#include "cmServerDictionary.h"
-#include "cm_uv.h"
#ifdef _WIN32
# include "io.h"
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 558391f30..56003df75 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -2,6 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmServerProtocol.h"
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cm_uv.h"
+
#include "cmAlgorithms.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileMonitor.h"
@@ -13,17 +24,8 @@
#include "cmServerDictionary.h"
#include "cmState.h"
#include "cmSystemTools.h"
-#include "cm_uv.h"
#include "cmake.h"
-#include <algorithm>
-#include <cassert>
-#include <functional>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
// Get rid of some windows macros:
#undef max
@@ -166,7 +168,7 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
std::pair<int, int> cmServerProtocol1::ProtocolVersion() const
{
- return std::make_pair(1, 2);
+ return { 1, 2 };
}
static void setErrorMessage(std::string* errorMessage, const std::string& text)
@@ -378,8 +380,7 @@ void cmServerProtocol1::HandleCMakeFileChanges(const std::string& path,
SendSignal(kFILE_CHANGE_SIGNAL, obj);
}
-const cmServerResponse cmServerProtocol1::Process(
- const cmServerRequest& request)
+cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request)
{
assert(this->m_State >= STATE_ACTIVE);
@@ -434,7 +435,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
keys = allKeys;
} else {
for (auto const& i : keys) {
- if (std::find(allKeys.begin(), allKeys.end(), i) == allKeys.end()) {
+ if (!cmContains(allKeys, i)) {
return request.ReportError("Key \"" + i + "\" not found in cache.");
}
}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 2f55a208f..8446c3e76 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -4,13 +4,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
-#include "cmake.h"
-
#include <memory>
#include <string>
#include <utility>
+#include "cm_jsoncpp_value.h"
+
+#include "cmake.h"
+
class cmConnection;
class cmFileMonitor;
class cmServer;
@@ -80,7 +81,7 @@ public:
virtual std::pair<int, int> ProtocolVersion() const = 0;
virtual bool IsExperimental() const = 0;
- virtual const cmServerResponse Process(const cmServerRequest& request) = 0;
+ virtual cmServerResponse Process(const cmServerRequest& request) = 0;
bool Activate(cmServer* server, const cmServerRequest& request,
std::string* errorMessage);
@@ -106,7 +107,7 @@ class cmServerProtocol1 : public cmServerProtocol
public:
std::pair<int, int> ProtocolVersion() const override;
bool IsExperimental() const override;
- const cmServerResponse Process(const cmServerRequest& request) override;
+ cmServerResponse Process(const cmServerRequest& request) override;
private:
bool DoActivate(const cmServerRequest& request,
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 41555e8e3..8c3a4cb48 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -2,22 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetCommand.h"
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmSetCommand
-bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmSetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -45,7 +44,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
std::string m = "Only the first value argument is used when setting "
"an environment variable. Argument '" +
args[2] + "' and later are unused.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
}
return true;
}
@@ -59,13 +58,13 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
// SET (VAR) // Removes the definition of VAR.
if (args.size() == 1) {
- this->Makefile->RemoveDefinition(variable);
+ status.GetMakefile().RemoveDefinition(variable);
return true;
}
// SET (VAR PARENT_SCOPE) // Removes the definition of VAR
// in the parent scope.
if (args.size() == 2 && args.back() == "PARENT_SCOPE") {
- this->Makefile->RaiseScope(variable, nullptr);
+ status.GetMakefile().RaiseScope(variable, nullptr);
return true;
}
@@ -106,7 +105,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
if (parentScope) {
- this->Makefile->RaiseScope(variable, value.c_str());
+ status.GetMakefile().RaiseScope(variable, value.c_str());
return true;
}
@@ -116,7 +115,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
if ((args.back() == "CACHE") ||
(args.size() > 1 && args[args.size() - 2] == "CACHE") ||
(force && !cache)) {
- this->SetError("given invalid arguments for CACHE mode.");
+ status.SetError("given invalid arguments for CACHE mode.");
return false;
}
@@ -125,7 +124,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) {
std::string m = "implicitly converting '" + args[cacheStart + 1] +
"' to 'STRING' type.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
// Setting this may not be required, since it's
// initialized as a string. Keeping this here to
// ensure that the type is actually converting to a string.
@@ -135,7 +134,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
}
// see if this is already in the cache
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
const char* existingValue = state->GetCacheEntryValue(variable);
if (existingValue &&
(state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
@@ -150,11 +149,11 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
// if it is meant to be in the cache then define it in the cache
if (cache) {
- this->Makefile->AddCacheDefinition(variable, value.c_str(), docstring,
- type, force);
+ status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
+ type, force);
} else {
// add the definition
- this->Makefile->AddDefinition(variable, value.c_str());
+ status.GetMakefile().AddDefinition(variable, value);
}
return true;
}
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index 76e3eae9b..0973d33aa 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmSetCommand
+/**
* \brief Set a CMAKE variable
*
* cmSetCommand sets a variable to a value with expansion.
*/
-class cmSetCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmSetCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 8d3961a79..35daca6ff 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -2,31 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetDirectoryPropertiesCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
+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::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string errors;
- bool ret = cmSetDirectoryPropertiesCommand::RunCommand(
- this->Makefile, args.begin() + 1, args.end(), errors);
+ bool ret =
+ RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors);
if (!ret) {
- this->SetError(errors);
+ status.SetError(errors);
}
return ret;
}
-bool cmSetDirectoryPropertiesCommand::RunCommand(
- cmMakefile* mf, std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend, std::string& errors)
+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) {
@@ -43,8 +49,9 @@ bool cmSetDirectoryPropertiesCommand::RunCommand(
errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
return false;
}
- mf->SetProperty(prop, value.c_str());
+ mf.SetProperty(prop, value.c_str());
}
return true;
}
+}
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 473347c1a..c243dd70f 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -8,30 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmSetDirectoryPropertiesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmSetDirectoryPropertiesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
- /**
- * Static entry point for use by other commands
- */
- static bool RunCommand(cmMakefile* mf,
- std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend,
- std::string& errors);
-};
+bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index e9343c7db..112d832e6 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -2,8 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetPropertyCommand.h"
+#include <set>
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmMakefile.h"
@@ -11,25 +13,72 @@
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-cmSetPropertyCommand::cmSetPropertyCommand()
-{
- this->AppendMode = false;
- this->AppendAsString = false;
- this->Remove = true;
+namespace {
+bool HandleGlobalMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleDirectoryMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleTargetMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleTarget(cmTarget* target, cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+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 HandleSource(cmSourceFile* sf, const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleTest(cmTest* test, const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleCacheMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleInstallMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
+bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove);
}
-bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmSetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -51,14 +100,20 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
} else if (scopeName == "INSTALL") {
scope = cmProperty::INSTALL;
} else {
- std::ostringstream e;
- e << "given invalid scope " << scopeName << ". "
- << "Valid scopes are GLOBAL, DIRECTORY, "
- "TARGET, SOURCE, TEST, CACHE, INSTALL.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given invalid scope ", scopeName,
+ ". "
+ "Valid scopes are GLOBAL, DIRECTORY, "
+ "TARGET, SOURCE, TEST, CACHE, INSTALL."));
return false;
}
+ bool appendAsString = false;
+ bool appendMode = false;
+ bool remove = true;
+ std::set<std::string> names;
+ std::string propertyName;
+ std::string propertyValue;
+
// Parse the rest of the arguments up to the values.
enum Doing
{
@@ -74,54 +129,59 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
doing = DoingProperty;
} else if (arg == "APPEND") {
doing = DoingNone;
- this->AppendMode = true;
- this->Remove = false;
- this->AppendAsString = false;
+ appendMode = true;
+ remove = false;
+ appendAsString = false;
} else if (arg == "APPEND_STRING") {
doing = DoingNone;
- this->AppendMode = true;
- this->Remove = false;
- this->AppendAsString = true;
+ appendMode = true;
+ remove = false;
+ appendAsString = true;
} else if (doing == DoingNames) {
- this->Names.insert(arg);
+ names.insert(arg);
} else if (doing == DoingProperty) {
- this->PropertyName = arg;
+ propertyName = arg;
doing = DoingValues;
} else if (doing == DoingValues) {
- this->PropertyValue += sep;
+ propertyValue += sep;
sep = ";";
- this->PropertyValue += arg;
- this->Remove = false;
+ propertyValue += arg;
+ remove = false;
} else {
- std::ostringstream e;
- e << "given invalid argument \"" << arg << "\".";
- this->SetError(e.str());
+ status.SetError(cmStrCat("given invalid argument \"", arg, "\"."));
return false;
}
}
// Make sure a property name was found.
- if (this->PropertyName.empty()) {
- this->SetError("not given a PROPERTY <name> argument.");
+ if (propertyName.empty()) {
+ status.SetError("not given a PROPERTY <name> argument.");
return false;
}
// Dispatch property setting.
switch (scope) {
case cmProperty::GLOBAL:
- return this->HandleGlobalMode();
+ return HandleGlobalMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::DIRECTORY:
- return this->HandleDirectoryMode();
+ return HandleDirectoryMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::TARGET:
- return this->HandleTargetMode();
+ return HandleTargetMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::SOURCE_FILE:
- return this->HandleSourceMode();
+ return HandleSourceMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::TEST:
- return this->HandleTestMode();
+ return HandleTestMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::CACHE:
- return this->HandleCacheMode();
+ return HandleCacheMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::INSTALL:
- return this->HandleInstallMode();
+ return HandleInstallMode(status, names, propertyName, propertyValue,
+ appendAsString, appendMode, remove);
case cmProperty::VARIABLE:
case cmProperty::CACHED_VARIABLE:
@@ -130,57 +190,66 @@ bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
-bool cmSetPropertyCommand::HandleGlobalMode()
+namespace {
+bool HandleGlobalMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- if (!this->Names.empty()) {
- this->SetError("given names for GLOBAL scope.");
+ if (!names.empty()) {
+ status.SetError("given names for GLOBAL scope.");
return false;
}
// Set or append the property.
- cmake* cm = this->Makefile->GetCMakeInstance();
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
+ const char* value = propertyValue.c_str();
+ if (remove) {
value = nullptr;
}
- if (this->AppendMode) {
- cm->AppendProperty(name, value ? value : "", this->AppendAsString);
+ if (appendMode) {
+ cm->AppendProperty(propertyName, value ? value : "", appendAsString);
} else {
- cm->SetProperty(name, value);
+ cm->SetProperty(propertyName, value);
}
return true;
}
-bool cmSetPropertyCommand::HandleDirectoryMode()
+bool HandleDirectoryMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- if (this->Names.size() > 1) {
- this->SetError("allows at most one name for DIRECTORY scope.");
+ if (names.size() > 1) {
+ status.SetError("allows at most one name for DIRECTORY scope.");
return false;
}
// Default to the current directory.
- cmMakefile* mf = this->Makefile;
+ cmMakefile* mf = &status.GetMakefile();
// Lookup the directory if given.
- if (!this->Names.empty()) {
+ if (!names.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = *this->Names.begin();
+ std::string dir = *names.begin();
if (!cmSystemTools::FileIsFullPath(dir)) {
- dir = this->Makefile->GetCurrentSourceDirectory();
- dir += "/";
- dir += *this->Names.begin();
+ dir = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
+ *names.begin());
}
// The local generators are associated with collapsed paths.
dir = cmSystemTools::CollapseFullPath(dir);
- mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
if (!mf) {
// Could not find the directory.
- this->SetError(
+ status.SetError(
"DIRECTORY scope provided but requested directory was not found. "
"This could be because the directory argument was invalid or, "
"it is valid but has not been processed yet.");
@@ -189,109 +258,124 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
}
// Set or append the property.
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
+ const char* value = propertyValue.c_str();
+ if (remove) {
value = nullptr;
}
- if (this->AppendMode) {
- mf->AppendProperty(name, value ? value : "", this->AppendAsString);
+ if (appendMode) {
+ mf->AppendProperty(propertyName, value ? value : "", appendAsString);
} else {
- mf->SetProperty(name, value);
+ mf->SetProperty(propertyName, value);
}
return true;
}
-bool cmSetPropertyCommand::HandleTargetMode()
+bool HandleTargetMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- for (std::string const& name : this->Names) {
- if (this->Makefile->IsAlias(name)) {
- this->SetError("can not be used on an ALIAS target.");
+ for (std::string const& name : names) {
+ if (status.GetMakefile().IsAlias(name)) {
+ status.SetError("can not be used on an ALIAS target.");
return false;
}
- if (cmTarget* target = this->Makefile->FindTargetToUse(name)) {
+ if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
// Handle the current target.
- if (!this->HandleTarget(target)) {
+ if (!HandleTarget(target, status.GetMakefile(), propertyName,
+ propertyValue, appendAsString, appendMode, remove)) {
return false;
}
} else {
- std::ostringstream e;
- e << "could not find TARGET " << name
- << ". Perhaps it has not yet been created.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("could not find TARGET ", name,
+ ". Perhaps it has not yet been created."));
return false;
}
}
return true;
}
-bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
+bool HandleTarget(cmTarget* target, cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue, const bool appendAsString,
+ const bool appendMode, const bool remove)
{
// Set or append the property.
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
+ const char* value = propertyValue.c_str();
+ if (remove) {
value = nullptr;
}
- if (this->AppendMode) {
- target->AppendProperty(name, value, this->AppendAsString);
+ if (appendMode) {
+ target->AppendProperty(propertyName, value, appendAsString);
} else {
- target->SetProperty(name, value);
+ target->SetProperty(propertyName, value);
}
// Check the resulting value.
- target->CheckProperty(name, this->Makefile);
+ target->CheckProperty(propertyName, &makefile);
return true;
}
-bool cmSetPropertyCommand::HandleSourceMode()
+bool HandleSourceMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- for (std::string const& name : this->Names) {
+ for (std::string const& name : names) {
// Get the source file.
- if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(name)) {
- if (!this->HandleSource(sf)) {
+ if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+ if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
+ appendMode, remove)) {
return false;
}
} else {
- std::ostringstream e;
- e << "given SOURCE name that could not be found or created: " << name;
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "given SOURCE name that could not be found or created: ", name));
return false;
}
}
return true;
}
-bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
+bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
+ const std::string& propertyValue, const bool appendAsString,
+ const bool appendMode, const bool remove)
{
// Set or append the property.
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
+ const char* value = propertyValue.c_str();
+ if (remove) {
value = nullptr;
}
- if (this->AppendMode) {
- sf->AppendProperty(name, value, this->AppendAsString);
+ if (appendMode) {
+ sf->AppendProperty(propertyName, value, appendAsString);
} else {
- sf->SetProperty(name, value);
+ sf->SetProperty(propertyName, value);
}
return true;
}
-bool cmSetPropertyCommand::HandleTestMode()
+bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
// Look for tests with all names given.
std::set<std::string>::iterator next;
- for (std::set<std::string>::iterator ni = this->Names.begin();
- ni != this->Names.end(); ni = next) {
+ for (auto ni = names.begin(); ni != names.end(); ni = next) {
next = ni;
++next;
- if (cmTest* test = this->Makefile->GetTest(*ni)) {
- if (this->HandleTest(test)) {
- this->Names.erase(ni);
+ if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
+ if (HandleTest(test, propertyName, propertyValue, appendAsString,
+ appendMode, remove)) {
+ names.erase(ni);
} else {
return false;
}
@@ -299,137 +383,145 @@ bool cmSetPropertyCommand::HandleTestMode()
}
// Names that are still left were not found.
- if (!this->Names.empty()) {
+ if (!names.empty()) {
std::ostringstream e;
e << "given TEST names that do not exist:\n";
- for (std::string const& name : this->Names) {
+ for (std::string const& name : names) {
e << " " << name << "\n";
}
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
return true;
}
-bool cmSetPropertyCommand::HandleTest(cmTest* test)
+bool HandleTest(cmTest* test, const std::string& propertyName,
+ const std::string& propertyValue, const bool appendAsString,
+ const bool appendMode, const bool remove)
{
// Set or append the property.
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
+ const char* value = propertyValue.c_str();
+ if (remove) {
value = nullptr;
}
- if (this->AppendMode) {
- test->AppendProperty(name, value, this->AppendAsString);
+ if (appendMode) {
+ test->AppendProperty(propertyName, value, appendAsString);
} else {
- test->SetProperty(name, value);
+ test->SetProperty(propertyName, value);
}
return true;
}
-bool cmSetPropertyCommand::HandleCacheMode()
+bool HandleCacheMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- if (this->PropertyName == "ADVANCED") {
- if (!this->Remove && !cmSystemTools::IsOn(this->PropertyValue) &&
- !cmSystemTools::IsOff(this->PropertyValue)) {
- std::ostringstream e;
- e << "given non-boolean value \"" << this->PropertyValue
- << R"(" for CACHE property "ADVANCED". )";
- this->SetError(e.str());
+ if (propertyName == "ADVANCED") {
+ if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
+ status.SetError(cmStrCat("given non-boolean value \"", propertyValue,
+ R"(" for CACHE property "ADVANCED". )"));
return false;
}
- } else if (this->PropertyName == "TYPE") {
- if (!cmState::IsCacheEntryType(this->PropertyValue)) {
- std::ostringstream e;
- e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
- this->SetError(e.str());
+ } else if (propertyName == "TYPE") {
+ if (!cmState::IsCacheEntryType(propertyValue)) {
+ status.SetError(
+ cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, "\""));
return false;
}
- } else if (this->PropertyName != "HELPSTRING" &&
- this->PropertyName != "STRINGS" &&
- this->PropertyName != "VALUE") {
- std::ostringstream e;
- e << "given invalid CACHE property " << this->PropertyName << ". "
- << "Settable CACHE properties are: "
- << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.";
- this->SetError(e.str());
+ } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" &&
+ propertyName != "VALUE") {
+ status.SetError(
+ cmStrCat("given invalid CACHE property ", propertyName,
+ ". "
+ "Settable CACHE properties are: "
+ "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE."));
return false;
}
- for (std::string const& name : this->Names) {
+ for (std::string const& name : names) {
// Get the source file.
- cmMakefile* mf = this->GetMakefile();
- cmake* cm = mf->GetCMakeInstance();
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
const char* existingValue = cm->GetState()->GetCacheEntryValue(name);
if (existingValue) {
- if (!this->HandleCacheEntry(name)) {
+ if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
+ propertyValue, appendAsString, appendMode,
+ remove)) {
return false;
}
} else {
- std::ostringstream e;
- e << "could not find CACHE variable " << name
- << ". Perhaps it has not yet been created.";
- this->SetError(e.str());
+ status.SetError(cmStrCat("could not find CACHE variable ", name,
+ ". Perhaps it has not yet been created."));
return false;
}
}
return true;
}
-bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey)
+bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
// Set or append the property.
- std::string const& name = this->PropertyName;
- const char* value = this->PropertyValue.c_str();
- cmState* state = this->Makefile->GetState();
- if (this->Remove) {
- state->RemoveCacheEntryProperty(cacheKey, name);
+ const char* value = propertyValue.c_str();
+ cmState* state = makefile.GetState();
+ if (remove) {
+ state->RemoveCacheEntryProperty(cacheKey, propertyName);
}
- if (this->AppendMode) {
- state->AppendCacheEntryProperty(cacheKey, name, value,
- this->AppendAsString);
+ if (appendMode) {
+ state->AppendCacheEntryProperty(cacheKey, propertyName, value,
+ appendAsString);
} else {
- state->SetCacheEntryProperty(cacheKey, name, value);
+ state->SetCacheEntryProperty(cacheKey, propertyName, value);
}
return true;
}
-bool cmSetPropertyCommand::HandleInstallMode()
+bool HandleInstallMode(cmExecutionStatus& status,
+ const std::set<std::string>& names,
+ const std::string& propertyName,
+ const std::string& propertyValue,
+ const bool appendAsString, const bool appendMode,
+ const bool remove)
{
- cmake* cm = this->Makefile->GetCMakeInstance();
+ cmake* cm = status.GetMakefile().GetCMakeInstance();
- for (std::string const& name : this->Names) {
+ for (std::string const& name : names) {
if (cmInstalledFile* file =
- cm->GetOrCreateInstalledFile(this->Makefile, name)) {
- if (!this->HandleInstall(file)) {
+ cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
+ if (!HandleInstall(file, status.GetMakefile(), propertyName,
+ propertyValue, appendAsString, appendMode, remove)) {
return false;
}
} else {
- std::ostringstream e;
- e << "given INSTALL name that could not be found or created: " << name;
- this->SetError(e.str());
+ status.SetError(cmStrCat(
+ "given INSTALL name that could not be found or created: ", name));
return false;
}
}
return true;
}
-bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file)
+bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
+ const std::string& propertyName,
+ const std::string& propertyValue, const bool appendAsString,
+ const bool appendMode, const bool remove)
{
// Set or append the property.
- std::string const& name = this->PropertyName;
-
- cmMakefile* mf = this->Makefile;
-
- const char* value = this->PropertyValue.c_str();
- if (this->Remove) {
- file->RemoveProperty(name);
- } else if (this->AppendMode) {
- file->AppendProperty(mf, name, value, this->AppendAsString);
+ const char* value = propertyValue.c_str();
+ if (remove) {
+ file->RemoveProperty(propertyName);
+ } else if (appendMode) {
+ file->AppendProperty(&makefile, propertyName, value, appendAsString);
} else {
- file->SetProperty(mf, name, value);
+ file->SetProperty(&makefile, propertyName, value);
}
return true;
}
+}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index f1126bb7e..ec36f849e 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -5,53 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <set>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmInstalledFile;
-class cmSourceFile;
-class cmTarget;
-class cmTest;
-
-class cmSetPropertyCommand : public cmCommand
-{
-public:
- cmSetPropertyCommand();
-
- cmCommand* Clone() override { return new cmSetPropertyCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::set<std::string> Names;
- std::string PropertyName;
- std::string PropertyValue;
- bool Remove;
- bool AppendMode;
- bool AppendAsString;
- // Implementation of each property type.
- bool HandleGlobalMode();
- bool HandleDirectoryMode();
- bool HandleTargetMode();
- bool HandleTarget(cmTarget* target);
- bool HandleSourceMode();
- bool HandleSource(cmSourceFile* sf);
- bool HandleTestMode();
- bool HandleTest(cmTest* test);
- bool HandleCacheMode();
- bool HandleCacheEntry(std::string const&);
- bool HandleInstallMode();
- bool HandleInstall(cmInstalledFile* file);
-};
+bool cmSetPropertyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 9388e7ccf..7ff604be0 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -2,18 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetSourceFilesPropertiesCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
-class cmExecutionStatus;
+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);
-// cmSetSourceFilesPropertiesCommand
-bool cmSetSourceFilesPropertiesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -29,22 +34,24 @@ bool cmSetSourceFilesPropertiesCommand::InitialPass(
++j;
}
+ cmMakefile& mf = status.GetMakefile();
+
// now call the worker function
std::string errors;
- bool ret = cmSetSourceFilesPropertiesCommand::RunCommand(
- this->Makefile, args.begin(), args.begin() + numFiles,
- args.begin() + numFiles, args.end(), errors);
+ bool ret = RunCommand(&mf, args.begin(), args.begin() + numFiles,
+ args.begin() + numFiles, args.end(), errors);
if (!ret) {
- this->SetError(errors);
+ status.SetError(errors);
}
return ret;
}
-bool cmSetSourceFilesPropertiesCommand::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 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)
{
std::vector<std::string> propertyPairs;
bool generated = false;
@@ -87,7 +94,7 @@ bool cmSetSourceFilesPropertiesCommand::RunCommand(
propertyPairs.push_back(*j);
if (*j == "GENERATED") {
++j;
- if (j != propend && cmSystemTools::IsOn(*j)) {
+ if (j != propend && cmIsOn(*j)) {
generated = true;
}
} else {
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
index afb19f6e6..5eef7859a 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.h
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmSetSourceFilesPropertiesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmSetSourceFilesPropertiesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
- 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);
-};
+bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index 1dc7e69a3..8d917dbe5 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -5,30 +5,32 @@
#include <iterator>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-class cmExecutionStatus;
+static bool SetOneTarget(const std::string& tname,
+ std::vector<std::string>& propertyPairs,
+ cmMakefile* mf);
-// cmSetTargetPropertiesCommand
-bool cmSetTargetPropertiesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// 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) {
+ 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) {
- this->SetError("called with incorrect number of arguments.");
+ status.SetError("called with incorrect number of arguments.");
return false;
}
cmAppend(propertyPairs, j, args.end());
@@ -37,33 +39,32 @@ bool cmSetTargetPropertiesCommand::InitialPass(
numFiles++;
}
if (propertyPairs.empty()) {
- this->SetError("called with illegal arguments, maybe missing "
- "a PROPERTIES specifier?");
+ status.SetError("called with illegal arguments, maybe missing "
+ "a PROPERTIES specifier?");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// now loop over all the targets
- int i;
- for (i = 0; i < numFiles; ++i) {
- if (this->Makefile->IsAlias(args[i])) {
- this->SetError("can not be used on an ALIAS target.");
+ for (int i = 0; i < numFiles; ++i) {
+ if (mf.IsAlias(args[i])) {
+ status.SetError("can not be used on an ALIAS target.");
return false;
}
- bool ret = cmSetTargetPropertiesCommand::SetOneTarget(
- args[i], propertyPairs, this->Makefile);
+ bool ret = SetOneTarget(args[i], propertyPairs, &mf);
if (!ret) {
- std::string message = "Can not find target to add properties to: ";
- message += args[i];
- this->SetError(message);
+ status.SetError(
+ cmStrCat("Can not find target to add properties to: ", args[i]));
return false;
}
}
return true;
}
-bool cmSetTargetPropertiesCommand::SetOneTarget(
- const std::string& tname, std::vector<std::string>& propertyPairs,
- cmMakefile* mf)
+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
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index c9755da91..9d40c7498 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmSetTargetPropertiesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmSetTargetPropertiesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
- /**
- * Used by this command and cmSetPropertiesCommand
- */
- static bool SetOneTarget(const std::string& tname,
- std::vector<std::string>& propertyPairs,
- cmMakefile* mf);
-};
+bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index cc9587ca6..de61edaf0 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -5,20 +5,25 @@
#include <iterator>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmTest.h"
-class cmExecutionStatus;
+static bool SetOneTest(const std::string& tname,
+ std::vector<std::string>& propertyPairs, cmMakefile* mf,
+ std::string& errors);
-// cmSetTestsPropertiesCommand
-bool cmSetTestsPropertiesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// first collect up the list of files
std::vector<std::string> propertyPairs;
int numFiles = 0;
@@ -28,7 +33,7 @@ bool cmSetTestsPropertiesCommand::InitialPass(
// now loop through the rest of the arguments, new style
++j;
if (std::distance(j, args.end()) % 2 != 0) {
- this->SetError("called with incorrect number of arguments.");
+ status.SetError("called with incorrect number of arguments.");
return false;
}
cmAppend(propertyPairs, j, args.end());
@@ -37,8 +42,8 @@ bool cmSetTestsPropertiesCommand::InitialPass(
numFiles++;
}
if (propertyPairs.empty()) {
- this->SetError("called with illegal arguments, maybe "
- "missing a PROPERTIES specifier?");
+ status.SetError("called with illegal arguments, maybe "
+ "missing a PROPERTIES specifier?");
return false;
}
@@ -46,10 +51,9 @@ bool cmSetTestsPropertiesCommand::InitialPass(
int i;
for (i = 0; i < numFiles; ++i) {
std::string errors;
- bool ret = cmSetTestsPropertiesCommand::SetOneTest(args[i], propertyPairs,
- this->Makefile, errors);
+ bool ret = SetOneTest(args[i], propertyPairs, &mf, errors);
if (!ret) {
- this->SetError(errors);
+ status.SetError(errors);
return ret;
}
}
@@ -57,9 +61,9 @@ bool cmSetTestsPropertiesCommand::InitialPass(
return true;
}
-bool cmSetTestsPropertiesCommand::SetOneTest(
- const std::string& tname, std::vector<std::string>& propertyPairs,
- cmMakefile* mf, std::string& errors)
+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
@@ -70,8 +74,7 @@ bool cmSetTestsPropertiesCommand::SetOneTest(
}
}
} else {
- errors = "Can not find test to add properties to: ";
- errors += tname;
+ errors = cmStrCat("Can not find test to add properties to: ", tname);
return false;
}
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
index 84b2645b3..4b754641b 100644
--- a/Source/cmSetTestsPropertiesCommand.h
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -8,26 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmSetTestsPropertiesCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmSetTestsPropertiesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the input file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
- 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);
#endif
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index 9f041bc5f..d47f121e0 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -4,18 +4,18 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmSiteNameCommand
-bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmSiteNameCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 1) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::vector<std::string> paths;
@@ -26,12 +26,12 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
paths.emplace_back("/sbin");
paths.emplace_back("/usr/local/bin");
- const char* cacheValue = this->Makefile->GetDefinition(args[0]);
+ const char* cacheValue = status.GetMakefile().GetDefinition(args[0]);
if (cacheValue) {
return true;
}
- const char* temp = this->Makefile->GetDefinition("HOSTNAME");
+ const char* temp = status.GetMakefile().GetDefinition("HOSTNAME");
std::string hostname_cmd;
if (temp) {
hostname_cmd = temp;
@@ -50,7 +50,7 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
}
#else
// try to find the hostname for this computer
- if (!cmSystemTools::IsOff(hostname_cmd)) {
+ if (!cmIsOff(hostname_cmd)) {
std::string host;
cmSystemTools::RunSingleCommand(hostname_cmd, &host, nullptr, nullptr,
nullptr, cmSystemTools::OUTPUT_NONE);
@@ -71,7 +71,7 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args,
}
}
#endif
- this->Makefile->AddCacheDefinition(
+ status.GetMakefile().AddCacheDefinition(
args[0], siteName.c_str(),
"Name of the computer/site where compile is being run",
cmStateEnums::STRING);
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index 2d8dc1768..e8fc60807 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmSiteNameCommand
+/**
* \brief site_name command
*
* cmSiteNameCommand implements the site_name CMake command
*/
-class cmSiteNameCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmSiteNameCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSiteNameCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index d05fb68d9..2a345eb85 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -5,12 +5,13 @@
#include <array>
#include <utility>
-#include "cmCustomCommand.h"
#include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -20,11 +21,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name,
{
}
-cmSourceFile::~cmSourceFile()
-{
- this->SetCustomCommand(nullptr);
-}
-
std::string const& cmSourceFile::GetExtension() const
{
return this->Extension;
@@ -33,6 +29,11 @@ std::string const& cmSourceFile::GetExtension() const
const std::string cmSourceFile::propLANGUAGE = "LANGUAGE";
const std::string cmSourceFile::propLOCATION = "LOCATION";
const std::string cmSourceFile::propGENERATED = "GENERATED";
+const std::string cmSourceFile::propCOMPILE_DEFINITIONS =
+ "COMPILE_DEFINITIONS";
+const std::string cmSourceFile::propCOMPILE_OPTIONS = "COMPILE_OPTIONS";
+const std::string cmSourceFile::propINCLUDE_DIRECTORIES =
+ "INCLUDE_DIRECTORIES";
void cmSourceFile::SetObjectLibrary(std::string const& objlib)
{
@@ -44,11 +45,13 @@ std::string cmSourceFile::GetObjectLibrary() const
return this->ObjectLibrary;
}
-std::string cmSourceFile::GetLanguage()
+std::string const& cmSourceFile::GetOrDetermineLanguage()
{
// If the language was set explicitly by the user then use it.
if (const char* lang = this->GetProperty(propLANGUAGE)) {
- return lang;
+ // Assign to member in order to return a reference.
+ this->Language = lang;
+ return this->Language;
}
// Perform computation needed to get the language if necessary.
@@ -62,7 +65,7 @@ std::string cmSourceFile::GetLanguage()
this->Location.DirectoryIsAmbiguous()) {
// Finalize the file location to get the extension and set the
// language.
- this->GetFullPath();
+ this->ResolveFullPath();
} else {
// Use the known extension to get the language if possible.
std::string ext =
@@ -71,8 +74,8 @@ std::string cmSourceFile::GetLanguage()
}
}
- // Now try to determine the language.
- return static_cast<cmSourceFile const*>(this)->GetLanguage();
+ // Use the language determined from the file extension.
+ return this->Language;
}
std::string cmSourceFile::GetLanguage() const
@@ -82,13 +85,8 @@ std::string cmSourceFile::GetLanguage() const
return lang;
}
- // If the language was determined from the source file extension use it.
- if (!this->Language.empty()) {
- return this->Language;
- }
-
- // The language is not known.
- return "";
+ // Use the language determined from the file extension.
+ return this->Language;
}
cmSourceFileLocation const& cmSourceFile::GetLocation() const
@@ -96,7 +94,7 @@ cmSourceFileLocation const& cmSourceFile::GetLocation() const
return this->Location;
}
-std::string const& cmSourceFile::GetFullPath(std::string* error)
+std::string const& cmSourceFile::ResolveFullPath(std::string* error)
{
if (this->FullPath.empty()) {
if (this->FindFullPath(error)) {
@@ -150,9 +148,7 @@ bool cmSourceFile::FindFullPath(std::string* error)
for (auto exts : extsLists) {
for (std::string const& ext : *exts) {
if (!ext.empty()) {
- std::string extPath = fullPath;
- extPath += '.';
- extPath += ext;
+ std::string extPath = cmStrCat(fullPath, '.', ext);
if (cmSystemTools::FileExists(extPath)) {
this->FullPath = extPath;
return true;
@@ -177,10 +173,8 @@ bool cmSourceFile::FindFullPath(std::string* error)
}
// Compose error
- std::string err;
- err += "Cannot find source file:\n ";
- err += lPath;
- err += "\nTried extensions";
+ std::string err =
+ cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions");
for (auto exts : extsLists) {
for (std::string const& ext : *exts) {
err += " .";
@@ -238,18 +232,55 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
void cmSourceFile::SetProperty(const std::string& prop, const char* value)
{
- this->Properties.SetProperty(prop, value);
+ if (prop == propINCLUDE_DIRECTORIES) {
+ this->IncludeDirectories.clear();
+ if (value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->IncludeDirectories.emplace_back(value, lfbt);
+ }
+ } else if (prop == propCOMPILE_OPTIONS) {
+ this->CompileOptions.clear();
+ if (value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->CompileOptions.emplace_back(value, lfbt);
+ }
+ } else if (prop == propCOMPILE_DEFINITIONS) {
+ this->CompileDefinitions.clear();
+ if (value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->CompileDefinitions.emplace_back(value, lfbt);
+ }
+ } else {
+ this->Properties.SetProperty(prop, value);
+ }
// Update IsGenerated flag
if (prop == propGENERATED) {
- this->IsGenerated = cmSystemTools::IsOn(value);
+ this->IsGenerated = cmIsOn(value);
}
}
void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
bool asString)
{
- this->Properties.AppendProperty(prop, value, asString);
+ if (prop == propINCLUDE_DIRECTORIES) {
+ if (value && *value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->IncludeDirectories.emplace_back(value, lfbt);
+ }
+ } else if (prop == propCOMPILE_OPTIONS) {
+ if (value && *value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->CompileOptions.emplace_back(value, lfbt);
+ }
+ } else if (prop == propCOMPILE_DEFINITIONS) {
+ if (value && *value) {
+ cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
+ this->CompileDefinitions.emplace_back(value, lfbt);
+ }
+ } else {
+ this->Properties.AppendProperty(prop, value, asString);
+ }
// Update IsGenerated flag
if (prop == propGENERATED) {
@@ -275,7 +306,14 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
// LOCATION property we must commit now.
if (prop == propLOCATION) {
// Commit to a location.
- this->GetFullPath();
+ this->ResolveFullPath();
+ }
+
+ // Similarly, LANGUAGE can be determined by the file extension
+ // if it is requested by the user.
+ if (prop == propLANGUAGE) {
+ // The c_str pointer is valid until `this->Language` is modified.
+ return this->GetOrDetermineLanguage().c_str();
}
// Perform the normal property lookup.
@@ -292,6 +330,37 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
return this->FullPath.c_str();
}
+ // Check for the properties with backtraces.
+ if (prop == propINCLUDE_DIRECTORIES) {
+ if (this->IncludeDirectories.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(this->IncludeDirectories, ";");
+ return output.c_str();
+ }
+
+ if (prop == propCOMPILE_OPTIONS) {
+ if (this->CompileOptions.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(this->CompileOptions, ";");
+ return output.c_str();
+ }
+
+ if (prop == propCOMPILE_DEFINITIONS) {
+ if (this->CompileDefinitions.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(this->CompileDefinitions, ";");
+ return output.c_str();
+ }
+
const char* retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
cmMakefile const* mf = this->Location.GetMakefile();
@@ -316,22 +385,22 @@ const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
{
- return cmSystemTools::IsOn(this->GetProperty(prop));
+ return cmIsOn(this->GetProperty(prop));
}
-cmCustomCommand* cmSourceFile::GetCustomCommand()
+void cmSourceFile::SetProperties(cmPropertyMap properties)
{
- return this->CustomCommand;
+ this->Properties = std::move(properties);
+
+ this->IsGenerated = this->GetPropertyAsBool(propGENERATED);
}
-cmCustomCommand const* cmSourceFile::GetCustomCommand() const
+cmCustomCommand* cmSourceFile::GetCustomCommand() const
{
- return this->CustomCommand;
+ return this->CustomCommand.get();
}
-void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
+void cmSourceFile::SetCustomCommand(std::unique_ptr<cmCustomCommand> cc)
{
- cmCustomCommand* old = this->CustomCommand;
- this->CustomCommand = cc;
- delete old;
+ this->CustomCommand = std::move(cc);
}
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index edad4c7b5..82a3625b8 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -5,14 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmCustomCommand.h"
+#include "cmListFileCache.h"
#include "cmPropertyMap.h"
#include "cmSourceFileLocation.h"
#include "cmSourceFileLocationKind.h"
-#include <string>
-#include <vector>
-
-class cmCustomCommand;
class cmMakefile;
/** \class cmSourceFile
@@ -32,17 +34,11 @@ public:
cmMakefile* mf, const std::string& name,
cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
- ~cmSourceFile();
-
- cmSourceFile(const cmSourceFile&) = delete;
- cmSourceFile& operator=(const cmSourceFile&) = delete;
-
/**
- * Get the list of the custom commands for this source file
+ * Get the custom command for this source file
*/
- cmCustomCommand* GetCustomCommand();
- cmCustomCommand const* GetCustomCommand() const;
- void SetCustomCommand(cmCustomCommand* cc);
+ cmCustomCommand* GetCustomCommand() const;
+ void SetCustomCommand(std::unique_ptr<cmCustomCommand> cc);
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
@@ -62,15 +58,31 @@ public:
/// @return Equivalent to GetPropertyAsBool("GENERATED")
bool GetIsGenerated() const { return this->IsGenerated; }
+ const std::vector<BT<std::string>>& GetCompileOptions() const
+ {
+ return this->CompileOptions;
+ }
+
+ const std::vector<BT<std::string>>& GetCompileDefinitions() const
+ {
+ return this->CompileDefinitions;
+ }
+
+ const std::vector<BT<std::string>>& GetIncludeDirectories() const
+ {
+ return this->IncludeDirectories;
+ }
+
/**
- * The full path to the file. The non-const version of this method
- * may attempt to locate the file on disk and finalize its location.
- * The const version of this method may return an empty string if
- * the non-const version has not yet been called (yes this is a
- * horrible interface, but is necessary for backwards
- * compatibility).
+ * Resolves the full path to the file. Attempts to locate the file on disk
+ * and finalizes its location.
+ */
+ std::string const& ResolveFullPath(std::string* error = nullptr);
+
+ /**
+ * The resolved full path to the file. The returned file name might be empty
+ * if the path has not yet been resolved.
*/
- std::string const& GetFullPath(std::string* error = nullptr);
std::string const& GetFullPath() const;
/**
@@ -88,7 +100,7 @@ public:
/**
* Get the language of the compiler to use for this source file.
*/
- std::string GetLanguage();
+ std::string const& GetOrDetermineLanguage();
std::string GetLanguage() const;
/**
@@ -98,8 +110,9 @@ public:
void AddDepend(const std::string& d) { this->Depends.push_back(d); }
// Get the properties
- cmPropertyMap& GetProperties() { return this->Properties; }
const cmPropertyMap& GetProperties() const { return this->Properties; }
+ // Set the properties
+ void SetProperties(cmPropertyMap properties);
/**
* Check whether the given source file location could refer to this
@@ -113,12 +126,15 @@ public:
private:
cmSourceFileLocation Location;
cmPropertyMap Properties;
- cmCustomCommand* CustomCommand = nullptr;
+ std::unique_ptr<cmCustomCommand> CustomCommand;
std::string Extension;
std::string Language;
std::string FullPath;
std::string ObjectLibrary;
std::vector<std::string> Depends;
+ std::vector<BT<std::string>> CompileOptions;
+ std::vector<BT<std::string>> CompileDefinitions;
+ std::vector<BT<std::string>> IncludeDirectories;
bool FindFullPathFailed = false;
bool IsGenerated = false;
@@ -129,6 +145,9 @@ private:
static const std::string propLANGUAGE;
static const std::string propLOCATION;
static const std::string propGENERATED;
+ static const std::string propCOMPILE_DEFINITIONS;
+ static const std::string propCOMPILE_OPTIONS;
+ static const std::string propINCLUDE_DIRECTORIES;
};
// TODO: Factor out into platform information modules.
@@ -139,6 +158,8 @@ private:
"hpj" \
"|bat)$"
+#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
+
#define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$"
#endif
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index acacba26c..df702b050 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -2,15 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSourceFileLocation.h"
-#include "cmAlgorithms.h"
+#include <cassert>
+
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include <assert.h>
-
cmSourceFileLocation::cmSourceFileLocation() = default;
cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
@@ -110,8 +110,7 @@ void cmSourceFileLocation::UpdateExtension(const std::string& name)
// Check the source tree only because a file in the build tree should
// be specified by full path at least once. We do not want this
// detection to depend on whether the project has already been built.
- tryPath = this->Makefile->GetCurrentSourceDirectory();
- tryPath += "/";
+ tryPath = cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/');
}
if (!this->Directory.empty()) {
tryPath += this->Directory;
@@ -146,8 +145,7 @@ bool cmSourceFileLocation::MatchesAmbiguousExtension(
// adding an extension.
if (!(this->Name.size() > loc.Name.size() &&
this->Name[loc.Name.size()] == '.' &&
- cmHasLiteralPrefixImpl(this->Name.c_str(), loc.Name.c_str(),
- loc.Name.size()))) {
+ cmHasPrefix(this->Name, loc.Name))) {
return false;
}
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 7e1e836a0..8c3ec9fec 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include "cmStringAlgorithms.h"
+
class cmSourceGroupInternals
{
public:
@@ -17,8 +19,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
this->Internal = new cmSourceGroupInternals;
this->SetGroupRegex(regex);
if (parentName) {
- this->FullName = parentName;
- this->FullName += "\\";
+ this->FullName = cmStrCat(parentName, '\\');
}
this->FullName += this->Name;
}
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 7c6549446..581dc5dee 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -5,11 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmsys/RegularExpression.hxx"
#include <set>
#include <string>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
class cmSourceFile;
class cmSourceGroupInternals;
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 04b4d72ec..cc62952d8 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -2,16 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSourceGroupCommand.h"
-#include <algorithm>
+#include <cstddef>
+#include <map>
#include <set>
-#include <stddef.h>
#include <utility>
+#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceGroup.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace {
+
+using ParsedArguments = std::map<std::string, std::vector<std::string>>;
+using ExpectedOptions = std::vector<std::string>;
+
const std::string kTreeOptionName = "TREE";
const std::string kPrefixOptionName = "PREFIX";
const std::string kFilesOptionName = "FILES";
@@ -20,7 +27,7 @@ const std::string kSourceGroupOptionName = "<sg_name>";
std::vector<std::string> tokenizePath(const std::string& path)
{
- return cmSystemTools::tokenize(path, "\\/");
+ return cmTokenize(path, "\\/");
}
std::string getFullFilePath(const std::string& currentPath,
@@ -29,9 +36,7 @@ std::string getFullFilePath(const std::string& currentPath,
std::string fullPath = path;
if (!cmSystemTools::FileIsFullPath(path)) {
- fullPath = currentPath;
- fullPath += "/";
- fullPath += path;
+ fullPath = cmStrCat(currentPath, '/', path);
}
return cmSystemTools::CollapseFullPath(fullPath);
@@ -54,8 +59,8 @@ bool rootIsPrefix(const std::string& root,
const std::vector<std::string>& files, std::string& error)
{
for (std::string const& file : files) {
- if (!cmSystemTools::StringStartsWith(file, root.c_str())) {
- error = "ROOT: " + root + " is not a prefix of file: " + file;
+ if (!cmHasPrefix(file, root)) {
+ error = cmStrCat("ROOT: ", root, " is not a prefix of file: ", file);
return false;
}
}
@@ -73,10 +78,18 @@ std::vector<std::string> prepareFilesPathsForTree(
for (auto const& filePath : filesPaths) {
std::string fullPath =
cmSystemTools::CollapseFullPath(filePath, currentSourceDir);
- // If provided file path is actually not a file, silently ignore it.
- if (cmSystemTools::FileExists(fullPath, /*isFile=*/true)) {
- prepared.emplace_back(std::move(fullPath));
+ // If provided file path is actually not a directory, silently ignore it.
+ if (cmSystemTools::FileIsDirectory(fullPath)) {
+ continue;
+ }
+
+ // Handle directory that doesn't exist yet.
+ if (!fullPath.empty() &&
+ (fullPath.back() == '/' || fullPath.back() == '\\')) {
+ continue;
}
+
+ prepared.emplace_back(std::move(fullPath));
}
return prepared;
@@ -93,7 +106,7 @@ bool addFilesToItsSourceGroups(const std::string& root,
std::vector<std::string> tokenizedPath;
if (!prefix.empty()) {
- tokenizedPath = tokenizePath(prefix + '/' + sgFilesPath);
+ tokenizedPath = tokenizePath(cmStrCat(prefix, '/', sgFilesPath));
} else {
tokenizedPath = tokenizePath(sgFilesPath);
}
@@ -118,13 +131,8 @@ bool addFilesToItsSourceGroups(const std::string& root,
return true;
}
-}
-
-class cmExecutionStatus;
-// cmSourceGroupCommand
-cmSourceGroupCommand::ExpectedOptions
-cmSourceGroupCommand::getExpectedOptions() const
+ExpectedOptions getExpectedOptions()
{
ExpectedOptions options;
@@ -136,16 +144,14 @@ cmSourceGroupCommand::getExpectedOptions() const
return options;
}
-bool cmSourceGroupCommand::isExpectedOption(
- const std::string& argument, const ExpectedOptions& expectedOptions)
+bool isExpectedOption(const std::string& argument,
+ const ExpectedOptions& expectedOptions)
{
- return std::find(expectedOptions.begin(), expectedOptions.end(), argument) !=
- expectedOptions.end();
+ return cmContains(expectedOptions, argument);
}
-void cmSourceGroupCommand::parseArguments(
- const std::vector<std::string>& args,
- cmSourceGroupCommand::ParsedArguments& parsedArguments)
+void parseArguments(const std::vector<std::string>& args,
+ ParsedArguments& parsedArguments)
{
const ExpectedOptions expectedOptions = getExpectedOptions();
size_t i = 0;
@@ -174,21 +180,35 @@ void cmSourceGroupCommand::parseArguments(
}
}
-bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+} // namespace
+
+static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments,
+ std::string& errorMsg);
+
+static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments,
+ std::string& errorMsg);
+
+static bool checkSingleParameterArgumentPreconditions(
+ const std::string& argument, const ParsedArguments& parsedArguments,
+ std::string& errorMsg);
+
+bool cmSourceGroupCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// If only two arguments are given, the pre-1.8 version of the
// command is being invoked.
if (args.size() == 2 && args[1] != "FILES") {
- cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]);
+ cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]);
if (!sg) {
- this->SetError("Could not create or find source group");
+ status.SetError("Could not create or find source group");
return false;
}
@@ -206,21 +226,21 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
}
if (parsedArguments.find(kTreeOptionName) != parsedArguments.end()) {
- if (!processTree(parsedArguments, errorMsg)) {
- this->SetError(errorMsg);
+ if (!processTree(mf, parsedArguments, errorMsg)) {
+ status.SetError(errorMsg);
return false;
}
} else {
if (parsedArguments.find(kSourceGroupOptionName) ==
parsedArguments.end()) {
- this->SetError("Missing source group name.");
+ status.SetError("Missing source group name.");
return false;
}
- cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]);
+ cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]);
if (!sg) {
- this->SetError("Could not create or find source group");
+ status.SetError("Could not create or find source group");
return false;
}
@@ -236,9 +256,7 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
for (auto const& filesArg : filesArguments) {
std::string src = filesArg;
if (!cmSystemTools::FileIsFullPath(src)) {
- src = this->Makefile->GetCurrentSourceDirectory();
- src += "/";
- src += filesArg;
+ src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg);
}
src = cmSystemTools::CollapseFullPath(src);
sg->AddGroupFile(src);
@@ -248,8 +266,8 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
-bool cmSourceGroupCommand::checkArgumentsPreconditions(
- const ParsedArguments& parsedArguments, std::string& errorMsg) const
+static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments,
+ std::string& errorMsg)
{
return checkSingleParameterArgumentPreconditions(
kPrefixOptionName, parsedArguments, errorMsg) &&
@@ -259,8 +277,8 @@ bool cmSourceGroupCommand::checkArgumentsPreconditions(
parsedArguments, errorMsg);
}
-bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments,
- std::string& errorMsg)
+static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments,
+ std::string& errorMsg)
{
const std::string root =
cmSystemTools::CollapseFullPath(parsedArguments[kTreeOptionName].front());
@@ -268,9 +286,8 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments,
? ""
: parsedArguments[kPrefixOptionName].front();
- const std::vector<std::string> filesVector =
- prepareFilesPathsForTree(parsedArguments[kFilesOptionName],
- this->Makefile->GetCurrentSourceDirectory());
+ const std::vector<std::string> filesVector = prepareFilesPathsForTree(
+ parsedArguments[kFilesOptionName], mf.GetCurrentSourceDirectory());
if (!rootIsPrefix(root, filesVector, errorMsg)) {
return false;
@@ -279,16 +296,15 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments,
std::set<std::string> sourceGroupPaths =
getSourceGroupFilesPaths(root, filesVector);
- return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix,
- *(this->Makefile), errorMsg);
+ return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix, mf,
+ errorMsg);
}
-bool cmSourceGroupCommand::checkSingleParameterArgumentPreconditions(
+static bool checkSingleParameterArgumentPreconditions(
const std::string& argument, const ParsedArguments& parsedArguments,
- std::string& errorMsg) const
+ std::string& errorMsg)
{
- ParsedArguments::const_iterator foundArgument =
- parsedArguments.find(argument);
+ auto foundArgument = parsedArguments.find(argument);
if (foundArgument != parsedArguments.end()) {
const std::vector<std::string>& optionArguments = foundArgument->second;
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index ec5ad329a..ad3970157 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -5,54 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <map>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmSourceGroupCommand
- * \brief Adds a cmSourceGroup to the cmMakefile.
- *
- * cmSourceGroupCommand is used to define cmSourceGroups which split up
- * source files in to named, organized groups in the generated makefiles.
- */
-class cmSourceGroupCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmSourceGroupCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- typedef std::map<std::string, std::vector<std::string>> ParsedArguments;
- typedef std::vector<std::string> ExpectedOptions;
-
- ExpectedOptions getExpectedOptions() const;
-
- bool isExpectedOption(const std::string& argument,
- const ExpectedOptions& expectedOptions);
-
- void parseArguments(const std::vector<std::string>& args,
- cmSourceGroupCommand::ParsedArguments& parsedArguments);
-
- bool processTree(ParsedArguments& parsedArguments, std::string& errorMsg);
-
- bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments,
- std::string& errorMsg) const;
- bool checkSingleParameterArgumentPreconditions(
- const std::string& argument, const ParsedArguments& parsedArguments,
- std::string& errorMsg) const;
-};
+bool cmSourceGroupCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index fa7df0b2c..f9b5ed1c0 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -2,38 +2,37 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmState.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCacheManager.h"
#include "cmCommand.h"
#include "cmDefinitions.h"
-#include "cmDisallowedCommand.h"
+#include "cmExecutionStatus.h"
#include "cmGlobVerificationManager.h"
#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmUnexpectedCommand.h"
#include "cmake.h"
cmState::cmState()
{
- this->CacheManager = new cmCacheManager;
- this->GlobVerificationManager = new cmGlobVerificationManager;
+ this->CacheManager = cm::make_unique<cmCacheManager>();
+ this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
}
-cmState::~cmState()
-{
- delete this->CacheManager;
- delete this->GlobVerificationManager;
- cmDeleteAll(this->BuiltinCommands);
- cmDeleteAll(this->ScriptedCommands);
-}
+cmState::~cmState() = default;
const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
{
@@ -267,7 +266,7 @@ void cmState::RemoveCacheEntryProperty(std::string const& key,
cmStateSnapshot cmState::Reset()
{
- this->GlobalProperties.clear();
+ this->GlobalProperties.Clear();
this->PropertyDefinitions.clear();
this->GlobVerificationManager->Reset();
@@ -289,7 +288,7 @@ cmStateSnapshot cmState::Reset()
it->LinkDirectoriesBacktraces.clear();
it->DirectoryEnd = pos;
it->NormalTargetNames.clear();
- it->Properties.clear();
+ it->Properties.Clear();
it->Children.clear();
}
@@ -310,8 +309,8 @@ cmStateSnapshot cmState::Reset()
pos->Parent = this->VarTree.Root();
pos->Root = this->VarTree.Root();
- pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
- pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
+ pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir);
+ pos->Vars->Set("CMAKE_BINARY_DIR", binDir);
}
this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
@@ -326,7 +325,7 @@ cmStateSnapshot cmState::Reset()
this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
void cmState::DefineProperty(const std::string& name,
@@ -352,8 +351,7 @@ cmPropertyDefinition const* cmState::GetPropertyDefinition(
bool cmState::IsPropertyDefined(const std::string& name,
cmProperty::ScopeType scope) const
{
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
- this->PropertyDefinitions.find(scope);
+ auto it = this->PropertyDefinitions.find(scope);
if (it == this->PropertyDefinitions.end()) {
return false;
}
@@ -363,8 +361,7 @@ bool cmState::IsPropertyDefined(const std::string& name,
bool cmState::IsPropertyChained(const std::string& name,
cmProperty::ScopeType scope) const
{
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
- this->PropertyDefinitions.find(scope);
+ auto it = this->PropertyDefinitions.find(scope);
if (it == this->PropertyDefinitions.end()) {
return false;
}
@@ -373,8 +370,8 @@ bool cmState::IsPropertyChained(const std::string& name,
void cmState::SetLanguageEnabled(std::string const& l)
{
- std::vector<std::string>::iterator it = std::lower_bound(
- this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l);
+ auto it = std::lower_bound(this->EnabledLanguages.begin(),
+ this->EnabledLanguages.end(), l);
if (it == this->EnabledLanguages.end() || *it != l) {
this->EnabledLanguages.insert(it, l);
}
@@ -421,61 +418,107 @@ void cmState::SetIsGeneratorMultiConfig(bool b)
this->IsGeneratorMultiConfig = b;
}
-void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
+void cmState::AddBuiltinCommand(std::string const& name,
+ std::unique_ptr<cmCommand> command)
+{
+ this->AddBuiltinCommand(name, cmLegacyCommandWrapper(std::move(command)));
+}
+
+void cmState::AddBuiltinCommand(std::string const& name, Command command)
{
assert(name == cmSystemTools::LowerCase(name));
assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
- this->BuiltinCommands.insert(std::make_pair(name, command));
+ this->BuiltinCommands.emplace(name, std::move(command));
}
-void cmState::AddDisallowedCommand(std::string const& name, cmCommand* command,
+static bool InvokeBuiltinCommand(cmState::BuiltinCommand command,
+ std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status)
+{
+ cmMakefile& mf = status.GetMakefile();
+ std::vector<std::string> expandedArguments;
+ if (!mf.ExpandArguments(args, expandedArguments)) {
+ // There was an error expanding arguments. It was already
+ // reported, so we can skip this command without error.
+ return true;
+ }
+ return command(expandedArguments, status);
+}
+
+void cmState::AddBuiltinCommand(std::string const& name,
+ BuiltinCommand command)
+{
+ this->AddBuiltinCommand(
+ name,
+ [command](const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus& status) -> bool {
+ return InvokeBuiltinCommand(command, args, status);
+ });
+}
+
+void cmState::AddDisallowedCommand(std::string const& name,
+ BuiltinCommand command,
cmPolicies::PolicyID policy,
const char* message)
{
- this->AddBuiltinCommand(name,
- new cmDisallowedCommand(command, policy, message));
+ this->AddBuiltinCommand(
+ name,
+ [command, policy, message](const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus& status) -> bool {
+ cmMakefile& mf = status.GetMakefile();
+ switch (mf.GetPolicyStatus(policy)) {
+ case cmPolicies::WARN:
+ mf.IssueMessage(MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(policy));
+ break;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ mf.IssueMessage(MessageType::FATAL_ERROR, message);
+ return true;
+ }
+ return InvokeBuiltinCommand(command, args, status);
+ });
}
void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
- this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error));
+ this->AddBuiltinCommand(
+ name,
+ [name, error](std::vector<cmListFileArgument> const&,
+ cmExecutionStatus& status) -> bool {
+ const char* versionValue =
+ status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
+ if (name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
+ return true;
+ }
+ status.SetError(error);
+ return false;
+ });
}
-void cmState::AddScriptedCommand(std::string const& name, cmCommand* command)
+void cmState::AddScriptedCommand(std::string const& name, Command command)
{
std::string sName = cmSystemTools::LowerCase(name);
// if the command already exists, give a new name to the old command.
- if (cmCommand* oldCmd = this->GetCommand(sName)) {
- std::string const newName = "_" + sName;
- std::map<std::string, cmCommand*>::iterator pos =
- this->ScriptedCommands.find(newName);
- if (pos != this->ScriptedCommands.end()) {
- delete pos->second;
- this->ScriptedCommands.erase(pos);
- }
- this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone()));
+ if (Command oldCmd = this->GetCommandByExactName(sName)) {
+ this->ScriptedCommands["_" + sName] = oldCmd;
}
- // if the command already exists, free the old one
- std::map<std::string, cmCommand*>::iterator pos =
- this->ScriptedCommands.find(sName);
- if (pos != this->ScriptedCommands.end()) {
- delete pos->second;
- this->ScriptedCommands.erase(pos);
- }
- this->ScriptedCommands.insert(std::make_pair(sName, command));
+ this->ScriptedCommands[sName] = std::move(command);
}
-cmCommand* cmState::GetCommand(std::string const& name) const
+cmState::Command cmState::GetCommand(std::string const& name) const
{
return GetCommandByExactName(cmSystemTools::LowerCase(name));
}
-cmCommand* cmState::GetCommandByExactName(std::string const& name) const
+cmState::Command cmState::GetCommandByExactName(std::string const& name) const
{
- std::map<std::string, cmCommand*>::const_iterator pos;
- pos = this->ScriptedCommands.find(name);
+ auto pos = this->ScriptedCommands.find(name);
if (pos != this->ScriptedCommands.end()) {
return pos->second;
}
@@ -506,16 +549,11 @@ std::vector<std::string> cmState::GetCommandNames() const
void cmState::RemoveBuiltinCommand(std::string const& name)
{
assert(name == cmSystemTools::LowerCase(name));
- std::map<std::string, cmCommand*>::iterator i =
- this->BuiltinCommands.find(name);
- assert(i != this->BuiltinCommands.end());
- delete i->second;
- this->BuiltinCommands.erase(i);
+ this->BuiltinCommands.erase(name);
}
void cmState::RemoveUserDefinedCommands()
{
- cmDeleteAll(this->ScriptedCommands);
this->ScriptedCommands.clear();
}
@@ -584,7 +622,7 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
- return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
+ return cmIsOn(this->GetGlobalProperty(prop));
}
void cmState::SetSourceDirectory(std::string const& sourceDirectory)
@@ -750,7 +788,7 @@ cmStateSnapshot cmState::CreateBaseSnapshot()
assert(pos->Vars.IsValid());
pos->Parent = this->VarTree.Root();
pos->Root = this->VarTree.Root();
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
@@ -803,7 +841,7 @@ cmStateSnapshot cmState::CreateFunctionCallSnapshot(
cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
pos->Parent = origin;
pos->Vars = this->VarTree.Push(origin);
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreateMacroCallSnapshot(
@@ -818,7 +856,7 @@ cmStateSnapshot cmState::CreateMacroCallSnapshot(
assert(originSnapshot.Position->Vars.IsValid());
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreateIncludeFileSnapshot(
@@ -833,7 +871,7 @@ cmStateSnapshot cmState::CreateIncludeFileSnapshot(
assert(originSnapshot.Position->Vars.IsValid());
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreateVariableScopeSnapshot(
@@ -851,7 +889,7 @@ cmStateSnapshot cmState::CreateVariableScopeSnapshot(
pos->Parent = origin;
pos->Vars = this->VarTree.Push(origin);
assert(pos->Vars.IsValid());
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreateInlineListFileSnapshot(
@@ -865,7 +903,7 @@ cmStateSnapshot cmState::CreateInlineListFileSnapshot(
originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
@@ -877,7 +915,7 @@ cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
pos->Keep = false;
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
- return cmStateSnapshot(this, pos);
+ return { this, pos };
}
cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot)
@@ -909,7 +947,7 @@ cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot)
this->SnapshotData.Pop(pos);
}
- return cmStateSnapshot(this, prevPos);
+ return { this, prevPos };
}
static bool ParseEntryWithoutType(const std::string& entry, std::string& var,
diff --git a/Source/cmState.h b/Source/cmState.h
index 6abe71c0b..a7ca015c1 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -5,7 +5,9 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <functional>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -26,6 +28,7 @@ class cmGlobVerificationManager;
class cmPropertyDefinition;
class cmStateSnapshot;
class cmMessenger;
+class cmExecutionStatus;
class cmState
{
@@ -140,16 +143,24 @@ public:
bool GetIsGeneratorMultiConfig() const;
void SetIsGeneratorMultiConfig(bool b);
+ using Command = std::function<bool(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus&)>;
+ using BuiltinCommand = bool (*)(std::vector<std::string> const&,
+ cmExecutionStatus&);
+
// Returns a command from its name, case insensitive, or nullptr
- cmCommand* GetCommand(std::string const& name) const;
+ Command GetCommand(std::string const& name) const;
// Returns a command from its name, or nullptr
- cmCommand* GetCommandByExactName(std::string const& name) const;
+ Command GetCommandByExactName(std::string const& name) const;
- void AddBuiltinCommand(std::string const& name, cmCommand* command);
- void AddDisallowedCommand(std::string const& name, cmCommand* command,
+ void AddBuiltinCommand(std::string const& name,
+ std::unique_ptr<cmCommand> command);
+ void AddBuiltinCommand(std::string const& name, Command command);
+ void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
+ void AddDisallowedCommand(std::string const& name, BuiltinCommand command,
cmPolicies::PolicyID policy, const char* message);
void AddUnexpectedCommand(std::string const& name, const char* error);
- void AddScriptedCommand(std::string const& name, cmCommand* command);
+ void AddScriptedCommand(std::string const& name, Command command);
void RemoveBuiltinCommand(std::string const& name);
void RemoveUserDefinedCommands();
std::vector<std::string> GetCommandNames() const;
@@ -208,11 +219,11 @@ private:
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
std::vector<std::string> EnabledLanguages;
- std::map<std::string, cmCommand*> BuiltinCommands;
- std::map<std::string, cmCommand*> ScriptedCommands;
+ std::map<std::string, Command> BuiltinCommands;
+ std::map<std::string, Command> ScriptedCommands;
cmPropertyMap GlobalProperties;
- cmCacheManager* CacheManager;
- cmGlobVerificationManager* GlobVerificationManager;
+ std::unique_ptr<cmCacheManager> CacheManager;
+ std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>
BuildsystemDirectory;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 182d3fe73..1262f53d9 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -4,9 +4,10 @@
#include "cmStateDirectory.h"
#include <algorithm>
-#include <assert.h>
-#include <iterator>
-#include <utility>
+#include <cassert>
+#include <vector>
+
+#include <cm/iterator>
#include "cmAlgorithms.h"
#include "cmProperty.h"
@@ -175,11 +176,9 @@ cmStateDirectory::cmStateDirectory(
template <typename T, typename U>
cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
{
- std::vector<std::string>::const_iterator end =
- content.begin() + contentEndPosition;
+ auto end = content.begin() + contentEndPosition;
- std::vector<std::string>::const_reverse_iterator rbegin =
- cmMakeReverseIterator(end);
+ auto rbegin = cm::make_reverse_iterator(end);
rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
return cmMakeRange(rbegin.base(), end);
@@ -189,17 +188,14 @@ template <typename T, typename U, typename V>
cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces,
V contentEndPosition)
{
- std::vector<std::string>::const_iterator entryEnd =
- content.begin() + contentEndPosition;
+ auto entryEnd = content.begin() + contentEndPosition;
- std::vector<std::string>::const_reverse_iterator rbegin =
- cmMakeReverseIterator(entryEnd);
+ auto rbegin = cm::make_reverse_iterator(entryEnd);
rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
- std::vector<cmListFileBacktrace>::const_iterator it =
- backtraces.begin() + std::distance(content.begin(), rbegin.base());
+ auto it = backtraces.begin() + std::distance(content.begin(), rbegin.base());
- std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end();
+ auto end = backtraces.end();
return cmMakeRange(it, end);
}
@@ -271,22 +267,17 @@ void cmStateDirectory::AppendIncludeDirectoriesEntry(
void cmStateDirectory::PrependIncludeDirectoriesEntry(
const std::string& vec, const cmListFileBacktrace& lfbt)
{
- std::vector<std::string>::iterator entryEnd =
- this->DirectoryState->IncludeDirectories.begin() +
+ auto entryEnd = this->DirectoryState->IncludeDirectories.begin() +
this->Snapshot_.Position->IncludeDirectoryPosition;
- std::vector<std::string>::reverse_iterator rend =
- this->DirectoryState->IncludeDirectories.rend();
- std::vector<std::string>::reverse_iterator rbegin =
- cmMakeReverseIterator(entryEnd);
+ auto rend = this->DirectoryState->IncludeDirectories.rend();
+ auto rbegin = cm::make_reverse_iterator(entryEnd);
rbegin = std::find(rbegin, rend, cmPropertySentinal);
- std::vector<std::string>::iterator entryIt = rbegin.base();
- std::vector<std::string>::iterator entryBegin =
- this->DirectoryState->IncludeDirectories.begin();
+ auto entryIt = rbegin.base();
+ auto entryBegin = this->DirectoryState->IncludeDirectories.begin();
- std::vector<cmListFileBacktrace>::iterator btIt =
- this->DirectoryState->IncludeDirectoryBacktraces.begin() +
+ auto btIt = this->DirectoryState->IncludeDirectoryBacktraces.begin() +
std::distance(entryBegin, entryIt);
this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
@@ -446,22 +437,17 @@ void cmStateDirectory::AppendLinkDirectoriesEntry(
void cmStateDirectory::PrependLinkDirectoriesEntry(
const std::string& vec, const cmListFileBacktrace& lfbt)
{
- std::vector<std::string>::iterator entryEnd =
- this->DirectoryState->LinkDirectories.begin() +
+ auto entryEnd = this->DirectoryState->LinkDirectories.begin() +
this->Snapshot_.Position->LinkDirectoriesPosition;
- std::vector<std::string>::reverse_iterator rend =
- this->DirectoryState->LinkDirectories.rend();
- std::vector<std::string>::reverse_iterator rbegin =
- cmMakeReverseIterator(entryEnd);
+ auto rend = this->DirectoryState->LinkDirectories.rend();
+ auto rbegin = cm::make_reverse_iterator(entryEnd);
rbegin = std::find(rbegin, rend, cmPropertySentinal);
- std::vector<std::string>::iterator entryIt = rbegin.base();
- std::vector<std::string>::iterator entryBegin =
- this->DirectoryState->LinkDirectories.begin();
+ auto entryIt = rbegin.base();
+ auto entryBegin = this->DirectoryState->LinkDirectories.begin();
- std::vector<cmListFileBacktrace>::iterator btIt =
- this->DirectoryState->LinkDirectoriesBacktraces.begin() +
+ auto btIt = this->DirectoryState->LinkDirectoriesBacktraces.begin() +
std::distance(entryBegin, entryIt);
this->DirectoryState->LinkDirectories.insert(entryIt, vec);
@@ -662,17 +648,12 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
{
- return cmSystemTools::IsOn(this->GetProperty(prop));
+ return cmIsOn(this->GetProperty(prop));
}
std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
{
- std::vector<std::string> keys;
- keys.reserve(this->DirectoryState->Properties.size());
- for (auto const& it : this->DirectoryState->Properties) {
- keys.push_back(it.first);
- }
- return keys;
+ return this->DirectoryState->Properties.GetKeys();
}
void cmStateDirectory::AddNormalTargetName(std::string const& name)
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 69565940d..fe15563cb 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -14,6 +14,7 @@
#include "cmListFileCache.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
class cmStateDirectory
{
diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h
index ec0ed6c93..4efaf97eb 100644
--- a/Source/cmStatePrivate.h
+++ b/Source/cmStatePrivate.h
@@ -48,7 +48,7 @@ struct cmStateDetail::SnapshotDataType
struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap
{
- typedef cmPolicies::PolicyMap derived;
+ using derived = cmPolicies::PolicyMap;
PolicyStackEntry(bool w = false)
: Weak(w)
{
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 63bec710b..645907c21 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -4,11 +4,11 @@
#include "cmStateSnapshot.h"
#include <algorithm>
-#include <assert.h>
-#include <iterator>
+#include <cassert>
#include <string>
-#include "cmAlgorithms.h"
+#include <cm/iterator>
+
#include "cmDefinitions.h"
#include "cmListFileCache.h"
#include "cmPropertyMap.h"
@@ -66,8 +66,7 @@ bool cmStateSnapshot::IsValid() const
cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectory() const
{
- return cmStateSnapshot(this->State,
- this->Position->BuildSystemDirectory->DirectoryEnd);
+ return { this->State, this->Position->BuildSystemDirectory->DirectoryEnd };
}
cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectoryParent() const
@@ -126,7 +125,7 @@ cmStateSnapshot cmStateSnapshot::GetCallStackBottom() const
pos != this->State->SnapshotData.Root()) {
++pos;
}
- return cmStateSnapshot(this->State, pos);
+ return { this->State, pos };
}
void cmStateSnapshot::PushPolicy(cmPolicies::PolicyMap const& entry, bool weak)
@@ -222,14 +221,14 @@ bool cmStateSnapshot::IsInitialized(std::string const& name) const
}
void cmStateSnapshot::SetDefinition(std::string const& name,
- std::string const& value)
+ cm::string_view value)
{
- this->Position->Vars->Set(name, value.c_str());
+ this->Position->Vars->Set(name, value);
}
void cmStateSnapshot::RemoveDefinition(std::string const& name)
{
- this->Position->Vars->Set(name, nullptr);
+ this->Position->Vars->Unset(name);
}
std::vector<std::string> cmStateSnapshot::UnusedKeys() const
@@ -264,7 +263,11 @@ bool cmStateSnapshot::RaiseScope(std::string const& var, const char* varDef)
cmDefinitions::Raise(var, this->Position->Vars, this->Position->Root);
// Now update the definition in the parent scope.
- this->Position->Parent->Set(var, varDef);
+ if (varDef) {
+ this->Position->Parent->Set(var, varDef);
+ } else {
+ this->Position->Parent->Unset(var);
+ }
return true;
}
@@ -273,22 +276,18 @@ void InitializeContentFromParent(T& parentContent, T& thisContent,
U& parentBacktraces, U& thisBacktraces,
V& contentEndPosition)
{
- std::vector<std::string>::const_iterator parentBegin = parentContent.begin();
- std::vector<std::string>::const_iterator parentEnd = parentContent.end();
+ auto parentBegin = parentContent.begin();
+ auto parentEnd = parentContent.end();
- std::vector<std::string>::const_reverse_iterator parentRbegin =
- cmMakeReverseIterator(parentEnd);
- std::vector<std::string>::const_reverse_iterator parentRend =
- parentContent.rend();
+ auto parentRbegin = cm::make_reverse_iterator(parentEnd);
+ auto parentRend = parentContent.rend();
parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal);
- std::vector<std::string>::const_iterator parentIt = parentRbegin.base();
+ auto parentIt = parentRbegin.base();
thisContent = std::vector<std::string>(parentIt, parentEnd);
- std::vector<cmListFileBacktrace>::const_iterator btIt =
- parentBacktraces.begin() + std::distance(parentBegin, parentIt);
- std::vector<cmListFileBacktrace>::const_iterator btEnd =
- parentBacktraces.end();
+ auto btIt = parentBacktraces.begin() + std::distance(parentBegin, parentIt);
+ auto btEnd = parentBacktraces.end();
thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd);
@@ -324,7 +323,7 @@ void cmStateSnapshot::SetDefaultDefinitions()
#if defined(__CYGWIN__)
std::string legacy;
if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) &&
- cmSystemTools::IsOn(legacy.c_str())) {
+ cmIsOn(legacy.c_str())) {
this->SetDefinition("WIN32", "1");
this->SetDefinition("CMAKE_HOST_WIN32", "1");
}
@@ -422,7 +421,7 @@ cmState* cmStateSnapshot::GetState() const
cmStateDirectory cmStateSnapshot::GetDirectory() const
{
- return cmStateDirectory(this->Position->BuildSystemDirectory, *this);
+ return { this->Position->BuildSystemDirectory, *this };
}
void cmStateSnapshot::SetProjectName(const std::string& name)
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index c315f4851..021fd53c1 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -9,6 +9,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmLinkedTree.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
@@ -24,7 +26,7 @@ public:
std::string const* GetDefinition(std::string const& name) const;
bool IsInitialized(std::string const& name) const;
- void SetDefinition(std::string const& name, std::string const& value);
+ void SetDefinition(std::string const& name, cm::string_view value);
void RemoveDefinition(std::string const& name);
std::vector<std::string> UnusedKeys() const;
std::vector<std::string> ClosureKeys() const;
diff --git a/Source/cmStateTypes.h b/Source/cmStateTypes.h
index 7d6158e33..d089ea73d 100644
--- a/Source/cmStateTypes.h
+++ b/Source/cmStateTypes.h
@@ -10,7 +10,7 @@
namespace cmStateDetail {
struct SnapshotDataType;
-typedef cmLinkedTree<cmStateDetail::SnapshotDataType>::iterator PositionType;
+using PositionType = cmLinkedTree<cmStateDetail::SnapshotDataType>::iterator;
}
namespace cmStateEnums {
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index 49bad7870..073f4c940 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -5,10 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_static_string_view.hxx"
-#include "cm_string_view.hxx"
-
#include <algorithm>
+#include <cstddef>
#include <functional>
#include <initializer_list>
#include <memory>
@@ -17,6 +15,10 @@
#include <type_traits>
#include <utility>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
namespace cm {
class String;
@@ -713,7 +715,7 @@ template <typename T>
struct StringAdd
{
static const bool value = AsStringView<T>::value;
- typedef string_view temp_type;
+ using temp_type = string_view;
template <typename S>
static temp_type temp(S&& s)
{
@@ -724,7 +726,7 @@ struct StringAdd
template <typename L, typename R>
struct StringAdd<StringOpPlus<L, R>> : std::true_type
{
- typedef StringOpPlus<L, R> const& temp_type;
+ using temp_type = StringOpPlus<L, R> const&;
static temp_type temp(temp_type s) { return s; }
};
@@ -801,8 +803,8 @@ namespace std {
template <>
struct hash<cm::String>
{
- typedef cm::String argument_type;
- typedef size_t result_type;
+ using argument_type = cm::String;
+ using result_type = size_t;
result_type operator()(argument_type const& s) const noexcept
{
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
new file mode 100644
index 000000000..bb6dcd734
--- /dev/null
+++ b/Source/cmStringAlgorithms.cxx
@@ -0,0 +1,325 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmStringAlgorithms.h"
+
+#include <algorithm>
+#include <cerrno>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+
+std::string cmTrimWhitespace(cm::string_view str)
+{
+ auto start = str.begin();
+ while (start != str.end() && cmIsSpace(*start)) {
+ ++start;
+ }
+ if (start == str.end()) {
+ return std::string();
+ }
+ auto stop = str.end() - 1;
+ while (cmIsSpace(*stop)) {
+ --stop;
+ }
+ return std::string(start, stop + 1);
+}
+
+std::string cmRemoveQuotes(cm::string_view str)
+{
+ // We process only strings that have two quotes at least.
+ // Also front() and back() are only defined behavior on non empty strings.
+ if (str.size() >= 2 && //
+ str.front() == '"' && //
+ str.back() == '"') {
+ // Remove a quote from the front and back
+ str.remove_prefix(1);
+ str.remove_suffix(1);
+ }
+ return std::string(str);
+}
+
+std::string cmEscapeQuotes(cm::string_view str)
+{
+ std::string result;
+ result.reserve(str.size());
+ for (const char ch : str) {
+ if (ch == '"') {
+ result += '\\';
+ }
+ result += ch;
+ }
+ return result;
+}
+
+std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
+{
+ std::vector<std::string> tokens;
+ cm::string_view::size_type tokend = 0;
+
+ do {
+ cm::string_view::size_type tokstart = str.find_first_not_of(sep, tokend);
+ if (tokstart == cm::string_view::npos) {
+ break; // no more tokens
+ }
+ tokend = str.find_first_of(sep, tokstart);
+ if (tokend == cm::string_view::npos) {
+ tokens.emplace_back(str.substr(tokstart));
+ } else {
+ tokens.emplace_back(str.substr(tokstart, tokend - tokstart));
+ }
+ } while (tokend != cm::string_view::npos);
+
+ if (tokens.empty()) {
+ tokens.emplace_back();
+ }
+ return tokens;
+}
+
+void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
+ bool emptyArgs)
+{
+ // If argument is empty, it is an empty list.
+ if (!emptyArgs && arg.empty()) {
+ return;
+ }
+
+ // if there are no ; in the name then just copy the current string
+ if (arg.find(';') == cm::string_view::npos) {
+ argsOut.emplace_back(arg);
+ return;
+ }
+
+ std::string newArg;
+ // Break the string at non-escaped semicolons not nested in [].
+ int squareNesting = 0;
+ cm::string_view::iterator last = arg.begin();
+ cm::string_view::iterator const cend = arg.end();
+ for (cm::string_view::iterator c = last; c != cend; ++c) {
+ switch (*c) {
+ case '\\': {
+ // We only want to allow escaping of semicolons. Other
+ // escapes should not be processed here.
+ cm::string_view::iterator cnext = c + 1;
+ if ((cnext != cend) && *cnext == ';') {
+ newArg.append(last, c);
+ // Skip over the escape character
+ last = cnext;
+ c = cnext;
+ }
+ } break;
+ case '[': {
+ ++squareNesting;
+ } break;
+ case ']': {
+ --squareNesting;
+ } break;
+ case ';': {
+ // Break the string here if we are not nested inside square
+ // brackets.
+ if (squareNesting == 0) {
+ newArg.append(last, c);
+ // Skip over the semicolon
+ last = c + 1;
+ if (!newArg.empty() || emptyArgs) {
+ // Add the last argument if the string is not empty.
+ argsOut.push_back(newArg);
+ newArg.clear();
+ }
+ }
+ } break;
+ default: {
+ // Just append this character.
+ } break;
+ }
+ }
+ newArg.append(last, cend);
+ if (!newArg.empty() || emptyArgs) {
+ // Add the last argument if the string is not empty.
+ argsOut.push_back(std::move(newArg));
+ }
+}
+
+std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs)
+{
+ std::vector<std::string> argsOut;
+ cmExpandList(arg, argsOut, emptyArgs);
+ return argsOut;
+}
+
+namespace {
+template <std::size_t N, typename T>
+inline void MakeDigits(cm::string_view& view, char (&digits)[N],
+ const char* pattern, T value)
+{
+ int res = std::snprintf(digits, N, pattern, value);
+ if (res > 0 && res < static_cast<int>(N)) {
+ view = cm::string_view(digits, static_cast<std::size_t>(res));
+ }
+}
+} // unnamed namespace
+
+cmAlphaNum::cmAlphaNum(int val)
+{
+ MakeDigits(View_, Digits_, "%i", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned int val)
+{
+ MakeDigits(View_, Digits_, "%u", val);
+}
+
+cmAlphaNum::cmAlphaNum(long int val)
+{
+ MakeDigits(View_, Digits_, "%li", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned long int val)
+{
+ MakeDigits(View_, Digits_, "%lu", val);
+}
+
+cmAlphaNum::cmAlphaNum(long long int val)
+{
+ MakeDigits(View_, Digits_, "%lli", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned long long int val)
+{
+ MakeDigits(View_, Digits_, "%llu", val);
+}
+
+cmAlphaNum::cmAlphaNum(float val)
+{
+ MakeDigits(View_, Digits_, "%g", static_cast<double>(val));
+}
+
+cmAlphaNum::cmAlphaNum(double val)
+{
+ MakeDigits(View_, Digits_, "%g", val);
+}
+
+std::string cmCatViews(std::initializer_list<cm::string_view> views)
+{
+ std::size_t total_size = 0;
+ for (cm::string_view const& view : views) {
+ total_size += view.size();
+ }
+
+ std::string result(total_size, '\0');
+ std::string::iterator sit = result.begin();
+ for (cm::string_view const& view : views) {
+ sit = std::copy_n(view.data(), view.size(), sit);
+ }
+ return result;
+}
+
+bool cmIsInternallyOn(cm::string_view val)
+{
+ return (val.size() == 4) && //
+ (val[0] == 'I' || val[0] == 'i') && //
+ (val[1] == '_') && //
+ (val[2] == 'O' || val[2] == 'o') && //
+ (val[3] == 'N' || val[3] == 'n');
+}
+
+bool cmIsNOTFOUND(cm::string_view val)
+{
+ return (val == "NOTFOUND") || cmHasLiteralSuffix(val, "-NOTFOUND");
+}
+
+bool cmIsOn(cm::string_view val)
+{
+ switch (val.size()) {
+ case 1:
+ return val[0] == '1' || val[0] == 'Y' || val[0] == 'y';
+ case 2:
+ return //
+ (val[0] == 'O' || val[0] == 'o') && //
+ (val[1] == 'N' || val[1] == 'n');
+ case 3:
+ return //
+ (val[0] == 'Y' || val[0] == 'y') && //
+ (val[1] == 'E' || val[1] == 'e') && //
+ (val[2] == 'S' || val[2] == 's');
+ case 4:
+ return //
+ (val[0] == 'T' || val[0] == 't') && //
+ (val[1] == 'R' || val[1] == 'r') && //
+ (val[2] == 'U' || val[2] == 'u') && //
+ (val[3] == 'E' || val[3] == 'e');
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool cmIsOff(cm::string_view val)
+{
+ switch (val.size()) {
+ case 0:
+ return true;
+ case 1:
+ return val[0] == '0' || val[0] == 'N' || val[0] == 'n';
+ case 2:
+ return //
+ (val[0] == 'N' || val[0] == 'n') && //
+ (val[1] == 'O' || val[1] == 'o');
+ case 3:
+ return //
+ (val[0] == 'O' || val[0] == 'o') && //
+ (val[1] == 'F' || val[1] == 'f') && //
+ (val[2] == 'F' || val[2] == 'f');
+ case 5:
+ return //
+ (val[0] == 'F' || val[0] == 'f') && //
+ (val[1] == 'A' || val[1] == 'a') && //
+ (val[2] == 'L' || val[2] == 'l') && //
+ (val[3] == 'S' || val[3] == 's') && //
+ (val[4] == 'E' || val[4] == 'e');
+ case 6:
+ return //
+ (val[0] == 'I' || val[0] == 'i') && //
+ (val[1] == 'G' || val[1] == 'g') && //
+ (val[2] == 'N' || val[2] == 'n') && //
+ (val[3] == 'O' || val[3] == 'o') && //
+ (val[4] == 'R' || val[4] == 'r') && //
+ (val[5] == 'E' || val[5] == 'e');
+ default:
+ break;
+ }
+
+ return cmIsNOTFOUND(val);
+}
+
+bool cmStrToLong(const char* str, long* value)
+{
+ errno = 0;
+ char* endp;
+ *value = strtol(str, &endp, 10);
+ return (*endp == '\0') && (endp != str) && (errno == 0);
+}
+
+bool cmStrToLong(std::string const& str, long* value)
+{
+ return cmStrToLong(str.c_str(), value);
+}
+
+bool cmStrToULong(const char* str, unsigned long* value)
+{
+ errno = 0;
+ char* endp;
+ while (cmIsSpace(*str)) {
+ ++str;
+ }
+ if (*str == '-') {
+ return false;
+ }
+ *value = strtoul(str, &endp, 10);
+ return (*endp == '\0') && (endp != str) && (errno == 0);
+}
+
+bool cmStrToULong(std::string const& str, unsigned long* value)
+{
+ return cmStrToULong(str.c_str(), value);
+}
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
new file mode 100644
index 000000000..0e405dea6
--- /dev/null
+++ b/Source/cmStringAlgorithms.h
@@ -0,0 +1,294 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmStringAlgorithms_h
+#define cmStringAlgorithms_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cctype>
+#include <cstring>
+#include <initializer_list>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/string_view>
+
+#include "cmRange.h"
+
+/** String range type. */
+using cmStringRange = cmRange<std::vector<std::string>::const_iterator>;
+
+/** Callable string comparison struct. */
+struct cmStrCmp
+{
+ cmStrCmp(std::string str)
+ : Test_(std::move(str))
+ {
+ }
+
+ bool operator()(cm::string_view sv) const { return Test_ == sv; }
+
+private:
+ std::string const Test_;
+};
+
+/** Returns true if the character @a ch is a whitespace character. **/
+inline bool cmIsSpace(char ch)
+{
+ return ((ch & 0x80) == 0) && std::isspace(ch);
+}
+
+/** Returns a string that has whitespace removed from the start and the end. */
+std::string cmTrimWhitespace(cm::string_view str);
+
+/** Returns a string that has quotes removed from the start and the end. */
+std::string cmRemoveQuotes(cm::string_view str);
+
+/** Escape quotes in a string. */
+std::string cmEscapeQuotes(cm::string_view str);
+
+/** Joins elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmJoin(Range const& rng, cm::string_view separator)
+{
+ if (rng.empty()) {
+ return std::string();
+ }
+
+ std::ostringstream os;
+ auto it = rng.begin();
+ auto const end = rng.end();
+ os << *it;
+ while (++it != end) {
+ os << separator << *it;
+ }
+ return os.str();
+}
+
+/** Extract tokens that are separated by any of the characters in @a sep. */
+std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
+
+/**
+ * Expand the ; separated string @a arg into multiple arguments.
+ * All found arguments are appended to @a argsOut.
+ */
+void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
+ bool emptyArgs = false);
+
+/**
+ * Expand out any arguments in the string range [@a first, @a last) that have
+ * ; separated strings into multiple arguments. All found arguments are
+ * appended to @a argsOut.
+ */
+template <class InputIt>
+void cmExpandLists(InputIt first, InputIt last,
+ std::vector<std::string>& argsOut)
+{
+ for (; first != last; ++first) {
+ ExpandList(*first, argsOut);
+ }
+}
+
+/**
+ * Same as cmExpandList but a new vector is created containing
+ * the expanded arguments from the string @a arg.
+ */
+std::vector<std::string> cmExpandedList(cm::string_view arg,
+ bool emptyArgs = false);
+
+/**
+ * Same as cmExpandList but a new vector is created containing the expanded
+ * versions of all arguments in the string range [@a first, @a last).
+ */
+template <class InputIt>
+std::vector<std::string> cmExpandedLists(InputIt first, InputIt last)
+{
+ std::vector<std::string> argsOut;
+ for (; first != last; ++first) {
+ cmExpandList(*first, argsOut);
+ }
+ return argsOut;
+}
+
+/** Concatenate string pieces into a single string. */
+std::string cmCatViews(std::initializer_list<cm::string_view> views);
+
+/** Utility class for cmStrCat. */
+class cmAlphaNum
+{
+public:
+ cmAlphaNum(cm::string_view view)
+ : View_(view)
+ {
+ }
+ cmAlphaNum(std::string const& str)
+ : View_(str)
+ {
+ }
+ cmAlphaNum(const char* str)
+ : View_(str)
+ {
+ }
+ cmAlphaNum(char ch)
+ : View_(Digits_, 1)
+ {
+ Digits_[0] = ch;
+ }
+ cmAlphaNum(int val);
+ cmAlphaNum(unsigned int val);
+ cmAlphaNum(long int val);
+ cmAlphaNum(unsigned long int val);
+ cmAlphaNum(long long int val);
+ cmAlphaNum(unsigned long long int val);
+ cmAlphaNum(float val);
+ cmAlphaNum(double val);
+
+ cm::string_view View() const { return View_; }
+
+private:
+ cm::string_view View_;
+ char Digits_[32];
+};
+
+/** Concatenate string pieces and numbers into a single string. */
+template <typename... AV>
+inline std::string cmStrCat(cmAlphaNum const& a, cmAlphaNum const& b,
+ AV const&... args)
+{
+ return cmCatViews(
+ { a.View(), b.View(), static_cast<cmAlphaNum const&>(args).View()... });
+}
+
+/** Joins wrapped elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmWrap(cm::string_view prefix, Range const& rng,
+ cm::string_view suffix, cm::string_view sep)
+{
+ if (rng.empty()) {
+ return std::string();
+ }
+ return cmCatViews(
+ { prefix, cmJoin(rng, cmCatViews({ suffix, sep, prefix })), suffix });
+}
+
+/** Joins wrapped elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmWrap(char prefix, Range const& rng, char suffix,
+ cm::string_view sep)
+{
+ return cmWrap(cm::string_view(&prefix, 1), rng, cm::string_view(&suffix, 1),
+ sep);
+}
+
+/**
+ * Does a string indicates that CMake/CPack/CTest internally
+ * forced this value. This is not the same as On, but this
+ * may be considered as "internally switched on".
+ */
+bool cmIsInternallyOn(cm::string_view val);
+inline bool cmIsInternallyOn(const char* val)
+{
+ if (!val) {
+ return false;
+ }
+ return cmIsInternallyOn(cm::string_view(val));
+}
+
+/** Return true if value is NOTFOUND or ends in -NOTFOUND. */
+bool cmIsNOTFOUND(cm::string_view val);
+
+/**
+ * Does a string indicate a true or ON value? This is not the same as ifdef.
+ */
+bool cmIsOn(cm::string_view val);
+inline bool cmIsOn(const char* val)
+{
+ if (!val) {
+ return false;
+ }
+ return cmIsOn(cm::string_view(val));
+}
+
+/**
+ * Does a string indicate a false or off value ? Note that this is
+ * not the same as !IsOn(...) because there are a number of
+ * ambiguous values such as "/usr/local/bin" a path will result in
+ * IsON and IsOff both returning false. Note that the special path
+ * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
+ */
+bool cmIsOff(cm::string_view val);
+inline bool cmIsOff(const char* val)
+{
+ if (!val) {
+ return true;
+ }
+ return cmIsOff(cm::string_view(val));
+}
+
+/** Returns true if string @a str starts with the character @a prefix. */
+inline bool cmHasPrefix(cm::string_view str, char prefix)
+{
+ return !str.empty() && (str.front() == prefix);
+}
+
+/** Returns true if string @a str starts with string @a prefix. */
+inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix)
+{
+ return str.compare(0, prefix.size(), prefix) == 0;
+}
+
+/** Returns true if string @a str starts with string @a prefix. */
+template <size_t N>
+inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N])
+{
+ return cmHasPrefix(str, cm::string_view(prefix, N - 1));
+}
+
+/** Returns true if string @a str ends with the character @a suffix. */
+inline bool cmHasSuffix(cm::string_view str, char suffix)
+{
+ return !str.empty() && (str.back() == suffix);
+}
+
+/** Returns true if string @a str ends with string @a suffix. */
+inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix)
+{
+ return str.size() >= suffix.size() &&
+ str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+/** Returns true if string @a str ends with string @a suffix. */
+template <size_t N>
+inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N])
+{
+ return cmHasSuffix(str, cm::string_view(suffix, N - 1));
+}
+
+/** Removes an existing suffix character of from the string @a str. */
+inline void cmStripSuffixIfExists(std::string& str, char suffix)
+{
+ if (cmHasSuffix(str, suffix)) {
+ str.pop_back();
+ }
+}
+
+/** Removes an existing suffix string of from the string @a str. */
+inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
+{
+ if (cmHasSuffix(str, suffix)) {
+ str.resize(str.size() - suffix.size());
+ }
+}
+
+/** Converts a string to long. Expects that the whole string is an integer. */
+bool cmStrToLong(const char* str, long* value);
+bool cmStrToLong(std::string const& str, long* value);
+
+/** Converts a string to unsigned long. Expects that the whole string is an
+ * integer */
+bool cmStrToULong(const char* str, unsigned long* value);
+bool cmStrToULong(std::string const& str, unsigned long* value);
+
+#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 998f90415..9212195f5 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -4,143 +4,71 @@
#include "cmStringCommand.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <ctype.h>
-#include <iterator>
-#include <memory> // IWYU pragma: keep
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "cmAlgorithms.h"
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+
+#include <cm/iterator>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_static_string_view.hxx"
+
#include "cmCryptoHash.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmUuid.h"
-class cmExecutionStatus;
+namespace {
-bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
-{
- if (args.empty()) {
- this->SetError("must be called with at least one argument.");
- return false;
- }
-
- const std::string& subCommand = args[0];
- if (subCommand == "REGEX") {
- return this->HandleRegexCommand(args);
- }
- if (subCommand == "REPLACE") {
- return this->HandleReplaceCommand(args);
- }
- if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
- subCommand == "SHA256" || subCommand == "SHA384" ||
- subCommand == "SHA512" || subCommand == "SHA3_224" ||
- subCommand == "SHA3_256" || subCommand == "SHA3_384" ||
- subCommand == "SHA3_512") {
- return this->HandleHashCommand(args);
- }
- if (subCommand == "TOLOWER") {
- return this->HandleToUpperLowerCommand(args, false);
- }
- if (subCommand == "TOUPPER") {
- return this->HandleToUpperLowerCommand(args, true);
- }
- if (subCommand == "COMPARE") {
- return this->HandleCompareCommand(args);
- }
- if (subCommand == "ASCII") {
- return this->HandleAsciiCommand(args);
- }
- if (subCommand == "CONFIGURE") {
- return this->HandleConfigureCommand(args);
- }
- if (subCommand == "LENGTH") {
- return this->HandleLengthCommand(args);
- }
- if (subCommand == "APPEND") {
- return this->HandleAppendCommand(args);
- }
- if (subCommand == "PREPEND") {
- return this->HandlePrependCommand(args);
- }
- if (subCommand == "CONCAT") {
- return this->HandleConcatCommand(args);
- }
- if (subCommand == "JOIN") {
- return this->HandleJoinCommand(args);
- }
- if (subCommand == "SUBSTRING") {
- return this->HandleSubstringCommand(args);
- }
- if (subCommand == "STRIP") {
- return this->HandleStripCommand(args);
- }
- if (subCommand == "REPEAT") {
- return this->HandleRepeatCommand(args);
- }
- if (subCommand == "RANDOM") {
- return this->HandleRandomCommand(args);
- }
- if (subCommand == "FIND") {
- return this->HandleFindCommand(args);
- }
- if (subCommand == "TIMESTAMP") {
- return this->HandleTimestampCommand(args);
- }
- if (subCommand == "MAKE_C_IDENTIFIER") {
- return this->HandleMakeCIdentifierCommand(args);
- }
- if (subCommand == "GENEX_STRIP") {
- return this->HandleGenexStripCommand(args);
- }
- if (subCommand == "UUID") {
- return this->HandleUuidCommand(args);
- }
+bool RegexMatch(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+bool RegexMatchAll(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+bool RegexReplace(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
- std::string e = "does not recognize sub-command " + subCommand;
- this->SetError(e);
- return false;
-}
+bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
+ size_t varIdx, cmMakefile& makefile);
-bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args)
+bool HandleHashCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() != 3) {
- std::ostringstream e;
- e << args[0] << " requires an output variable and an input string";
- this->SetError(e.str());
+ status.SetError(
+ cmStrCat(args[0], " requires an output variable and an input string"));
return false;
}
- std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
+ std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0]));
if (hash) {
std::string out = hash->HashString(args[2]);
- this->Makefile->AddDefinition(args[1], out.c_str());
+ status.GetMakefile().AddDefinition(args[1], out);
return true;
}
return false;
#else
- std::ostringstream e;
- e << args[0] << " not available during bootstrap";
- this->SetError(e.str().c_str());
+ status.SetError(cmStrCat(args[0], " not available during bootstrap"));
return false;
#endif
}
-bool cmStringCommand::HandleToUpperLowerCommand(
- std::vector<std::string> const& args, bool toUpper)
+bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
+ bool toUpper, cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("no output variable specified");
+ status.SetError("no output variable specified");
return false;
}
@@ -154,14 +82,27 @@ bool cmStringCommand::HandleToUpperLowerCommand(
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar, output.c_str());
+ status.GetMakefile().AddDefinition(outvar, output);
return true;
}
-bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
+bool HandleToUpperCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleToUpperLowerCommand(args, true, status);
+}
+
+bool HandleToLowerCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleToUpperLowerCommand(args, false, status);
+}
+
+bool HandleAsciiCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("No output variable specified");
+ status.SetError("No output variable specified");
return false;
}
std::string::size_type cc;
@@ -172,27 +113,26 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
if (ch > 0 && ch < 256) {
output += static_cast<char>(ch);
} else {
- std::string error = "Character with code ";
- error += args[cc];
- error += " does not exist.";
- this->SetError(error);
+ std::string error =
+ cmStrCat("Character with code ", args[cc], " does not exist.");
+ status.SetError(error);
return false;
}
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar, output.c_str());
+ status.GetMakefile().AddDefinition(outvar, output);
return true;
}
-bool cmStringCommand::HandleConfigureCommand(
- std::vector<std::string> const& args)
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("No input string specified.");
+ status.SetError("No input string specified.");
return false;
}
if (args.size() < 3) {
- this->SetError("No output variable specified.");
+ status.SetError("No output variable specified.");
return false;
}
@@ -205,75 +145,75 @@ bool cmStringCommand::HandleConfigureCommand(
} else if (args[i] == "ESCAPE_QUOTES") {
escapeQuotes = true;
} else {
- std::ostringstream err;
- err << "Unrecognized argument \"" << args[i] << "\"";
- this->SetError(err.str());
+ status.SetError(cmStrCat("Unrecognized argument \"", args[i], "\""));
return false;
}
}
// Configure the string.
std::string output;
- this->Makefile->ConfigureString(args[1], output, atOnly, escapeQuotes);
+ status.GetMakefile().ConfigureString(args[1], output, atOnly, escapeQuotes);
// Store the output in the provided variable.
- this->Makefile->AddDefinition(args[2], output.c_str());
+ status.GetMakefile().AddDefinition(args[2], output);
return true;
}
-bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
+bool HandleRegexCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command REGEX requires a mode to be specified.");
+ status.SetError("sub-command REGEX requires a mode to be specified.");
return false;
}
std::string const& mode = args[1];
if (mode == "MATCH") {
if (args.size() < 5) {
- this->SetError("sub-command REGEX, mode MATCH needs "
- "at least 5 arguments total to command.");
+ status.SetError("sub-command REGEX, mode MATCH needs "
+ "at least 5 arguments total to command.");
return false;
}
- return this->RegexMatch(args);
+ return RegexMatch(args, status);
}
if (mode == "MATCHALL") {
if (args.size() < 5) {
- this->SetError("sub-command REGEX, mode MATCHALL needs "
- "at least 5 arguments total to command.");
+ status.SetError("sub-command REGEX, mode MATCHALL needs "
+ "at least 5 arguments total to command.");
return false;
}
- return this->RegexMatchAll(args);
+ return RegexMatchAll(args, status);
}
if (mode == "REPLACE") {
if (args.size() < 6) {
- this->SetError("sub-command REGEX, mode REPLACE needs "
- "at least 6 arguments total to command.");
+ status.SetError("sub-command REGEX, mode REPLACE needs "
+ "at least 6 arguments total to command.");
return false;
}
- return this->RegexReplace(args);
+ return RegexReplace(args, status);
}
std::string e = "sub-command REGEX does not recognize mode " + mode;
- this->SetError(e);
+ status.SetError(e);
return false;
}
-bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
+bool RegexMatch(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
//"STRING(REGEX MATCH <regular_expression> <output variable>
// <input> [<input>...])\n";
std::string const& regex = args[2];
std::string const& outvar = args[3];
- this->Makefile->ClearMatches();
+ status.GetMakefile().ClearMatches();
// Compile the regular expression.
cmsys::RegularExpression re;
if (!re.compile(regex.c_str())) {
std::string e =
"sub-command REGEX, mode MATCH failed to compile regex \"" + regex +
"\".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
@@ -283,38 +223,39 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
// Scan through the input for all matches.
std::string output;
if (re.find(input)) {
- this->Makefile->StoreMatches(re);
+ status.GetMakefile().StoreMatches(re);
std::string::size_type l = re.start();
std::string::size_type r = re.end();
if (r - l == 0) {
std::string e = "sub-command REGEX, mode MATCH regex \"" + regex +
"\" matched an empty string.";
- this->SetError(e);
+ status.SetError(e);
return false;
}
output = input.substr(l, r - l);
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar, output.c_str());
+ status.GetMakefile().AddDefinition(outvar, output);
return true;
}
-bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
+bool RegexMatchAll(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
//"STRING(REGEX MATCHALL <regular_expression> <output variable> <input>
// [<input>...])\n";
std::string const& regex = args[2];
std::string const& outvar = args[3];
- this->Makefile->ClearMatches();
+ status.GetMakefile().ClearMatches();
// Compile the regular expression.
cmsys::RegularExpression re;
if (!re.compile(regex.c_str())) {
std::string e =
"sub-command REGEX, mode MATCHALL failed to compile regex \"" + regex +
"\".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
@@ -325,14 +266,14 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
std::string output;
const char* p = input.c_str();
while (re.find(p)) {
- this->Makefile->ClearMatches();
- this->Makefile->StoreMatches(re);
+ status.GetMakefile().ClearMatches();
+ status.GetMakefile().StoreMatches(re);
std::string::size_type l = re.start();
std::string::size_type r = re.end();
if (r - l == 0) {
std::string e = "sub-command REGEX, mode MATCHALL regex \"" + regex +
"\" matched an empty string.";
- this->SetError(e);
+ status.SetError(e);
return false;
}
if (!output.empty()) {
@@ -343,32 +284,33 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar, output.c_str());
+ status.GetMakefile().AddDefinition(outvar, output);
return true;
}
-bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
+bool RegexReplace(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
//"STRING(REGEX REPLACE <regular_expression> <replace_expression>
// <output variable> <input> [<input>...])\n"
std::string const& regex = args[2];
std::string const& replace = args[3];
std::string const& outvar = args[4];
- cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile);
+ cmStringReplaceHelper replaceHelper(regex, replace, &status.GetMakefile());
if (!replaceHelper.IsReplaceExpressionValid()) {
- this->SetError(
+ status.SetError(
"sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
return false;
}
- this->Makefile->ClearMatches();
+ status.GetMakefile().ClearMatches();
if (!replaceHelper.IsRegularExpressionValid()) {
std::string e =
"sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
"\".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
@@ -378,21 +320,22 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string output;
if (!replaceHelper.Replace(input, output)) {
- this->SetError(
+ status.SetError(
"sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
return false;
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar, output.c_str());
+ status.GetMakefile().AddDefinition(outvar, output);
return true;
}
-bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
+bool HandleFindCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// check if all required parameters were passed
if (args.size() < 4 || args.size() > 5) {
- this->SetError("sub-command FIND requires 3 or 4 parameters.");
+ status.SetError("sub-command FIND requires 3 or 4 parameters.");
return false;
}
@@ -404,7 +347,7 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
// if we have 5 arguments the last one must be REVERSE
if (args.size() == 5 && args[4] != "REVERSE") {
- this->SetError("sub-command FIND: unknown last parameter");
+ status.SetError("sub-command FIND: unknown last parameter");
return false;
}
@@ -415,9 +358,9 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
// ensure that the user cannot accidentally specify REVERSE as a variable
if (outvar == "REVERSE") {
- this->SetError("sub-command FIND does not allow one to select REVERSE as "
- "the output variable. "
- "Maybe you missed the actual output variable?");
+ status.SetError("sub-command FIND does not allow one to select REVERSE as "
+ "the output variable. "
+ "Maybe you missed the actual output variable?");
return false;
}
@@ -429,22 +372,20 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& args)
pos = sstring.rfind(schar);
}
if (std::string::npos != pos) {
- std::ostringstream s;
- s << pos;
- this->Makefile->AddDefinition(outvar, s.str().c_str());
+ status.GetMakefile().AddDefinition(outvar, std::to_string(pos));
return true;
}
// the character was not found, but this is not really an error
- this->Makefile->AddDefinition(outvar, "-1");
+ status.GetMakefile().AddDefinition(outvar, "-1");
return true;
}
-bool cmStringCommand::HandleCompareCommand(
- std::vector<std::string> const& args)
+bool HandleCompareCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command COMPARE requires a mode to be specified.");
+ status.SetError("sub-command COMPARE requires a mode to be specified.");
return false;
}
std::string const& mode = args[1];
@@ -452,10 +393,10 @@ bool cmStringCommand::HandleCompareCommand(
(mode == "LESS_EQUAL") || (mode == "GREATER") ||
(mode == "GREATER_EQUAL")) {
if (args.size() < 5) {
- std::string e = "sub-command COMPARE, mode ";
- e += mode;
- e += " needs at least 5 arguments total to command.";
- this->SetError(e);
+ std::string e =
+ cmStrCat("sub-command COMPARE, mode ", mode,
+ " needs at least 5 arguments total to command.");
+ status.SetError(e);
return false;
}
@@ -478,22 +419,22 @@ bool cmStringCommand::HandleCompareCommand(
result = !(left == right);
}
if (result) {
- this->Makefile->AddDefinition(outvar, "1");
+ status.GetMakefile().AddDefinition(outvar, "1");
} else {
- this->Makefile->AddDefinition(outvar, "0");
+ status.GetMakefile().AddDefinition(outvar, "0");
}
return true;
}
std::string e = "sub-command COMPARE does not recognize mode " + mode;
- this->SetError(e);
+ status.SetError(e);
return false;
}
-bool cmStringCommand::HandleReplaceCommand(
- std::vector<std::string> const& args)
+bool HandleReplaceCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 5) {
- this->SetError("sub-command REPLACE requires at least four arguments.");
+ status.SetError("sub-command REPLACE requires at least four arguments.");
return false;
}
@@ -506,15 +447,15 @@ bool cmStringCommand::HandleReplaceCommand(
cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
replaceExpression.c_str());
- this->Makefile->AddDefinition(variableName, input.c_str());
+ status.GetMakefile().AddDefinition(variableName, input);
return true;
}
-bool cmStringCommand::HandleSubstringCommand(
- std::vector<std::string> const& args)
+bool HandleSubstringCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 5) {
- this->SetError("sub-command SUBSTRING requires four arguments.");
+ status.SetError("sub-command SUBSTRING requires four arguments.");
return false;
}
@@ -526,28 +467,25 @@ bool cmStringCommand::HandleSubstringCommand(
size_t stringLength = stringValue.size();
int intStringLength = static_cast<int>(stringLength);
if (begin < 0 || begin > intStringLength) {
- std::ostringstream ostr;
- ostr << "begin index: " << begin << " is out of range 0 - "
- << stringLength;
- this->SetError(ostr.str());
+ status.SetError(
+ cmStrCat("begin index: ", begin, " is out of range 0 - ", stringLength));
return false;
}
if (end < -1) {
- std::ostringstream ostr;
- ostr << "end index: " << end << " should be -1 or greater";
- this->SetError(ostr.str());
+ status.SetError(cmStrCat("end index: ", end, " should be -1 or greater"));
return false;
}
- this->Makefile->AddDefinition(variableName,
- stringValue.substr(begin, end).c_str());
+ status.GetMakefile().AddDefinition(variableName,
+ stringValue.substr(begin, end));
return true;
}
-bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args)
+bool HandleLengthCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("sub-command LENGTH requires two arguments.");
+ status.SetError("sub-command LENGTH requires two arguments.");
return false;
}
@@ -558,14 +496,15 @@ bool cmStringCommand::HandleLengthCommand(std::vector<std::string> const& args)
char buffer[1024];
sprintf(buffer, "%d", static_cast<int>(length));
- this->Makefile->AddDefinition(variableName, buffer);
+ status.GetMakefile().AddDefinition(variableName, buffer);
return true;
}
-bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
+bool HandleAppendCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command APPEND requires at least one argument.");
+ status.SetError("sub-command APPEND requires at least one argument.");
return false;
}
@@ -577,20 +516,20 @@ bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
const std::string& variable = args[1];
std::string value;
- const char* oldValue = this->Makefile->GetDefinition(variable);
+ const char* oldValue = status.GetMakefile().GetDefinition(variable);
if (oldValue) {
value = oldValue;
}
value += cmJoin(cmMakeRange(args).advance(2), std::string());
- this->Makefile->AddDefinition(variable, value.c_str());
+ status.GetMakefile().AddDefinition(variable, value);
return true;
}
-bool cmStringCommand::HandlePrependCommand(
- std::vector<std::string> const& args)
+bool HandlePrependCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command PREPEND requires at least one argument.");
+ status.SetError("sub-command PREPEND requires at least one argument.");
return false;
}
@@ -602,67 +541,69 @@ bool cmStringCommand::HandlePrependCommand(
const std::string& variable = args[1];
std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
- const char* oldValue = this->Makefile->GetDefinition(variable);
+ const char* oldValue = status.GetMakefile().GetDefinition(variable);
if (oldValue) {
value += oldValue;
}
- this->Makefile->AddDefinition(variable, value.c_str());
+ status.GetMakefile().AddDefinition(variable, value);
return true;
}
-bool cmStringCommand::HandleConcatCommand(std::vector<std::string> const& args)
+bool HandleConcatCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command CONCAT requires at least one argument.");
+ status.SetError("sub-command CONCAT requires at least one argument.");
return false;
}
- return this->joinImpl(args, std::string(), 1);
+ return joinImpl(args, std::string(), 1, status.GetMakefile());
}
-bool cmStringCommand::HandleJoinCommand(std::vector<std::string> const& args)
+bool HandleJoinCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("sub-command JOIN requires at least two arguments.");
+ status.SetError("sub-command JOIN requires at least two arguments.");
return false;
}
- return this->joinImpl(args, args[1], 2);
+ return joinImpl(args, args[1], 2, status.GetMakefile());
}
-bool cmStringCommand::joinImpl(std::vector<std::string> const& args,
- std::string const& glue, const size_t varIdx)
+bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
+ const size_t varIdx, cmMakefile& makefile)
{
std::string const& variableName = args[varIdx];
// NOTE Items to concat/join placed right after the variable for
// both `CONCAT` and `JOIN` sub-commands.
std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue);
- this->Makefile->AddDefinition(variableName, value.c_str());
+ makefile.AddDefinition(variableName, value);
return true;
}
-bool cmStringCommand::HandleMakeCIdentifierCommand(
- std::vector<std::string> const& args)
+bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("sub-command MAKE_C_IDENTIFIER requires two arguments.");
+ status.SetError("sub-command MAKE_C_IDENTIFIER requires two arguments.");
return false;
}
const std::string& input = args[1];
const std::string& variableName = args[2];
- this->Makefile->AddDefinition(variableName,
- cmSystemTools::MakeCidentifier(input).c_str());
+ status.GetMakefile().AddDefinition(variableName,
+ cmSystemTools::MakeCidentifier(input));
return true;
}
-bool cmStringCommand::HandleGenexStripCommand(
- std::vector<std::string> const& args)
+bool HandleGenexStripCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("sub-command GENEX_STRIP requires two arguments.");
+ status.SetError("sub-command GENEX_STRIP requires two arguments.");
return false;
}
@@ -673,14 +614,15 @@ bool cmStringCommand::HandleGenexStripCommand(
const std::string& variableName = args[2];
- this->Makefile->AddDefinition(variableName, result.c_str());
+ status.GetMakefile().AddDefinition(variableName, result);
return true;
}
-bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args)
+bool HandleStripCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("sub-command STRIP requires two arguments.");
+ status.SetError("sub-command STRIP requires two arguments.");
return false;
}
@@ -712,13 +654,16 @@ bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args)
outLength = endPos - startPos + 1;
}
- this->Makefile->AddDefinition(
- variableName, stringValue.substr(startPos, outLength).c_str());
+ status.GetMakefile().AddDefinition(variableName,
+ stringValue.substr(startPos, outLength));
return true;
}
-bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
+bool HandleRepeatCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
+ cmMakefile& makefile = status.GetMakefile();
+
// `string(REPEAT "<str>" <times> OUTPUT_VARIABLE)`
enum ArgPos : std::size_t
{
@@ -730,16 +675,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
};
if (args.size() != ArgPos::TOTAL_ARGS) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "sub-command REPEAT requires three arguments.");
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "sub-command REPEAT requires three arguments.");
return true;
}
unsigned long times;
- if (!cmSystemTools::StringToULong(args[ArgPos::TIMES].c_str(), &times)) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "repeat count is not a positive number.");
+ if (!cmStrToULong(args[ArgPos::TIMES], &times)) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "repeat count is not a positive number.");
return true;
}
@@ -766,14 +710,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args)
break;
}
- this->Makefile->AddDefinition(variableName, result.c_str());
+ makefile.AddDefinition(variableName, result);
return true;
}
-bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
+bool HandleRandomCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2 || args.size() == 3 || args.size() == 5) {
- this->SetError("sub-command RANDOM requires at least one argument.");
+ status.SetError("sub-command RANDOM requires at least one argument.");
return false;
}
@@ -810,11 +755,11 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
double sizeofAlphabet = static_cast<double>(alphabet.size());
if (sizeofAlphabet < 1) {
- this->SetError("sub-command RANDOM invoked with bad alphabet.");
+ status.SetError("sub-command RANDOM invoked with bad alphabet.");
return false;
}
if (length < 1) {
- this->SetError("sub-command RANDOM invoked with bad length.");
+ status.SetError("sub-command RANDOM invoked with bad length.");
return false;
}
const std::string& variableName = args.back();
@@ -833,19 +778,19 @@ bool cmStringCommand::HandleRandomCommand(std::vector<std::string> const& args)
}
result.push_back(0);
- this->Makefile->AddDefinition(variableName, result.data());
+ status.GetMakefile().AddDefinition(variableName, result.data());
return true;
}
-bool cmStringCommand::HandleTimestampCommand(
- std::vector<std::string> const& args)
+bool HandleTimestampCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("sub-command TIMESTAMP requires at least one argument.");
+ status.SetError("sub-command TIMESTAMP requires at least one argument.");
return false;
}
if (args.size() > 4) {
- this->SetError("sub-command TIMESTAMP takes at most three arguments.");
+ status.SetError("sub-command TIMESTAMP takes at most three arguments.");
return false;
}
@@ -865,25 +810,26 @@ bool cmStringCommand::HandleTimestampCommand(
} else {
std::string e = " TIMESTAMP sub-command does not recognize option " +
args[argsIndex] + ".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
}
cmTimestamp timestamp;
std::string result = timestamp.CurrentTime(formatString, utcFlag);
- this->Makefile->AddDefinition(outputVariable, result.c_str());
+ status.GetMakefile().AddDefinition(outputVariable, result);
return true;
}
-bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
+bool HandleUuidCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
unsigned int argsIndex = 1;
if (args.size() < 2) {
- this->SetError("UUID sub-command requires an output variable.");
+ status.SetError("UUID sub-command requires an output variable.");
return false;
}
@@ -898,21 +844,21 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
if (args[argsIndex] == "NAMESPACE") {
++argsIndex;
if (argsIndex >= args.size()) {
- this->SetError("UUID sub-command, NAMESPACE requires a value.");
+ status.SetError("UUID sub-command, NAMESPACE requires a value.");
return false;
}
uuidNamespaceString = args[argsIndex++];
} else if (args[argsIndex] == "NAME") {
++argsIndex;
if (argsIndex >= args.size()) {
- this->SetError("UUID sub-command, NAME requires a value.");
+ status.SetError("UUID sub-command, NAME requires a value.");
return false;
}
uuidName = args[argsIndex++];
} else if (args[argsIndex] == "TYPE") {
++argsIndex;
if (argsIndex >= args.size()) {
- this->SetError("UUID sub-command, TYPE requires a value.");
+ status.SetError("UUID sub-command, TYPE requires a value.");
return false;
}
uuidType = args[argsIndex++];
@@ -922,7 +868,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
} else {
std::string e =
"UUID sub-command does not recognize option " + args[argsIndex] + ".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
}
@@ -932,7 +878,7 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
std::vector<unsigned char> uuidNamespace;
if (!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace)) {
- this->SetError("UUID sub-command, malformed NAMESPACE UUID.");
+ status.SetError("UUID sub-command, malformed NAMESPACE UUID.");
return false;
}
@@ -942,12 +888,12 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName);
} else {
std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'.";
- this->SetError(e);
+ status.SetError(e);
return false;
}
if (uuid.empty()) {
- this->SetError("UUID sub-command, generation failed.");
+ status.SetError("UUID sub-command, generation failed.");
return false;
}
@@ -955,12 +901,57 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
uuid = cmSystemTools::UpperCase(uuid);
}
- this->Makefile->AddDefinition(outputVariable, uuid.c_str());
+ status.GetMakefile().AddDefinition(outputVariable, uuid);
return true;
#else
- std::ostringstream e;
- e << args[0] << " not available during bootstrap";
- this->SetError(e.str().c_str());
+ status.SetError(cmStrCat(args[0], " not available during bootstrap"));
return false;
#endif
}
+
+} // namespace
+
+bool cmStringCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.empty()) {
+ status.SetError("must be called with at least one argument.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "REGEX"_s, HandleRegexCommand },
+ { "REPLACE"_s, HandleReplaceCommand },
+ { "MD5"_s, HandleHashCommand },
+ { "SHA1"_s, HandleHashCommand },
+ { "SHA224"_s, HandleHashCommand },
+ { "SHA256"_s, HandleHashCommand },
+ { "SHA384"_s, HandleHashCommand },
+ { "SHA512"_s, HandleHashCommand },
+ { "SHA3_224"_s, HandleHashCommand },
+ { "SHA3_256"_s, HandleHashCommand },
+ { "SHA3_384"_s, HandleHashCommand },
+ { "SHA3_512"_s, HandleHashCommand },
+ { "TOLOWER"_s, HandleToLowerCommand },
+ { "TOUPPER"_s, HandleToUpperCommand },
+ { "COMPARE"_s, HandleCompareCommand },
+ { "ASCII"_s, HandleAsciiCommand },
+ { "CONFIGURE"_s, HandleConfigureCommand },
+ { "LENGTH"_s, HandleLengthCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "PREPEND"_s, HandlePrependCommand },
+ { "CONCAT"_s, HandleConcatCommand },
+ { "JOIN"_s, HandleJoinCommand },
+ { "SUBSTRING"_s, HandleSubstringCommand },
+ { "STRIP"_s, HandleStripCommand },
+ { "REPEAT"_s, HandleRepeatCommand },
+ { "RANDOM"_s, HandleRandomCommand },
+ { "FIND"_s, HandleFindCommand },
+ { "TIMESTAMP"_s, HandleTimestampCommand },
+ { "MAKE_C_IDENTIFIER"_s, HandleMakeCIdentifierCommand },
+ { "GENEX_STRIP"_s, HandleGenexStripCommand },
+ { "UUID"_s, HandleUuidCommand },
+ };
+
+ return subcommand(args[0], args, status);
+}
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index acde60549..bd71ba293 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -5,62 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmStringCommand
+/**
* \brief Common string operations
*
*/
-class cmStringCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmStringCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool HandleConfigureCommand(std::vector<std::string> const& args);
- bool HandleAsciiCommand(std::vector<std::string> const& args);
- bool HandleRegexCommand(std::vector<std::string> const& args);
- bool RegexMatch(std::vector<std::string> const& args);
- bool RegexMatchAll(std::vector<std::string> const& args);
- bool RegexReplace(std::vector<std::string> const& args);
- bool HandleHashCommand(std::vector<std::string> const& args);
- bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
- bool toUpper);
- bool HandleCompareCommand(std::vector<std::string> const& args);
- bool HandleReplaceCommand(std::vector<std::string> const& args);
- bool HandleLengthCommand(std::vector<std::string> const& args);
- bool HandleSubstringCommand(std::vector<std::string> const& args);
- bool HandleAppendCommand(std::vector<std::string> const& args);
- bool HandlePrependCommand(std::vector<std::string> const& args);
- bool HandleConcatCommand(std::vector<std::string> const& args);
- bool HandleJoinCommand(std::vector<std::string> const& args);
- bool HandleStripCommand(std::vector<std::string> const& args);
- bool HandleRepeatCommand(std::vector<std::string> const& args);
- bool HandleRandomCommand(std::vector<std::string> const& args);
- bool HandleFindCommand(std::vector<std::string> const& args);
- bool HandleTimestampCommand(std::vector<std::string> const& args);
- bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
- bool HandleGenexStripCommand(std::vector<std::string> const& args);
- bool HandleUuidCommand(std::vector<std::string> const& args);
-
- bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
- size_t varIdx);
-};
+bool cmStringCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
index 4a6298782..998c135e8 100644
--- a/Source/cmStringReplaceHelper.cxx
+++ b/Source/cmStringReplaceHelper.cxx
@@ -3,10 +3,11 @@
#include "cmStringReplaceHelper.h"
-#include "cmMakefile.h"
#include <sstream>
#include <utility>
+#include "cmMakefile.h"
+
cmStringReplaceHelper::cmStringReplaceHelper(const std::string& regex,
std::string replace_expr,
cmMakefile* makefile)
diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h
index b3e470416..74d481d70 100644
--- a/Source/cmStringReplaceHelper.h
+++ b/Source/cmStringReplaceHelper.h
@@ -3,12 +3,12 @@
#ifndef cmStringReplaceHelper_h
#define cmStringReplaceHelper_h
-#include "cmsys/RegularExpression.hxx"
-
#include <string>
#include <utility>
#include <vector>
+#include "cmsys/RegularExpression.hxx"
+
class cmMakefile;
class cmStringReplaceHelper
diff --git a/Source/cmSubcommandTable.cxx b/Source/cmSubcommandTable.cxx
new file mode 100644
index 000000000..f6194f816
--- /dev/null
+++ b/Source/cmSubcommandTable.cxx
@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmSubcommandTable.h"
+
+#include <algorithm>
+
+#include "cmExecutionStatus.h"
+#include "cmStringAlgorithms.h"
+
+cmSubcommandTable::cmSubcommandTable(std::initializer_list<InitElem> init)
+ : Impl(init.begin(), init.end())
+{
+ std::sort(this->Impl.begin(), this->Impl.end(),
+ [](Elem const& left, Elem const& right) {
+ return left.first < right.first;
+ });
+}
+
+bool cmSubcommandTable::operator()(cm::string_view key,
+ std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ auto const it = std::lower_bound(
+ this->Impl.begin(), this->Impl.end(), key,
+ [](Elem const& elem, cm::string_view k) { return elem.first < k; });
+ if (it != this->Impl.end() && it->first == key) {
+ return it->second(args, status);
+ }
+ status.SetError(cmStrCat("does not recognize sub-command ", key));
+ return false;
+}
diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h
new file mode 100644
index 000000000..65eb8c794
--- /dev/null
+++ b/Source/cmSubcommandTable.h
@@ -0,0 +1,37 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmSubcommandTable_h
+#define cmSubcommandTable_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <initializer_list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
+class cmExecutionStatus;
+
+class cmSubcommandTable
+{
+public:
+ using Command = bool (*)(std::vector<std::string> const&,
+ cmExecutionStatus&);
+
+ using Elem = std::pair<cm::string_view, Command>;
+ using InitElem = std::pair<cm::static_string_view, Command>;
+
+ cmSubcommandTable(std::initializer_list<InitElem> init);
+
+ bool operator()(cm::string_view key, std::vector<std::string> const& args,
+ cmExecutionStatus& status) const;
+
+private:
+ std::vector<Elem> Impl;
+};
+
+#endif
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
index 9d36228d2..2477d7a33 100644
--- a/Source/cmSubdirCommand.cxx
+++ b/Source/cmSubdirCommand.cxx
@@ -2,21 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSubdirCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-// cmSubdirCommand
-bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmSubdirCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
bool res = true;
bool excludeFromAll = false;
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
if (i == "EXCLUDE_FROM_ALL") {
@@ -29,24 +29,21 @@ bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args,
}
// if they specified a relative path then compute the full
- std::string srcPath =
- this->Makefile->GetCurrentSourceDirectory() + "/" + i;
+ std::string srcPath = mf.GetCurrentSourceDirectory() + "/" + i;
if (cmSystemTools::FileIsDirectory(srcPath)) {
- std::string binPath =
- this->Makefile->GetCurrentBinaryDirectory() + "/" + i;
- this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, false);
+ std::string binPath = mf.GetCurrentBinaryDirectory() + "/" + i;
+ mf.AddSubDirectory(srcPath, binPath, excludeFromAll, false);
}
// otherwise it is a full path
else if (cmSystemTools::FileIsDirectory(i)) {
// we must compute the binPath from the srcPath, we just take the last
// element from the source path and use that
- std::string binPath = this->Makefile->GetCurrentBinaryDirectory() + "/" +
+ std::string binPath = mf.GetCurrentBinaryDirectory() + "/" +
cmSystemTools::GetFilenameName(i);
- this->Makefile->AddSubDirectory(i, binPath, excludeFromAll, false);
+ mf.AddSubDirectory(i, binPath, excludeFromAll, false);
} else {
- std::string error = "Incorrect SUBDIRS command. Directory: ";
- error += i + " does not exist.";
- this->SetError(error);
+ status.SetError(cmStrCat("Incorrect SUBDIRS command. Directory: ", i,
+ " does not exist."));
res = false;
}
}
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index adab75711..3254e842e 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -8,31 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmSubdirCommand
- * \brief Specify a list of subdirectories to build.
- *
- * cmSubdirCommand specifies a list of subdirectories to process
- * by CMake. For each subdirectory listed, CMake will descend
- * into that subdirectory and process any CMakeLists.txt found.
- */
-class cmSubdirCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmSubdirCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSubdirCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSubdirDependsCommand.cxx b/Source/cmSubdirDependsCommand.cxx
index 0bb2c0ac4..496c60da7 100644
--- a/Source/cmSubdirDependsCommand.cxx
+++ b/Source/cmSubdirDependsCommand.cxx
@@ -4,8 +4,8 @@
class cmExecutionStatus;
-bool cmSubdirDependsCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
+bool cmSubdirDependsCommand(std::vector<std::string> const&,
+ cmExecutionStatus&)
{
return true;
}
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index 2db28c66c..bf99bd17d 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -8,16 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmSubdirDependsCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmSubdirDependsCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmSubdirDependsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 15014811e..c4a4220f8 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2,16 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSystemTools.h"
+#include "cm_uv.h"
+
#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
-#include "cm_uv.h"
+#include "cmStringAlgorithms.h"
+
+#if !defined(CMAKE_BOOTSTRAP)
+# include "cm_libarchive.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmArchiveWrite.h"
# include "cmLocale.h"
-# include "cm_libarchive.h"
# ifndef __LA_INT64_T
# define __LA_INT64_T la_int64_t
# endif
@@ -20,7 +23,7 @@
# endif
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmCryptoHash.h"
#endif
@@ -32,33 +35,36 @@
# include "cmMachO.h"
#endif
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <iostream>
+#include <sstream>
+#include <utility>
+#include <vector>
+
+#include <fcntl.h>
+
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/System.h"
#include "cmsys/Terminal.h"
-#include <algorithm>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <iostream>
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <utility>
-#include <vector>
#if defined(_WIN32)
# include <windows.h>
// include wincrypt.h after windows.h
# include <wincrypt.h>
#else
-# include <sys/time.h>
# include <unistd.h>
+
+# include <sys/time.h>
#endif
#if defined(_WIN32) && \
@@ -83,11 +89,6 @@ cmSystemTools::OutputCallback s_StdoutCallback;
} // namespace
-static bool cm_isspace(char c)
-{
- return ((c & 0x80) == 0) && isspace(c);
-}
-
#if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
// For GetEnvironmentVariables
# if defined(_WIN32)
@@ -97,7 +98,7 @@ extern char** environ;
# endif
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
static std::string cm_archive_entry_pathname(struct archive_entry* entry)
{
# if cmsys_STL_HAS_WSTRING
@@ -151,12 +152,10 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64 view)
std::string key = regEntry.match(1);
std::string val;
if (ReadRegistryValue(key.c_str(), val, view)) {
- std::string reg = "[";
- reg += key + "]";
+ std::string reg = cmStrCat('[', key, ']');
cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str());
} else {
- std::string reg = "[";
- reg += key + "]";
+ std::string reg = cmStrCat('[', key, ']');
cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
}
}
@@ -169,49 +168,20 @@ void cmSystemTools::ExpandRegistryValues(std::string& source,
while (regEntry.find(source)) {
// the arguments are the second match
std::string key = regEntry.match(1);
- std::string reg = "[";
- reg += key + "]";
+ std::string reg = cmStrCat('[', key, ']');
cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
}
}
#endif
-std::string cmSystemTools::EscapeQuotes(const std::string& str)
-{
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch == '"') {
- result += '\\';
- }
- result += *ch;
- }
- return result;
-}
-
-std::string cmSystemTools::HelpFileName(std::string name)
+std::string cmSystemTools::HelpFileName(cm::string_view str)
{
+ std::string name(str);
cmSystemTools::ReplaceString(name, "<", "");
cmSystemTools::ReplaceString(name, ">", "");
return name;
}
-std::string cmSystemTools::TrimWhitespace(const std::string& s)
-{
- std::string::const_iterator start = s.begin();
- while (start != s.end() && cm_isspace(*start)) {
- ++start;
- }
- if (start == s.end()) {
- return "";
- }
- std::string::const_iterator stop = s.end() - 1;
- while (cm_isspace(*stop)) {
- --stop;
- }
- return std::string(start, stop + 1);
-}
-
void cmSystemTools::Error(const std::string& m)
{
std::string message = "CMake Error: " + m;
@@ -276,121 +246,11 @@ void cmSystemTools::Message(const std::string& m, const char* title)
void cmSystemTools::ReportLastSystemError(const char* msg)
{
- std::string m = msg;
- m += ": System Error: ";
- m += Superclass::GetLastSystemError();
+ std::string m =
+ cmStrCat(msg, ": System Error: ", Superclass::GetLastSystemError());
cmSystemTools::Error(m);
}
-bool cmSystemTools::IsInternallyOn(const char* val)
-{
- if (!val) {
- return false;
- }
- std::string v = val;
- if (v.size() > 4) {
- return false;
- }
-
- for (char& c : v) {
- c = static_cast<char>(toupper(c));
- }
- return v == "I_ON";
-}
-
-bool cmSystemTools::IsOn(const char* val)
-{
- if (!val) {
- return false;
- }
- /* clang-format off */
- // "1"
- if (val[0] == '1' && val[1] == '\0') {
- return true;
- }
- // "ON"
- if ((val[0] == 'O' || val[0] == 'o') &&
- (val[1] == 'N' || val[1] == 'n') && val[2] == '\0') {
- return true;
- }
- // "Y", "YES"
- if ((val[0] == 'Y' || val[0] == 'y') && (val[1] == '\0' || (
- (val[1] == 'E' || val[1] == 'e') &&
- (val[2] == 'S' || val[2] == 's') && val[3] == '\0'))) {
- return true;
- }
- // "TRUE"
- if ((val[0] == 'T' || val[0] == 't') &&
- (val[1] == 'R' || val[1] == 'r') &&
- (val[2] == 'U' || val[2] == 'u') &&
- (val[3] == 'E' || val[3] == 'e') && val[4] == '\0') {
- return true;
- }
- /* clang-format on */
- return false;
-}
-
-bool cmSystemTools::IsOn(const std::string& val)
-{
- return cmSystemTools::IsOn(val.c_str());
-}
-
-bool cmSystemTools::IsNOTFOUND(const char* val)
-{
- if (strcmp(val, "NOTFOUND") == 0) {
- return true;
- }
- return cmHasLiteralSuffix(val, "-NOTFOUND");
-}
-
-bool cmSystemTools::IsOff(const char* val)
-{
- // ""
- if (!val || val[0] == '\0') {
- return true;
- }
- /* clang-format off */
- // "0"
- if (val[0] == '0' && val[1] == '\0') {
- return true;
- }
- // "OFF"
- if ((val[0] == 'O' || val[0] == 'o') &&
- (val[1] == 'F' || val[1] == 'f') &&
- (val[2] == 'F' || val[2] == 'f') && val[3] == '\0') {
- return true;
- }
- // "N", "NO"
- if ((val[0] == 'N' || val[0] == 'n') && (val[1] == '\0' || (
- (val[1] == 'O' || val[1] == 'o') && val[2] == '\0'))) {
- return true;
- }
- // "FALSE"
- if ((val[0] == 'F' || val[0] == 'f') &&
- (val[1] == 'A' || val[1] == 'a') &&
- (val[2] == 'L' || val[2] == 'l') &&
- (val[3] == 'S' || val[3] == 's') &&
- (val[4] == 'E' || val[4] == 'e') && val[5] == '\0') {
- return true;
- }
- // "IGNORE"
- if ((val[0] == 'I' || val[0] == 'i') &&
- (val[1] == 'G' || val[1] == 'g') &&
- (val[2] == 'N' || val[2] == 'n') &&
- (val[3] == 'O' || val[3] == 'o') &&
- (val[4] == 'R' || val[4] == 'r') &&
- (val[5] == 'E' || val[5] == 'e') && val[6] == '\0') {
- return true;
- }
- /* clang-format on */
- return cmSystemTools::IsNOTFOUND(val);
-}
-
-bool cmSystemTools::IsOff(const std::string& val)
-{
- return cmSystemTools::IsOff(val.c_str());
-}
-
void cmSystemTools::ParseWindowsCommandLine(const char* command,
std::vector<std::string>& args)
{
@@ -424,7 +284,7 @@ void cmSystemTools::ParseWindowsCommandLine(const char* command,
} else {
arg.append(backslashes, '\\');
backslashes = 0;
- if (cm_isspace(*c)) {
+ if (cmIsSpace(*c)) {
if (in_quotes) {
arg.append(1, *c);
} else if (in_argument) {
@@ -487,10 +347,9 @@ std::vector<std::string> cmSystemTools::HandleResponseFile(
if (cmHasLiteralPrefix(arg, "@")) {
cmsys::ifstream responseFile(arg.substr(1).c_str(), std::ios::in);
if (!responseFile) {
- std::string error = "failed to open for reading (";
- error += cmSystemTools::GetLastSystemError();
- error += "):\n ";
- error += arg.substr(1);
+ std::string error = cmStrCat("failed to open for reading (",
+ cmSystemTools::GetLastSystemError(),
+ "):\n ", cm::string_view(arg).substr(1));
cmSystemTools::Error(error);
} else {
std::string line;
@@ -843,9 +702,7 @@ bool cmSystemTools::DoesFileExistWithExtensions(
std::string hname;
for (std::string const& headerExt : headerExts) {
- hname = name;
- hname += ".";
- hname += headerExt;
+ hname = cmStrCat(name, '.', headerExt);
if (cmSystemTools::FileExists(hname)) {
return true;
}
@@ -863,7 +720,7 @@ std::string cmSystemTools::FileExistsInParentDirectories(
cmSystemTools::ConvertToUnixSlashes(dir);
std::string prevDir;
while (dir != prevDir) {
- std::string path = dir + "/" + file;
+ std::string path = cmStrCat(dir, "/", file);
if (cmSystemTools::FileExists(path)) {
return path;
}
@@ -1003,10 +860,22 @@ bool cmSystemTools::RenameFile(const std::string& oldname,
#endif
}
+void cmSystemTools::MoveFileIfDifferent(const std::string& source,
+ const std::string& destination)
+{
+ if (FilesDiffer(source, destination)) {
+ if (RenameFile(source, destination)) {
+ return;
+ }
+ CopyFileAlways(source, destination);
+ }
+ RemoveFile(source);
+}
+
std::string cmSystemTools::ComputeFileHash(const std::string& source,
cmCryptoHash::Algo algo)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmCryptoHash hash(algo);
return hash.HashFile(source);
#else
@@ -1019,7 +888,7 @@ std::string cmSystemTools::ComputeFileHash(const std::string& source,
std::string cmSystemTools::ComputeStringMD5(const std::string& input)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmCryptoHash md5(cmCryptoHash::AlgoMD5);
return md5.HashString(input);
#else
@@ -1035,7 +904,7 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
{
std::string thumbprint;
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
BYTE* certData = NULL;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = NULL;
@@ -1139,9 +1008,7 @@ void cmSystemTools::GlobDirs(const std::string& path,
for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i) {
if ((std::string(d.GetFile(i)) != ".") &&
(std::string(d.GetFile(i)) != "..")) {
- std::string fname = startPath;
- fname += "/";
- fname += d.GetFile(i);
+ std::string fname = cmStrCat(startPath, '/', d.GetFile(i));
if (cmSystemTools::FileIsDirectory(fname)) {
fname += finishPath;
cmSystemTools::GlobDirs(fname, files);
@@ -1151,75 +1018,6 @@ void cmSystemTools::GlobDirs(const std::string& path,
}
}
-void cmSystemTools::ExpandListArgument(const std::string& arg,
- std::vector<std::string>& argsOut,
- bool emptyArgs)
-{
- // If argument is empty, it is an empty list.
- if (!emptyArgs && arg.empty()) {
- return;
- }
- // if there are no ; in the name then just copy the current string
- if (arg.find(';') == std::string::npos) {
- argsOut.push_back(arg);
- return;
- }
- std::string newArg;
- const char* last = arg.c_str();
- // Break the string at non-escaped semicolons not nested in [].
- int squareNesting = 0;
- for (const char* c = last; *c; ++c) {
- switch (*c) {
- case '\\': {
- // We only want to allow escaping of semicolons. Other
- // escapes should not be processed here.
- const char* next = c + 1;
- if (*next == ';') {
- newArg.append(last, c - last);
- // Skip over the escape character
- last = c = next;
- }
- } break;
- case '[': {
- ++squareNesting;
- } break;
- case ']': {
- --squareNesting;
- } break;
- case ';': {
- // Break the string here if we are not nested inside square
- // brackets.
- if (squareNesting == 0) {
- newArg.append(last, c - last);
- // Skip over the semicolon
- last = c + 1;
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(newArg);
- newArg.clear();
- }
- }
- } break;
- default: {
- // Just append this character.
- } break;
- }
- }
- newArg.append(last);
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(newArg);
- }
-}
-
-std::vector<std::string> cmSystemTools::ExpandedListArgument(
- const std::string& arg, bool emptyArgs)
-{
- std::vector<std::string> argsOut;
- ExpandListArgument(arg, argsOut, emptyArgs);
- return argsOut;
-}
-
bool cmSystemTools::SimpleGlob(const std::string& glob,
std::vector<std::string>& files,
int type /* = 0 */)
@@ -1264,65 +1062,6 @@ bool cmSystemTools::SimpleGlob(const std::string& glob,
return res;
}
-cmSystemTools::FileFormat cmSystemTools::GetFileFormat(std::string const& ext)
-{
- if (ext.empty()) {
- return cmSystemTools::NO_FILE_FORMAT;
- }
- if (ext == "c" || ext == ".c" || ext == "m" || ext == ".m") {
- return cmSystemTools::C_FILE_FORMAT;
- }
- if (ext == "C" || ext == ".C" || ext == "M" || ext == ".M" || ext == "c++" ||
- ext == ".c++" || ext == "cc" || ext == ".cc" || ext == "cpp" ||
- ext == ".cpp" || ext == "cxx" || ext == ".cxx" || ext == "mm" ||
- ext == ".mm") {
- return cmSystemTools::CXX_FILE_FORMAT;
- }
- if (ext == "f" || ext == ".f" || ext == "F" || ext == ".F" || ext == "f77" ||
- ext == ".f77" || ext == "f90" || ext == ".f90" || ext == "for" ||
- ext == ".for" || ext == "f95" || ext == ".f95") {
- return cmSystemTools::FORTRAN_FILE_FORMAT;
- }
- if (ext == "java" || ext == ".java") {
- return cmSystemTools::JAVA_FILE_FORMAT;
- }
- if (ext == "cu" || ext == ".cu") {
- return cmSystemTools::CUDA_FILE_FORMAT;
- }
- if (ext == "H" || ext == ".H" || ext == "h" || ext == ".h" || ext == "h++" ||
- ext == ".h++" || ext == "hm" || ext == ".hm" || ext == "hpp" ||
- ext == ".hpp" || ext == "hxx" || ext == ".hxx" || ext == "in" ||
- ext == ".in" || ext == "txx" || ext == ".txx") {
- return cmSystemTools::HEADER_FILE_FORMAT;
- }
- if (ext == "rc" || ext == ".rc") {
- return cmSystemTools::RESOURCE_FILE_FORMAT;
- }
- if (ext == "def" || ext == ".def") {
- return cmSystemTools::DEFINITION_FILE_FORMAT;
- }
- if (ext == "lib" || ext == ".lib" || ext == "a" || ext == ".a") {
- return cmSystemTools::STATIC_LIBRARY_FILE_FORMAT;
- }
- if (ext == "o" || ext == ".o" || ext == "obj" || ext == ".obj") {
- return cmSystemTools::OBJECT_FILE_FORMAT;
- }
-#ifdef __APPLE__
- if (ext == "dylib" || ext == ".dylib") {
- return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT;
- }
- if (ext == "so" || ext == ".so" || ext == "bundle" || ext == ".bundle") {
- return cmSystemTools::MODULE_FILE_FORMAT;
- }
-#else // __APPLE__
- if (ext == "so" || ext == ".so" || ext == "sl" || ext == ".sl" ||
- ext == "dll" || ext == ".dll") {
- return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT;
- }
-#endif // __APPLE__
- return cmSystemTools::UNKNOWN_FILE_FORMAT;
-}
-
std::string cmSystemTools::ConvertToOutputPath(std::string const& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1381,8 +1120,13 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
assert(local_path.front() != '\"');
assert(remote_path.front() != '\"');
- // The local path should never have a trailing slash.
- assert(local_path.empty() || local_path.back() != '/');
+ // The local path should never have a trailing slash except if it is just the
+ // bare root directory
+ assert(local_path.empty() || local_path.back() != '/' ||
+ local_path.size() == 1 ||
+ (local_path.size() == 3 && local_path[1] == ':' &&
+ ((local_path[0] >= 'A' && local_path[0] <= 'Z') ||
+ (local_path[0] >= 'a' && local_path[0] <= 'z'))));
// If the path is already relative then just return the path.
if (!cmSystemTools::FileIsFullPath(remote_path)) {
@@ -1448,12 +1192,11 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
return relative;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
bool cmSystemTools::UnsetEnv(const char* value)
{
# if !defined(HAVE_UNSETENV)
- std::string var = value;
- var += "=";
+ std::string var = cmStrCat(value, '=');
return cmSystemTools::PutEnv(var.c_str());
# else
unsetenv(value);
@@ -1513,7 +1256,7 @@ void cmSystemTools::EnableVSConsoleOutput()
// output and allow it to be captured on the fly.
cmSystemTools::PutEnv("vsconsoleoutput=1");
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
// VS sets an environment variable to tell MS tools like "cl" to report
// output through a backdoor pipe instead of stdout/stderr. Unset the
// environment variable to close this backdoor for any path of process
@@ -1535,14 +1278,12 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
std::string const& mtime,
std::string const& format)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
if (!fout) {
- std::string e = "Cannot open output file \"";
- e += outFileName;
- e += "\": ";
- e += cmSystemTools::GetLastSystemError();
+ std::string e = cmStrCat("Cannot open output file \"", outFileName,
+ "\": ", cmSystemTools::GetLastSystemError());
cmSystemTools::Error(e);
return false;
}
@@ -1589,7 +1330,7 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
#endif
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
namespace {
# define BSDTAR_FILESIZE_PRINTF "%lu"
# define BSDTAR_FILESIZE_TYPE unsigned long
@@ -1885,7 +1626,7 @@ bool cmSystemTools::ExtractTar(const std::string& outFileName,
const std::vector<std::string>& files,
bool verbose)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
return extract_tar(outFileName, files, verbose, true);
#else
(void)outFileName;
@@ -1899,7 +1640,7 @@ bool cmSystemTools::ListTar(const std::string& outFileName,
const std::vector<std::string>& files,
bool verbose)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
return extract_tar(outFileName, files, verbose, false);
#else
(void)outFileName;
@@ -1914,8 +1655,8 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
std::vector<char>& err)
{
line.clear();
- std::vector<char>::iterator outiter = out.begin();
- std::vector<char>::iterator erriter = err.begin();
+ auto outiter = out.begin();
+ auto erriter = err.begin();
cmProcessOutput processOutput;
std::string strdata;
while (true) {
@@ -2225,40 +1966,34 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
}
#endif
exe_dir = cmSystemTools::GetActualCaseForPath(exe_dir);
- cmSystemToolsCMakeCommand = exe_dir;
- cmSystemToolsCMakeCommand += "/cmake";
- cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension();
-#ifndef CMAKE_BUILD_WITH_CMAKE
+ cmSystemToolsCMakeCommand =
+ cmStrCat(exe_dir, "/cmake", cmSystemTools::GetExecutableExtension());
+#ifdef CMAKE_BOOTSTRAP
// The bootstrap cmake does not provide the other tools,
// so use the directory where they are about to be built.
exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
#endif
- cmSystemToolsCTestCommand = exe_dir;
- cmSystemToolsCTestCommand += "/ctest";
- cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension();
- cmSystemToolsCPackCommand = exe_dir;
- cmSystemToolsCPackCommand += "/cpack";
- cmSystemToolsCPackCommand += cmSystemTools::GetExecutableExtension();
- cmSystemToolsCMakeGUICommand = exe_dir;
- cmSystemToolsCMakeGUICommand += "/cmake-gui";
- cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension();
+ cmSystemToolsCTestCommand =
+ cmStrCat(exe_dir, "/ctest", cmSystemTools::GetExecutableExtension());
+ cmSystemToolsCPackCommand =
+ cmStrCat(exe_dir, "/cpack", cmSystemTools::GetExecutableExtension());
+ cmSystemToolsCMakeGUICommand =
+ cmStrCat(exe_dir, "/cmake-gui", cmSystemTools::GetExecutableExtension());
if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand)) {
cmSystemToolsCMakeGUICommand.clear();
}
- cmSystemToolsCMakeCursesCommand = exe_dir;
- cmSystemToolsCMakeCursesCommand += "/ccmake";
- cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension();
+ cmSystemToolsCMakeCursesCommand =
+ cmStrCat(exe_dir, "/ccmake", cmSystemTools::GetExecutableExtension());
if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand)) {
cmSystemToolsCMakeCursesCommand.clear();
}
- cmSystemToolsCMClDepsCommand = exe_dir;
- cmSystemToolsCMClDepsCommand += "/cmcldeps";
- cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension();
+ cmSystemToolsCMClDepsCommand =
+ cmStrCat(exe_dir, "/cmcldeps", cmSystemTools::GetExecutableExtension());
if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand)) {
cmSystemToolsCMClDepsCommand.clear();
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Install tree has
// - "<prefix><CMAKE_BIN_DIR>/cmake"
// - "<prefix><CMAKE_DATA_DIR>"
@@ -2456,7 +2191,8 @@ struct cmSystemToolsRPathInfo
#if defined(CMAKE_USE_ELF_PARSER)
bool cmSystemTools::ChangeRPath(std::string const& file,
std::string const& oldRPath,
- std::string const& newRPath, std::string* emsg,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath, std::string* emsg,
bool* changed)
{
if (changed) {
@@ -2490,8 +2226,9 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return true;
}
if (emsg) {
- *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
- *emsg += elf.GetErrorMessage();
+ *emsg =
+ cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ",
+ elf.GetErrorMessage());
}
return false;
}
@@ -2543,7 +2280,9 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
// Construct the new value which preserves the part of the path
// not being changed.
- rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
+ if (!removeEnvironmentRPath) {
+ rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
+ }
rp[rp_count].Value += newRPath;
rp[rp_count].Value += se[i]->Value.substr(pos + oldRPath.length());
@@ -2555,9 +2294,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
// least one null terminator.
if (rp[rp_count].Size < rp[rp_count].Value.length() + 1) {
if (emsg) {
- *emsg = "The replacement path is too long for the ";
- *emsg += se_name[i];
- *emsg += " entry.";
+ *emsg = cmStrCat("The replacement path is too long for the ",
+ se_name[i], " entry.");
}
return false;
}
@@ -2593,9 +2331,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
// Seek to the RPATH position.
if (!f.seekp(rp[i].Position)) {
if (emsg) {
- *emsg = "Error seeking to ";
- *emsg += rp[i].Name;
- *emsg += " position.";
+ *emsg = cmStrCat("Error seeking to ", rp[i].Name, " position.");
}
return false;
}
@@ -2610,9 +2346,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
// Make sure it wrote correctly.
if (!f) {
if (emsg) {
- *emsg = "Error writing the new ";
- *emsg += rp[i].Name;
- *emsg += " string to the file.";
+ *emsg = cmStrCat("Error writing the new ", rp[i].Name,
+ " string to the file.");
}
return false;
}
@@ -2629,6 +2364,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
bool cmSystemTools::ChangeRPath(std::string const& /*file*/,
std::string const& /*oldRPath*/,
std::string const& /*newRPath*/,
+ bool /*removeEnvironmentRPath*/,
std::string* /*emsg*/, bool* /*changed*/)
{
return false;
@@ -2640,7 +2376,8 @@ bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
{
const char* endl = lhss;
const char* endr = rhss;
- unsigned long lhs, rhs;
+ unsigned long lhs;
+ unsigned long rhs;
while (((*endl >= '0') && (*endl <= '9')) ||
((*endr >= '0') && (*endr <= '9'))) {
@@ -2825,8 +2562,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
// Adjust the entry list as necessary to remove the run path
unsigned long entriesErased = 0;
- for (cmELF::DynamicEntryList::iterator it = dentries.begin();
- it != dentries.end();) {
+ for (auto it = dentries.begin(); it != dentries.end();) {
if (it->first == cmELF::TagRPath || it->first == cmELF::TagRunPath) {
it = dentries.erase(it);
entriesErased++;
@@ -2951,61 +2687,20 @@ bool cmSystemTools::CheckRPath(std::string const& file,
bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
{
+#ifdef _WIN32
// Windows sometimes locks files temporarily so try a few times.
- for (int i = 0; i < 10; ++i) {
+ WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
+
+ for (unsigned int i = 0; i < retry.Count; ++i) {
if (cmSystemTools::RemoveADirectory(dir)) {
return true;
}
- cmSystemTools::Delay(100);
+ cmSystemTools::Delay(retry.Delay);
}
return false;
-}
-
-std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
- const std::string& sep)
-{
- std::vector<std::string> tokens;
- std::string::size_type tokend = 0;
-
- do {
- std::string::size_type tokstart = str.find_first_not_of(sep, tokend);
- if (tokstart == std::string::npos) {
- break; // no more tokens
- }
- tokend = str.find_first_of(sep, tokstart);
- if (tokend == std::string::npos) {
- tokens.push_back(str.substr(tokstart));
- } else {
- tokens.push_back(str.substr(tokstart, tokend - tokstart));
- }
- } while (tokend != std::string::npos);
-
- if (tokens.empty()) {
- tokens.emplace_back();
- }
- return tokens;
-}
-
-bool cmSystemTools::StringToLong(const char* str, long* value)
-{
- errno = 0;
- char* endp;
- *value = strtol(str, &endp, 10);
- return (*endp == '\0') && (endp != str) && (errno == 0);
-}
-
-bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
-{
- errno = 0;
- char* endp;
- while (isspace(*str)) {
- ++str;
- }
- if (*str == '-') {
- return false;
- }
- *value = strtoul(str, &endp, 10);
- return (*endp == '\0') && (endp != str) && (errno == 0);
+#else
+ return cmSystemTools::RemoveADirectory(dir);
+#endif
}
std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 016c2665f..ee149a029 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -5,16 +5,20 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCryptoHash.h"
-#include "cmDuration.h"
-#include "cmProcessOutput.h"
-#include "cmsys/Process.h"
-#include "cmsys/SystemTools.hxx" // IWYU pragma: export
+#include <cstddef>
#include <functional>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <cm/string_view>
+
+#include "cmsys/Process.h"
+#include "cmsys/SystemTools.hxx" // IWYU pragma: export
+
+#include "cmCryptoHash.h"
+#include "cmDuration.h"
+#include "cmProcessOutput.h"
+
/** \class cmSystemTools
* \brief A collection of useful functions for CMake.
*
@@ -24,51 +28,8 @@
class cmSystemTools : public cmsys::SystemTools
{
public:
- typedef cmsys::SystemTools Superclass;
- typedef cmProcessOutput::Encoding Encoding;
-
- /**
- * Expand the ; separated string @a arg into multiple arguments.
- * All found arguments are appended to @a argsOut.
- */
- static void ExpandListArgument(const std::string& arg,
- std::vector<std::string>& argsOut,
- bool emptyArgs = false);
-
- /**
- * Expand out any arguments in the string range [@a first, @a last) that have
- * ; separated strings into multiple arguments. All found arguments are
- * appended to @a argsOut.
- */
- template <class InputIt>
- static void ExpandLists(InputIt first, InputIt last,
- std::vector<std::string>& argsOut)
- {
- for (; first != last; ++first) {
- cmSystemTools::ExpandListArgument(*first, argsOut);
- }
- }
-
- /**
- * Same as ExpandListArgument but a new vector is created containing
- * the expanded arguments from the string @a arg.
- */
- static std::vector<std::string> ExpandedListArgument(const std::string& arg,
- bool emptyArgs = false);
-
- /**
- * Same as ExpandList but a new vector is created containing the expanded
- * versions of all arguments in the string range [@a first, @a last).
- */
- template <class InputIt>
- static std::vector<std::string> ExpandedLists(InputIt first, InputIt last)
- {
- std::vector<std::string> argsOut;
- for (; first != last; ++first) {
- cmSystemTools::ExpandListArgument(*first, argsOut);
- }
- return argsOut;
- }
+ using Superclass = cmsys::SystemTools;
+ using Encoding = cmProcessOutput::Encoding;
/**
* Look for and replace registry values in a string
@@ -76,16 +37,8 @@ public:
static void ExpandRegistryValues(std::string& source,
KeyWOW64 view = KeyWOW64_Default);
- //! Escape quotes in a string.
- static std::string EscapeQuotes(const std::string& str);
-
/** Map help document name to file name. */
- static std::string HelpFileName(std::string);
-
- /**
- * Returns a string that has whitespace removed from the start and the end.
- */
- static std::string TrimWhitespace(const std::string& s);
+ static std::string HelpFileName(cm::string_view);
using MessageCallback = std::function<void(const std::string&, const char*)>;
/**
@@ -144,31 +97,6 @@ public:
cmSystemTools::s_ErrorOccured = false;
}
- /**
- * Does a string indicates that CMake/CPack/CTest internally
- * forced this value. This is not the same as On, but this
- * may be considered as "internally switched on".
- */
- static bool IsInternallyOn(const char* val);
- /**
- * does a string indicate a true or on value ? This is not the same
- * as ifdef.
- */
- static bool IsOn(const char* val);
- static bool IsOn(const std::string& val);
-
- /**
- * does a string indicate a false or off value ? Note that this is
- * not the same as !IsOn(...) because there are a number of
- * ambiguous values such as "/usr/local/bin" a path will result in
- * IsON and IsOff both returning false. Note that the special path
- * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
- */
- static bool IsOff(const char* val);
- static bool IsOff(const std::string& val);
-
- //! Return true if value is NOTFOUND or ends in -NOTFOUND.
- static bool IsNOTFOUND(const char* value);
//! Return true if the path is a framework
static bool IsPathToFramework(const std::string& value);
@@ -206,6 +134,10 @@ public:
static bool RenameFile(const std::string& oldname,
const std::string& newname);
+ //! Rename a file if contents are different, delete the source otherwise
+ static void MoveFileIfDifferent(const std::string& source,
+ const std::string& destination);
+
//! Compute the hash of a file
static std::string ComputeFileHash(const std::string& source,
cmCryptoHash::Algo algo);
@@ -299,27 +231,6 @@ public:
static void EnableRunCommandOutput() { s_DisableRunCommandOutput = false; }
static bool GetRunCommandOutput() { return s_DisableRunCommandOutput; }
- /**
- * Some constants for different file formats.
- */
- enum FileFormat
- {
- NO_FILE_FORMAT = 0,
- C_FILE_FORMAT,
- CXX_FILE_FORMAT,
- FORTRAN_FILE_FORMAT,
- JAVA_FILE_FORMAT,
- CUDA_FILE_FORMAT,
- HEADER_FILE_FORMAT,
- RESOURCE_FILE_FORMAT,
- DEFINITION_FILE_FORMAT,
- STATIC_LIBRARY_FILE_FORMAT,
- SHARED_LIBRARY_FILE_FORMAT,
- MODULE_FILE_FORMAT,
- OBJECT_FILE_FORMAT,
- UNKNOWN_FILE_FORMAT
- };
-
enum CompareOp
{
OP_EQUAL = 1,
@@ -350,11 +261,6 @@ public:
*/
static int strverscmp(std::string const& lhs, std::string const& rhs);
- /**
- * Determine the file type based on the extension
- */
- static FileFormat GetFileFormat(std::string const& ext);
-
/** Windows if this is true, the CreateProcess in RunCommand will
* not show new console windows when running programs.
*/
@@ -401,7 +307,7 @@ public:
static std::string ForceToRelativePath(std::string const& local_path,
std::string const& remote_path);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
/** Remove an environment variable */
static bool UnsetEnv(const char* value);
@@ -499,6 +405,7 @@ public:
/** Try to set the RPATH in an ELF binary. */
static bool ChangeRPath(std::string const& file, std::string const& oldRPath,
std::string const& newRPath,
+ bool removeEnvironmentRPath,
std::string* emsg = nullptr,
bool* changed = nullptr);
@@ -513,14 +420,6 @@ public:
/** Remove a directory; repeat a few times in case of locked files. */
static bool RepeatedRemoveDirectory(const std::string& dir);
- /** Tokenize a string */
- static std::vector<std::string> tokenize(const std::string& str,
- const std::string& sep);
-
- /** Convert string to long. Expected that the whole string is an integer */
- static bool StringToLong(const char* str, long* value);
- static bool StringToULong(const char* str, unsigned long* value);
-
/** Encode a string as a URL. */
static std::string EncodeURL(std::string const& in,
bool escapeSlashes = true);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 98c66da2c..2db89dea1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2,16 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTarget.h"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
-#include <assert.h>
+#include <cassert>
+#include <cstring>
#include <initializer_list>
#include <iterator>
#include <set>
#include <sstream>
-#include <string.h>
#include <unordered_set>
+#include <cm/memory>
+
+#include "cmsys/RegularExpression.hxx"
+
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmGeneratorExpression.h"
@@ -86,8 +89,7 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>(
std::ostringstream ss;
const char* sep = "";
for (std::string const& entry : entries) {
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
for (std::string const& file : files) {
if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
file.back() == '>') {
@@ -168,7 +170,8 @@ public:
cmPropertyMap Properties;
bool IsGeneratorProvided;
bool HaveInstallRule;
- bool DLLPlatform;
+ bool IsDLLPlatform;
+ bool IsAIX;
bool IsAndroid;
bool IsImportedTarget;
bool ImportedGloballyVisible;
@@ -188,6 +191,8 @@ public:
std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
std::vector<std::string> CompileDefinitionsEntries;
std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+ std::vector<std::string> PrecompileHeadersEntries;
+ std::vector<cmListFileBacktrace> PrecompileHeadersBacktraces;
std::vector<std::string> SourceEntries;
std::vector<cmListFileBacktrace> SourceBacktraces;
std::vector<std::string> LinkOptionsEntries;
@@ -217,7 +222,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
impl->Name = name;
impl->IsGeneratorProvided = false;
impl->HaveInstallRule = false;
- impl->DLLPlatform = false;
+ impl->IsDLLPlatform = false;
+ impl->IsAIX = false;
impl->IsAndroid = false;
impl->IsImportedTarget =
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
@@ -225,21 +231,32 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
impl->BuildInterfaceIncludesAppended = false;
// Check whether this is a DLL platform.
- impl->DLLPlatform =
+ impl->IsDLLPlatform =
!impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
+ // Check whether we are targeting AIX.
+ impl->IsAIX =
+ (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "AIX");
+
// Check whether we are targeting an Android platform.
impl->IsAndroid =
(impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
- std::string gKey;
- gKey.reserve(128);
- gKey += "CMAKE_";
- auto InitProperty = [this, mf, &gKey](const std::string& property,
- const char* default_value) {
+ std::string defKey;
+ defKey.reserve(128);
+ defKey += "CMAKE_";
+ auto initProp = [this, mf, &defKey](const std::string& property) {
// Replace everything after "CMAKE_"
- gKey.replace(gKey.begin() + 6, gKey.end(), property);
- if (const char* value = mf->GetDefinition(gKey)) {
+ defKey.replace(defKey.begin() + 6, defKey.end(), property);
+ if (const char* value = mf->GetDefinition(defKey)) {
+ this->SetProperty(property, value);
+ }
+ };
+ auto initPropValue = [this, mf, &defKey](const std::string& property,
+ const char* default_value) {
+ // Replace everything after "CMAKE_"
+ defKey.replace(defKey.begin() + 6, defKey.end(), property);
+ if (const char* value = mf->GetDefinition(defKey)) {
this->SetProperty(property, value);
} else if (default_value) {
this->SetProperty(property, default_value);
@@ -249,113 +266,127 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
// Setup default property values.
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetType() != cmStateEnums::UTILITY) {
- InitProperty("ANDROID_API", nullptr);
- InitProperty("ANDROID_API_MIN", nullptr);
- InitProperty("ANDROID_ARCH", nullptr);
- InitProperty("ANDROID_STL_TYPE", nullptr);
- InitProperty("ANDROID_SKIP_ANT_STEP", nullptr);
- InitProperty("ANDROID_PROCESS_MAX", nullptr);
- InitProperty("ANDROID_PROGUARD", nullptr);
- InitProperty("ANDROID_PROGUARD_CONFIG_PATH", nullptr);
- InitProperty("ANDROID_SECURE_PROPS_PATH", nullptr);
- InitProperty("ANDROID_NATIVE_LIB_DIRECTORIES", nullptr);
- InitProperty("ANDROID_NATIVE_LIB_DEPENDENCIES", nullptr);
- InitProperty("ANDROID_JAVA_SOURCE_DIR", nullptr);
- InitProperty("ANDROID_JAR_DIRECTORIES", nullptr);
- InitProperty("ANDROID_JAR_DEPENDENCIES", nullptr);
- InitProperty("ANDROID_ASSETS_DIRECTORIES", nullptr);
- InitProperty("ANDROID_ANT_ADDITIONAL_OPTIONS", nullptr);
- InitProperty("BUILD_RPATH", nullptr);
- InitProperty("BUILD_RPATH_USE_ORIGIN", nullptr);
- InitProperty("INSTALL_NAME_DIR", nullptr);
- InitProperty("INSTALL_RPATH", "");
- InitProperty("INSTALL_RPATH_USE_LINK_PATH", "OFF");
- InitProperty("INTERPROCEDURAL_OPTIMIZATION", nullptr);
- InitProperty("SKIP_BUILD_RPATH", "OFF");
- InitProperty("BUILD_WITH_INSTALL_RPATH", "OFF");
- InitProperty("ARCHIVE_OUTPUT_DIRECTORY", nullptr);
- InitProperty("LIBRARY_OUTPUT_DIRECTORY", nullptr);
- InitProperty("RUNTIME_OUTPUT_DIRECTORY", nullptr);
- InitProperty("PDB_OUTPUT_DIRECTORY", nullptr);
- InitProperty("COMPILE_PDB_OUTPUT_DIRECTORY", nullptr);
- InitProperty("FRAMEWORK", nullptr);
- InitProperty("Fortran_FORMAT", nullptr);
- InitProperty("Fortran_MODULE_DIRECTORY", nullptr);
- InitProperty("Fortran_COMPILER_LAUNCHER", nullptr);
- InitProperty("GNUtoMS", nullptr);
- InitProperty("OSX_ARCHITECTURES", nullptr);
- InitProperty("IOS_INSTALL_COMBINED", nullptr);
- InitProperty("AUTOMOC", nullptr);
- InitProperty("AUTOUIC", nullptr);
- InitProperty("AUTORCC", nullptr);
- InitProperty("AUTOGEN_ORIGIN_DEPENDS", nullptr);
- InitProperty("AUTOGEN_PARALLEL", nullptr);
- InitProperty("AUTOMOC_COMPILER_PREDEFINES", nullptr);
- InitProperty("AUTOMOC_DEPEND_FILTERS", nullptr);
- InitProperty("AUTOMOC_MACRO_NAMES", nullptr);
- InitProperty("AUTOMOC_MOC_OPTIONS", nullptr);
- InitProperty("AUTOUIC_OPTIONS", nullptr);
- InitProperty("AUTOUIC_SEARCH_PATHS", nullptr);
- InitProperty("AUTORCC_OPTIONS", nullptr);
- InitProperty("LINK_DEPENDS_NO_SHARED", nullptr);
- InitProperty("LINK_INTERFACE_LIBRARIES", nullptr);
- InitProperty("MSVC_RUNTIME_LIBRARY", nullptr);
- InitProperty("WIN32_EXECUTABLE", nullptr);
- InitProperty("MACOSX_BUNDLE", nullptr);
- InitProperty("MACOSX_RPATH", nullptr);
- InitProperty("NO_SYSTEM_FROM_IMPORTED", nullptr);
- InitProperty("BUILD_WITH_INSTALL_NAME_DIR", nullptr);
- InitProperty("C_CLANG_TIDY", nullptr);
- InitProperty("C_COMPILER_LAUNCHER", nullptr);
- InitProperty("C_CPPLINT", nullptr);
- InitProperty("C_CPPCHECK", nullptr);
- InitProperty("C_INCLUDE_WHAT_YOU_USE", nullptr);
- InitProperty("LINK_WHAT_YOU_USE", nullptr);
- InitProperty("C_STANDARD", nullptr);
- InitProperty("C_STANDARD_REQUIRED", nullptr);
- InitProperty("C_EXTENSIONS", nullptr);
- InitProperty("CXX_CLANG_TIDY", nullptr);
- InitProperty("CXX_COMPILER_LAUNCHER", nullptr);
- InitProperty("CXX_CPPLINT", nullptr);
- InitProperty("CXX_CPPCHECK", nullptr);
- InitProperty("CXX_INCLUDE_WHAT_YOU_USE", nullptr);
- InitProperty("CXX_STANDARD", nullptr);
- InitProperty("CXX_STANDARD_REQUIRED", nullptr);
- InitProperty("CXX_EXTENSIONS", nullptr);
- InitProperty("CUDA_STANDARD", nullptr);
- InitProperty("CUDA_STANDARD_REQUIRED", nullptr);
- InitProperty("CUDA_EXTENSIONS", nullptr);
- InitProperty("CUDA_COMPILER_LAUNCHER", nullptr);
- InitProperty("CUDA_SEPARABLE_COMPILATION", nullptr);
- InitProperty("LINK_SEARCH_START_STATIC", nullptr);
- InitProperty("LINK_SEARCH_END_STATIC", nullptr);
- InitProperty("FOLDER", nullptr);
- InitProperty("Swift_MODULE_DIRECTORY", nullptr);
- InitProperty("VS_JUST_MY_CODE_DEBUGGING", nullptr);
+ initProp("ANDROID_API");
+ initProp("ANDROID_API_MIN");
+ initProp("ANDROID_ARCH");
+ initProp("ANDROID_STL_TYPE");
+ initProp("ANDROID_SKIP_ANT_STEP");
+ initProp("ANDROID_PROCESS_MAX");
+ initProp("ANDROID_PROGUARD");
+ initProp("ANDROID_PROGUARD_CONFIG_PATH");
+ initProp("ANDROID_SECURE_PROPS_PATH");
+ initProp("ANDROID_NATIVE_LIB_DIRECTORIES");
+ initProp("ANDROID_NATIVE_LIB_DEPENDENCIES");
+ initProp("ANDROID_JAVA_SOURCE_DIR");
+ initProp("ANDROID_JAR_DIRECTORIES");
+ initProp("ANDROID_JAR_DEPENDENCIES");
+ initProp("ANDROID_ASSETS_DIRECTORIES");
+ initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
+ initProp("BUILD_RPATH");
+ initProp("BUILD_RPATH_USE_ORIGIN");
+ initProp("INSTALL_NAME_DIR");
+ initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
+ initPropValue("INSTALL_RPATH", "");
+ initPropValue("INSTALL_RPATH_USE_LINK_PATH", "OFF");
+ initProp("INTERPROCEDURAL_OPTIMIZATION");
+ initPropValue("SKIP_BUILD_RPATH", "OFF");
+ initPropValue("BUILD_WITH_INSTALL_RPATH", "OFF");
+ initProp("ARCHIVE_OUTPUT_DIRECTORY");
+ initProp("LIBRARY_OUTPUT_DIRECTORY");
+ initProp("RUNTIME_OUTPUT_DIRECTORY");
+ initProp("PDB_OUTPUT_DIRECTORY");
+ initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
+ initProp("FRAMEWORK");
+ initProp("Fortran_FORMAT");
+ initProp("Fortran_MODULE_DIRECTORY");
+ initProp("Fortran_COMPILER_LAUNCHER");
+ initProp("GNUtoMS");
+ initProp("OSX_ARCHITECTURES");
+ initProp("IOS_INSTALL_COMBINED");
+ initProp("AUTOMOC");
+ initProp("AUTOUIC");
+ initProp("AUTORCC");
+ initProp("AUTOGEN_ORIGIN_DEPENDS");
+ initProp("AUTOGEN_PARALLEL");
+ initProp("AUTOMOC_COMPILER_PREDEFINES");
+ initProp("AUTOMOC_DEPEND_FILTERS");
+ initProp("AUTOMOC_MACRO_NAMES");
+ initProp("AUTOMOC_MOC_OPTIONS");
+ initProp("AUTOUIC_OPTIONS");
+ initProp("AUTOMOC_PATH_PREFIX");
+ initProp("AUTOUIC_SEARCH_PATHS");
+ initProp("AUTORCC_OPTIONS");
+ initProp("LINK_DEPENDS_NO_SHARED");
+ initProp("LINK_INTERFACE_LIBRARIES");
+ initProp("MSVC_RUNTIME_LIBRARY");
+ initProp("WIN32_EXECUTABLE");
+ initProp("MACOSX_BUNDLE");
+ initProp("MACOSX_RPATH");
+ initProp("NO_SYSTEM_FROM_IMPORTED");
+ initProp("BUILD_WITH_INSTALL_NAME_DIR");
+ initProp("C_CLANG_TIDY");
+ initProp("C_COMPILER_LAUNCHER");
+ initProp("C_CPPLINT");
+ initProp("C_CPPCHECK");
+ initProp("C_INCLUDE_WHAT_YOU_USE");
+ initProp("LINK_WHAT_YOU_USE");
+ initProp("C_STANDARD");
+ initProp("C_STANDARD_REQUIRED");
+ initProp("C_EXTENSIONS");
+ initProp("OBJC_STANDARD");
+ initProp("OBJC_STANDARD_REQUIRED");
+ initProp("OBJC_EXTENSIONS");
+ initProp("CXX_CLANG_TIDY");
+ initProp("CXX_COMPILER_LAUNCHER");
+ initProp("CXX_CPPLINT");
+ initProp("CXX_CPPCHECK");
+ initProp("CXX_INCLUDE_WHAT_YOU_USE");
+ initProp("CXX_STANDARD");
+ initProp("CXX_STANDARD_REQUIRED");
+ initProp("CXX_EXTENSIONS");
+ initProp("OBJCXX_STANDARD");
+ initProp("OBJCXX_STANDARD_REQUIRED");
+ initProp("OBJCXX_EXTENSIONS");
+ initProp("CUDA_STANDARD");
+ initProp("CUDA_STANDARD_REQUIRED");
+ initProp("CUDA_EXTENSIONS");
+ initProp("CUDA_COMPILER_LAUNCHER");
+ initProp("CUDA_SEPARABLE_COMPILATION");
+ initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
+ initProp("LINK_SEARCH_START_STATIC");
+ initProp("LINK_SEARCH_END_STATIC");
+ initProp("FOLDER");
+ initProp("Swift_LANGUAGE_VERSION");
+ initProp("Swift_MODULE_DIRECTORY");
+ initProp("VS_JUST_MY_CODE_DEBUGGING");
+ initProp("DISABLE_PRECOMPILE_HEADERS");
+ initProp("UNITY_BUILD");
+ initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
- InitProperty("XCODE_SCHEME_ADDRESS_SANITIZER", nullptr);
- InitProperty("XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN", nullptr);
- InitProperty("XCODE_SCHEME_THREAD_SANITIZER", nullptr);
- InitProperty("XCODE_SCHEME_THREAD_SANITIZER_STOP", nullptr);
- InitProperty("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER", nullptr);
- InitProperty("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP", nullptr);
- InitProperty("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER", nullptr);
- InitProperty("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP", nullptr);
- InitProperty("XCODE_SCHEME_MALLOC_SCRIBBLE", nullptr);
- InitProperty("XCODE_SCHEME_MALLOC_GUARD_EDGES", nullptr);
- InitProperty("XCODE_SCHEME_GUARD_MALLOC", nullptr);
- InitProperty("XCODE_SCHEME_ZOMBIE_OBJECTS", nullptr);
- InitProperty("XCODE_SCHEME_MALLOC_STACK", nullptr);
- InitProperty("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE", nullptr);
- InitProperty("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS", nullptr);
+ initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
+ initProp("XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN");
+ initProp("XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING");
+ initProp("XCODE_SCHEME_THREAD_SANITIZER");
+ initProp("XCODE_SCHEME_THREAD_SANITIZER_STOP");
+ initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER");
+ initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP");
+ initProp("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER");
+ initProp("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP");
+ initProp("XCODE_SCHEME_MALLOC_SCRIBBLE");
+ initProp("XCODE_SCHEME_MALLOC_GUARD_EDGES");
+ initProp("XCODE_SCHEME_GUARD_MALLOC");
+ initProp("XCODE_SCHEME_ZOMBIE_OBJECTS");
+ initProp("XCODE_SCHEME_MALLOC_STACK");
+ initProp("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE");
+ initProp("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS");
}
#endif
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (this->GetGlobalGenerator()->IsXcode()) {
- InitProperty("XCODE_GENERATE_SCHEME", nullptr);
+ initProp("XCODE_GENERATE_SCHEME");
}
}
@@ -380,9 +411,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) {
continue;
}
- std::string property = prop;
- property += configUpper;
- InitProperty(property, nullptr);
+ std::string property = cmStrCat(prop, configUpper);
+ initProp(property);
}
// Initialize per-configuration name postfix property from the
@@ -392,9 +422,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
// property directly.
if (impl->TargetType != cmStateEnums::EXECUTABLE &&
impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) {
- std::string property = cmSystemTools::UpperCase(configName);
- property += "_POSTFIX";
- InitProperty(property, nullptr);
+ std::string property =
+ cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
+ initProp(property);
}
}
}
@@ -433,16 +463,18 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetType() != cmStateEnums::UTILITY) {
- InitProperty("C_VISIBILITY_PRESET", nullptr);
- InitProperty("CXX_VISIBILITY_PRESET", nullptr);
- InitProperty("CUDA_VISIBILITY_PRESET", nullptr);
- InitProperty("VISIBILITY_INLINES_HIDDEN", nullptr);
+ initProp("C_VISIBILITY_PRESET");
+ initProp("CXX_VISIBILITY_PRESET");
+ initProp("OBJC_VISIBILITY_PRESET");
+ initProp("OBJCXX_VISIBILITY_PRESET");
+ initProp("CUDA_VISIBILITY_PRESET");
+ initProp("VISIBILITY_INLINES_HIDDEN");
}
if (impl->TargetType == cmStateEnums::EXECUTABLE) {
- InitProperty("ANDROID_GUI", nullptr);
- InitProperty("CROSSCOMPILING_EMULATOR", nullptr);
- InitProperty("ENABLE_EXPORTS", nullptr);
+ initProp("ANDROID_GUI");
+ initProp("CROSSCOMPILING_EMULATOR");
+ initProp("ENABLE_EXPORTS");
}
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
@@ -450,12 +482,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
impl->TargetType == cmStateEnums::EXECUTABLE) {
- InitProperty("WINDOWS_EXPORT_ALL_SYMBOLS", nullptr);
+ initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetType() != cmStateEnums::UTILITY) {
- InitProperty("POSITION_INDEPENDENT_CODE", nullptr);
+ initProp("POSITION_INDEPENDENT_CODE");
}
// Record current policies for later use.
@@ -471,12 +503,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetType() != cmStateEnums::UTILITY) {
- InitProperty("JOB_POOL_COMPILE", nullptr);
- InitProperty("JOB_POOL_LINK", nullptr);
+ initProp("JOB_POOL_COMPILE");
+ initProp("JOB_POOL_LINK");
}
if (impl->TargetType <= cmStateEnums::UTILITY) {
- InitProperty("DOTNET_TARGET_FRAMEWORK_VERSION", nullptr);
+ initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
@@ -488,8 +520,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (globals) {
const std::string genName = mf->GetGlobalGenerator()->GetName();
if (cmHasLiteralPrefix(genName, "Visual Studio")) {
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(globals, props);
+ std::vector<std::string> props = cmExpandedList(globals);
const std::string vsGlobal = "VS_GLOBAL_";
for (const std::string& i : props) {
// split NAME=VALUE
@@ -497,7 +528,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (assignment != std::string::npos) {
const std::string propName = vsGlobal + i.substr(0, assignment);
const std::string propValue = i.substr(assignment + 1);
- InitProperty(propName, propValue.c_str());
+ initPropValue(propName, propValue.c_str());
}
}
}
@@ -588,6 +619,11 @@ void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd)
impl->PreBuildCommands.push_back(cmd);
}
+void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd)
+{
+ impl->PreBuildCommands.push_back(std::move(cmd));
+}
+
std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const
{
return impl->PreLinkCommands;
@@ -598,6 +634,11 @@ void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd)
impl->PreLinkCommands.push_back(cmd);
}
+void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd)
+{
+ impl->PreLinkCommands.push_back(std::move(cmd));
+}
+
std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const
{
return impl->PostBuildCommands;
@@ -608,6 +649,11 @@ void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd)
impl->PostBuildCommands.push_back(cmd);
}
+void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd)
+{
+ impl->PostBuildCommands.push_back(std::move(cmd));
+}
+
void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
{
if (!srcs.empty()) {
@@ -679,13 +725,9 @@ std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s)
return src;
}
-cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
+std::string cmTarget::GetSourceCMP0049(const std::string& s)
{
- std::string src = impl->ProcessSourceItemCMP0049(s);
- if (!s.empty() && src.empty()) {
- return nullptr;
- }
- return this->AddSource(src);
+ return impl->ProcessSourceItemCMP0049(s);
}
struct CreateLocation
@@ -731,8 +773,7 @@ public:
bool operator()(std::string const& entry)
{
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
+ std::vector<std::string> files = cmExpandedList(entry);
std::vector<cmSourceFileLocation> locations;
locations.reserve(files.size());
std::transform(files.begin(), files.end(), std::back_inserter(locations),
@@ -766,8 +807,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src, bool before)
void cmTarget::ClearDependencyInformation(cmMakefile& mf)
{
- std::string depname = this->GetName();
- depname += "_LIB_DEPENDS";
+ std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS");
mf.RemoveCacheDefinition(depname);
}
@@ -935,8 +975,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
impl->TargetType <= cmStateEnums::MODULE_LIBRARY &&
(this->GetPolicyStatusCMP0073() == cmPolicies::OLD ||
this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) {
- std::string targetEntry = impl->Name;
- targetEntry += "_LIB_DEPENDS";
+ std::string targetEntry = cmStrCat(impl->Name, "_LIB_DEPENDS");
std::string dependencies;
const char* old_val = mf.GetDefinition(targetEntry);
if (old_val) {
@@ -1011,6 +1050,16 @@ cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
return cmMakeRange(impl->CompileDefinitionsBacktraces);
}
+cmStringRange cmTarget::GetPrecompileHeadersEntries() const
+{
+ return cmMakeRange(impl->PrecompileHeadersEntries);
+}
+
+cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const
+{
+ return cmMakeRange(impl->PrecompileHeadersBacktraces);
+}
+
cmStringRange cmTarget::GetSourceEntries() const
{
return cmMakeRange(impl->SourceEntries);
@@ -1062,6 +1111,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(COMPILE_FEATURES);
MAKE_STATIC_PROP(COMPILE_OPTIONS);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
MAKE_STATIC_PROP(EXPORT_NAME);
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
@@ -1075,21 +1126,19 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
MAKE_STATIC_PROP(TYPE);
#undef MAKE_STATIC_PROP
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
- std::ostringstream e;
- e << "MANUALLY_ADDED_DEPENDENCIES property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "MANUALLY_ADDED_DEPENDENCIES property is read-only\n");
return;
}
if (prop == propNAME) {
- std::ostringstream e;
- e << "NAME property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == propTYPE) {
- std::ostringstream e;
- e << "TYPE property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "TYPE property is read-only\n");
return;
}
if (prop == propEXPORT_NAME && this->IsImported()) {
@@ -1162,6 +1211,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
+ } else if (prop == propPRECOMPILE_HEADERS) {
+ impl->PrecompileHeadersEntries.clear();
+ impl->PrecompileHeadersBacktraces.clear();
+ if (value) {
+ impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
+ impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ }
} else if (prop == propLINK_LIBRARIES) {
impl->LinkImplementationPropertyEntries.clear();
impl->LinkImplementationPropertyBacktraces.clear();
@@ -1179,7 +1236,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
impl->SourceBacktraces.push_back(lfbt);
}
} else if (prop == propIMPORTED_GLOBAL) {
- if (!cmSystemTools::IsOn(value)) {
+ if (!cmIsOn(value)) {
std::ostringstream e;
e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\""
<< impl->Name << "\")\n";
@@ -1202,6 +1259,38 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
<< impl->Name << "\")\n";
impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
+ } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) {
+ if (this->GetProperty("PRECOMPILE_HEADERS")) {
+ std::ostringstream e;
+ e << "PRECOMPILE_HEADERS property is already set on target (\""
+ << impl->Name << "\")\n";
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return;
+ }
+ auto reusedTarget =
+ impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
+ value);
+ if (!reusedTarget) {
+ const std::string e(
+ "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target");
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+ return;
+ }
+
+ std::string reusedFrom = reusedTarget->GetSafeProperty(prop);
+ if (reusedFrom.empty()) {
+ reusedFrom = value;
+ }
+
+ impl->Properties.SetProperty(prop, reusedFrom.c_str());
+
+ reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str());
+ reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ cmStrCat(reusedFrom, ".dir/").c_str());
+
+ this->SetProperty("COMPILE_PDB_NAME",
+ reusedTarget->GetProperty("COMPILE_PDB_NAME"));
+ this->AddUtility(reusedFrom, impl->Makefile);
} else {
impl->Properties.SetProperty(prop, value);
}
@@ -1216,9 +1305,8 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
return;
}
if (prop == "NAME") {
- std::ostringstream e;
- e << "NAME property is read-only\n";
- impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "NAME property is read-only\n");
return;
}
if (prop == "EXPORT_NAME" && this->IsImported()) {
@@ -1279,6 +1367,20 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
}
+ } else if (prop == "PRECOMPILE_HEADERS") {
+ if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
+ std::ostringstream e;
+ e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target "
+ "(\""
+ << impl->Name << "\")\n";
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return;
+ }
+ if (value && *value) {
+ impl->PrecompileHeadersEntries.emplace_back(value);
+ cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
+ impl->PrecompileHeadersBacktraces.push_back(lfbt);
+ }
} else if (prop == "LINK_LIBRARIES") {
if (value && *value) {
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
@@ -1327,13 +1429,11 @@ void cmTarget::AppendBuildInterfaceIncludes()
void cmTarget::InsertInclude(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- std::vector<std::string>::iterator position = before
- ? impl->IncludeDirectoriesEntries.begin()
- : impl->IncludeDirectoriesEntries.end();
+ auto position = before ? impl->IncludeDirectoriesEntries.begin()
+ : impl->IncludeDirectoriesEntries.end();
- std::vector<cmListFileBacktrace>::iterator btPosition = before
- ? impl->IncludeDirectoriesBacktraces.begin()
- : impl->IncludeDirectoriesBacktraces.end();
+ auto btPosition = before ? impl->IncludeDirectoriesBacktraces.begin()
+ : impl->IncludeDirectoriesBacktraces.end();
impl->IncludeDirectoriesEntries.insert(position, entry);
impl->IncludeDirectoriesBacktraces.insert(btPosition, bt);
@@ -1342,13 +1442,11 @@ void cmTarget::InsertInclude(std::string const& entry,
void cmTarget::InsertCompileOption(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- std::vector<std::string>::iterator position = before
- ? impl->CompileOptionsEntries.begin()
- : impl->CompileOptionsEntries.end();
+ auto position = before ? impl->CompileOptionsEntries.begin()
+ : impl->CompileOptionsEntries.end();
- std::vector<cmListFileBacktrace>::iterator btPosition = before
- ? impl->CompileOptionsBacktraces.begin()
- : impl->CompileOptionsBacktraces.end();
+ auto btPosition = before ? impl->CompileOptionsBacktraces.begin()
+ : impl->CompileOptionsBacktraces.end();
impl->CompileOptionsEntries.insert(position, entry);
impl->CompileOptionsBacktraces.insert(btPosition, bt);
@@ -1364,12 +1462,11 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
void cmTarget::InsertLinkOption(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- std::vector<std::string>::iterator position =
+ auto position =
before ? impl->LinkOptionsEntries.begin() : impl->LinkOptionsEntries.end();
- std::vector<cmListFileBacktrace>::iterator btPosition = before
- ? impl->LinkOptionsBacktraces.begin()
- : impl->LinkOptionsBacktraces.end();
+ auto btPosition = before ? impl->LinkOptionsBacktraces.begin()
+ : impl->LinkOptionsBacktraces.end();
impl->LinkOptionsEntries.insert(position, entry);
impl->LinkOptionsBacktraces.insert(btPosition, bt);
@@ -1378,18 +1475,23 @@ void cmTarget::InsertLinkOption(std::string const& entry,
void cmTarget::InsertLinkDirectory(std::string const& entry,
cmListFileBacktrace const& bt, bool before)
{
- std::vector<std::string>::iterator position = before
- ? impl->LinkDirectoriesEntries.begin()
- : impl->LinkDirectoriesEntries.end();
+ auto position = before ? impl->LinkDirectoriesEntries.begin()
+ : impl->LinkDirectoriesEntries.end();
- std::vector<cmListFileBacktrace>::iterator btPosition = before
- ? impl->LinkDirectoriesBacktraces.begin()
- : impl->LinkDirectoriesBacktraces.end();
+ auto btPosition = before ? impl->LinkDirectoriesBacktraces.begin()
+ : impl->LinkDirectoriesBacktraces.end();
impl->LinkDirectoriesEntries.insert(position, entry);
impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
}
+void cmTarget::InsertPrecompileHeader(std::string const& entry,
+ cmListFileBacktrace const& bt)
+{
+ impl->PrecompileHeadersEntries.push_back(entry);
+ impl->PrecompileHeadersBacktraces.push_back(bt);
+}
+
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
const char* value,
cmMakefile* context,
@@ -1455,8 +1557,7 @@ static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
cmMakefile* context)
{
std::vector<cmTarget*> targets = context->GetOwnedImportedTargets();
- std::vector<cmTarget*>::const_iterator it =
- std::find(targets.begin(), targets.end(), target);
+ auto it = std::find(targets.begin(), targets.end(), target);
if (it == targets.end()) {
std::ostringstream e;
e << "Attempt to promote imported target \"" << target->GetName()
@@ -1501,7 +1602,6 @@ const char* cmTarget::GetComputedProperty(
const char* cmTarget::GetProperty(const std::string& prop) const
{
- static std::unordered_set<std::string> specialProps;
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
MAKE_STATIC_PROP(LINK_LIBRARIES);
MAKE_STATIC_PROP(TYPE);
@@ -1511,6 +1611,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(LINK_OPTIONS);
MAKE_STATIC_PROP(LINK_DIRECTORIES);
+ MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
MAKE_STATIC_PROP(IMPORTED);
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
@@ -1519,23 +1620,24 @@ const char* cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(SOURCE_DIR);
MAKE_STATIC_PROP(SOURCES);
#undef MAKE_STATIC_PROP
- if (specialProps.empty()) {
- specialProps.insert(propLINK_LIBRARIES);
- specialProps.insert(propTYPE);
- specialProps.insert(propINCLUDE_DIRECTORIES);
- specialProps.insert(propCOMPILE_FEATURES);
- specialProps.insert(propCOMPILE_OPTIONS);
- specialProps.insert(propCOMPILE_DEFINITIONS);
- specialProps.insert(propLINK_OPTIONS);
- specialProps.insert(propLINK_DIRECTORIES);
- specialProps.insert(propIMPORTED);
- specialProps.insert(propIMPORTED_GLOBAL);
- specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES);
- specialProps.insert(propNAME);
- specialProps.insert(propBINARY_DIR);
- specialProps.insert(propSOURCE_DIR);
- specialProps.insert(propSOURCES);
- }
+ static std::unordered_set<std::string> const specialProps{
+ propLINK_LIBRARIES,
+ propTYPE,
+ propINCLUDE_DIRECTORIES,
+ propCOMPILE_FEATURES,
+ propCOMPILE_OPTIONS,
+ propCOMPILE_DEFINITIONS,
+ propPRECOMPILE_HEADERS,
+ propLINK_OPTIONS,
+ propLINK_DIRECTORIES,
+ propIMPORTED,
+ propIMPORTED_GLOBAL,
+ propMANUALLY_ADDED_DEPENDENCIES,
+ propNAME,
+ propBINARY_DIR,
+ propSOURCE_DIR,
+ propSOURCES
+ };
if (specialProps.count(prop)) {
if (prop == propLINK_LIBRARIES) {
if (impl->LinkImplementationPropertyEntries.empty()) {
@@ -1614,6 +1716,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const
output = cmJoin(impl->Utilities, ";");
return output.c_str();
}
+ if (prop == propPRECOMPILE_HEADERS) {
+ if (impl->PrecompileHeadersEntries.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(impl->PrecompileHeadersEntries, ";");
+ return output.c_str();
+ }
if (prop == propIMPORTED) {
return this->IsImported() ? "TRUE" : "FALSE";
}
@@ -1660,7 +1771,7 @@ const char* cmTarget::GetSafeProperty(const std::string& prop) const
bool cmTarget::GetPropertyAsBool(const std::string& prop) const
{
- return cmSystemTools::IsOn(this->GetProperty(prop));
+ return cmIsOn(this->GetProperty(prop));
}
cmPropertyMap const& cmTarget::GetProperties() const
@@ -1668,6 +1779,16 @@ cmPropertyMap const& cmTarget::GetProperties() const
return impl->Properties;
}
+bool cmTarget::IsDLLPlatform() const
+{
+ return impl->IsDLLPlatform;
+}
+
+bool cmTarget::IsAIX() const
+{
+ return impl->IsAIX;
+}
+
bool cmTarget::IsImported() const
{
return impl->IsImportedTarget;
@@ -1709,7 +1830,8 @@ const char* cmTarget::GetSuffixVariableInternal(
? "CMAKE_SHARED_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
case cmStateEnums::ImportLibraryArtifact:
- return "CMAKE_IMPORT_LIBRARY_SUFFIX";
+ return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
+ : "CMAKE_IMPORT_LIBRARY_SUFFIX");
}
break;
default:
@@ -1749,7 +1871,8 @@ const char* cmTarget::GetPrefixVariableInternal(
? "CMAKE_SHARED_LIBRARY_PREFIX"
: "");
case cmStateEnums::ImportLibraryArtifact:
- return "CMAKE_IMPORT_LIBRARY_PREFIX";
+ return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
+ : "CMAKE_IMPORT_LIBRARY_PREFIX");
}
break;
default:
@@ -1783,8 +1906,7 @@ std::string cmTarget::ImportedGetFullPath(
if (loc) {
result = loc;
} else {
- std::string impProp = "IMPORTED_LOCATION";
- impProp += suffix;
+ std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
if (const char* config_location = this->GetProperty(impProp)) {
result = config_location;
} else if (const char* location =
@@ -1799,8 +1921,7 @@ std::string cmTarget::ImportedGetFullPath(
result = imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
- std::string impProp = "IMPORTED_IMPLIB";
- impProp += suffix;
+ std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
if (const char* config_implib = this->GetProperty(impProp)) {
result = config_implib;
} else if (const char* implib =
@@ -1813,8 +1934,7 @@ std::string cmTarget::ImportedGetFullPath(
}
if (result.empty()) {
- result = this->GetName();
- result += "-NOTFOUND";
+ result = cmStrCat(this->GetName(), "-NOTFOUND");
}
return result;
}
@@ -1868,27 +1988,26 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
// Track the configuration-specific property suffix.
- suffix = "_";
- suffix += config_upper;
+ suffix = cmStrCat('_', config_upper);
std::vector<std::string> mappedConfigs;
{
- std::string mapProp = "MAP_IMPORTED_CONFIG_";
- mapProp += config_upper;
+ std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
if (const char* mapValue = this->GetProperty(mapProp)) {
- cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
+ cmExpandList(mapValue, mappedConfigs, true);
}
}
// If we needed to find one of the mapped configurations but did not
// On a DLL platform there may be only IMPORTED_IMPLIB for a shared
// library or an executable with exports.
- bool allowImp = (impl->DLLPlatform &&
+ bool allowImp = (this->IsDLLPlatform() &&
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->IsExecutableWithExports()));
+ this->IsExecutableWithExports())) ||
+ (this->IsAIX() && this->IsExecutableWithExports());
// If a mapping was found, check its configurations.
- for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
+ for (auto mci = mappedConfigs.begin();
!*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
// Look for this configuration.
if (mci->empty()) {
@@ -1904,19 +2023,16 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
} else {
std::string mcUpper = cmSystemTools::UpperCase(*mci);
- std::string locProp = locPropBase + "_";
- locProp += mcUpper;
+ std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
*loc = this->GetProperty(locProp);
if (allowImp) {
- std::string impProp = "IMPORTED_IMPLIB_";
- impProp += mcUpper;
+ std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
*imp = this->GetProperty(impProp);
}
// If it was found, use it for all properties below.
if (*loc || *imp) {
- suffix = "_";
- suffix += mcUpper;
+ suffix = cmStrCat('_', mcUpper);
}
}
}
@@ -1933,12 +2049,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// If we have not yet found it then there are no mapped
// configurations. Look for an exact-match.
if (!*loc && !*imp) {
- std::string locProp = locPropBase;
- locProp += suffix;
+ std::string locProp = cmStrCat(locPropBase, suffix);
*loc = this->GetProperty(locProp);
if (allowImp) {
- std::string impProp = "IMPORTED_IMPLIB";
- impProp += suffix;
+ std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
*imp = this->GetProperty(impProp);
}
}
@@ -1962,19 +2076,15 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
if (!*loc && !*imp) {
std::vector<std::string> availableConfigs;
if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
- cmSystemTools::ExpandListArgument(iconfigs, availableConfigs);
+ cmExpandList(iconfigs, availableConfigs);
}
- for (std::vector<std::string>::const_iterator aci =
- availableConfigs.begin();
+ for (auto aci = availableConfigs.begin();
!*loc && !*imp && aci != availableConfigs.end(); ++aci) {
- suffix = "_";
- suffix += cmSystemTools::UpperCase(*aci);
- std::string locProp = locPropBase;
- locProp += suffix;
+ suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci));
+ std::string locProp = cmStrCat(locPropBase, suffix);
*loc = this->GetProperty(locProp);
if (allowImp) {
- std::string impProp = "IMPORTED_IMPLIB";
- impProp += suffix;
+ std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
*imp = this->GetProperty(impProp);
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2bd9e6db6..65a1ce36f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -16,6 +16,7 @@
#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmTargetLinkLibraryType.h"
class cmCustomCommand;
@@ -42,13 +43,6 @@ public:
VisibilityImportedGlobally
};
- enum CustomCommandType
- {
- PRE_BUILD,
- PRE_LINK,
- POST_BUILD
- };
-
cmTarget(std::string const& name, cmStateEnums::TargetType type,
Visibility vis, cmMakefile* mf);
@@ -90,24 +84,27 @@ public:
//! Get the list of the PRE_BUILD custom commands for this target
std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
void AddPreBuildCommand(cmCustomCommand const& cmd);
+ void AddPreBuildCommand(cmCustomCommand&& cmd);
//! Get the list of the PRE_LINK custom commands for this target
std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
void AddPreLinkCommand(cmCustomCommand const& cmd);
+ void AddPreLinkCommand(cmCustomCommand&& cmd);
//! Get the list of the POST_BUILD custom commands for this target
std::vector<cmCustomCommand> const& GetPostBuildCommands() const;
void AddPostBuildCommand(cmCustomCommand const& cmd);
+ void AddPostBuildCommand(cmCustomCommand&& cmd);
//! Add sources to the target.
void AddSources(std::vector<std::string> const& srcs);
void AddTracedSources(std::vector<std::string> const& srcs);
- cmSourceFile* AddSourceCMP0049(const std::string& src);
+ std::string GetSourceCMP0049(const std::string& src);
cmSourceFile* AddSource(const std::string& src, bool before = false);
//! how we identify a library, by name and type
- typedef std::pair<std::string, cmTargetLinkLibraryType> LibraryID;
- typedef std::vector<LibraryID> LinkLibraryVectorType;
+ using LibraryID = std::pair<std::string, cmTargetLinkLibraryType>;
+ using LinkLibraryVectorType = std::vector<LibraryID>;
LinkLibraryVectorType const& GetOriginalLinkLibraries() const;
//! Clear the dependency information recorded for this target, if any.
@@ -181,6 +178,12 @@ public:
//! Get all properties
cmPropertyMap const& GetProperties() const;
+ //! Return whether or not the target is for a DLL platform.
+ bool IsDLLPlatform() const;
+
+ //! Return whether or not we are targeting AIX.
+ bool IsAIX() const;
+
bool IsImported() const;
bool IsImportedGloballyVisible() const;
@@ -209,6 +212,8 @@ public:
cmListFileBacktrace const& bt, bool before = false);
void InsertLinkDirectory(std::string const& entry,
cmListFileBacktrace const& bt, bool before = false);
+ void InsertPrecompileHeader(std::string const& entry,
+ cmListFileBacktrace const& bt);
void AppendBuildInterfaceIncludes();
@@ -230,6 +235,9 @@ public:
cmStringRange GetCompileDefinitionsEntries() const;
cmBacktraceRange GetCompileDefinitionsBacktraces() const;
+ cmStringRange GetPrecompileHeadersEntries() const;
+ cmBacktraceRange GetPrecompileHeadersBacktraces() const;
+
cmStringRange GetSourceEntries() const;
cmBacktraceRange GetSourceBacktraces() const;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index c4dc8383b..edee16700 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -2,50 +2,57 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileDefinitionsCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetCompileDefinitionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+class TargetCompileDefinitionsImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "COMPILE_DEFINITIONS");
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetCompileDefinitionsCommand::HandleMissingTarget(
- const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify compile definitions for target \"" << name
- << "\" "
- "which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify compile definitions for target \"", name,
+ "\" which is not built by this project."));
+ }
-std::string cmTargetCompileDefinitionsCommand::Join(
- const std::vector<std::string>& content)
-{
- std::string defs;
- std::string sep;
- for (std::string const& it : content) {
- if (cmHasLiteralPrefix(it, "-D")) {
- defs += sep + it.substr(2);
- } else {
- defs += sep + it;
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool /*prepend*/, bool /*system*/) override
+ {
+ tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+ return true; // Successfully handled.
+ }
+
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ std::string defs;
+ std::string sep;
+ for (std::string const& it : content) {
+ if (cmHasLiteralPrefix(it, "-D")) {
+ defs += sep + it.substr(2);
+ } else {
+ defs += sep + it;
+ }
+ sep = ";";
}
- sep = ";";
+ return defs;
}
- return defs;
-}
+};
+
+} // namespace
-bool cmTargetCompileDefinitionsCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
+bool cmTargetCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
- return true; // Successfully handled.
+ return TargetCompileDefinitionsImpl(status).HandleArguments(
+ args, "COMPILE_DEFINITIONS");
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index d41483a1d..05ff092e8 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -8,34 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetCompileDefinitionsCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetCompileDefinitionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- std::string Join(const std::vector<std::string>& content) override;
-};
+bool cmTargetCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index c9e394b1c..06be4f0dd 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -2,46 +2,54 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileFeaturesCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
class cmTarget;
-bool cmTargetCompileFeaturesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
-{
- return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
-}
+namespace {
-void cmTargetCompileFeaturesCommand::HandleMissingTarget(
- const std::string& name)
+class TargetCompileFeaturesImpl : public cmTargetPropCommandBase
{
- std::ostringstream e;
- e << "Cannot specify compile features for target \"" << name
- << "\" "
- "which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-std::string cmTargetCompileFeaturesCommand::Join(
- const std::vector<std::string>& content)
-{
- return cmJoin(content, ";");
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify compile features for target \"", name,
+ "\" which is not built by this project."));
+ }
-bool cmTargetCompileFeaturesCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
-{
- for (std::string const& it : content) {
- std::string error;
- if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
- this->SetError(error);
- return false; // Not (successfully) handled.
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool /*prepend*/, bool /*system*/) override
+ {
+ for (std::string const& it : content) {
+ std::string error;
+ if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
+ this->SetError(error);
+ return false; // Not (successfully) handled.
+ }
}
+ return true; // Successfully handled.
+ }
+
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ return cmJoin(content, ";");
}
- return true; // Successfully handled.
+};
+
+} // namespace
+
+bool cmTargetCompileFeaturesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return TargetCompileFeaturesImpl(status).HandleArguments(args,
+ "COMPILE_FEATURES");
}
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 45240a5a1..db0c04b7e 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -8,26 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
-{
- cmCommand* Clone() override { return new cmTargetCompileFeaturesCommand; }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- std::string Join(const std::vector<std::string>& content) override;
-};
+bool cmTargetCompileFeaturesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 8b4763a8c..e39b72670 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -2,41 +2,49 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileOptionsCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetCompileOptionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+class TargetCompileOptionsImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE);
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetCompileOptionsCommand::HandleMissingTarget(
- const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify compile options for target \"" << name
- << "\" which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify compile options for target \"", name,
+ "\" which is not built by this project."));
+ }
-std::string cmTargetCompileOptionsCommand::Join(
- const std::vector<std::string>& content)
-{
- return cmJoin(content, ";");
-}
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool /*prepend*/, bool /*system*/) override
+ {
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ tgt->InsertCompileOption(this->Join(content), lfbt);
+ return true; // Successfully handled.
+ }
+
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ return cmJoin(content, ";");
+ }
+};
+
+} // namespace
-bool cmTargetCompileOptionsCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
+bool cmTargetCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- tgt->InsertCompileOption(this->Join(content), lfbt);
- return true; // Successfully handled.
+ return TargetCompileOptionsImpl(status).HandleArguments(
+ args, "COMPILE_OPTIONS", TargetCompileOptionsImpl::PROCESS_BEFORE);
}
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index 6fb151a9d..3ab1a89c5 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -8,34 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetCompileOptionsCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetCompileOptionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- std::string Join(const std::vector<std::string>& content) override;
-};
+bool cmTargetCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 5ea008523..4ca78faa9 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -31,7 +31,7 @@ public:
operator cmGeneratorTarget const*() const { return this->Target; }
cmGeneratorTarget const* operator->() const { return this->Target; }
cmGeneratorTarget const& operator*() const { return *this->Target; }
- friend bool operator<(cmTargetDepend l, cmTargetDepend r)
+ friend bool operator<(cmTargetDepend const& l, cmTargetDepend const& r)
{
return l.Target < r.Target;
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index d6918c09b..95b69f399 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -3,34 +3,44 @@
#include "cmTargetIncludeDirectoriesCommand.h"
#include <set>
-#include <sstream>
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetIncludeDirectoriesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+class TargetIncludeDirectoriesImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "INCLUDE_DIRECTORIES",
- ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM));
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetIncludeDirectoriesCommand::HandleMissingTarget(
- const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify include directories for target \"" << name
- << "\" which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify include directories for target \"", name,
+ "\" which is not built by this project."));
+ }
+
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool system) override;
+
+ void HandleInterfaceContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool system) override;
-std::string cmTargetIncludeDirectoriesCommand::Join(
+ std::string Join(const std::vector<std::string>& content) override;
+};
+
+std::string TargetIncludeDirectoriesImpl::Join(
const std::vector<std::string>& content)
{
std::string dirs;
@@ -39,16 +49,16 @@ std::string cmTargetIncludeDirectoriesCommand::Join(
for (std::string const& it : content) {
if (cmSystemTools::FileIsFullPath(it) ||
cmGeneratorExpression::Find(it) == 0) {
- dirs += sep + it;
+ dirs += cmStrCat(sep, it);
} else {
- dirs += sep + prefix + it;
+ dirs += cmStrCat(sep, prefix, it);
}
sep = ";";
}
return dirs;
}
-bool cmTargetIncludeDirectoriesCommand::HandleDirectContent(
+bool TargetIncludeDirectoriesImpl::HandleDirectContent(
cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
bool system)
{
@@ -70,16 +80,27 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent(
return true; // Successfully handled.
}
-void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent(
+void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
bool system)
{
cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend,
system);
-
if (system) {
std::string joined = this->Join(content);
tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
joined.c_str());
}
}
+
+} // namespace
+
+bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return TargetIncludeDirectoriesImpl(status).HandleArguments(
+ args, "INCLUDE_DIRECTORIES",
+ TargetIncludeDirectoriesImpl::ArgumentFlags(
+ TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
+ TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
+}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index 57bf8fcf3..9958f419a 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -8,38 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetIncludeDirectoriesCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetIncludeDirectoriesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
-
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- void HandleInterfaceContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- std::string Join(const std::vector<std::string>& content) override;
-};
+bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx
index 269f7513e..0c68d604c 100644
--- a/Source/cmTargetLinkDirectoriesCommand.cxx
+++ b/Source/cmTargetLinkDirectoriesCommand.cxx
@@ -2,34 +2,44 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetLinkDirectoriesCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetLinkDirectoriesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+class TargetLinkDirectoriesImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "LINK_DIRECTORIES", PROCESS_BEFORE);
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetLinkDirectoriesCommand::HandleMissingTarget(
- const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify link directories for target \"" << name
- << "\" which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify link directories for target \"", name,
+ "\" which is not built by this project."));
+ }
+
+ std::string Join(const std::vector<std::string>& content) override;
-std::string cmTargetLinkDirectoriesCommand::Join(
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool /*system*/) override
+ {
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ tgt->InsertLinkDirectory(this->Join(content), lfbt, prepend);
+ return true; // Successfully handled.
+ }
+};
+
+std::string TargetLinkDirectoriesImpl::Join(
const std::vector<std::string>& content)
{
std::vector<std::string> directories;
@@ -50,12 +60,11 @@ std::string cmTargetLinkDirectoriesCommand::Join(
return cmJoin(directories, ";");
}
-bool cmTargetLinkDirectoriesCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool)
-{
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+} // namespace
- tgt->InsertLinkDirectory(this->Join(content), lfbt, prepend);
-
- return true; // Successfully handled.
+bool cmTargetLinkDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return TargetLinkDirectoriesImpl(status).HandleArguments(
+ args, "LINK_DIRECTORIES", TargetLinkDirectoriesImpl::PROCESS_BEFORE);
}
diff --git a/Source/cmTargetLinkDirectoriesCommand.h b/Source/cmTargetLinkDirectoriesCommand.h
index 52c75a0b9..3724d6cf8 100644
--- a/Source/cmTargetLinkDirectoriesCommand.h
+++ b/Source/cmTargetLinkDirectoriesCommand.h
@@ -8,34 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetLinkDirectoriesCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetLinkDirectoriesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
- std::string Join(const std::vector<std::string>& content) override;
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
-};
+bool cmTargetLinkDirectoriesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 3883b5228..0d2383a1c 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -2,9 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetLinkLibrariesCommand.h"
+#include <cstring>
#include <sstream>
-#include <string.h>
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -12,46 +13,67 @@
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmTargetLinkLibraryType.h"
#include "cmake.h"
-class cmExecutionStatus;
+namespace {
-const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = {
- "general", "debug", "optimized"
+enum ProcessingState
+{
+ ProcessingLinkLibraries,
+ ProcessingPlainLinkInterface,
+ ProcessingKeywordLinkInterface,
+ ProcessingPlainPublicInterface,
+ ProcessingKeywordPublicInterface,
+ ProcessingPlainPrivateInterface,
+ ProcessingKeywordPrivateInterface
};
-// cmTargetLinkLibrariesCommand
-bool cmTargetLinkLibrariesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+const char* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" };
+
+} // namespace
+
+static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
+ int right);
+
+static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
+ ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt);
+
+bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Must have at least one argument.
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+
+ cmMakefile& mf = status.GetMakefile();
+
// Alias targets cannot be on the LHS of this command.
- if (this->Makefile->IsAlias(args[0])) {
- this->SetError("can not be used on an ALIAS target.");
+ if (mf.IsAlias(args[0])) {
+ status.SetError("can not be used on an ALIAS target.");
return false;
}
// Lookup the target for which libraries are specified.
- this->Target =
- this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
- args[0]);
- if (!this->Target) {
+ cmTarget* target =
+ mf.GetCMakeInstance()->GetGlobalGenerator()->FindTarget(args[0]);
+ if (!target) {
const std::vector<cmTarget*>& importedTargets =
- this->Makefile->GetOwnedImportedTargets();
+ mf.GetOwnedImportedTargets();
for (cmTarget* importedTarget : importedTargets) {
if (importedTarget->GetName() == args[0]) {
- this->Target = importedTarget;
+ target = importedTarget;
break;
}
}
}
- if (!this->Target) {
+ if (!target) {
MessageType t = MessageType::FATAL_ERROR; // fail by default
std::ostringstream e;
e << "Cannot specify link libraries for target \"" << args[0] << "\" "
@@ -59,7 +81,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// The bad target is the only argument. Check how policy CMP0016 is set,
// and accept, warn or fail respectively:
if (args.size() < 2) {
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0016)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0016)) {
case cmPolicies::WARN:
t = MessageType::AUTHOR_WARNING;
// Print the warning.
@@ -83,10 +105,10 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// Now actually print the message.
switch (t) {
case MessageType::AUTHOR_WARNING:
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
break;
case MessageType::FATAL_ERROR:
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
break;
default:
@@ -96,11 +118,11 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
}
// Having a UTILITY library on the LHS is a bug.
- if (this->Target->GetType() == cmStateEnums::UTILITY) {
+ if (target->GetType() == cmStateEnums::UTILITY) {
std::ostringstream e;
const char* modal = nullptr;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0039)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0039)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n";
modal = "should";
@@ -113,9 +135,9 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
messageType = MessageType::FATAL_ERROR;
}
if (modal) {
- e << "Utility target \"" << this->Target->GetName() << "\" " << modal
+ e << "Utility target \"" << target->GetName() << "\" " << modal
<< " not be used as the target of a target_link_libraries call.";
- this->Makefile->IssueMessage(messageType, e.str());
+ mf.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
@@ -133,15 +155,15 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// Start with primary linking and switch to link interface
// specification if the keyword is encountered as the first argument.
- this->CurrentProcessingState = ProcessingLinkLibraries;
+ ProcessingState currentProcessingState = ProcessingLinkLibraries;
// Add libraries, note that there is an optional prefix
// of debug and optimized that can be used.
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "LINK_INTERFACE_LIBRARIES") {
- this->CurrentProcessingState = ProcessingPlainLinkInterface;
+ currentProcessingState = ProcessingPlainLinkInterface;
if (i != 1) {
- this->Makefile->IssueMessage(
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The LINK_INTERFACE_LIBRARIES option must appear as the second "
"argument, just after the target name.");
@@ -149,84 +171,83 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
}
} else if (args[i] == "INTERFACE") {
if (i != 1 &&
- this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
- this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
- this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
- this->Makefile->IssueMessage(
+ currentProcessingState != ProcessingKeywordPrivateInterface &&
+ currentProcessingState != ProcessingKeywordPublicInterface &&
+ currentProcessingState != ProcessingKeywordLinkInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
- this->CurrentProcessingState = ProcessingKeywordLinkInterface;
+ currentProcessingState = ProcessingKeywordLinkInterface;
} else if (args[i] == "LINK_PUBLIC") {
if (i != 1 &&
- this->CurrentProcessingState != ProcessingPlainPrivateInterface &&
- this->CurrentProcessingState != ProcessingPlainPublicInterface) {
- this->Makefile->IssueMessage(
+ currentProcessingState != ProcessingPlainPrivateInterface &&
+ currentProcessingState != ProcessingPlainPublicInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
- this->CurrentProcessingState = ProcessingPlainPublicInterface;
+ currentProcessingState = ProcessingPlainPublicInterface;
} else if (args[i] == "PUBLIC") {
if (i != 1 &&
- this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
- this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
- this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
- this->Makefile->IssueMessage(
+ currentProcessingState != ProcessingKeywordPrivateInterface &&
+ currentProcessingState != ProcessingKeywordPublicInterface &&
+ currentProcessingState != ProcessingKeywordLinkInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
- this->CurrentProcessingState = ProcessingKeywordPublicInterface;
+ currentProcessingState = ProcessingKeywordPublicInterface;
} else if (args[i] == "LINK_PRIVATE") {
- if (i != 1 &&
- this->CurrentProcessingState != ProcessingPlainPublicInterface &&
- this->CurrentProcessingState != ProcessingPlainPrivateInterface) {
- this->Makefile->IssueMessage(
+ if (i != 1 && currentProcessingState != ProcessingPlainPublicInterface &&
+ currentProcessingState != ProcessingPlainPrivateInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
- this->CurrentProcessingState = ProcessingPlainPrivateInterface;
+ currentProcessingState = ProcessingPlainPrivateInterface;
} else if (args[i] == "PRIVATE") {
if (i != 1 &&
- this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
- this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
- this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
- this->Makefile->IssueMessage(
+ currentProcessingState != ProcessingKeywordPrivateInterface &&
+ currentProcessingState != ProcessingKeywordPublicInterface &&
+ currentProcessingState != ProcessingKeywordLinkInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
- this->CurrentProcessingState = ProcessingKeywordPrivateInterface;
+ currentProcessingState = ProcessingKeywordPrivateInterface;
} else if (args[i] == "debug") {
if (haveLLT) {
- this->LinkLibraryTypeSpecifierWarning(llt, DEBUG_LibraryType);
+ LinkLibraryTypeSpecifierWarning(mf, llt, DEBUG_LibraryType);
}
llt = DEBUG_LibraryType;
haveLLT = true;
} else if (args[i] == "optimized") {
if (haveLLT) {
- this->LinkLibraryTypeSpecifierWarning(llt, OPTIMIZED_LibraryType);
+ LinkLibraryTypeSpecifierWarning(mf, llt, OPTIMIZED_LibraryType);
}
llt = OPTIMIZED_LibraryType;
haveLLT = true;
} else if (args[i] == "general") {
if (haveLLT) {
- this->LinkLibraryTypeSpecifierWarning(llt, GENERAL_LibraryType);
+ LinkLibraryTypeSpecifierWarning(mf, llt, GENERAL_LibraryType);
}
llt = GENERAL_LibraryType;
haveLLT = true;
} else if (haveLLT) {
// The link type was specified by the previous argument.
haveLLT = false;
- if (!this->HandleLibrary(args[i], llt)) {
+ if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
return false;
}
} else {
@@ -237,9 +258,8 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// only there for backwards compatibility when mixing projects built
// with old versions of CMake and new)
llt = GENERAL_LibraryType;
- std::string linkType = args[0];
- linkType += "_LINK_TYPE";
- const char* linkTypeString = this->Makefile->GetDefinition(linkType);
+ std::string linkType = cmStrCat(args[0], "_LINK_TYPE");
+ const char* linkTypeString = mf.GetDefinition(linkType);
if (linkTypeString) {
if (strcmp(linkTypeString, "debug") == 0) {
llt = DEBUG_LibraryType;
@@ -248,7 +268,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
llt = OPTIMIZED_LibraryType;
}
}
- if (!this->HandleLibrary(args[i], llt)) {
+ if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
return false;
}
}
@@ -256,15 +276,14 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// Make sure the last argument was not a library type specifier.
if (haveLLT) {
- std::ostringstream e;
- e << "The \"" << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[llt]
- << "\" argument must be followed by a library.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("The \"", LinkLibraryTypeNames[llt],
+ "\" argument must be followed by a library."));
cmSystemTools::SetFatalErrorOccured();
}
const cmPolicies::PolicyStatus policy22Status =
- this->Target->GetPolicyStatusCMP0022();
+ target->GetPolicyStatusCMP0022();
// If any of the LINK_ options were given, make sure the
// LINK_INTERFACE_LIBRARIES target property exists.
@@ -273,41 +292,40 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// result in an empty link interface.
if ((policy22Status == cmPolicies::OLD ||
policy22Status == cmPolicies::WARN) &&
- this->CurrentProcessingState != ProcessingLinkLibraries &&
- !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
- this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
+ currentProcessingState != ProcessingLinkLibraries &&
+ !target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
+ target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
}
return true;
}
-void cmTargetLinkLibrariesCommand::LinkLibraryTypeSpecifierWarning(int left,
- int right)
+static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
+ int right)
{
- std::ostringstream w;
- w << "Link library type specifier \""
- << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[left]
- << "\" is followed by specifier \""
- << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[right]
- << "\" instead of a library name. "
- << "The first specifier will be ignored.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ "Link library type specifier \"", LinkLibraryTypeNames[left],
+ "\" is followed by specifier \"", LinkLibraryTypeNames[right],
+ "\" instead of a library name. The first specifier will be ignored."));
}
-bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
- cmTargetLinkLibraryType llt)
+static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
+ ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt)
{
- if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
- this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
- this->Makefile->IssueMessage(
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
+ currentProcessingState != ProcessingKeywordLinkInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"INTERFACE library can only be used with the INTERFACE keyword of "
"target_link_libraries");
return false;
}
- if (this->Target->IsImported() &&
- this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
- this->Makefile->IssueMessage(
+ if (target->IsImported() &&
+ currentProcessingState != ProcessingKeywordLinkInterface) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"IMPORTED library can only be used with the INTERFACE keyword of "
"target_link_libraries");
@@ -315,19 +333,18 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
}
cmTarget::TLLSignature sig =
- (this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
- this->CurrentProcessingState == ProcessingPlainPublicInterface ||
- this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
- this->CurrentProcessingState == ProcessingKeywordPublicInterface ||
- this->CurrentProcessingState == ProcessingKeywordLinkInterface)
+ (currentProcessingState == ProcessingPlainPrivateInterface ||
+ currentProcessingState == ProcessingPlainPublicInterface ||
+ currentProcessingState == ProcessingKeywordPrivateInterface ||
+ currentProcessingState == ProcessingKeywordPublicInterface ||
+ currentProcessingState == ProcessingKeywordLinkInterface)
? cmTarget::KeywordTLLSignature
: cmTarget::PlainTLLSignature;
- if (!this->Target->PushTLLCommandTrace(
- sig, this->Makefile->GetExecutionContext())) {
+ if (!target->PushTLLCommandTrace(sig, mf.GetExecutionContext())) {
std::ostringstream e;
const char* modal = nullptr;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0023)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0023)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
modal = "should";
@@ -348,14 +365,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
e << "The " << existingSig
<< " signature for target_link_libraries has "
"already been used with the target \""
- << this->Target->GetName()
+ << target->GetName()
<< "\". All uses of target_link_libraries with a target " << modal
<< " be either all-keyword or all-plain.\n";
- this->Target->GetTllSignatureTraces(e,
- sig == cmTarget::KeywordTLLSignature
- ? cmTarget::PlainTLLSignature
- : cmTarget::KeywordTLLSignature);
- this->Makefile->IssueMessage(messageType, e.str());
+ target->GetTllSignatureTraces(e,
+ sig == cmTarget::KeywordTLLSignature
+ ? cmTarget::PlainTLLSignature
+ : cmTarget::KeywordTLLSignature);
+ mf.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
@@ -365,9 +382,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
bool warnRemoteInterface = false;
bool rejectRemoteLinking = false;
bool encodeRemoteReference = false;
- if (this->Makefile != this->Target->GetMakefile()) {
+ if (&mf != target->GetMakefile()) {
// The LHS target was created in another directory.
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0079)) {
case cmPolicies::WARN:
warnRemoteInterface = true;
CM_FALLTHROUGH;
@@ -388,7 +405,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
// same directory as the target was created. Add a suffix to
// the name to tell ResolveLinkItem to look up the name in the
// caller's directory.
- cmDirectoryId const dirId = this->Makefile->GetDirectoryId();
+ cmDirectoryId const dirId = mf.GetDirectoryId();
libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String;
} else {
// This is an absolute path or a library name added by a caller
@@ -400,20 +417,21 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
// Handle normal case where the command was called with another keyword than
// INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES"
// property of the target on the LHS shall be populated.)
- if (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
- this->CurrentProcessingState != ProcessingPlainLinkInterface) {
+ if (currentProcessingState != ProcessingKeywordLinkInterface &&
+ currentProcessingState != ProcessingPlainLinkInterface) {
if (rejectRemoteLinking) {
- std::ostringstream e;
- e << "Attempt to add link library \"" << lib << "\" to target \""
- << this->Target->GetName()
- << "\" which is not built in this directory.\n"
- << "This is allowed only when policy CMP0079 is set to NEW.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Attempt to add link library \"", lib, "\" to target \"",
+ target->GetName(),
+ "\" which is not built in this "
+ "directory.\nThis is allowed only when policy CMP0079 "
+ "is set to NEW."));
return false;
}
- cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib);
+ cmTarget* tgt = mf.GetGlobalGenerator()->FindTarget(lib);
if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
(tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
@@ -421,47 +439,48 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
(tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
(tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
!tgt->IsExecutableWithExports()) {
- std::ostringstream e;
- e << "Target \"" << lib << "\" of type "
- << cmState::GetTargetTypeName(tgt->GetType())
- << " may not be linked into another target. One may link only to "
- "INTERFACE, OBJECT, STATIC or SHARED libraries, or to executables "
- "with the ENABLE_EXPORTS property set.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", lib, "\" of type ",
+ cmState::GetTargetTypeName(tgt->GetType()),
+ " may not be linked into another target. One may link only to "
+ "INTERFACE, OBJECT, STATIC or SHARED libraries, or to ",
+ "executables with the ENABLE_EXPORTS property set."));
}
- this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt);
+ target->AddLinkLibrary(mf, lib, libRef, llt);
}
if (warnRemoteInterface) {
- std::ostringstream w;
- /* clang-format off */
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0079) << "\n"
- "Target\n " << this->Target->GetName() << "\nis not created in this "
- "directory. For compatibility with older versions of CMake, link "
- "library\n " << lib << "\nwill be looked up in the directory in "
- "which the target was created rather than in this calling "
- "directory.";
- /* clang-format on */
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n ",
+ target->GetName(),
+ "\nis not created in this "
+ "directory. For compatibility with older versions of CMake, link "
+ "library\n ",
+ lib,
+ "\nwill be looked up in the directory in which "
+ "the target was created rather than in this calling directory."));
}
// Handle (additional) case where the command was called with PRIVATE /
// LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES"
// property of the target on the LHS shall only be populated if it is a
// STATIC library.)
- if (this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
- this->CurrentProcessingState == ProcessingPlainPrivateInterface) {
- if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
- this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ if (currentProcessingState == ProcessingKeywordPrivateInterface ||
+ currentProcessingState == ProcessingPlainPrivateInterface) {
+ if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::string configLib =
- this->Target->GetDebugGeneratorExpressions(libRef, llt);
+ target->GetDebugGeneratorExpressions(libRef, llt);
if (cmGeneratorExpression::IsValidTargetName(lib) ||
cmGeneratorExpression::Find(lib) != std::string::npos) {
configLib = "$<LINK_ONLY:" + configLib + ">";
}
- this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
- configLib.c_str());
+ target->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str());
}
return true;
}
@@ -469,23 +488,23 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
// Handle general case where the command was called with another keyword than
// PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES"
// property of the target on the LHS shall be populated.)
- this->Target->AppendProperty(
+ target->AppendProperty(
"INTERFACE_LINK_LIBRARIES",
- this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str());
+ target->GetDebugGeneratorExpressions(libRef, llt).c_str());
// Stop processing if called without any keyword.
- if (this->CurrentProcessingState == ProcessingLinkLibraries) {
+ if (currentProcessingState == ProcessingLinkLibraries) {
return true;
}
// Stop processing if policy CMP0022 is set to NEW.
const cmPolicies::PolicyStatus policy22Status =
- this->Target->GetPolicyStatusCMP0022();
+ target->GetPolicyStatusCMP0022();
if (policy22Status != cmPolicies::OLD &&
policy22Status != cmPolicies::WARN) {
return true;
}
// Stop processing if called with an INTERFACE library on the LHS.
- if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
@@ -495,29 +514,27 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
{
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> debugConfigs =
- this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+ mf.GetCMakeInstance()->GetDebugConfigs();
std::string prop;
// Include this library in the link interface for the target.
if (llt == DEBUG_LibraryType || llt == GENERAL_LibraryType) {
// Put in the DEBUG configuration interfaces.
for (std::string const& dc : debugConfigs) {
- prop = "LINK_INTERFACE_LIBRARIES_";
- prop += dc;
- this->Target->AppendProperty(prop, libRef.c_str());
+ prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
+ target->AppendProperty(prop, libRef.c_str());
}
}
if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
// Put in the non-DEBUG configuration interfaces.
- this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str());
+ target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str());
// Make sure the DEBUG configuration interfaces exist so that the
// general one will not be used as a fall-back.
for (std::string const& dc : debugConfigs) {
- prop = "LINK_INTERFACE_LIBRARIES_";
- prop += dc;
- if (!this->Target->GetProperty(prop)) {
- this->Target->SetProperty(prop, "");
+ prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
+ if (!target->GetProperty(prop)) {
+ target->SetProperty(prop, "");
}
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 54f8cf4b8..4b2deabea 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -8,56 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmTargetLinkLibraryType.h"
-
class cmExecutionStatus;
-class cmTarget;
-
-/** \class cmTargetLinkLibrariesCommand
- * \brief Specify a list of libraries to link into executables.
- *
- * cmTargetLinkLibrariesCommand is used to specify a list of libraries to link
- * into executable(s) or shared objects. The names of the libraries
- * should be those defined by the LIBRARY(library) command(s).
- *
- * Additionally, it allows to propagate usage-requirements (including link
- * libraries) from one target into another.
- */
-class cmTargetLinkLibrariesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetLinkLibrariesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void LinkLibraryTypeSpecifierWarning(int left, int right);
- static const char* LinkLibraryTypeNames[3];
-
- cmTarget* Target = nullptr;
- enum ProcessingState
- {
- ProcessingLinkLibraries,
- ProcessingPlainLinkInterface,
- ProcessingKeywordLinkInterface,
- ProcessingPlainPublicInterface,
- ProcessingKeywordPublicInterface,
- ProcessingPlainPrivateInterface,
- ProcessingKeywordPrivateInterface
- };
-
- ProcessingState CurrentProcessingState = ProcessingLinkLibraries;
- bool HandleLibrary(const std::string& lib, cmTargetLinkLibraryType llt);
-};
+bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx
index 536648638..df9416fad 100644
--- a/Source/cmTargetLinkOptionsCommand.cxx
+++ b/Source/cmTargetLinkOptionsCommand.cxx
@@ -2,40 +2,49 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetLinkOptionsCommand.h"
-#include <sstream>
-
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetLinkOptionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+class TargetLinkOptionsImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "LINK_OPTIONS", PROCESS_BEFORE);
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetLinkOptionsCommand::HandleMissingTarget(const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify link options for target \"" << name
- << "\" which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify link options for target \"", name,
+ "\" which is not built by this project."));
+ }
-std::string cmTargetLinkOptionsCommand::Join(
- const std::vector<std::string>& content)
-{
- return cmJoin(content, ";");
-}
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool /*system*/) override
+ {
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ tgt->InsertLinkOption(this->Join(content), lfbt, prepend);
+ return true; // Successfully handled.
+ }
+
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ return cmJoin(content, ";");
+ }
+};
+
+} // namespace
-bool cmTargetLinkOptionsCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool)
+bool cmTargetLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- tgt->InsertLinkOption(this->Join(content), lfbt, prepend);
- return true; // Successfully handled.
+ return TargetLinkOptionsImpl(status).HandleArguments(
+ args, "LINK_OPTIONS", TargetLinkOptionsImpl::PROCESS_BEFORE);
}
diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h
index a1fc9fc2e..13fb40cb6 100644
--- a/Source/cmTargetLinkOptionsCommand.h
+++ b/Source/cmTargetLinkOptionsCommand.h
@@ -8,34 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetLinkOptionsCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetLinkOptionsCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
- std::string Join(const std::vector<std::string>& content) override;
-};
+bool cmTargetLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
new file mode 100644
index 000000000..c6e2e5c4f
--- /dev/null
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -0,0 +1,87 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmTargetPrecompileHeadersCommand.h"
+
+#include <utility>
+
+#include "cmGeneratorExpression.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
+
+namespace {
+
+std::vector<std::string> ConvertToAbsoluteContent(
+ const std::vector<std::string>& content, std::string const& baseDir)
+{
+ std::vector<std::string> absoluteContent;
+ absoluteContent.reserve(content.size());
+ for (std::string const& src : content) {
+ std::string absoluteSrc;
+ // Use '<foo.h>' and '"foo.h"' includes and absolute paths as-is.
+ // Interpret relative paths with respect to the source directory.
+ // If the path starts in a generator expression, assume it is absolute.
+ if (cmHasLiteralPrefix(src, "<") || cmHasLiteralPrefix(src, "\"") ||
+ cmSystemTools::FileIsFullPath(src) ||
+ cmGeneratorExpression::Find(src) == 0) {
+ absoluteSrc = src;
+ } else {
+ absoluteSrc = cmStrCat(baseDir, '/', src);
+ }
+ absoluteContent.emplace_back(std::move(absoluteSrc));
+ }
+ return absoluteContent;
+}
+
+class TargetPrecompileHeadersImpl : public cmTargetPropCommandBase
+{
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
+
+private:
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool /*prepend*/, bool /*system*/) override
+ {
+ std::string const& base = this->Makefile->GetCurrentSourceDirectory();
+ tgt->AppendProperty(
+ "PRECOMPILE_HEADERS",
+ this->Join(ConvertToAbsoluteContent(content, base)).c_str());
+ return true;
+ }
+
+ void HandleInterfaceContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool system) override
+ {
+ std::string const& base = this->Makefile->GetCurrentSourceDirectory();
+ cmTargetPropCommandBase::HandleInterfaceContent(
+ tgt, ConvertToAbsoluteContent(content, base), prepend, system);
+ }
+
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify precompile headers for target \"", name,
+ "\" which is not built by this project."));
+ }
+
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ return cmJoin(content, ";");
+ }
+};
+
+} // namespace
+
+bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return TargetPrecompileHeadersImpl(status).HandleArguments(
+ args, "PRECOMPILE_HEADERS",
+ TargetPrecompileHeadersImpl::PROCESS_REUSE_FROM);
+}
diff --git a/Source/cmTargetPrecompileHeadersCommand.h b/Source/cmTargetPrecompileHeadersCommand.h
new file mode 100644
index 000000000..8b0ac9777
--- /dev/null
+++ b/Source/cmTargetPrecompileHeadersCommand.h
@@ -0,0 +1,16 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmTargetPrecompileHeadersCommand_h
+#define cmTargetPrecompileHeadersCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+class cmExecutionStatus;
+
+bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 1b8ee812f..bbc1e16f7 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -2,12 +2,24 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetPropCommandBase.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
#include "cmake.h"
+cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status)
+ : Makefile(&status.GetMakefile())
+ , Status(status)
+{
+}
+
+void cmTargetPropCommandBase::SetError(std::string const& e)
+{
+ this->Status.SetError(e);
+}
+
bool cmTargetPropCommandBase::HandleArguments(
std::vector<std::string> const& args, const std::string& prop,
ArgumentFlags flags)
@@ -32,12 +44,13 @@ bool cmTargetPropCommandBase::HandleArguments(
this->HandleMissingTarget(args[0]);
return false;
}
- if ((this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
+ if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) &&
(this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
+ (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
(this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
+ (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
(this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
- (this->Target->GetType() != cmStateEnums::EXECUTABLE)) {
+ (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) {
this->SetError("called with non-compilable target type");
return false;
}
@@ -64,6 +77,19 @@ bool cmTargetPropCommandBase::HandleArguments(
++argIndex;
}
+ if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") {
+ if (args.size() != 3) {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ ++argIndex;
+
+ this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM",
+ args[argIndex].c_str());
+
+ ++argIndex;
+ }
+
this->Property = prop;
while (argIndex < args.size()) {
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 943285df1..601ad0113 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -8,18 +8,24 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
+class cmExecutionStatus;
+class cmMakefile;
class cmTarget;
-class cmTargetPropCommandBase : public cmCommand
+class cmTargetPropCommandBase
{
public:
+ cmTargetPropCommandBase(cmExecutionStatus& status);
+ virtual ~cmTargetPropCommandBase() = default;
+
+ void SetError(std::string const& e);
+
enum ArgumentFlags
{
- NO_FLAGS = 0,
- PROCESS_BEFORE = 1,
- PROCESS_SYSTEM = 2
+ NO_FLAGS = 0x0,
+ PROCESS_BEFORE = 0x1,
+ PROCESS_SYSTEM = 0x2,
+ PROCESS_REUSE_FROM = 0x3
};
bool HandleArguments(std::vector<std::string> const& args,
@@ -29,6 +35,7 @@ public:
protected:
std::string Property;
cmTarget* Target = nullptr;
+ cmMakefile* Makefile;
virtual void HandleInterfaceContent(cmTarget* tgt,
const std::vector<std::string>& content,
@@ -48,6 +55,8 @@ private:
bool PopulateTargetProperies(const std::string& scope,
const std::vector<std::string>& content,
bool prepend, bool system);
+
+ cmExecutionStatus& Status;
};
#endif
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index 3f763afaf..baab8da0a 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -11,6 +11,7 @@
#include "cmMessenger.h"
#include "cmPolicies.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
std::string const& tgtName, cmMessenger* messenger,
@@ -56,22 +57,21 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
if (std::islower(prop[0])) {
return true;
}
- static std::unordered_set<std::string> builtIns;
- if (builtIns.empty()) {
- builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
- builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
- builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
- builtIns.insert("COMPATIBLE_INTERFACE_STRING");
- builtIns.insert("EXPORT_NAME");
- builtIns.insert("EXPORT_PROPERTIES");
- builtIns.insert("IMPORTED");
- builtIns.insert("IMPORTED_GLOBAL");
- builtIns.insert("MANUALLY_ADDED_DEPENDENCIES");
- builtIns.insert("NAME");
- builtIns.insert("PRIVATE_HEADER");
- builtIns.insert("PUBLIC_HEADER");
- builtIns.insert("TYPE");
- }
+ static std::unordered_set<std::string> const builtIns{
+ "COMPATIBLE_INTERFACE_BOOL",
+ "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ "COMPATIBLE_INTERFACE_STRING",
+ "EXPORT_NAME",
+ "EXPORT_PROPERTIES",
+ "IMPORTED",
+ "IMPORTED_GLOBAL",
+ "MANUALLY_ADDED_DEPENDENCIES",
+ "NAME",
+ "PRIVATE_HEADER",
+ "PUBLIC_HEADER",
+ "TYPE"
+ };
if (builtIns.count(prop)) {
return true;
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index efbf95f7f..3b11acdc1 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -7,9 +7,9 @@
#include <string>
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmMessenger;
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 11e288fe6..c2e0b28fe 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -4,55 +4,61 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmTargetPropCommandBase.h"
-class cmExecutionStatus;
+namespace {
-bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+class TargetSourcesImpl : public cmTargetPropCommandBase
{
- return this->HandleArguments(args, "SOURCES");
-}
+public:
+ using cmTargetPropCommandBase::cmTargetPropCommandBase;
-void cmTargetSourcesCommand::HandleInterfaceContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
- bool system)
-{
- cmTargetPropCommandBase::HandleInterfaceContent(
- tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system);
-}
+protected:
+ void HandleInterfaceContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool prepend, bool system) override
+ {
+ cmTargetPropCommandBase::HandleInterfaceContent(
+ tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system);
+ }
-void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
-{
- std::ostringstream e;
- e << "Cannot specify sources for target \"" << name
- << "\" "
- "which is not built by this project.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
+private:
+ void HandleMissingTarget(const std::string& name) override
+ {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Cannot specify sources for target \"", name,
+ "\" which is not built by this project."));
+ }
-std::string cmTargetSourcesCommand::Join(
- const std::vector<std::string>& content)
-{
- return cmJoin(content, ";");
-}
+ bool HandleDirectContent(cmTarget* tgt,
+ const std::vector<std::string>& content,
+ bool /*prepend*/, bool /*system*/) override
+ {
+ tgt->AppendProperty(
+ "SOURCES",
+ this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
+ return true; // Successfully handled.
+ }
-bool cmTargetSourcesCommand::HandleDirectContent(
- cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
-{
- tgt->AppendProperty(
- "SOURCES",
- this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
- return true; // Successfully handled.
-}
+ std::string Join(const std::vector<std::string>& content) override
+ {
+ return cmJoin(content, ";");
+ }
+
+ std::vector<std::string> ConvertToAbsoluteContent(
+ cmTarget* tgt, const std::vector<std::string>& content,
+ bool isInterfaceContent);
+};
-std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent(
+std::vector<std::string> TargetSourcesImpl::ConvertToAbsoluteContent(
cmTarget* tgt, const std::vector<std::string>& content,
bool isInterfaceContent)
{
@@ -75,9 +81,8 @@ std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent(
absoluteSrc = src;
} else {
changedPath = true;
- absoluteSrc = this->Makefile->GetCurrentSourceDirectory();
- absoluteSrc += "/";
- absoluteSrc += src;
+ absoluteSrc =
+ cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', src);
}
absoluteContent.push_back(absoluteSrc);
}
@@ -122,3 +127,11 @@ std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent(
return useAbsoluteContent ? absoluteContent : content;
}
+
+} // namespace
+
+bool cmTargetSourcesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return TargetSourcesImpl(status).HandleArguments(args, "SOURCES");
+}
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index b01e3ca25..5eecf3454 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -8,44 +8,9 @@
#include <string>
#include <vector>
-#include "cmTargetPropCommandBase.h"
-
-class cmCommand;
class cmExecutionStatus;
-class cmTarget;
-
-class cmTargetSourcesCommand : public cmTargetPropCommandBase
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmTargetSourcesCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- void HandleInterfaceContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
-
-private:
- void HandleMissingTarget(const std::string& name) override;
-
- bool HandleDirectContent(cmTarget* tgt,
- const std::vector<std::string>& content,
- bool prepend, bool system) override;
-
- std::string Join(const std::vector<std::string>& content) override;
- std::vector<std::string> ConvertToAbsoluteContent(
- cmTarget* tgt, const std::vector<std::string>& content,
- bool isInterfaceContent);
-};
+bool cmTargetSourcesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index 7d45cf5e3..d5c61c173 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -5,10 +5,11 @@
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmState.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
cmTest::cmTest(cmMakefile* mf)
- : Backtrace(mf->GetBacktrace())
+ : CommandExpandLists(false)
+ , Backtrace(mf->GetBacktrace())
{
this->Makefile = mf;
this->OldStyle = true;
@@ -46,7 +47,7 @@ const char* cmTest::GetProperty(const std::string& prop) const
bool cmTest::GetPropertyAsBool(const std::string& prop) const
{
- return cmSystemTools::IsOn(this->GetProperty(prop));
+ return cmIsOn(this->GetProperty(prop));
}
void cmTest::SetProperty(const std::string& prop, const char* value)
@@ -59,3 +60,13 @@ void cmTest::AppendProperty(const std::string& prop, const char* value,
{
this->Properties.AppendProperty(prop, value, asString);
}
+
+bool cmTest::GetCommandExpandLists() const
+{
+ return this->CommandExpandLists;
+}
+
+void cmTest::SetCommandExpandLists(bool b)
+{
+ this->CommandExpandLists = b;
+}
diff --git a/Source/cmTest.h b/Source/cmTest.h
index 88dc73089..dd246c4e6 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -5,12 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmListFileCache.h"
-#include "cmPropertyMap.h"
-
#include <string>
#include <vector>
+#include "cmListFileCache.h"
+#include "cmPropertyMap.h"
+
class cmMakefile;
/** \class cmTest
@@ -51,10 +51,15 @@ public:
bool GetOldStyle() const { return this->OldStyle; }
void SetOldStyle(bool b) { this->OldStyle = b; }
+ /** Set/Get whether lists in command lines should be expanded. */
+ bool GetCommandExpandLists() const;
+ void SetCommandExpandLists(bool b);
+
private:
cmPropertyMap Properties;
std::string Name;
std::vector<std::string> Command;
+ bool CommandExpandLists;
bool OldStyle;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 571cd0909..333d4d5ee 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -2,18 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTestGenerator.h"
+#include <memory>
#include <ostream>
#include <utility>
+#include <vector>
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
-#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTest.h"
@@ -76,12 +78,22 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Start the test command.
os << indent << "add_test(" << this->Test->GetName() << " ";
- // Get the test command line to be executed.
- std::vector<std::string> const& command = this->Test->GetCommand();
+ // Evaluate command line arguments
+ std::vector<std::string> argv =
+ EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);
+
+ // Expand arguments if COMMAND_EXPAND_LISTS is set
+ if (this->Test->GetCommandExpandLists()) {
+ argv = cmExpandedLists(argv.begin(), argv.end());
+ // Expanding lists on an empty command may have left it empty
+ if (argv.empty()) {
+ argv.emplace_back();
+ }
+ }
// Check whether the command executable is a target whose name is to
// be translated.
- std::string exe = command[0];
+ std::string exe = argv[0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(exe);
if (target && target->GetType() == cmStateEnums::EXECUTABLE) {
// Use the target file on disk.
@@ -90,8 +102,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// 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;
- cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
@@ -101,29 +112,26 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
}
} else {
// Use the command name given.
- exe = ge.Parse(exe)->Evaluate(this->LG, config);
cmSystemTools::ConvertToUnixSlashes(exe);
}
// Generate the command line with full escapes.
os << cmOutputConverter::EscapeForCMake(exe);
- for (std::string const& arg : cmMakeRange(command).advance(1)) {
- os << " "
- << cmOutputConverter::EscapeForCMake(
- ge.Parse(arg)->Evaluate(this->LG, config));
+
+ for (auto const& arg : cmMakeRange(argv).advance(1)) {
+ os << " " << cmOutputConverter::EscapeForCMake(arg);
}
// Finish the test command.
os << ")\n";
// Output properties for the test.
- cmPropertyMap& pm = this->Test->GetProperties();
os << indent << "set_tests_properties(" << this->Test->GetName()
<< " PROPERTIES ";
- for (auto const& i : pm) {
+ for (auto const& i : this->Test->GetProperties().GetList()) {
os << " " << i.first << " "
<< cmOutputConverter::EscapeForCMake(
- ge.Parse(i.second.GetValue())->Evaluate(this->LG, config));
+ ge.Parse(i.second)->Evaluate(this->LG, config));
}
this->GenerateInternalProperties(os);
os << ")" << std::endl;
@@ -173,12 +181,11 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
fout << ")" << std::endl;
// Output properties for the test.
- cmPropertyMap& pm = this->Test->GetProperties();
fout << indent << "set_tests_properties(" << this->Test->GetName()
<< " PROPERTIES ";
- for (auto const& i : pm) {
+ for (auto const& i : this->Test->GetProperties().GetList()) {
fout << " " << i.first << " "
- << cmOutputConverter::EscapeForCMake(i.second.GetValue());
+ << cmOutputConverter::EscapeForCMake(i.second);
}
this->GenerateInternalProperties(fout);
fout << ")" << std::endl;
@@ -208,3 +215,16 @@ void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
os << "\"";
}
+
+std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments(
+ const std::vector<std::string>& argv, cmGeneratorExpression& ge,
+ const std::string& config) const
+{
+ // Evaluate executable name and arguments
+ auto evaluatedRange =
+ cmMakeRange(argv).transform([&](const std::string& arg) {
+ return ge.Parse(arg)->Evaluate(this->LG, config);
+ });
+
+ return { evaluatedRange.begin(), evaluatedRange.end() };
+}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 8b9cf78a1..e388c1643 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -5,12 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmScriptGenerator.h"
-
#include <iosfwd>
#include <string>
#include <vector>
+#include "cmScriptGenerator.h"
+
+class cmGeneratorExpression;
class cmLocalGenerator;
class cmTest;
@@ -38,6 +39,9 @@ public:
private:
void GenerateInternalProperties(std::ostream& os);
+ std::vector<std::string> EvaluateCommandLineArguments(
+ const std::vector<std::string>& argv, cmGeneratorExpression& ge,
+ const std::string& config) const;
protected:
void GenerateScriptConfigs(std::ostream& os, Indent indent) override;
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index da5d21ebb..390fd16b0 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -2,10 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTimestamp.h"
+#include <cstdlib>
#include <cstring>
#include <sstream>
-#include <stdlib.h>
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
std::string cmTimestamp::CurrentTime(const std::string& formatString,
@@ -109,7 +110,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const
time_t result = mktime(&tm);
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
if (tz_was_set) {
cmSystemTools::PutEnv(tz_old);
} else {
@@ -131,8 +132,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
struct tm& timeStruct,
const time_t timeT) const
{
- std::string formatString = "%";
- formatString += flag;
+ std::string formatString = cmStrCat('%', flag);
switch (flag) {
case 'a':
@@ -168,9 +168,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
return std::string();
}
- std::ostringstream ss;
- ss << static_cast<long int>(difftime(timeT, unixEpoch));
- return ss.str();
+ return std::to_string(static_cast<long int>(difftime(timeT, unixEpoch)));
}
default: {
return formatString;
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index d5fbdfd67..40338f8b2 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -5,8 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <ctime>
#include <string>
-#include <time.h>
/** \class cmTimestamp
* \brief Utility class to generate string representation of a timestamp
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index 82378780e..e525e851f 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -8,9 +8,11 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
+#include "cmCommand.h"
#include "cmCoreTryCompile.h"
-class cmCommand;
class cmExecutionStatus;
/** \class cmTryCompileCommand
@@ -24,7 +26,10 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override { return new cmTryCompileCommand; }
+ std::unique_ptr<cmCommand> Clone() override
+ {
+ return cm::make_unique<cmTryCompileCommand>();
+ }
/**
* This is called when the command is first encountered in
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index a92c2a05c..0e8e986ab 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -2,8 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTryRunCommand.h"
+#include <cstdio>
+
#include "cmsys/FStream.hxx"
-#include <stdio.h>
#include "cmDuration.h"
#include "cmMakefile.h"
@@ -11,6 +12,7 @@
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -137,7 +139,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
// now put the output into the variables
if (!this->RunOutputVariable.empty()) {
this->Makefile->AddDefinition(this->RunOutputVariable,
- runOutputContents.c_str());
+ runOutputContents);
}
if (!this->OutputVariable.empty()) {
@@ -148,8 +150,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
if (compileOutput) {
runOutputContents = compileOutput + runOutputContents;
}
- this->Makefile->AddDefinition(this->OutputVariable,
- runOutputContents.c_str());
+ this->Makefile->AddDefinition(this->OutputVariable, runOutputContents);
}
}
}
@@ -170,8 +171,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
const std::string& emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty()) {
- std::vector<std::string> emulatorWithArgs;
- cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
finalCommand +=
cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]);
finalCommand += " ";
@@ -214,20 +214,17 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
// copy the executable out of the CMakeFiles/ directory, so it is not
// removed at the end of TRY_RUN and the user can run it manually
// on the target platform.
- std::string copyDest = this->Makefile->GetHomeOutputDirectory();
- copyDest += "/CMakeFiles";
- copyDest += "/";
- copyDest += cmSystemTools::GetFilenameWithoutExtension(this->OutputFile);
- copyDest += "-";
- copyDest += this->RunResultVariable;
- copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile);
+ std::string copyDest =
+ cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/CMakeFiles/",
+ cmSystemTools::GetFilenameWithoutExtension(this->OutputFile), '-',
+ this->RunResultVariable,
+ cmSystemTools::GetFilenameExtension(this->OutputFile));
cmSystemTools::CopyFileAlways(this->OutputFile, copyDest);
- std::string resultFileName = this->Makefile->GetHomeOutputDirectory();
- resultFileName += "/TryRunResults.cmake";
+ std::string resultFileName =
+ cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/TryRunResults.cmake");
- std::string detailsString = "For details see ";
- detailsString += resultFileName;
+ std::string detailsString = cmStrCat("For details see ", resultFileName);
std::string internalRunOutputName =
this->RunResultVariable + "__TRYRUN_OUTPUT";
@@ -236,10 +233,10 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (!this->Makefile->GetDefinition(this->RunResultVariable)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
- std::string comment;
- comment += "Run result of TRY_RUN(), indicates whether the executable "
- "would have been able to run on its target platform.\n";
- comment += detailsString;
+ std::string comment =
+ cmStrCat("Run result of TRY_RUN(), indicates whether the executable "
+ "would have been able to run on its target platform.\n",
+ detailsString);
this->Makefile->AddCacheDefinition(this->RunResultVariable,
"PLEASE_FILL_OUT-FAILED_TO_RUN",
comment.c_str(), cmStateEnums::STRING);
@@ -259,11 +256,10 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (!this->Makefile->GetDefinition(internalRunOutputName)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
- std::string comment;
- comment +=
+ std::string comment = cmStrCat(
"Output of TRY_RUN(), contains the text, which the executable "
- "would have printed on stdout and stderr on its target platform.\n";
- comment += detailsString;
+ "would have printed on stdout and stderr on its target platform.\n",
+ detailsString);
this->Makefile->AddCacheDefinition(
internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(),
@@ -295,15 +291,15 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
/* clang-format on */
}
- std::string comment = "\n";
- comment += this->RunResultVariable;
- comment += "\n indicates whether the executable would have been able "
+ std::string comment =
+ cmStrCat('\n', this->RunResultVariable,
+ "\n indicates whether the executable would have been able "
"to run on its\n"
- " target platform. If so, set ";
- comment += this->RunResultVariable;
- comment += " to\n"
+ " target platform. If so, set ",
+ this->RunResultVariable,
+ " to\n"
" the exit code (in many cases 0 for success), otherwise "
- "enter \"FAILED_TO_RUN\".\n";
+ "enter \"FAILED_TO_RUN\".\n");
if (out) {
comment += internalRunOutputName;
comment +=
@@ -344,10 +340,11 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
}
firstTryRun = false;
- std::string errorMessage = "TRY_RUN() invoked in cross-compiling mode, "
- "please set the following cache variables "
- "appropriately:\n";
- errorMessage += " " + this->RunResultVariable + " (advanced)\n";
+ std::string errorMessage =
+ cmStrCat("TRY_RUN() invoked in cross-compiling mode, "
+ "please set the following cache variables "
+ "appropriately:\n ",
+ this->RunResultVariable, " (advanced)\n");
if (out) {
errorMessage += " " + internalRunOutputName + " (advanced)\n";
}
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index c54622c63..c53a69474 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -8,9 +8,11 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
+#include "cmCommand.h"
#include "cmCoreTryCompile.h"
-class cmCommand;
class cmExecutionStatus;
/** \class cmTryRunCommand
@@ -24,7 +26,10 @@ public:
/**
* This is a virtual constructor for the command.
*/
- cmCommand* Clone() override { return new cmTryRunCommand; }
+ std::unique_ptr<cmCommand> Clone() override
+ {
+ return cm::make_unique<cmTryRunCommand>();
+ }
/**
* This is called when the command is first encountered in
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index db674636c..23dabb770 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -3,9 +3,9 @@
#define cmUVHandlePtr_cxx
#include "cmUVHandlePtr.h"
-#include <assert.h>
+#include <cassert>
+#include <cstdlib>
#include <mutex>
-#include <stdlib.h>
#include "cm_uv.h"
@@ -122,7 +122,7 @@ uv_handle_ptr_<T>::operator T*() const
return this->handle.get();
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
template <>
struct uv_handle_deleter<uv_async_t>
{
@@ -230,7 +230,7 @@ int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
return uv_timer_start(*this, cb, timeout, repeat);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
uv_tty_ptr::operator uv_stream_t*() const
{
return reinterpret_cast<uv_stream_t*>(handle.get());
@@ -259,7 +259,7 @@ UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index c09e4bfdf..3083b60c8 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -240,8 +240,8 @@ struct uv_tty_ptr : public uv_handle_ptr_<uv_tty_t>
int init(uv_loop_t& loop, int fd, int readable, void* data = nullptr);
};
-typedef uv_handle_ptr_<uv_stream_t> uv_stream_ptr;
-typedef uv_handle_ptr_<uv_handle_t> uv_handle_ptr;
+using uv_stream_ptr = uv_handle_ptr_<uv_stream_t>;
+using uv_handle_ptr = uv_handle_ptr_<uv_handle_t>;
#ifndef cmUVHandlePtr_cxx
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 90ece0bc5..543c3308a 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -2,17 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUVProcessChain.h"
-#include "cmAlgorithms.h"
+#include <cassert>
+#include <istream> // IWYU pragma: keep
+#include <iterator>
+#include <utility>
+
+#include <cm/memory>
+
+#include "cm_uv.h"
+
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
#include "cmUVStreambuf.h"
-#include "cm_uv.h"
-
-#include <assert.h>
-
-#include <iterator>
-#include <memory>
-#include <utility>
struct cmUVProcessChain::InternalData
{
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
index 2b3352070..05a7cc82c 100644
--- a/Source/cmUVProcessChain.h
+++ b/Source/cmUVProcessChain.h
@@ -3,15 +3,15 @@
#ifndef cmUVProcessChain_h
#define cmUVProcessChain_h
-#include "cm_uv.h"
-
#include <array>
+#include <cstddef>
+#include <cstdint>
#include <iosfwd>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
-#include <stdint.h>
+#include "cm_uv.h"
class cmUVProcessChain;
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index 873352b1a..1c8a7717c 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -3,15 +3,15 @@
#ifndef cmUVStreambuf_h
#define cmUVStreambuf_h
-#include "cmUVHandlePtr.h"
-
-#include "cm_uv.h"
-
#include <algorithm>
#include <cstring>
#include <streambuf>
#include <vector>
+#include "cm_uv.h"
+
+#include "cmUVHandlePtr.h"
+
/*
* This file is based on example code from:
*
@@ -61,7 +61,7 @@ public:
cmBasicUVStreambuf* close();
protected:
- typename cmBasicUVStreambuf::int_type underflow() override;
+ typename cmBasicUVStreambuf<CharT, Traits>::int_type underflow() override;
std::streamsize showmanyc() override;
// FIXME: Add write support
diff --git a/Source/cmUnexpectedCommand.cxx b/Source/cmUnexpectedCommand.cxx
deleted file mode 100644
index a8de9e689..000000000
--- a/Source/cmUnexpectedCommand.cxx
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmUnexpectedCommand.h"
-
-#include <stdlib.h>
-
-#include "cmMakefile.h"
-
-class cmExecutionStatus;
-
-bool cmUnexpectedCommand::InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&)
-{
- const char* versionValue =
- this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
- if (this->Name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
- return true;
- }
-
- this->SetError(this->Error);
- return false;
-}
diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h
deleted file mode 100644
index 33d6bdc2c..000000000
--- a/Source/cmUnexpectedCommand.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmUnexpectedCommand_h
-#define cmUnexpectedCommand_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "cmCommand.h"
-
-class cmExecutionStatus;
-
-class cmUnexpectedCommand : public cmCommand
-{
-public:
- cmUnexpectedCommand(std::string name, const char* error)
- : Name(std::move(name))
- , Error(error)
- {
- }
-
- cmCommand* Clone() override
- {
- return new cmUnexpectedCommand(this->Name, this->Error);
- }
-
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- std::string Name;
- const char* Error;
-};
-
-#endif
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index cfaa1fd27..3ba95e99f 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -2,18 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUnsetCommand.h"
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmUnsetCommand
-bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmUnsetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty() || args.size() > 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
@@ -24,27 +23,27 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
// what is the variable name
auto const& envVarName = variable.substr(4, variable.size() - 5);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::UnsetEnv(envVarName.c_str());
#endif
return true;
}
// unset(VAR)
if (args.size() == 1) {
- this->Makefile->RemoveDefinition(variable);
+ status.GetMakefile().RemoveDefinition(variable);
return true;
}
// unset(VAR CACHE)
if ((args.size() == 2) && (args[1] == "CACHE")) {
- this->Makefile->RemoveCacheDefinition(variable);
+ status.GetMakefile().RemoveCacheDefinition(variable);
return true;
}
// unset(VAR PARENT_SCOPE)
if ((args.size() == 2) && (args[1] == "PARENT_SCOPE")) {
- this->Makefile->RaiseScope(variable, nullptr);
+ status.GetMakefile().RaiseScope(variable, nullptr);
return true;
}
// ERROR: second argument isn't CACHE or PARENT_SCOPE
- this->SetError("called with an invalid second argument");
+ status.SetError("called with an invalid second argument");
return false;
}
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index 4e1208a45..be4c166e8 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -8,29 +8,14 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmUnsetCommand
+/**
* \brief Unset a CMAKE variable
*
* cmUnsetCommand unsets or removes a variable.
*/
-class cmUnsetCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmUnsetCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmUnsetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx
index 43581947c..1fd386bda 100644
--- a/Source/cmUseMangledMesaCommand.cxx
+++ b/Source/cmUseMangledMesaCommand.cxx
@@ -5,29 +5,30 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cmExecutionStatus.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
+namespace {
+void CopyAndFullPathMesaHeader(const std::string& source,
+ const std::string& outdir);
+}
-bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmUseMangledMesaCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// expected two arguments:
// argument one: the full path to gl_mangle.h
// argument two : directory for output of edited headers
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
const std::string& inputDir = args[0];
- std::string glh = inputDir;
- glh += "/";
- glh += "gl.h";
+ std::string glh = cmStrCat(inputDir, "/gl.h");
if (!cmSystemTools::FileExists(glh)) {
- std::string e = "Bad path to Mesa, could not find: ";
- e += glh;
- e += " ";
- this->SetError(e);
+ std::string e = cmStrCat("Bad path to Mesa, could not find: ", glh, ' ');
+ status.SetError(e);
return false;
}
const std::string& destDir = args[1];
@@ -39,25 +40,22 @@ bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args,
}
cmSystemTools::MakeDirectory(destDir);
for (std::string const& f : files) {
- std::string path = inputDir;
- path += "/";
- path += f;
- this->CopyAndFullPathMesaHeader(path, destDir);
+ std::string path = cmStrCat(inputDir, '/', f);
+ CopyAndFullPathMesaHeader(path, destDir);
}
return true;
}
-void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(
- const std::string& source, const std::string& outdir)
+namespace {
+void CopyAndFullPathMesaHeader(const std::string& source,
+ const std::string& outdir)
{
- std::string dir, file;
+ std::string dir;
+ std::string file;
cmSystemTools::SplitProgramPath(source, dir, file);
- std::string outFile = outdir;
- outFile += "/";
- outFile += file;
- std::string tempOutputFile = outFile;
- tempOutputFile += ".tmp";
+ std::string outFile = cmStrCat(outdir, '/', file);
+ std::string tempOutputFile = cmStrCat(outFile, ".tmp");
cmsys::ofstream fout(tempOutputFile.c_str());
if (!fout) {
cmSystemTools::Error("Could not open file for write in copy operation: " +
@@ -100,6 +98,6 @@ void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(
// close the files before attempting to copy
fin.close();
fout.close();
- cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile);
- cmSystemTools::RemoveFile(tempOutputFile);
+ cmSystemTools::MoveFileIfDifferent(tempOutputFile, outFile);
+}
}
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index e2f1d9b90..215e4a3cc 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -8,20 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmUseMangledMesaCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmUseMangledMesaCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- void CopyAndFullPathMesaHeader(const std::string& source,
- const std::string& outdir);
-};
+bool cmUseMangledMesaCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index b59a587cd..a43165cce 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -2,48 +2,48 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUtilitySourceCommand.h"
-#include <string.h>
+#include <cstring>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmUtilitySourceCommand
-bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmUtilitySourceCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string>::const_iterator arg = args.begin();
+ auto arg = args.begin();
// The first argument is the cache entry name.
std::string const& cacheEntry = *arg++;
- const char* cacheValue = this->Makefile->GetDefinition(cacheEntry);
+ const char* cacheValue = status.GetMakefile().GetDefinition(cacheEntry);
// If it exists already and appears up to date then we are done. If
// the string contains "(IntDir)" but that is not the
// CMAKE_CFG_INTDIR setting then the value is out of date.
std::string const& intDir =
- this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
+ status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");
bool haveCacheValue = false;
- if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) {
+ if (status.GetMakefile().IsOn("CMAKE_CROSSCOMPILING")) {
haveCacheValue = (cacheValue != nullptr);
if (!haveCacheValue) {
- std::string msg = "UTILITY_SOURCE is used in cross compiling mode for ";
- msg += cacheEntry;
- msg += ". If your intention is to run this executable, you need to "
- "preload the cache with the full path to a version of that "
- "program, which runs on this build machine.";
+ std::string msg = cmStrCat(
+ "UTILITY_SOURCE is used in cross compiling mode for ", cacheEntry,
+ ". If your intention is to run this executable, you need to "
+ "preload the cache with the full path to a version of that "
+ "program, which runs on this build machine.");
cmSystemTools::Message(msg, "Warning");
}
} else {
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
haveCacheValue = (cacheValue &&
(strstr(cacheValue, "(IntDir)") == nullptr ||
(intDir == "$(IntDir)")) &&
@@ -62,7 +62,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// The third argument specifies the relative directory of the source
// of the utility.
std::string const& relativeSource = *arg++;
- std::string utilitySource = this->Makefile->GetCurrentSourceDirectory();
+ std::string utilitySource = status.GetMakefile().GetCurrentSourceDirectory();
utilitySource = utilitySource + "/" + relativeSource;
// If the directory doesn't exist, the source has not been included.
@@ -80,11 +80,12 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// The source exists.
const std::string& cmakeCFGout =
- this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
- std::string utilityDirectory = this->Makefile->GetCurrentBinaryDirectory();
+ status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");
+ std::string utilityDirectory =
+ status.GetMakefile().GetCurrentBinaryDirectory();
std::string exePath;
- if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
- exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ if (status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
+ exePath = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH");
}
if (!exePath.empty()) {
utilityDirectory = exePath;
@@ -94,21 +95,22 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
// Construct the cache entry for the executable's location.
std::string utilityExecutable = utilityDirectory + "/" + cmakeCFGout + "/" +
- utilityName + this->Makefile->GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
+ utilityName +
+ status.GetMakefile().GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
// make sure we remove any /./ in the name
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- this->Makefile->AddCacheDefinition(cacheEntry, utilityExecutable.c_str(),
- "Path to an internal program.",
- cmStateEnums::FILEPATH);
+ status.GetMakefile().AddCacheDefinition(
+ cacheEntry, utilityExecutable.c_str(), "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);
- this->Makefile->AddCacheDefinition(utilityExecutable, utilityName.c_str(),
- "Executable to project name.",
- cmStateEnums::INTERNAL);
+ status.GetMakefile().AddCacheDefinition(
+ utilityExecutable, utilityName.c_str(), "Executable to project name.",
+ cmStateEnums::INTERNAL);
return true;
}
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index 165eceff6..934d53905 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -8,16 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmUtilitySourceCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmUtilitySourceCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmUtilitySourceCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 51ecbd180..cd52b3f30 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUuid.h"
-#include "cmCryptoHash.h"
-
#include <array>
-#include <string.h>
+#include <cstring>
+
+#include "cmCryptoHash.h"
static const std::array<int, 5> kUuidGroups = { { 4, 2, 2, 2, 6 } };
@@ -53,7 +53,7 @@ void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
std::string cmUuid::FromDigest(const unsigned char* digest,
unsigned char version) const
{
- typedef unsigned char byte_t;
+ using byte_t = unsigned char;
byte_t uuid[16] = { 0 };
memcpy(uuid, digest, 16);
@@ -114,14 +114,12 @@ std::string cmUuid::BinaryToString(const unsigned char* input) const
std::string cmUuid::ByteToHex(unsigned char byte) const
{
- std::string result;
+ std::string result(" ");
for (int i = 0; i < 2; ++i) {
unsigned char rest = byte % 16;
byte /= 16;
-
char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA));
-
- result = c + result;
+ result.at(1 - i) = c;
}
return result;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index c78361e26..dd9f058b8 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -2,10 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVSSetupHelper.h"
-#include "cmSystemTools.h"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
#ifndef VSSetupConstants
# define VSSetupConstants
/* clang-format off */
@@ -195,7 +197,7 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) {
return false;
}
- vcToolsVersion = cmSystemTools::TrimWhitespace(vcToolsVersion);
+ vcToolsVersion = cmTrimWhitespace(vcToolsVersion);
std::string const vcToolsDir = vcRoot + "/VC/Tools/MSVC/" + vcToolsVersion;
if (!cmSystemTools::FileIsDirectory(vcToolsDir)) {
return false;
@@ -364,8 +366,8 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
// We are not looking for a specific instance.
// If we've been given a hint then use it.
if (!envVSCommonToolsDir.empty()) {
- std::string currentVSLocation = instanceInfo.GetInstallLocation();
- currentVSLocation += "/Common7/Tools";
+ std::string currentVSLocation =
+ cmStrCat(instanceInfo.GetInstallLocation(), "/Common7/Tools");
if (cmSystemTools::ComparePath(currentVSLocation,
envVSCommonToolsDir)) {
chosenInstanceInfo = instanceInfo;
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 1bda54a47..0980cef53 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -8,13 +8,13 @@
#endif
// Published by Visual Studio Setup team
-#include "cmvssetup/Setup.Configuration.h"
-
#include <string>
#include <vector>
#include <windows.h>
+#include "cmvssetup/Setup.Configuration.h"
+
template <class T>
class SmartCOMPtr
{
@@ -74,26 +74,8 @@ class SmartBSTR
{
public:
SmartBSTR() { str = NULL; }
- SmartBSTR(const SmartBSTR& src)
- {
- if (src.str != NULL) {
- str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
- } else {
- str = ::SysAllocStringByteLen(NULL, 0);
- }
- }
- SmartBSTR& operator=(const SmartBSTR& src)
- {
- if (str != src.str) {
- ::SysFreeString(str);
- if (src.str != NULL) {
- str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
- } else {
- str = ::SysAllocStringByteLen(NULL, 0);
- }
- }
- return *this;
- }
+ SmartBSTR(const SmartBSTR& src) = delete;
+ SmartBSTR& operator=(const SmartBSTR& src) = delete;
operator BSTR() const { return str; }
BSTR* operator&() throw() { return &str; }
~SmartBSTR() throw() { ::SysFreeString(str); }
diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
index c02157ad1..6b93c636a 100644
--- a/Source/cmVariableRequiresCommand.cxx
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -2,32 +2,32 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableRequiresCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
// cmLibraryCommand
-bool cmVariableRequiresCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmVariableRequiresCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string const& testVariable = args[0];
- if (!this->Makefile->IsOn(testVariable)) {
+ if (!status.GetMakefile().IsOn(testVariable)) {
return true;
}
std::string const& resultVariable = args[1];
bool requirementsMet = true;
std::string notSet;
bool hasAdvanced = false;
- cmState* state = this->Makefile->GetState();
+ cmState* state = status.GetMakefile().GetState();
for (unsigned int i = 2; i < args.size(); ++i) {
- if (!this->Makefile->IsOn(args[i])) {
+ if (!status.GetMakefile().IsOn(args[i])) {
requirementsMet = false;
notSet += args[i];
notSet += "\n";
@@ -37,21 +37,20 @@ bool cmVariableRequiresCommand::InitialPass(
}
}
}
- const char* reqVar = this->Makefile->GetDefinition(resultVariable);
+ const char* reqVar = status.GetMakefile().GetDefinition(resultVariable);
// if reqVar is unset, then set it to requirementsMet
// if reqVar is set to true, but requirementsMet is false , then
// set reqVar to false.
- if (!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) {
- this->Makefile->AddDefinition(resultVariable, requirementsMet);
+ if (!reqVar || (!requirementsMet && status.GetMakefile().IsOn(reqVar))) {
+ status.GetMakefile().AddDefinitionBool(resultVariable, requirementsMet);
}
if (!requirementsMet) {
- std::string message = "Variable assertion failed:\n";
- message +=
- testVariable + " Requires that the following unset variables are set:\n";
- message += notSet;
- message += "\nPlease set them, or set ";
- message += testVariable + " to false, and re-configure.\n";
+ std::string message =
+ cmStrCat("Variable assertion failed:\n", testVariable,
+ " Requires that the following unset variables are set:\n",
+ notSet, "\nPlease set them, or set ", testVariable,
+ " to false, and re-configure.\n");
if (hasAdvanced) {
message +=
"One or more of the required variables is advanced."
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 94970c584..fb0520ed7 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -8,16 +8,9 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmVariableRequiresCommand : public cmCommand
-{
-public:
- cmCommand* Clone() override { return new cmVariableRequiresCommand; }
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmVariableRequiresCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 3df142099..4995da972 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -66,8 +66,7 @@ bool cmVariableWatch::VariableAccessed(const std::string& variable,
int access_type, const char* newValue,
const cmMakefile* mf) const
{
- cmVariableWatch::StringToVectorOfPairs::const_iterator mit =
- this->WatchMap.find(variable);
+ auto mit = this->WatchMap.find(variable);
if (mit != this->WatchMap.end()) {
// The strategy here is to copy the list of callbacks, and ignore
// new callbacks that existing ones may add.
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 123010179..e4b3b7c47 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -20,10 +20,9 @@ class cmMakefile;
class cmVariableWatch
{
public:
- typedef void (*WatchMethod)(const std::string& variable, int access_type,
- void* client_data, const char* newValue,
- const cmMakefile* mf);
- typedef void (*DeleteData)(void* client_data);
+ using WatchMethod = void (*)(const std::string&, int, void*, const char*,
+ const cmMakefile*);
+ using DeleteData = void (*)(void*);
cmVariableWatch();
~cmVariableWatch();
@@ -77,8 +76,8 @@ protected:
Pair& operator=(const Pair&) = delete;
};
- typedef std::vector<std::shared_ptr<Pair>> VectorOfPairs;
- typedef std::map<std::string, VectorOfPairs> StringToVectorOfPairs;
+ using VectorOfPairs = std::vector<std::shared_ptr<Pair>>;
+ using StringToVectorOfPairs = std::map<std::string, VectorOfPairs>;
StringToVectorOfPairs WatchMap;
};
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 5fe55bd53..f2c8f3cdb 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -2,12 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableWatchCommand.h"
-#include <sstream>
+#include <memory>
+#include <utility>
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVariableWatch.h"
#include "cmake.h"
@@ -54,24 +56,22 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
newLFF.Name = data->Command;
newLFF.Line = 9999;
- cmExecutionStatus status;
+ cmExecutionStatus status(*makefile);
if (!makefile->ExecuteCommand(newLFF, status)) {
- std::ostringstream error;
- error << "Error in cmake code at\nUnknown:0:\n"
- << "A command failed during the invocation of callback \""
- << data->Command << "\".";
- cmSystemTools::Error(error.str());
+ cmSystemTools::Error(
+ cmStrCat("Error in cmake code at\nUnknown:0:\nA command failed "
+ "during the invocation of callback \"",
+ data->Command, "\"."));
data->InCallback = false;
return;
}
processed = true;
}
if (!processed) {
- std::ostringstream msg;
- msg << "Variable \"" << variable << "\" was accessed using "
- << accessString << " with value \"" << (newValue ? newValue : "")
- << "\".";
- makefile->IssueMessage(MessageType::LOG, msg.str());
+ makefile->IssueMessage(
+ MessageType::LOG,
+ cmStrCat("Variable \"", variable, "\" was accessed using ", accessString,
+ " with value \"", (newValue ? newValue : ""), "\"."));
}
data->InCallback = false;
@@ -84,21 +84,46 @@ static void deleteVariableWatchCallbackData(void* client_data)
delete data;
}
-cmVariableWatchCommand::cmVariableWatchCommand() = default;
-
-cmVariableWatchCommand::~cmVariableWatchCommand()
+/** This command does not really have a final pass but it needs to
+ stay alive since it owns variable watch callback information. */
+class FinalAction
{
- for (std::string const& wv : this->WatchedVariables) {
- this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
- wv, cmVariableWatchCommandVariableAccessed);
+public:
+ /* NOLINTNEXTLINE(performance-unnecessary-value-param) */
+ FinalAction(cmMakefile* makefile, std::string variable)
+ : Action(std::make_shared<Impl>(makefile, std::move(variable)))
+ {
}
-}
-bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+ void operator()(cmMakefile&) const {}
+
+private:
+ struct Impl
+ {
+ Impl(cmMakefile* makefile, std::string variable)
+ : Makefile(makefile)
+ , Variable(std::move(variable))
+ {
+ }
+
+ ~Impl()
+ {
+ this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
+ this->Variable, cmVariableWatchCommandVariableAccessed);
+ }
+
+ cmMakefile* Makefile;
+ std::string Variable;
+ };
+
+ std::shared_ptr<Impl const> Action;
+};
+
+bool cmVariableWatchCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("must be called with at least one argument.");
+ status.SetError("must be called with at least one argument.");
return false;
}
std::string const& variable = args[0];
@@ -107,9 +132,7 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
command = args[1];
}
if (variable == "CMAKE_CURRENT_LIST_FILE") {
- std::ostringstream ostr;
- ostr << "cannot be set on the variable: " << variable;
- this->SetError(ostr.str());
+ status.SetError(cmStrCat("cannot be set on the variable: ", variable));
return false;
}
@@ -118,13 +141,14 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
data->InCallback = false;
data->Command = command;
- this->WatchedVariables.insert(variable);
- if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
+ if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch(
variable, cmVariableWatchCommandVariableAccessed, data,
deleteVariableWatchCallbackData)) {
deleteVariableWatchCallbackData(data);
return false;
}
+ status.GetMakefile().AddFinalAction(
+ FinalAction(&status.GetMakefile(), variable));
return true;
}
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index 6a8115d74..3f9f2443a 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -5,45 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <set>
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmVariableWatchCommand
+/**
* \brief Watch when the variable changes and invoke command
*
*/
-class cmVariableWatchCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmVariableWatchCommand; }
-
- //! Default constructor
- cmVariableWatchCommand();
-
- //! Destructor.
- ~cmVariableWatchCommand() override;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
- /** This command does not really have a final pass but it needs to
- stay alive since it owns variable watch callback information. */
- bool HasFinalPass() const override { return true; }
-
-protected:
- std::set<std::string> WatchedVariables;
-};
+bool cmVariableWatchCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index fa102f882..94b649527 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2,6 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVisualStudio10TargetGenerator.h"
+#include <iterator>
+#include <set>
+
+#include <cm/memory>
+
+#include "windows.h"
+
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
@@ -16,11 +23,6 @@
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmVisualStudioGeneratorOptions.h"
-#include "windows.h"
-
-#include <iterator>
-#include <memory> // IWYU pragma: keep
-#include <set>
static void ConvertToWindowsSlash(std::string& s);
@@ -120,7 +122,7 @@ struct cmVisualStudio10TargetGenerator::Elem
class cmVS10GeneratorOptions : public cmVisualStudioGeneratorOptions
{
public:
- typedef cmVisualStudio10TargetGenerator::Elem Elem;
+ using Elem = cmVisualStudio10TargetGenerator::Elem;
cmVS10GeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool,
cmVS7FlagTable const* table,
cmVisualStudio10TargetGenerator* g = nullptr)
@@ -363,10 +365,9 @@ void cmVisualStudio10TargetGenerator::Generate()
return;
}
}
- std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
- path += "/";
- path += this->Name;
- path += ProjectFileExtension;
+ std::string path =
+ cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->Name, ProjectFileExtension);
cmGeneratedFileStream BuildFileStream(path);
const std::string PathToProjectFile = path;
BuildFileStream.SetCopyIfDifferent(true);
@@ -505,6 +506,11 @@ void cmVisualStudio10TargetGenerator::Generate()
if (targetFrameworkVersion) {
e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
}
+ if (this->ProjectType == vcxproj &&
+ this->GlobalGenerator->TargetsWindowsCE()) {
+ e1.Element("EnableRedirectPlatform", "true");
+ e1.Element("RedirectPlatformValue", this->Platform);
+ }
if (this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE()) {
const char* targetFrameworkId = this->GeneratorTarget->GetProperty(
@@ -520,6 +526,13 @@ void cmVisualStudio10TargetGenerator::Generate()
}
e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
}
+ if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
+ .empty()) {
+ e1.Element(
+ "CudaToolkitCustomDir",
+ this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() +
+ "nvcc");
+ }
}
// Disable the project upgrade prompt that is displayed the first time a
@@ -606,10 +619,17 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.SetHasElements();
if (this->GlobalGenerator->IsCudaEnabled()) {
+ auto customDir =
+ this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
+ std::string cudaPath = customDir.empty()
+ ? "$(VCTargetsPath)\\BuildCustomizations\\"
+ : customDir +
+ "CUDAVisualStudioIntegration\\extras\\"
+ "visual_studio_integration\\MSBuildExtensions\\";
Elem(e1, "Import")
.Attribute("Project",
- "$(VCTargetsPath)\\BuildCustomizations\\CUDA " +
- this->GlobalGenerator->GetPlatformToolsetCudaString() +
+ std::move(cudaPath) + "CUDA " +
+ this->GlobalGenerator->GetPlatformToolsetCuda() +
".props");
}
if (this->GlobalGenerator->IsMasmEnabled()) {
@@ -622,9 +642,8 @@ void cmVisualStudio10TargetGenerator::Generate()
std::string propsTemplate =
GetCMakeFilePath("Templates/MSBuild/nasm.props.in");
- std::string propsLocal;
- propsLocal += this->DefaultArtifactDir;
- propsLocal += "\\nasm.props";
+ std::string propsLocal =
+ cmStrCat(this->DefaultArtifactDir, "\\nasm.props");
ConvertToWindowsSlash(propsLocal);
this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
true);
@@ -692,10 +711,17 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.SetHasElements();
this->WriteTargetsFileReferences(e1);
if (this->GlobalGenerator->IsCudaEnabled()) {
+ auto customDir =
+ this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString();
+ std::string cudaPath = customDir.empty()
+ ? "$(VCTargetsPath)\\BuildCustomizations\\"
+ : customDir +
+ "CUDAVisualStudioIntegration\\extras\\"
+ "visual_studio_integration\\MSBuildExtensions\\";
Elem(e1, "Import")
.Attribute("Project",
- "$(VCTargetsPath)\\BuildCustomizations\\CUDA " +
- this->GlobalGenerator->GetPlatformToolsetCudaString() +
+ std::move(cudaPath) + "CUDA " +
+ this->GlobalGenerator->GetPlatformToolsetCuda() +
".targets");
}
if (this->GlobalGenerator->IsMasmEnabled()) {
@@ -744,7 +770,7 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
std::vector<std::string> packageReferences;
if (const char* vsPackageReferences =
this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmSystemTools::ExpandListArgument(vsPackageReferences, packageReferences);
+ cmExpandList(vsPackageReferences, packageReferences);
}
if (!packageReferences.empty()) {
Elem e1(e0, "ItemGroup");
@@ -771,14 +797,14 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
std::vector<std::string> references;
if (const char* vsDotNetReferences =
this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
- cmSystemTools::ExpandListArgument(vsDotNetReferences, references);
+ cmExpandList(vsDotNetReferences, references);
}
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
- for (auto const& i : props) {
+ 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.GetValue();
+ std::string path = i.second;
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
}
@@ -832,7 +858,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
const char* privateReference = "True";
if (const char* value = this->GeneratorTarget->GetProperty(
"VS_DOTNET_REFERENCES_COPY_LOCAL")) {
- if (cmSystemTools::IsOff(value)) {
+ if (cmIsOff(value)) {
privateReference = "False";
}
}
@@ -847,8 +873,8 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
const char* imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit;
- cmSystemTools::ExpandListArgument(std::string(imports), argsSplit, false);
+ std::vector<std::string> argsSplit =
+ cmExpandedList(std::string(imports), false);
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -867,13 +893,13 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
static const std::string refpropPrefix = "VS_DOTNET_REFERENCEPROP_";
static const std::string refpropInfix = "_TAG_";
const std::string refPropFullPrefix = refpropPrefix + ref + refpropInfix;
- typedef std::map<std::string, std::string> CustomTags;
+ using CustomTags = std::map<std::string, std::string>;
CustomTags tags;
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
- for (const auto& i : props) {
+ 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.GetValue();
+ std::string refVal = i.second;
if (!refTag.empty() && !refVal.empty()) {
tags[refTag] = refVal;
}
@@ -967,12 +993,12 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
}
}
const cmPropertyMap& props = oi->GetProperties();
- for (const auto& p : props) {
+ for (const std::string& p : props.GetKeys()) {
static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.first.find(propNamePrefix) == 0) {
- std::string tagName = p.first.substr(propNamePrefix.length());
+ if (p.find(propNamePrefix) == 0) {
+ std::string tagName = p.substr(propNamePrefix.length());
if (!tagName.empty()) {
- std::string value = props.GetPropertyValue(p.first);
+ std::string value = props.GetPropertyValue(p);
if (!value.empty()) {
e2.Element(tagName.c_str(), value);
}
@@ -1068,7 +1094,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
std::vector<std::string> references;
if (const char* vsWinRTReferences =
this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
- cmSystemTools::ExpandListArgument(vsWinRTReferences, references);
+ cmExpandList(vsWinRTReferences, references);
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
@@ -1111,7 +1137,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
std::string configType;
if (const char* vsConfigurationType =
this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
- configType = vsConfigurationType;
+ configType = cmGeneratorExpression::Evaluate(vsConfigurationType,
+ this->LocalGenerator, c);
} else {
switch (this->GeneratorTarget->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
@@ -1266,8 +1293,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
e1.Element("PlatformToolset", toolset);
}
- std::string postfixName = cmSystemTools::UpperCase(config);
- postfixName += "_POSTFIX";
+ std::string postfixName =
+ cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
std::string assemblyName = this->GeneratorTarget->GetOutputName(
config, cmStateEnums::RuntimeBinaryArtifact);
if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
@@ -1372,9 +1399,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
// preventing dependent rebuilds.
this->ForceOld(sourcePath);
} else {
- std::string error = "Could not create file: [";
- error += sourcePath;
- error += "] ";
+ std::string error =
+ cmStrCat("Could not create file: [", sourcePath, "] ");
cmSystemTools::Error(error + cmSystemTools::GetLastSystemError());
}
}
@@ -1404,7 +1430,6 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
std::string comment = lg->ConstructComment(ccg);
comment = cmVS10EscapeComment(comment);
std::string script = lg->ConstructScript(ccg);
- bool symbolic = false;
// input files for custom command
std::stringstream additional_inputs;
{
@@ -1431,12 +1456,6 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
ConvertToWindowsSlash(dep);
additional_inputs << sep << dep;
sep = ";";
- if (!symbolic) {
- if (cmSourceFile* sf = this->Makefile->GetSource(
- dep, cmSourceFileLocationKind::Known)) {
- symbolic = sf->GetPropertyAsBool("SYMBOLIC");
- }
- }
}
}
if (this->ProjectType != csproj) {
@@ -1445,6 +1464,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
// output files for custom command
std::stringstream outputs;
+ bool symbolic = false;
{
const char* sep = "";
for (std::string const& o : ccg.GetOutputs()) {
@@ -1563,11 +1583,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->AddMissingSourceGroups(groupsUsed, sourceGroups);
// Write out group file
- std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
- path += "/";
- path += this->Name;
- path += computeProjectFileExtension(this->GeneratorTarget);
- path += ".filters";
+ std::string path = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->Name,
+ computeProjectFileExtension(this->GeneratorTarget), ".filters");
cmGeneratedFileStream fout(path);
fout.SetCopyIfDifferent(true);
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
@@ -1962,11 +1980,11 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
const std::string& enableDebug =
cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
if (!enableDebug.empty()) {
- e2.WritePlatformConfigTag(
- "EnableDebuggingInformation",
- "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] +
- "|" + this->Platform + "'",
- cmSystemTools::IsOn(enableDebug) ? "true" : "false");
+ e2.WritePlatformConfigTag("EnableDebuggingInformation",
+ "'$(Configuration)|$(Platform)'=='" +
+ this->Configurations[i] + "|" +
+ this->Platform + "'",
+ cmIsOn(enableDebug) ? "true" : "false");
}
}
}
@@ -1983,7 +2001,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
"DisableOptimizations",
"'$(Configuration)|$(Platform)'=='" + this->Configurations[i] +
"|" + this->Platform + "'",
- (cmSystemTools::IsOn(disableOptimizations) ? "true" : "false"));
+ (cmIsOn(disableOptimizations) ? "true" : "false"));
}
}
}
@@ -2063,6 +2081,17 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
return;
}
+
+ const bool haveUnityBuild =
+ this->GeneratorTarget->GetPropertyAsBool("UNITY_BUILD");
+
+ if (haveUnityBuild &&
+ this->GlobalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VS15) {
+ Elem e1(e0, "PropertyGroup");
+ e1.Element("EnableUnitySupport", "true");
+ }
+
Elem e1(e0, "ItemGroup");
e1.SetHasElements();
@@ -2112,6 +2141,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
this->WriteExtraSource(e1, si.Source);
break;
case cmGeneratorTarget::SourceKindHeader:
+ case cmGeneratorTarget::SourceKindUnityBatched:
this->WriteHeaderSource(e1, si.Source);
break;
case cmGeneratorTarget::SourceKindIDL:
@@ -2161,9 +2191,51 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
Elem e2(e1, tool);
this->WriteSource(e2, si.Source);
+
+ bool useNativeUnityBuild = false;
+ if (haveUnityBuild &&
+ this->GlobalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VS15) {
+ // Magic value taken from cmGlobalVisualStudioVersionedGenerator.cxx
+ static const std::string vs15 = "141";
+ std::string toolset =
+ this->GlobalGenerator->GetPlatformToolsetString();
+ cmSystemTools::ReplaceString(toolset, "v", "");
+
+ if (toolset.empty() ||
+ cmSystemTools::VersionCompareGreaterEq(toolset, vs15)) {
+ useNativeUnityBuild = true;
+ }
+ }
+
+ if (haveUnityBuild && strcmp(tool, "ClCompile") == 0 &&
+ si.Source->GetProperty("UNITY_SOURCE_FILE")) {
+ if (useNativeUnityBuild) {
+ e2.Attribute(
+ "IncludeInUnityFile",
+ si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")
+ ? "false"
+ : "true");
+ e2.Attribute("CustomUnityFile", "true");
+
+ std::string unityDir = cmSystemTools::GetFilenamePath(
+ si.Source->GetProperty("UNITY_SOURCE_FILE"));
+ e2.Attribute("UnityFilesDirectory", unityDir);
+ } else {
+ // Visual Studio versions prior to 2017 do not know about unity
+ // builds, thus we exclude the files alredy part of unity sources.
+ if (!si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")) {
+ exclude_configs = si.Configs;
+ }
+ }
+ }
+
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
this->OutputSourceSpecificFlags(e2, si.Source);
}
+ if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
+ e2.Element("PrecompiledHeader", "NotUsing");
+ }
if (!exclude_configs.empty()) {
this->WriteExcludeFromBuild(e2, exclude_configs);
}
@@ -2248,8 +2320,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
for (std::string const& config : this->Configurations) {
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configDefines = defines;
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += configUpper;
+ std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
if (const char* ccdefs = sf.GetProperty(defPropName)) {
if (!configDefines.empty()) {
configDefines += ";";
@@ -2258,10 +2329,28 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmGeneratorExpression::Find(ccdefs) != std::string::npos;
configDefines += ccdefs;
}
+
+ // Add precompile headers compile options.
+ std::string customAndPchOptions = options;
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, lang);
+ if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ std::string pchOptions;
+ if (sf.GetFullPath() == pchSource) {
+ pchOptions =
+ this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+ } else {
+ pchOptions =
+ this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
+ }
+ customAndPchOptions += pchOptions;
+ }
+
// if we have flags or defines for this config then
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
- !includes.empty() || compileAs || noWinRT) {
+ !includes.empty() || compileAs || noWinRT ||
+ !customAndPchOptions.empty()) {
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
@@ -2294,14 +2383,15 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} else {
clOptions.Parse(flags);
}
- if (!options.empty()) {
+ if (!customAndPchOptions.empty()) {
std::string expandedOptions;
if (configDependentOptions) {
this->LocalGenerator->AppendCompileOptions(
expandedOptions,
- genexInterpreter.Evaluate(options, "COMPILE_OPTIONS"));
+ genexInterpreter.Evaluate(customAndPchOptions, "COMPILE_OPTIONS"));
} else {
- this->LocalGenerator->AppendCompileOptions(expandedOptions, options);
+ this->LocalGenerator->AppendCompileOptions(expandedOptions,
+ customAndPchOptions);
}
clOptions.Parse(expandedOptions);
}
@@ -2340,7 +2430,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
if (this->ProjectType == csproj) {
std::string f = source->GetFullPath();
- typedef std::map<std::string, std::string> CsPropMap;
+ using CsPropMap = std::map<std::string, std::string>;
CsPropMap sourceFileTags;
// set <Link> tag if necessary
std::string link;
@@ -2387,49 +2477,32 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
if (ttype <= cmStateEnums::UTILITY) {
if (const char* workingDir = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_WORKING_DIRECTORY")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(workingDir);
- std::string genWorkingDir =
- cge->Evaluate(this->LocalGenerator, config);
-
+ std::string genWorkingDir = cmGeneratorExpression::Evaluate(
+ workingDir, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
genWorkingDir);
}
if (const char* environment =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(environment);
- std::string genEnvironment =
- cge->Evaluate(this->LocalGenerator, config);
-
+ std::string genEnvironment = cmGeneratorExpression::Evaluate(
+ environment, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
genEnvironment);
}
if (const char* debuggerCommand =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
-
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(debuggerCommand);
- std::string genDebuggerCommand =
- cge->Evaluate(this->LocalGenerator, config);
-
+ std::string genDebuggerCommand = cmGeneratorExpression::Evaluate(
+ debuggerCommand, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
genDebuggerCommand);
}
if (const char* commandArguments = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_COMMAND_ARGUMENTS")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(commandArguments);
- std::string genCommandArguments =
- cge->Evaluate(this->LocalGenerator, config);
-
+ std::string genCommandArguments = cmGeneratorExpression::Evaluate(
+ commandArguments, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
genCommandArguments);
}
@@ -2439,17 +2512,14 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
e1.WritePlatformConfigTag(
"IntDir", cond, "$(Platform)\\$(Configuration)\\$(ProjectName)\\");
} else {
- std::string intermediateDir =
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- intermediateDir += "/";
- intermediateDir += config;
- intermediateDir += "/";
+ std::string intermediateDir = cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
+ config, '/');
std::string outDir;
std::string targetNameFull;
if (ttype == cmStateEnums::OBJECT_LIBRARY) {
outDir = intermediateDir;
- targetNameFull = this->GeneratorTarget->GetName();
- targetNameFull += ".lib";
+ targetNameFull = cmStrCat(this->GeneratorTarget->GetName(), ".lib");
} else {
outDir = this->GeneratorTarget->GetDirectory(config) + "/";
targetNameFull = this->GeneratorTarget->GetFullName(config);
@@ -2617,8 +2687,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string langForClCompile;
if (this->ProjectType == csproj) {
langForClCompile = "CSharp";
- } else if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) !=
- cm::cend(clLangs)) {
+ } else if (cmContains(clLangs, linkLanguage)) {
langForClCompile = linkLanguage;
} else {
std::set<std::string> languages;
@@ -2650,6 +2719,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->IPOEnabledConfigurations.insert(configName);
}
+ // Precompile Headers
+ std::string pchHeader =
+ this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
+ if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) {
+ clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ }
+
// Get preprocessor definitions for this directory.
std::string defineFlags = this->Makefile->GetDefineFlags();
if (this->MSTools) {
@@ -2665,7 +2741,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
// replace this setting with "true" below.
clOptions.AddFlag("UseFullPaths", "false");
}
- clOptions.AddFlag("PrecompiledHeader", "NotUsing");
clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)");
}
}
@@ -2730,9 +2805,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
// Add a definition for the configuration name.
- std::string configDefine = "CMAKE_INTDIR=\"";
- configDefine += configName;
- configDefine += "\"";
+ std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"');
clOptions.AddDefine(configDefine);
if (const std::string* exportMacro =
this->GeneratorTarget->GetExportMacro()) {
@@ -2757,7 +2830,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
}
if (const char* winRT = clOptions.GetFlag("CompileAsWinRT")) {
- if (cmSystemTools::IsOn(winRT)) {
+ if (cmIsOn(winRT)) {
this->TargetCompileAsWinRT = true;
}
}
@@ -3027,9 +3100,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.AddDefines(targetDefines);
// Add a definition for the configuration name.
- std::string configDefine = "CMAKE_INTDIR=\"";
- configDefine += configName;
- configDefine += "\"";
+ std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"');
cudaOptions.AddDefine(configDefine);
if (const std::string* exportMacro =
this->GeneratorTarget->GetExportMacro()) {
@@ -3094,6 +3165,82 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
"-Wno-deprecated-gpu-targets");
}
+ // For static libraries that have device linking enabled compute
+ // the libraries
+ if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY &&
+ doDeviceLinking) {
+ cmComputeLinkInformation* pcli =
+ this->GeneratorTarget->GetLinkInformation(configName);
+ if (!pcli) {
+ cmSystemTools::Error(
+ "CMake can not compute cmComputeLinkInformation for target: " +
+ this->Name);
+ return false;
+ }
+
+ // Would like to use:
+ // cmLinkLineDeviceComputer computer(this->LocalGenerator,
+ // this->LocalGenerator->GetStateSnapshot().GetDirectory());
+ // std::string computed_libs = computer.ComputeLinkLibraries(cli,
+ // std::string{}); but it outputs in "<libA> <libB>" format instead of
+ // "<libA>;<libB>"
+ // Note:
+ // Any modification of this algorithm should be reflected also in
+ // cmLinkLineDeviceComputer
+ cmComputeLinkInformation& cli = *pcli;
+ std::vector<std::string> libVec;
+ const std::string currentBinDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
+ const auto& libs = cli.GetItems();
+ for (cmComputeLinkInformation::Item const& l : libs) {
+
+ if (l.Target) {
+ auto managedType = l.Target->GetManagedType(configName);
+ // Do not allow C# targets to be added to the LIB listing. LIB files
+ // are used for linking C++ dependencies. C# libraries do not have lib
+ // files. Instead, they compile down to C# reference libraries (DLL
+ // files). The
+ // `<ProjectReference>` elements added to the vcxproj are enough for
+ // the IDE to deduce the DLL file required by other C# projects that
+ // need its reference library.
+ if (managedType == cmGeneratorTarget::ManagedType::Managed) {
+ continue;
+ }
+ const auto type = l.Target->GetType();
+
+ bool skip = false;
+ switch (type) {
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ skip = true;
+ break;
+ case cmStateEnums::STATIC_LIBRARY:
+ skip = l.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
+ break;
+ default:
+ break;
+ }
+ if (skip) {
+ continue;
+ }
+ }
+
+ if (l.IsPath) {
+ std::string path = this->LocalGenerator->MaybeConvertToRelativePath(
+ currentBinDir, l.Value);
+ ConvertToWindowsSlash(path);
+ if (!cmVS10IsTargetsFile(l.Value)) {
+ libVec.push_back(path);
+ }
+ } else {
+ libVec.push_back(l.Value);
+ }
+ }
+
+ cudaLinkOptions.AddFlag("AdditionalDependencies", libVec);
+ }
+
this->CudaLinkOptions[configName] = std::move(pOptions);
return true;
}
@@ -3270,15 +3417,32 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
std::vector<cmSourceFile const*> manifest_srcs;
this->GeneratorTarget->GetManifests(manifest_srcs, config);
- if (!manifest_srcs.empty()) {
- std::ostringstream oss;
- for (cmSourceFile const* mi : manifest_srcs) {
- std::string m = this->ConvertPath(mi->GetFullPath(), false);
- ConvertToWindowsSlash(m);
- oss << m << ";";
- }
+
+ const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
+
+ if (!manifest_srcs.empty() || dpiAware) {
Elem e2(e1, "Manifest");
- e2.Element("AdditionalManifestFiles", oss.str());
+ if (!manifest_srcs.empty()) {
+ std::ostringstream oss;
+ for (cmSourceFile const* mi : manifest_srcs) {
+ std::string m = this->ConvertPath(mi->GetFullPath(), false);
+ ConvertToWindowsSlash(m);
+ oss << m << ";";
+ }
+ e2.Element("AdditionalManifestFiles", oss.str());
+ }
+ if (dpiAware) {
+ if (!strcmp(dpiAware, "PerMonitor")) {
+ e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
+ } else if (cmIsOn(dpiAware)) {
+ e2.Element("EnableDpiAwareness", "true");
+ } else if (cmIsOff(dpiAware)) {
+ e2.Element("EnableDpiAwareness", "false");
+ } else {
+ cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " +
+ std::string(dpiAware));
+ }
+ }
}
}
@@ -3328,22 +3492,16 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
if (const char* nativeLibDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(nativeLibDirectoriesExpression);
- std::string nativeLibDirs =
- cge->Evaluate(this->LocalGenerator, configName);
+ std::string nativeLibDirs = cmGeneratorExpression::Evaluate(
+ nativeLibDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDirectories", nativeLibDirs);
}
if (const char* nativeLibDependenciesExpression =
this->GeneratorTarget->GetProperty(
"ANDROID_NATIVE_LIB_DEPENDENCIES")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(nativeLibDependenciesExpression);
- std::string nativeLibDeps =
- cge->Evaluate(this->LocalGenerator, configName);
+ std::string nativeLibDeps = cmGeneratorExpression::Evaluate(
+ nativeLibDependenciesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDependencies", nativeLibDeps);
}
@@ -3354,11 +3512,8 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
if (const char* jarDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(jarDirectoriesExpression);
- std::string jarDirectories =
- cge->Evaluate(this->LocalGenerator, configName);
+ std::string jarDirectories = cmGeneratorExpression::Evaluate(
+ jarDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("JarDirectories", jarDirectories);
}
@@ -3427,9 +3582,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
linkType = "EXE";
}
std::string flags;
- std::string linkFlagVarBase = "CMAKE_";
- linkFlagVarBase += linkType;
- linkFlagVarBase += "_LINKER_FLAGS";
+ std::string linkFlagVarBase = cmStrCat("CMAKE_", linkType, "_LINKER_FLAGS");
flags += " ";
flags += this->Makefile->GetRequiredDefinition(linkFlagVarBase);
std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
@@ -3441,8 +3594,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
flags += " ";
flags += targetLinkFlags;
}
- std::string flagsProp = "LINK_FLAGS_";
- flagsProp += CONFIG;
+ std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
if (const char* flagsConfig =
this->GeneratorTarget->GetProperty(flagsProp)) {
flags += " ";
@@ -3467,8 +3619,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec, config);
- if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(),
- "CUDA") != linkClosure->Languages.end() &&
+ if (cmContains(linkClosure->Languages, "CUDA") &&
this->CudaOptions[config] != nullptr) {
switch (this->CudaOptions[config]->GetCudaRuntime()) {
case cmVisualStudioGeneratorOptions::CudaRuntimeStatic:
@@ -3483,9 +3634,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
break;
}
}
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += linkLanguage;
- standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string standardLibsVar =
+ cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar);
cmSystemTools::ParseWindowsCommandLine(libs.c_str(), libVec);
linkOptions.AddFlag("AdditionalDependencies", libVec);
@@ -3549,13 +3699,12 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
linkOptions.AddFlag("GenerateDebugInformation", "false");
- std::string pdb = this->GeneratorTarget->GetPDBDirectory(config);
- pdb += "/";
- pdb += targetNames.PDB;
- std::string imLib = this->GeneratorTarget->GetDirectory(
- config, cmStateEnums::ImportLibraryArtifact);
- imLib += "/";
- imLib += targetNames.ImportLibrary;
+ std::string pdb = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config),
+ '/', targetNames.PDB);
+ std::string imLib =
+ cmStrCat(this->GeneratorTarget->GetDirectory(
+ config, cmStateEnums::ImportLibraryArtifact),
+ '/', targetNames.ImportLibrary);
linkOptions.AddFlag("ImportLibrary", imLib);
linkOptions.AddFlag("ProgramDataBaseFile", pdb);
@@ -3645,7 +3794,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLibOptions(
}
cmComputeLinkInformation& cli = *pcli;
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
const ItemVector& libs = cli.GetItems();
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -3690,7 +3839,7 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
const cmComputeLinkInformation& cli, std::vector<std::string>& libVec,
std::vector<std::string>& vsTargetVec, const std::string& config)
{
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& libs = cli.GetItems();
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -3755,8 +3904,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
{
for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) {
if (cmSystemTools::ComparePath(targetsFile, i.File)) {
- if (std::find(i.Configs.begin(), i.Configs.end(), config) ==
- i.Configs.end()) {
+ if (!cmContains(i.Configs, config)) {
i.Configs.push_back(config);
}
return;
@@ -3917,8 +4065,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
{
cmGlobalGenerator::TargetDependSet const& unordered =
this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget);
- typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
- OrderedTargetDependSet;
+ using OrderedTargetDependSet =
+ cmGlobalVisualStudioGenerator::OrderedTargetDependSet;
OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET);
Elem e1(e0, "ItemGroup");
e1.SetHasElements();
@@ -3938,10 +4086,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
if (p) {
path = p;
} else {
- path = lg->GetCurrentBinaryDirectory();
- path += "/";
- path += dt->GetName();
- path += computeProjectFileExtension(dt);
+ path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
+ computeProjectFileExtension(dt));
}
ConvertToWindowsSlash(path);
Elem e2(e1, "ProjectReference");
@@ -3950,32 +4096,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
e2.Element("Name", name);
this->WriteDotNetReferenceCustomTags(e2, name);
- // If the dependency target is not managed (compiled with /clr or
- // C# target) and not a WinRT component we cannot reference it and
- // have to set 'ReferenceOutputAssembly' to false.
- auto referenceNotManaged =
- dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed;
- // Workaround to check for manually set /clr flags.
- if (referenceNotManaged) {
- if (const auto* flags = dt->GetProperty("COMPILE_OPTIONS")) {
- std::string flagsStr = flags;
- if (flagsStr.find("clr") != std::string::npos) {
- // There is a warning already issued when building the flags.
- referenceNotManaged = false;
- }
- }
- }
- // Workaround for static library C# targets
- if (referenceNotManaged && dt->GetType() == cmStateEnums::STATIC_LIBRARY) {
- referenceNotManaged = !dt->IsCSharpOnly();
- }
-
- // Referencing WinRT components is okay.
- if (referenceNotManaged) {
- referenceNotManaged = !dt->GetPropertyAsBool("VS_WINRT_COMPONENT");
- }
-
- if (referenceNotManaged) {
+ // Don't reference targets that don't produce any output.
+ if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
e2.Element("ReferenceOutputAssembly", "false");
e2.Element("CopyToOutputDirectory", "Never");
}
@@ -4024,7 +4146,7 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
std::unique_ptr<Elem> spe1;
if (const char* vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
- cmSystemTools::ExpandListArgument(vsSDKReferences, sdkReferences);
+ cmExpandList(vsSDKReferences, sdkReferences);
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
for (std::string const& ri : sdkReferences) {
Elem(*spe1, "SDKReference").Attribute("Include", ri);
@@ -4699,12 +4821,12 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties(
{
if (this->ProjectType == csproj) {
const cmPropertyMap& props = sf->GetProperties();
- for (auto const& p : props) {
+ for (const std::string& p : props.GetKeys()) {
static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.first.find(propNamePrefix) == 0) {
- std::string tagName = p.first.substr(propNamePrefix.length());
+ if (p.find(propNamePrefix) == 0) {
+ std::string tagName = p.substr(propNamePrefix.length());
if (!tagName.empty()) {
- const std::string val = props.GetPropertyValue(p.first);
+ const std::string val = props.GetPropertyValue(p);
if (!val.empty()) {
tags[tagName] = val;
} else {
@@ -4748,8 +4870,8 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
const char* relativeFilePath) const
{
// Always search in the standard modules location.
- std::string path = cmSystemTools::GetCMakeRoot() + "/";
- path += relativeFilePath;
+ std::string path =
+ cmStrCat(cmSystemTools::GetCMakeRoot(), '/', relativeFilePath);
ConvertToWindowsSlash(path);
return path;
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index d453d1a13..a18a33dd8 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -186,8 +186,8 @@ private:
private:
friend class cmVS10GeneratorOptions;
- typedef cmVS10GeneratorOptions Options;
- typedef std::map<std::string, std::unique_ptr<Options>> OptionsMap;
+ using Options = cmVS10GeneratorOptions;
+ using OptionsMap = std::map<std::string, std::unique_ptr<Options>>;
OptionsMap ClOptions;
OptionsMap RcOptions;
OptionsMap CudaOptions;
@@ -224,16 +224,16 @@ private:
std::string DefaultArtifactDir;
bool AddedDefaultCertificate = false;
// managed C++/C# relevant members
- typedef std::pair<std::string, std::string> DotNetHintReference;
- typedef std::vector<DotNetHintReference> DotNetHintReferenceList;
- typedef std::map<std::string, DotNetHintReferenceList>
- DotNetHintReferenceMap;
+ using DotNetHintReference = std::pair<std::string, std::string>;
+ using DotNetHintReferenceList = std::vector<DotNetHintReference>;
+ using DotNetHintReferenceMap =
+ std::map<std::string, DotNetHintReferenceList>;
DotNetHintReferenceMap DotNetHintReferences;
- typedef std::set<std::string> UsingDirectories;
- typedef std::map<std::string, UsingDirectories> UsingDirectoriesMap;
+ using UsingDirectories = std::set<std::string>;
+ using UsingDirectoriesMap = std::map<std::string, UsingDirectories>;
UsingDirectoriesMap AdditionalUsingDirectories;
- typedef std::map<std::string, ToolSources> ToolSourceMap;
+ using ToolSourceMap = std::map<std::string, ToolSources>;
ToolSourceMap Tools;
std::string GetCMakeFilePath(const char* name) const;
};
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index e1b0c70b6..1139aa974 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -1,5 +1,7 @@
#include "cmVisualStudioGeneratorOptions.h"
+#include <cm/iterator>
+
#include "cmAlgorithms.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmOutputConverter.h"
@@ -193,7 +195,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
std::string arch_name = arch[0];
std::vector<std::string> codes;
if (!code.empty()) {
- codes = cmSystemTools::tokenize(code[0], ",");
+ codes = cmTokenize(code[0], ",");
}
if (codes.empty()) {
codes.push_back(arch_name);
@@ -220,7 +222,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
cmSystemTools::ReplaceString(entry, "]", "");
cmSystemTools::ReplaceString(entry, "\"", "");
- std::vector<std::string> codes = cmSystemTools::tokenize(entry, ",");
+ std::vector<std::string> codes = cmTokenize(entry, ",");
if (codes.size() >= 2) {
auto gencode_arch = cm::cbegin(codes);
for (auto ci = gencode_arch + 1; ci != cm::cend(codes); ++ci) {
@@ -269,8 +271,8 @@ void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
}
if (keyValue[1].front() == '\'' && keyValue[1].back() == '\'') {
- keyValue[1] =
- keyValue[1].substr(1, std::max(0, cm::isize(keyValue[1]) - 2));
+ keyValue[1] = keyValue[1].substr(
+ 1, std::max(std::string::size_type(0), keyValue[1].length() - 2));
}
if (keyValue[0] == "level") {
@@ -325,9 +327,9 @@ void cmVisualStudioGeneratorOptions::ParseFinish()
// "rtSingleThreadedDLL", "10", /libs:dll
// "rtSingleThreadedDebug", "5", /dbglibs /libs:static
// "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll
- std::string rl = "rtMultiThreaded";
- rl += this->FortranRuntimeDebug ? "Debug" : "";
- rl += this->FortranRuntimeDLL ? "DLL" : "";
+ std::string rl =
+ cmStrCat("rtMultiThreaded", this->FortranRuntimeDebug ? "Debug" : "",
+ this->FortranRuntimeDLL ? "DLL" : "");
this->FlagMap["RuntimeLibrary"] = rl;
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index a30a67fc2..560593e01 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -14,7 +14,7 @@
class cmLocalVisualStudioGenerator;
-typedef cmIDEFlagTable cmVS7FlagTable;
+using cmVS7FlagTable = cmIDEFlagTable;
class cmVisualStudioGeneratorOptions : public cmIDEOptions
{
diff --git a/Source/cmVisualStudioSlnData.h b/Source/cmVisualStudioSlnData.h
index 9c1dffc05..5ce7d74f8 100644
--- a/Source/cmVisualStudioSlnData.h
+++ b/Source/cmVisualStudioSlnData.h
@@ -45,9 +45,9 @@ public:
const std::string& projectRelativePath);
private:
- typedef std::map<std::string, cmSlnProjectEntry> ProjectStorage;
+ using ProjectStorage = std::map<std::string, cmSlnProjectEntry>;
ProjectStorage ProjectsByGUID;
- typedef std::map<std::string, ProjectStorage::iterator> ProjectStringIndex;
+ using ProjectStringIndex = std::map<std::string, ProjectStorage::iterator>;
ProjectStringIndex ProjectNameIndex;
};
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 93532765f..4533e9b69 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -2,13 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVisualStudioSlnParser.h"
-#include "cmSystemTools.h"
-#include "cmVisualStudioSlnData.h"
-#include "cmsys/FStream.hxx"
-
#include <cassert>
#include <stack>
+#include "cmsys/FStream.hxx"
+
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmVisualStudioSlnData.h"
+
namespace {
enum LineFormat
{
@@ -50,7 +52,7 @@ public:
void CopyVerbatim(const std::string& line) { this->Tag = line; }
private:
- typedef std::pair<std::string, bool> StringData;
+ using StringData = std::pair<std::string, bool>;
std::string Tag;
StringData Arg;
std::vector<StringData> Values;
@@ -192,8 +194,8 @@ bool cmVisualStudioSlnParser::State::Process(
assert(!line.IsComment());
switch (this->Stack.top()) {
case FileStateStart:
- if (!cmSystemTools::StringStartsWith(
- line.GetTag().c_str(), "Microsoft Visual Studio Solution File")) {
+ if (!cmHasLiteralPrefix(line.GetTag(),
+ "Microsoft Visual Studio Solution File")) {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
@@ -462,7 +464,7 @@ bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output,
if (!this->ParseBOM(input, line, state))
return false;
do {
- line = cmSystemTools::TrimWhitespace(line);
+ line = cmTrimWhitespace(line);
if (line.empty())
continue;
ParsedLine parsedLine;
@@ -578,9 +580,9 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line,
return true;
}
const std::string& key = line.substr(0, idxEqualSign);
- parsedLine.SetTag(cmSystemTools::TrimWhitespace(key));
+ parsedLine.SetTag(cmTrimWhitespace(key));
const std::string& value = line.substr(idxEqualSign + 1);
- parsedLine.AddValue(cmSystemTools::TrimWhitespace(value));
+ parsedLine.AddValue(cmTrimWhitespace(value));
return true;
}
@@ -589,18 +591,17 @@ bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag,
{
size_t idxLeftParen = fullTag.find('(');
if (idxLeftParen == fullTag.npos) {
- parsedLine.SetTag(cmSystemTools::TrimWhitespace(fullTag));
+ parsedLine.SetTag(cmTrimWhitespace(fullTag));
return true;
}
- parsedLine.SetTag(
- cmSystemTools::TrimWhitespace(fullTag.substr(0, idxLeftParen)));
+ parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen)));
size_t idxRightParen = fullTag.rfind(')');
if (idxRightParen == fullTag.npos) {
this->LastResult.SetError(ResultErrorInputStructure,
state.GetCurrentLine());
return false;
}
- const std::string& arg = cmSystemTools::TrimWhitespace(
+ const std::string& arg = cmTrimWhitespace(
fullTag.substr(idxLeftParen + 1, idxRightParen - idxLeftParen - 1));
if (arg.front() == '"') {
if (arg.back() != '"') {
@@ -617,7 +618,7 @@ bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag,
bool cmVisualStudioSlnParser::ParseValue(const std::string& value,
ParsedLine& parsedLine)
{
- const std::string& trimmed = cmSystemTools::TrimWhitespace(value);
+ const std::string& trimmed = cmTrimWhitespace(value);
if (trimmed.empty())
parsedLine.AddValue(trimmed);
else if (trimmed.front() == '"' && trimmed.back() == '"')
diff --git a/Source/cmVisualStudioSlnParser.h b/Source/cmVisualStudioSlnParser.h
index d6345a84d..6c05633b8 100644
--- a/Source/cmVisualStudioSlnParser.h
+++ b/Source/cmVisualStudioSlnParser.h
@@ -7,9 +7,10 @@
#include <bitset>
#include <iosfwd>
-#include <stddef.h>
#include <string>
+#include <stddef.h>
+
class cmSlnData;
class cmVisualStudioSlnParser
@@ -42,7 +43,7 @@ public:
DataGroupCount
};
- typedef std::bitset<DataGroupCount> DataGroupSet;
+ using DataGroupSet = std::bitset<DataGroupCount>;
static const DataGroupSet DataGroupProjects;
static const DataGroupSet DataGroupProjectDependencies;
diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h
index c19691aa2..60a66113e 100644
--- a/Source/cmVisualStudioWCEPlatformParser.h
+++ b/Source/cmVisualStudioWCEPlatformParser.h
@@ -6,10 +6,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <stddef.h>
#include <string>
#include <vector>
+#include <stddef.h>
+
#include "cmXMLParser.h"
// This class is used to parse XML with configuration
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index a01fa6f1c..26e7c7537 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -2,18 +2,46 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWhileCommand.h"
+#include <string>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
-#include <memory> // IWYU pragma: keep
+class cmWhileFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmWhileFunctionBlocker(cmMakefile* mf);
+ ~cmWhileFunctionBlocker() override;
+
+ cm::string_view StartCommandName() const override { return "while"_s; }
+ cm::string_view EndCommandName() const override { return "endwhile"_s; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+ std::vector<cmListFileArgument> Args;
+
+private:
+ cmMakefile* Makefile;
+};
cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf)
: Makefile(mf)
- , Depth(0)
{
this->Makefile->PushLoopBlock();
}
@@ -23,122 +51,93 @@ cmWhileFunctionBlocker::~cmWhileFunctionBlocker()
this->Makefile->PopLoopBlock();
}
-bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const
{
- // at end of for each execute recorded commands
- if (lff.Name.Lower == "while") {
- // record the number of while commands past this one
- this->Depth++;
- } else if (lff.Name.Lower == "endwhile") {
- // if this is the endwhile for this while loop then execute
- if (!this->Depth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
- }
+ return lff.Arguments.empty() || lff.Arguments == this->Args;
+}
- std::string errorString;
-
- std::vector<cmExpandedCommandArgument> expandedArguments;
- mf.ExpandArguments(this->Args, expandedArguments);
- MessageType messageType;
-
- cmListFileContext execContext = this->GetStartingContext();
-
- cmCommandContext commandContext;
- commandContext.Line = execContext.Line;
- commandContext.Name = execContext.Name;
-
- cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
- mf.GetBacktrace(commandContext));
-
- bool isTrue =
- conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
-
- while (isTrue) {
- if (!errorString.empty()) {
- std::string err = "had incorrect arguments: ";
- for (cmListFileArgument const& arg : this->Args) {
- err += (arg.Delim ? "\"" : "");
- err += arg.Value;
- err += (arg.Delim ? "\"" : "");
- err += " ";
- }
- err += "(";
- err += errorString;
- err += ").";
- mf.IssueMessage(messageType, err);
- if (messageType == MessageType::FATAL_ERROR) {
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- }
-
- // Invoke all the functions that were collected in the block.
- for (cmListFileFunction const& fn : this->Functions) {
- cmExecutionStatus status;
- mf.ExecuteCommand(fn, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- return true;
- }
- if (status.GetBreakInvoked()) {
- return true;
- }
- if (status.GetContinueInvoked()) {
- break;
- }
- if (cmSystemTools::GetFatalErrorOccured()) {
- return true;
- }
- }
- expandedArguments.clear();
- mf.ExpandArguments(this->Args, expandedArguments);
- isTrue = conditionEvaluator.IsTrue(expandedArguments, errorString,
- messageType);
- }
- return true;
- }
- // decrement for each nested while that ends
- this->Depth--;
- }
+bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus)
+{
+ cmMakefile& mf = inStatus.GetMakefile();
+ std::string errorString;
- // record the command
- this->Functions.push_back(lff);
+ std::vector<cmExpandedCommandArgument> expandedArguments;
+ mf.ExpandArguments(this->Args, expandedArguments);
+ MessageType messageType;
- // always return true
- return true;
-}
+ cmListFileContext execContext = this->GetStartingContext();
-bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile&)
-{
- if (lff.Name.Lower == "endwhile") {
- // if the endwhile has arguments, then make sure
- // they match the arguments of the matching while
- if (lff.Arguments.empty() || lff.Arguments == this->Args) {
- return true;
+ cmCommandContext commandContext;
+ commandContext.Line = execContext.Line;
+ commandContext.Name = execContext.Name;
+
+ cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
+ mf.GetBacktrace(commandContext));
+
+ bool isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
+
+ while (isTrue) {
+ if (!errorString.empty()) {
+ std::string err = "had incorrect arguments: ";
+ for (cmListFileArgument const& arg : this->Args) {
+ err += (arg.Delim ? "\"" : "");
+ err += arg.Value;
+ err += (arg.Delim ? "\"" : "");
+ err += " ";
+ }
+ err += "(";
+ err += errorString;
+ err += ").";
+ mf.IssueMessage(messageType, err);
+ if (messageType == MessageType::FATAL_ERROR) {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ }
+
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& fn : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(fn, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ return true;
+ }
}
+ expandedArguments.clear();
+ mf.ExpandArguments(this->Args, expandedArguments);
+ isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
}
- return false;
+ return true;
}
-bool cmWhileCommand::InvokeInitialPass(
- const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
// create a function blocker
- cmWhileFunctionBlocker* f = new cmWhileFunctionBlocker(this->Makefile);
- f->Args = args;
- this->Makefile->AddFunctionBlocker(f);
-
+ {
+ cmMakefile& makefile = status.GetMakefile();
+ auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile);
+ fb->Args = args;
+ makefile.AddFunctionBlocker(std::move(fb));
+ }
return true;
}
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index 6f6d40549..beca652c6 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -5,58 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
#include <vector>
-#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmWhileFunctionBlocker : public cmFunctionBlocker
-{
-public:
- cmWhileFunctionBlocker(cmMakefile* mf);
- ~cmWhileFunctionBlocker() override;
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<cmListFileArgument> Args;
- std::vector<cmListFileFunction> Functions;
-
-private:
- cmMakefile* Makefile;
- int Depth;
-};
+struct cmListFileArgument;
/// \brief Starts a while loop
-class cmWhileCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmWhileCommand; }
-
- /**
- * This overrides the default InvokeInitialPass implementation.
- * It records the arguments before expansion.
- */
- bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
- cmExecutionStatus&) override;
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus&) override
- {
- return false;
- }
-};
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index cbf070e91..aa0d6b3d5 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -2,30 +2,34 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWorkerPool.h"
-#include "cmRange.h"
-#include "cmUVHandlePtr.h"
-#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
-#include "cm_uv.h"
-
#include <algorithm>
#include <array>
#include <condition_variable>
+#include <cstddef>
#include <deque>
#include <functional>
#include <mutex>
-#include <stddef.h>
#include <thread>
+#include <cm/memory>
+
+#include "cm_uv.h"
+
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+#include "cmUVHandlePtr.h"
+#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
+
/**
* @brief libuv pipe buffer class
*/
class cmUVPipeBuffer
{
public:
- typedef cmRange<char const*> DataRange;
- typedef std::function<void(DataRange)> DataFunction;
+ using DataRange = cmRange<const char*>;
+ using DataFunction = std::function<void(DataRange)>;
/// On error the ssize_t argument is a non zero libuv error code
- typedef std::function<void(ssize_t)> EndFunction;
+ using EndFunction = std::function<void(ssize_t)>;
public:
/**
@@ -304,13 +308,11 @@ void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus,
proc.Result()->TermSignal = termSignal;
if (!proc.Result()->error()) {
if (termSignal != 0) {
- proc.Result()->ErrorMessage = "Process was terminated by signal ";
- proc.Result()->ErrorMessage +=
- std::to_string(proc.Result()->TermSignal);
+ proc.Result()->ErrorMessage = cmStrCat(
+ "Process was terminated by signal ", proc.Result()->TermSignal);
} else if (exitStatus != 0) {
- proc.Result()->ErrorMessage = "Process failed with return value ";
- proc.Result()->ErrorMessage +=
- std::to_string(proc.Result()->ExitStatus);
+ proc.Result()->ErrorMessage = cmStrCat(
+ "Process failed with return value ", proc.Result()->ExitStatus);
}
}
@@ -330,9 +332,8 @@ void cmUVReadOnlyProcess::UVPipeOutEnd(ssize_t error)
{
// Process pipe error
if ((error != 0) && !Result()->error()) {
- Result()->ErrorMessage =
- "Reading from stdout pipe failed with libuv error code ";
- Result()->ErrorMessage += std::to_string(error);
+ Result()->ErrorMessage = cmStrCat(
+ "Reading from stdout pipe failed with libuv error code ", error);
}
// Try finish
UVTryFinish();
@@ -349,9 +350,8 @@ void cmUVReadOnlyProcess::UVPipeErrEnd(ssize_t error)
{
// Process pipe error
if ((error != 0) && !Result()->error()) {
- Result()->ErrorMessage =
- "Reading from stderr pipe failed with libuv error code ";
- Result()->ErrorMessage += std::to_string(error);
+ Result()->ErrorMessage = cmStrCat(
+ "Reading from stderr pipe failed with libuv error code ", error);
}
// Try finish
UVTryFinish();
diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h
index f08bb4f8d..91799223a 100644
--- a/Source/cmWorkerPool.h
+++ b/Source/cmWorkerPool.h
@@ -5,14 +5,13 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmAlgorithms.h" // IWYU pragma: keep
-
-#include <memory> // IWYU pragma: keep
-#include <stdint.h>
+#include <cstdint>
#include <string>
#include <utility>
#include <vector>
+#include <cm/memory>
+
// -- Types
class cmWorkerPoolInternal;
@@ -127,7 +126,7 @@ public:
/**
* Job handle type
*/
- typedef std::unique_ptr<JobT> JobHandleT;
+ using JobHandleT = std::unique_ptr<JobT>;
/**
* Fence job base class
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx
index 816f1044c..5700b1cc7 100644
--- a/Source/cmWorkingDirectory.cxx
+++ b/Source/cmWorkingDirectory.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWorkingDirectory.h"
-#include "cmSystemTools.h"
-
#include <cerrno>
+#include "cmSystemTools.h"
+
cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir)
{
this->OldDir = cmSystemTools::GetCurrentWorkingDirectory();
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 49dbf1a19..34e21b2f2 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -4,22 +4,23 @@
#include "cmsys/FStream.hxx"
-#include "cmMakefile.h"
-#include "cmSystemTools.h"
#include "cm_sys_stat.h"
-class cmExecutionStatus;
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
// cmLibraryCommand
-bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmWriteFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
std::string message;
- std::vector<std::string>::const_iterator i = args.begin();
+ auto i = args.begin();
std::string const& fileName = *i;
bool overwrite = true;
@@ -33,10 +34,10 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
}
}
- if (!this->Makefile->CanIWriteThisFile(fileName)) {
+ if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
std::string e =
"attempted to write a file: " + fileName + " into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -65,10 +66,10 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args,
cmsys::ofstream file(fileName.c_str(),
overwrite ? std::ios::out : std::ios::app);
if (!file) {
- std::string error = "Internal CMake error when trying to open file: ";
- error += fileName;
- error += " for writing.";
- this->SetError(error);
+ std::string error =
+ cmStrCat("Internal CMake error when trying to open file: ", fileName,
+ " for writing.");
+ status.SetError(error);
return false;
}
file << message << std::endl;
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 9028f84aa..3e0e04376 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -8,28 +8,13 @@
#include <string>
#include <vector>
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmWriteFileCommand
+/**
* \brief Writes a message to a file
*
*/
-class cmWriteFileCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- cmCommand* Clone() override { return new cmWriteFileCommand; }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmWriteFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index 1747c9c99..b301ab121 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -2,9 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmXCodeObject.h"
-#include <CoreFoundation/CoreFoundation.h>
#include <ostream>
+#include <CoreFoundation/CoreFoundation.h>
+
#include "cmSystemTools.h"
const char* cmXCodeObject::PBXTypeNames[] = {
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index 51e5d36d2..d9be3d2db 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -12,6 +12,8 @@
#include <utility>
#include <vector>
+#include "cmAlgorithms.h"
+
class cmGeneratorTarget;
class cmXCodeObject
@@ -80,15 +82,10 @@ 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 !(std::find(this->List.begin(), this->List.end(), o) ==
- this->List.end());
- }
+ bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); }
void AddUniqueObject(cmXCodeObject* value)
{
- if (std::find(this->List.begin(), this->List.end(), value) ==
- this->List.end()) {
+ if (!cmContains(this->List, value)) {
this->List.push_back(value);
}
}
@@ -109,8 +106,7 @@ public:
bool HasComment() const { return (!this->Comment.empty()); }
cmXCodeObject* GetObject(const char* name) const
{
- std::map<std::string, cmXCodeObject*>::const_iterator i =
- this->ObjectAttributes.find(name);
+ auto const i = this->ObjectAttributes.find(name);
if (i != this->ObjectAttributes.end()) {
return i->second;
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index c33bb7e8f..afc95f56c 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -27,14 +27,11 @@ void cmXCodeScheme::WriteXCodeSharedScheme(const std::string& xcProjDir,
{
// Create shared scheme sub-directory tree
//
- std::string xcodeSchemeDir = xcProjDir;
- xcodeSchemeDir += "/xcshareddata/xcschemes";
+ std::string xcodeSchemeDir = cmStrCat(xcProjDir, "/xcshareddata/xcschemes");
cmSystemTools::MakeDirectory(xcodeSchemeDir.c_str());
- std::string xcodeSchemeFile = xcodeSchemeDir;
- xcodeSchemeFile += "/";
- xcodeSchemeFile += this->TargetName;
- xcodeSchemeFile += ".xcscheme";
+ std::string xcodeSchemeFile =
+ cmStrCat(xcodeSchemeDir, '/', this->TargetName, ".xcscheme");
cmGeneratedFileStream fout(xcodeSchemeFile);
fout.SetCopyIfDifferent(true);
@@ -140,7 +137,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
xout.Attribute("launchStyle", "0");
xout.Attribute("useCustomWorkingDirectory", "NO");
xout.Attribute("ignoresPersistentStateOnLaunch", "NO");
- xout.Attribute("debugDocumentVersioning", "YES");
+ WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
+ "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
+ true);
xout.Attribute("debugServiceExtension", "internal");
xout.Attribute("allowLocationSimulation", "YES");
@@ -217,8 +216,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (const char* argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments;
- cmSystemTools::ExpandListArgument(argList, arguments);
+ std::vector<std::string> arguments = cmExpandedList(argList);
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -238,8 +236,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (const char* envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs;
- cmSystemTools::ExpandListArgument(envList, envs);
+ std::vector<std::string> envs = cmExpandedList(envList);
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
@@ -316,6 +313,21 @@ bool cmXCodeScheme::WriteLaunchActionAttribute(cmXMLWriter& xout,
return false;
}
+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);
+
+ if (isOn) {
+ xout.Attribute(attrName.c_str(), "YES");
+ } else {
+ xout.Attribute(attrName.c_str(), "NO");
+ }
+ return isOn;
+}
+
bool cmXCodeScheme::WriteLaunchActionAdditionalOption(
cmXMLWriter& xout, const std::string& key, const std::string& value,
const std::string& varName)
@@ -344,7 +356,9 @@ void cmXCodeScheme::WriteProfileAction(cmXMLWriter& xout,
xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
xout.Attribute("savedToolIdentifier", "");
xout.Attribute("useCustomWorkingDirectory", "NO");
- xout.Attribute("debugDocumentVersioning", "YES");
+ WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
+ "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
+ true);
xout.EndElement();
}
@@ -393,9 +407,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 (std::find(this->ConfigList.begin(), this->ConfigList.end(), name) ==
- this->ConfigList.end() &&
- !this->ConfigList.empty()) {
+ if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) {
return this->ConfigList[0];
}
diff --git a/Source/cmXCodeScheme.h b/Source/cmXCodeScheme.h
index 8c4712359..dff5e35e3 100644
--- a/Source/cmXCodeScheme.h
+++ b/Source/cmXCodeScheme.h
@@ -18,7 +18,7 @@
class cmXCodeScheme
{
public:
- typedef std::vector<const cmXCodeObject*> TestObjects;
+ using TestObjects = std::vector<const cmXCodeObject*>;
cmXCodeScheme(cmXCodeObject* xcObj, TestObjects tests,
const std::vector<std::string>& configList,
@@ -46,6 +46,11 @@ private:
const std::string& attrName,
const std::string& varName);
+ bool WriteLaunchActionBooleanAttribute(cmXMLWriter& xout,
+ const std::string& attrName,
+ const std::string& varName,
+ bool defaultValue);
+
bool WriteLaunchActionAdditionalOption(cmXMLWriter& xout,
const std::string& attrName,
const std::string& value,
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index 4c6c35acc..ad5c4ba28 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -2,12 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmXMLParser.h"
-#include "cm_expat.h"
-#include "cmsys/FStream.hxx"
-#include <ctype.h>
+#include <cctype>
+#include <cstring>
#include <iostream>
#include <sstream>
-#include <string.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cm_expat.h"
cmXMLParser::cmXMLParser()
{
diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h
index 98ba04956..1bc8d6469 100644
--- a/Source/cmXMLParser.h
+++ b/Source/cmXMLParser.h
@@ -42,7 +42,7 @@ public:
virtual int ParseChunk(const char* inputString,
std::string::size_type length);
virtual int CleanupParser();
- typedef void (*ReportFunction)(int, const char*, void*);
+ using ReportFunction = void (*)(int, const char*, void*);
void SetErrorCallback(ReportFunction f, void* d)
{
this->ReportCallback = f;
diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx
index d9bdc023b..8cd5f6e0d 100644
--- a/Source/cmXMLSafe.cxx
+++ b/Source/cmXMLSafe.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmXMLSafe.h"
-#include "cm_utf8.h"
-
+#include <cstdio>
+#include <cstring>
#include <sstream>
-#include <stdio.h>
-#include <string.h>
+
+#include "cm_utf8.h"
cmXMLSafe::cmXMLSafe(const char* s)
: Data(s)
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx
index f1ce60814..0811bd029 100644
--- a/Source/cmXMLWriter.cxx
+++ b/Source/cmXMLWriter.cxx
@@ -2,9 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmXMLWriter.h"
-#include "cmsys/FStream.hxx"
#include <cassert>
+#include "cmsys/FStream.hxx"
+
cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
: Output(output)
, IndentationElement(1, '\t')
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index 512e1031d..bc445aa5b 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -5,15 +5,16 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmXMLSafe.h"
-
#include <chrono>
+#include <cstddef>
#include <ctime>
#include <ostream>
#include <stack>
#include <string>
#include <vector>
+#include "cmXMLSafe.h"
+
class cmXMLWriter
{
public:
@@ -76,14 +77,11 @@ private:
void CloseStartElement();
private:
- static cmXMLSafe SafeAttribute(const char* value)
- {
- return cmXMLSafe(value);
- }
+ static cmXMLSafe SafeAttribute(const char* value) { return { value }; }
static cmXMLSafe SafeAttribute(std::string const& value)
{
- return cmXMLSafe(value);
+ return { value };
}
template <typename T>
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
index 821c112b3..122e02283 100644
--- a/Source/cm_codecvt.cxx
+++ b/Source/cm_codecvt.cxx
@@ -3,9 +3,10 @@
#include "cm_codecvt.hxx"
#if defined(_WIN32)
+# include <windows.h>
+
# include <assert.h>
# include <string.h>
-# include <windows.h>
# undef max
# include "cmsys/Encoding.hxx"
#endif
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx
index 2df39614c..b2cb9e6a3 100644
--- a/Source/cm_codecvt.hxx
+++ b/Source/cm_codecvt.hxx
@@ -5,8 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cwchar>
#include <locale>
-#include <wchar.h>
class codecvt : public std::codecvt<char, char, mbstate_t>
{
@@ -18,7 +18,7 @@ public:
ANSI
};
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
codecvt(Encoding e);
diff --git a/Source/cm_get_date.h b/Source/cm_get_date.h
index 6acf8dea3..38a690ee0 100644
--- a/Source/cm_get_date.h
+++ b/Source/cm_get_date.h
@@ -3,7 +3,7 @@
#ifndef cm_get_date_h
#define cm_get_date_h
-#include <time.h>
+#include <time.h> /* NOLINT(modernize-deprecated-headers) */
#ifdef __cplusplus
extern "C" {
diff --git a/Source/cm_static_string_view.hxx b/Source/cm_static_string_view.hxx
index 1bef0c68b..708ac9579 100644
--- a/Source/cm_static_string_view.hxx
+++ b/Source/cm_static_string_view.hxx
@@ -5,10 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_string_view.hxx"
-
#include <cstddef>
+#include <cm/string_view>
+
namespace cm {
/** A string_view that only binds to static storage.
diff --git a/Source/cm_string_view.cxx b/Source/cm_string_view.cxx
deleted file mode 100644
index 61fa80e82..000000000
--- a/Source/cm_string_view.cxx
+++ /dev/null
@@ -1,301 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-
-#include "cm_string_view.hxx"
-
-#ifndef CMake_HAVE_CXX_STRING_VIEW
-
-# include "cm_kwiml.h"
-
-# include <algorithm>
-# include <ostream>
-# include <stdexcept>
-
-namespace cm {
-
-string_view::const_reference string_view::at(size_type pos) const
-{
- if (pos >= size_) {
- throw std::out_of_range("Index out of range in string_view::at");
- }
- return data_[pos];
-}
-
-string_view::size_type string_view::copy(char* dest, size_type count,
- size_type pos) const
-{
- if (pos > size_) {
- throw std::out_of_range("Index out of range in string_view::copy");
- }
- size_type const rcount = std::min(count, size_ - pos);
- traits_type::copy(dest, data_ + pos, rcount);
- return rcount;
-}
-
-string_view string_view::substr(size_type pos, size_type count) const
-{
- if (pos > size_) {
- throw std::out_of_range("Index out of range in string_view::substr");
- }
- size_type const rcount = std::min(count, size_ - pos);
- return string_view(data_ + pos, rcount);
-}
-
-int string_view::compare(string_view v) const noexcept
-{
- size_type const rlen = std::min(size_, v.size_);
- int c = traits_type::compare(data_, v.data_, rlen);
- if (c == 0) {
- if (size_ < v.size_) {
- c = -1;
- } else if (size_ > v.size_) {
- c = 1;
- }
- }
- return c;
-}
-
-int string_view::compare(size_type pos1, size_type count1, string_view v) const
-{
- return substr(pos1, count1).compare(v);
-}
-
-int string_view::compare(size_type pos1, size_type count1, string_view v,
- size_type pos2, size_type count2) const
-{
- return substr(pos1, count1).compare(v.substr(pos2, count2));
-}
-
-int string_view::compare(const char* s) const
-{
- return compare(string_view(s));
-}
-
-int string_view::compare(size_type pos1, size_type count1, const char* s) const
-{
- return substr(pos1, count1).compare(string_view(s));
-}
-
-int string_view::compare(size_type pos1, size_type count1, const char* s,
- size_type count2) const
-{
- return substr(pos1, count1).compare(string_view(s, count2));
-}
-
-string_view::size_type string_view::find(string_view v, size_type pos) const
- noexcept
-{
- for (; pos + v.size_ <= size_; ++pos) {
- if (std::char_traits<char>::compare(data_ + pos, v.data_, v.size_) == 0) {
- return pos;
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::find(char c, size_type pos) const noexcept
-{
- return find(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::find(const char* s, size_type pos,
- size_type count) const
-{
- return find(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::find(const char* s, size_type pos) const
-{
- return find(string_view(s), pos);
-}
-
-string_view::size_type string_view::rfind(string_view v, size_type pos) const
- noexcept
-{
- if (size_ >= v.size_) {
- for (pos = std::min(pos, size_ - v.size_) + 1; pos > 0;) {
- --pos;
- if (std::char_traits<char>::compare(data_ + pos, v.data_, v.size_) ==
- 0) {
- return pos;
- }
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::rfind(char c, size_type pos) const noexcept
-{
- return rfind(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::rfind(const char* s, size_type pos,
- size_type count) const
-{
- return rfind(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::rfind(const char* s, size_type pos) const
-{
- return rfind(string_view(s), pos);
-}
-
-string_view::size_type string_view::find_first_of(string_view v,
- size_type pos) const noexcept
-{
- for (; pos < size_; ++pos) {
- if (traits_type::find(v.data_, v.size_, data_[pos])) {
- return pos;
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::find_first_of(char c, size_type pos) const
- noexcept
-{
- return find_first_of(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::find_first_of(const char* s, size_type pos,
- size_type count) const
-{
- return find_first_of(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::find_first_of(const char* s,
- size_type pos) const
-{
- return find_first_of(string_view(s), pos);
-}
-
-string_view::size_type string_view::find_last_of(string_view v,
- size_type pos) const noexcept
-{
- if (size_ > 0) {
- for (pos = std::min(pos, size_ - 1) + 1; pos > 0;) {
- --pos;
- if (traits_type::find(v.data_, v.size_, data_[pos])) {
- return pos;
- }
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::find_last_of(char c, size_type pos) const
- noexcept
-{
- return find_last_of(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::find_last_of(const char* s, size_type pos,
- size_type count) const
-{
- return find_last_of(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::find_last_of(const char* s,
- size_type pos) const
-{
- return find_last_of(string_view(s), pos);
-}
-
-string_view::size_type string_view::find_first_not_of(string_view v,
- size_type pos) const
- noexcept
-{
- for (; pos < size_; ++pos) {
- if (!traits_type::find(v.data_, v.size_, data_[pos])) {
- return pos;
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::find_first_not_of(char c,
- size_type pos) const
- noexcept
-{
- return find_first_not_of(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::find_first_not_of(const char* s,
- size_type pos,
- size_type count) const
-{
- return find_first_not_of(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::find_first_not_of(const char* s,
- size_type pos) const
-{
- return find_first_not_of(string_view(s), pos);
-}
-
-string_view::size_type string_view::find_last_not_of(string_view v,
- size_type pos) const
- noexcept
-{
- if (size_ > 0) {
- for (pos = std::min(pos, size_ - 1) + 1; pos > 0;) {
- --pos;
- if (!traits_type::find(v.data_, v.size_, data_[pos])) {
- return pos;
- }
- }
- }
- return npos;
-}
-
-string_view::size_type string_view::find_last_not_of(char c,
- size_type pos) const
- noexcept
-{
- return find_last_not_of(string_view(&c, 1), pos);
-}
-
-string_view::size_type string_view::find_last_not_of(const char* s,
- size_type pos,
- size_type count) const
-{
- return find_last_not_of(string_view(s, count), pos);
-}
-
-string_view::size_type string_view::find_last_not_of(const char* s,
- size_type pos) const
-{
- return find_last_not_of(string_view(s), pos);
-}
-
-std::ostream& operator<<(std::ostream& o, string_view v)
-{
- return o.write(v.data(), v.size());
-}
-
-std::string& operator+=(std::string& s, string_view v)
-{
- s.append(v.data(), v.size());
- return s;
-}
-}
-
-std::hash<cm::string_view>::result_type std::hash<cm::string_view>::operator()(
- argument_type const& s) const noexcept
-{
- // FNV-1a hash.
- static KWIML_INT_uint64_t const fnv_offset_basis = 0xcbf29ce484222325;
- static KWIML_INT_uint64_t const fnv_prime = 0x100000001b3;
- KWIML_INT_uint64_t h = fnv_offset_basis;
- for (char const& c : s) {
- h = h ^ KWIML_INT_uint64_t(KWIML_INT_uint8_t(c));
- h = h * fnv_prime;
- }
- return result_type(h);
-}
-#else
-// Avoid empty translation unit.
-void cm_string_view_cxx()
-{
-}
-#endif
diff --git a/Source/cm_string_view.hxx b/Source/cm_string_view.hxx
deleted file mode 100644
index d368ed8e2..000000000
--- a/Source/cm_string_view.hxx
+++ /dev/null
@@ -1,217 +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_string_view_hxx
-#define cm_string_view_hxx
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
-# define CMake_HAVE_CXX_STRING_VIEW
-#endif
-
-#ifdef CMake_HAVE_CXX_STRING_VIEW
-# include <string_view>
-namespace cm {
-using std::string_view;
-}
-#else
-# include <cstddef>
-# include <functional>
-# include <iosfwd>
-# include <iterator>
-# include <string>
-
-namespace cm {
-
-class string_view
-{
-public:
- using traits_type = std::string::traits_type;
- using value_type = char;
- using pointer = char*;
- using const_pointer = const char*;
- using reference = char&;
- using const_reference = char const&;
- using const_iterator = const char*;
- using iterator = const_iterator;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- using reverse_iterator = const_reverse_iterator;
- using size_type = std::string::size_type;
- using difference_type = std::string::difference_type;
-
- static size_type const npos = static_cast<size_type>(-1);
-
- string_view() noexcept = default;
- string_view(string_view const&) noexcept = default;
-
- string_view(const char* s, size_t count) noexcept
- : data_(s)
- , size_(count)
- {
- }
-
- string_view(const char* s) noexcept
- : data_(s)
- , size_(traits_type::length(s))
- {
- }
-
- // C++17 does not define this constructor. Instead it defines
- // a conversion operator on std::string to create a string_view.
- // Since this implementation is used in C++11, std::string does
- // not have that conversion.
- string_view(std::string const& s) noexcept
- : data_(s.data())
- , size_(s.size())
- {
- }
-
- // C++17 does not define this conversion. Instead it defines
- // a constructor on std::string that can take a string_view.
- // Since this implementation is used in C++11, std::string does
- // not have that constructor.
- explicit operator std::string() const { return std::string(data_, size_); }
-
- string_view& operator=(string_view const&) = default;
-
- const_iterator begin() const noexcept { return data_; }
- const_iterator end() const noexcept { return data_ + size_; }
- const_iterator cbegin() const noexcept { return begin(); }
- const_iterator cend() const noexcept { return end(); }
-
- const_reverse_iterator rbegin() const noexcept
- {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator rend() const noexcept
- {
- return const_reverse_iterator(begin());
- }
- const_reverse_iterator crbegin() const noexcept { return rbegin(); }
- const_reverse_iterator crend() const noexcept { return rend(); }
-
- const_reference operator[](size_type pos) const noexcept
- {
- return data_[pos];
- }
- const_reference at(size_type pos) const;
- const_reference front() const noexcept { return data_[0]; }
- const_reference back() const noexcept { return data_[size_ - 1]; }
- const_pointer data() const noexcept { return data_; }
-
- size_type size() const noexcept { return size_; }
- size_type length() const noexcept { return size_; }
- size_type max_size() const noexcept { return npos - 1; }
- bool empty() const noexcept { return size_ == 0; }
-
- void remove_prefix(size_type n) noexcept
- {
- data_ += n;
- size_ -= n;
- }
- void remove_suffix(size_type n) noexcept { size_ -= n; }
- void swap(string_view& v) noexcept
- {
- string_view tmp = v;
- v = *this;
- *this = tmp;
- }
-
- size_type copy(char* dest, size_type count, size_type pos = 0) const;
- string_view substr(size_type pos = 0, size_type count = npos) const;
-
- int compare(string_view v) const noexcept;
- int compare(size_type pos1, size_type count1, string_view v) const;
- int compare(size_type pos1, size_type count1, string_view v, size_type pos2,
- size_type count2) const;
- int compare(const char* s) const;
- int compare(size_type pos1, size_type count1, const char* s) const;
- int compare(size_type pos1, size_type count1, const char* s,
- size_type count2) const;
-
- size_type find(string_view v, size_type pos = 0) const noexcept;
- size_type find(char c, size_type pos = 0) const noexcept;
- size_type find(const char* s, size_type pos, size_type count) const;
- size_type find(const char* s, size_type pos = 0) const;
-
- size_type rfind(string_view v, size_type pos = npos) const noexcept;
- size_type rfind(char c, size_type pos = npos) const noexcept;
- size_type rfind(const char* s, size_type pos, size_type count) const;
- size_type rfind(const char* s, size_type pos = npos) const;
-
- size_type find_first_of(string_view v, size_type pos = 0) const noexcept;
- size_type find_first_of(char c, size_type pos = 0) const noexcept;
- size_type find_first_of(const char* s, size_type pos, size_type count) const;
- size_type find_first_of(const char* s, size_type pos = 0) const;
-
- size_type find_last_of(string_view v, size_type pos = npos) const noexcept;
- size_type find_last_of(char c, size_type pos = npos) const noexcept;
- size_type find_last_of(const char* s, size_type pos, size_type count) const;
- size_type find_last_of(const char* s, size_type pos = npos) const;
-
- size_type find_first_not_of(string_view v, size_type pos = 0) const noexcept;
- size_type find_first_not_of(char c, size_type pos = 0) const noexcept;
- size_type find_first_not_of(const char* s, size_type pos,
- size_type count) const;
- size_type find_first_not_of(const char* s, size_type pos = 0) const;
-
- size_type find_last_not_of(string_view v, size_type pos = npos) const
- noexcept;
- size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
- size_type find_last_not_of(const char* s, size_type pos,
- size_type count) const;
- size_type find_last_not_of(const char* s, size_type pos = npos) const;
-
-private:
- const char* data_ = nullptr;
- size_type size_ = 0;
-};
-
-std::ostream& operator<<(std::ostream& o, string_view v);
-
-std::string& operator+=(std::string& s, string_view v);
-
-inline bool operator==(string_view l, string_view r) noexcept
-{
- return l.compare(r) == 0;
-}
-
-inline bool operator!=(string_view l, string_view r) noexcept
-{
- return l.compare(r) != 0;
-}
-
-inline bool operator<(string_view l, string_view r) noexcept
-{
- return l.compare(r) < 0;
-}
-
-inline bool operator<=(string_view l, string_view r) noexcept
-{
- return l.compare(r) <= 0;
-}
-
-inline bool operator>(string_view l, string_view r) noexcept
-{
- return l.compare(r) > 0;
-}
-
-inline bool operator>=(string_view l, string_view r) noexcept
-{
- return l.compare(r) >= 0;
-}
-}
-
-namespace std {
-
-template <>
-struct hash<cm::string_view>
-{
- typedef cm::string_view argument_type;
- typedef size_t result_type;
- result_type operator()(argument_type const& s) const noexcept;
-};
-}
-
-#endif
-#endif
diff --git a/Source/cm_sys_stat.h b/Source/cm_sys_stat.h
index 796f027c1..919428634 100644
--- a/Source/cm_sys_stat.h
+++ b/Source/cm_sys_stat.h
@@ -4,16 +4,11 @@
#define cm_sys_stat_h
#if defined(_MSC_VER)
-typedef unsigned short mode_t;
-#endif
-
-#if defined(WIN32)
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
+using mode_t = unsigned short;
#endif
#include <sys/types.h>
// include sys/stat.h after sys/types.h
-#include <sys/stat.h>
+#include <sys/stat.h> // IWYU pragma: export
#endif
diff --git a/Source/cm_thread.hxx b/Source/cm_thread.hxx
deleted file mode 100644
index b1f064585..000000000
--- a/Source/cm_thread.hxx
+++ /dev/null
@@ -1,48 +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_THREAD_HXX
-#define CM_THREAD_HXX
-
-#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_uv.h"
-
-namespace cm {
-
-class shared_mutex
-{
- uv_rwlock_t _M_;
-
-public:
- shared_mutex() { uv_rwlock_init(&_M_); }
- ~shared_mutex() { uv_rwlock_destroy(&_M_); }
-
- shared_mutex(shared_mutex const&) = delete;
- shared_mutex& operator=(shared_mutex const&) = delete;
-
- void lock() { uv_rwlock_wrlock(&_M_); }
- void unlock() { uv_rwlock_wrunlock(&_M_); }
-
- void lock_shared() { uv_rwlock_rdlock(&_M_); }
- void unlock_shared() { uv_rwlock_rdunlock(&_M_); }
-};
-
-template <typename T>
-class shared_lock
-{
- T& _mutex;
-
-public:
- shared_lock(T& m)
- : _mutex(m)
- {
- _mutex.lock_shared();
- }
-
- ~shared_lock() { _mutex.unlock_shared(); }
-
- shared_lock(shared_lock const&) = delete;
- shared_lock& operator=(shared_lock const&) = delete;
-};
-}
-
-#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 3772f0998..f63a26400 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2,6 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmake.h"
+#include <cm/memory>
+#include <cm/string_view>
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
+# include <cm/iterator>
+#endif
+
+#include "cm_sys_stat.h"
+
#include "cmAlgorithms.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
@@ -19,28 +27,29 @@
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmUtils.hxx"
#include "cmVersionConfig.h"
#include "cmWorkingDirectory.h"
-#include "cm_sys_stat.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
+# include <unordered_map>
+
# include "cm_jsoncpp_writer.h"
# include "cmFileAPI.h"
# include "cmGraphVizWriter.h"
# include "cmVariableWatch.h"
-# include <unordered_map>
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# define CMAKE_USE_ECLIPSE
#endif
-#if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
# define CMAKE_BOOT_MINGW
#endif
@@ -68,7 +77,7 @@
# include "cmGlobalWatcomWMakeGenerator.h"
#endif
#include "cmGlobalUnixMakefileGenerator3.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmGlobalNinjaGenerator.h"
#endif
#include "cmExtraCodeLiteGenerator.h"
@@ -88,7 +97,7 @@
#endif
#if defined(__APPLE__)
-# if defined(CMAKE_BUILD_WITH_CMAKE)
+# if !defined(CMAKE_BOOTSTRAP)
# include "cmGlobalXCodeGenerator.h"
# define CMAKE_USE_XCODE 1
@@ -97,24 +106,23 @@
# include <sys/time.h>
#endif
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
#include <cstring>
#include <initializer_list>
#include <iostream>
-#include <iterator>
-#include <memory> // IWYU pragma: keep
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
#include <utility>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+
namespace {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-typedef std::unordered_map<std::string, Json::Value> JsonValueMapType;
+#if !defined(CMAKE_BOOTSTRAP)
+using JsonValueMapType = std::unordered_map<std::string, Json::Value>;
#endif
} // namespace
@@ -122,31 +130,25 @@ typedef std::unordered_map<std::string, Json::Value> JsonValueMapType;
static bool cmakeCheckStampFile(const std::string& stampName);
static bool cmakeCheckStampList(const std::string& stampList);
-void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
- void* ctx, const char* /*unused*/,
- const cmMakefile* /*unused*/)
+static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
+ void* ctx, const char* /*unused*/,
+ const cmMakefile* /*unused*/)
{
cmake* cm = reinterpret_cast<cmake*>(ctx);
cm->MarkCliAsUsed(variable);
}
cmake::cmake(Role role, cmState::Mode mode)
+ : FileTimeCache(cm::make_unique<cmFileTimeCache>())
+#ifndef CMAKE_BOOTSTRAP
+ , VariableWatch(cm::make_unique<cmVariableWatch>())
+#endif
+ , State(cm::make_unique<cmState>())
+ , Messenger(cm::make_unique<cmMessenger>())
{
- this->Trace = false;
- this->TraceExpand = false;
- this->WarnUninitialized = false;
- this->WarnUnused = false;
- this->WarnUnusedCli = true;
- this->CheckSystemVars = false;
- this->DebugOutput = false;
- this->DebugTryCompile = false;
- this->ClearBuildSystem = false;
- this->FileTimeCache = new cmFileTimeCache;
-
- this->State = new cmState;
+ this->TraceFile.close();
this->State->SetMode(mode);
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
- this->Messenger = new cmMessenger;
#ifdef __APPLE__
struct rlimit rlp;
@@ -158,16 +160,6 @@ cmake::cmake(Role role, cmState::Mode mode)
}
#endif
- this->GlobalGenerator = nullptr;
- this->GeneratorInstanceSet = false;
- this->GeneratorPlatformSet = false;
- this->GeneratorToolsetSet = false;
- this->CurrentWorkingMode = NORMAL_MODE;
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
- this->VariableWatch = new cmVariableWatch;
-#endif
-
this->AddDefaultGenerators();
this->AddDefaultExtraGenerators();
if (role == RoleScript || role == RoleProject) {
@@ -184,58 +176,41 @@ cmake::cmake(Role role, cmState::Mode mode)
// Make sure we can capture the build tool output.
cmSystemTools::EnableVSConsoleOutput();
- // Set up a list of source and header extensions
- // these are used to find files when the extension
- // is not given
- // The "c" extension MUST precede the "C" extension.
- this->SourceFileExtensions.emplace_back("c");
- this->SourceFileExtensions.emplace_back("C");
-
- this->SourceFileExtensions.emplace_back("c++");
- this->SourceFileExtensions.emplace_back("cc");
- this->SourceFileExtensions.emplace_back("cpp");
- this->SourceFileExtensions.emplace_back("cxx");
- this->SourceFileExtensions.emplace_back("cu");
- this->SourceFileExtensions.emplace_back("m");
- this->SourceFileExtensions.emplace_back("M");
- this->SourceFileExtensions.emplace_back("mm");
-
- std::copy(this->SourceFileExtensions.begin(),
- this->SourceFileExtensions.end(),
- std::inserter(this->SourceFileExtensionsSet,
- this->SourceFileExtensionsSet.end()));
-
- this->HeaderFileExtensions.emplace_back("h");
- this->HeaderFileExtensions.emplace_back("hh");
- this->HeaderFileExtensions.emplace_back("h++");
- this->HeaderFileExtensions.emplace_back("hm");
- this->HeaderFileExtensions.emplace_back("hpp");
- this->HeaderFileExtensions.emplace_back("hxx");
- this->HeaderFileExtensions.emplace_back("in");
- this->HeaderFileExtensions.emplace_back("txx");
-
- std::copy(this->HeaderFileExtensions.begin(),
- this->HeaderFileExtensions.end(),
- std::inserter(this->HeaderFileExtensionsSet,
- this->HeaderFileExtensionsSet.end()));
+ // Set up a list of source and header extensions.
+ // These are used to find files when the extension is not given.
+ {
+ auto setupExts = [](FileExtensions& exts,
+ std::initializer_list<cm::string_view> extList) {
+ // Fill ordered vector
+ exts.ordered.reserve(extList.size());
+ for (cm::string_view ext : extList) {
+ exts.ordered.emplace_back(ext);
+ };
+ // Fill unordered set
+ exts.unordered.insert(exts.ordered.begin(), exts.ordered.end());
+ };
+
+ // The "c" extension MUST precede the "C" extension.
+ setupExts(this->SourceFileExtensions,
+ { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
+ setupExts(this->HeaderFileExtensions,
+ { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
+ setupExts(this->CudaFileExtensions, { "cu" });
+ setupExts(this->FortranFileExtensions,
+ { "f", "F", "for", "f77", "f90", "f95", "f03" });
+ }
}
cmake::~cmake()
{
- delete this->State;
- delete this->Messenger;
if (this->GlobalGenerator) {
delete this->GlobalGenerator;
this->GlobalGenerator = nullptr;
}
cmDeleteAll(this->Generators);
-#ifdef CMAKE_BUILD_WITH_CMAKE
- delete this->VariableWatch;
-#endif
- delete this->FileTimeCache;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmake::ReportVersionJson() const
{
Json::Value version = Json::objectValue;
@@ -294,7 +269,7 @@ Json::Value cmake::ReportCapabilitiesJson() const
std::string cmake::ReportCapabilities() const
{
std::string result;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::FastWriter writer;
result = writer.write(this->ReportCapabilitiesJson());
#else
@@ -327,7 +302,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- std::string var, value;
+ std::string var;
+ std::string value;
cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
if (cmState::ParseCacheEntry(entry, var, value, type)) {
// The value is transformed if it is a filepath for example, so
@@ -447,6 +423,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
std::cout << "loading initial cache file " << path << "\n";
+ // Resolve script path specified on command line relative to $PWD.
+ path = cmSystemTools::CollapseFullPath(path);
this->ReadListFile(args, path);
} else if (arg.find("-P", 0) == 0) {
i++;
@@ -460,7 +438,12 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
// Register fake project commands that hint misuse in script mode.
- GetProjectCommandsInScriptMode(this->State);
+ GetProjectCommandsInScriptMode(this->GetState());
+ // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
+ // set to $PWD for -P mode.
+ this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeOutputDirectory(
+ cmSystemTools::GetCurrentWorkingDirectory());
this->ReadListFile(args, path);
} else if (arg.find("--find-package", 0) == 0) {
findPackageMode = true;
@@ -490,15 +473,9 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
// read in the list file to fill the cache
if (!path.empty()) {
this->CurrentSnapshot = this->State->Reset();
- std::string homeDir = this->GetHomeDirectory();
- std::string homeOutputDir = this->GetHomeOutputDirectory();
- this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
cmStateSnapshot snapshot = this->GetCurrentSnapshot();
- snapshot.GetDirectory().SetCurrentBinary(
- cmSystemTools::GetCurrentWorkingDirectory());
- snapshot.GetDirectory().SetCurrentSource(
- cmSystemTools::GetCurrentWorkingDirectory());
+ snapshot.GetDirectory().SetCurrentBinary(this->GetHomeOutputDirectory());
+ snapshot.GetDirectory().SetCurrentSource(this->GetHomeDirectory());
snapshot.SetDefaultDefinitions();
cmMakefile mf(gg, snapshot);
if (this->GetWorkingMode() != NORMAL_MODE) {
@@ -511,8 +488,6 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
if (!mf.ReadListFile(path)) {
cmSystemTools::Error("Error processing file: " + path);
}
- this->SetHomeDirectory(homeDir);
- this->SetHomeOutputDirectory(homeOutputDir);
}
// free generic one if generated
@@ -561,8 +536,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}
} else if (mode == "COMPILE") {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
- std::vector<std::string> includeDirs;
- cmSystemTools::ExpandListArgument(includes, includeDirs);
+ std::vector<std::string> includeDirs = cmExpandedList(includes);
gg->CreateGenerationObjects();
cmLocalGenerator* lg = gg->LocalGenerators[0];
@@ -578,8 +552,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
- std::vector<std::string> libList;
- cmSystemTools::ExpandListArgument(libs, libList);
+ std::vector<std::string> libList = cmExpandedList(libs);
for (std::string const& lib : libList) {
tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType);
}
@@ -629,16 +602,15 @@ void cmake::LoadEnvironmentPresets()
this->EnvironmentGenerator = envGenVar;
}
- auto readGeneratorVar = [&](std::string name, std::string& key) {
+ auto readGeneratorVar = [&](std::string const& name, std::string& key) {
std::string varValue;
if (cmSystemTools::GetEnv(name, varValue)) {
if (hasEnvironmentGenerator) {
key = varValue;
} else if (!this->GetIsInTryCompile()) {
- std::string message = "Warning: Environment variable ";
- message += name;
- message += " will be ignored, because CMAKE_GENERATOR ";
- message += "is not set.";
+ std::string message =
+ cmStrCat("Warning: Environment variable ", name,
+ " will be ignored, because CMAKE_GENERATOR is not set.");
cmSystemTools::Message(message, "Warning");
}
}
@@ -755,7 +727,18 @@ void cmake::SetArgs(const std::vector<std::string>& args)
} else if (arg.find("--debug-output", 0) == 0) {
std::cout << "Running with debug output on.\n";
this->SetDebugOutputOn(true);
+ } else if (arg.find("--log-level=", 0) == 0) {
+ const auto logLevel =
+ StringToLogLevel(arg.substr(sizeof("--log-level=") - 1));
+ if (logLevel == LogLevel::LOG_UNDEFINED) {
+ cmSystemTools::Error("Invalid level specified for --log-level");
+ return;
+ }
+ this->SetLogLevel(logLevel);
} else if (arg.find("--loglevel=", 0) == 0) {
+ // This is supported for backward compatibility. This option only
+ // appeared in the 3.15.x release series and was renamed to
+ // --log-level in 3.16.0
const auto logLevel =
StringToLogLevel(arg.substr(sizeof("--loglevel=") - 1));
if (logLevel == LogLevel::LOG_UNDEFINED) {
@@ -772,6 +755,11 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmSystemTools::ConvertToUnixSlashes(file);
this->AddTraceSource(file);
this->SetTrace(true);
+ } else if (arg.find("--trace-redirect=", 0) == 0) {
+ std::string file = arg.substr(strlen("--trace-redirect="));
+ cmSystemTools::ConvertToUnixSlashes(file);
+ this->SetTraceFile(file);
+ this->SetTrace(true);
} else if (arg.find("--trace", 0) == 0) {
std::cout << "Running with trace output on.\n";
this->SetTrace(true);
@@ -840,8 +828,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
kdevError = "\nThe KDevelop3 generator is not supported anymore.";
}
- cmSystemTools::Error("Could not create named generator " + value +
- kdevError);
+ cmSystemTools::Error(
+ cmStrCat("Could not create named generator ", value, kdevError));
this->PrintGeneratorList();
return;
}
@@ -902,6 +890,20 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
}
+void cmake::SetTraceFile(const std::string& file)
+{
+ this->TraceFile.close();
+ this->TraceFile.open(file.c_str());
+ if (!this->TraceFile) {
+ std::stringstream ss;
+ ss << "Error opening trace file " << file << ": "
+ << cmSystemTools::GetLastSystemError();
+ cmSystemTools::Error(ss.str());
+ return;
+ }
+ std::cout << "Trace will be written to " << file << "\n";
+}
+
void cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -912,10 +914,8 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
if (cmSystemTools::FileIsDirectory(arg)) {
std::string path = cmSystemTools::CollapseFullPath(arg);
cmSystemTools::ConvertToUnixSlashes(path);
- std::string cacheFile = path;
- cacheFile += "/CMakeCache.txt";
- std::string listFile = path;
- listFile += "/CMakeLists.txt";
+ std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
+ std::string listFile = cmStrCat(path, "/CMakeLists.txt");
if (cmSystemTools::FileExists(cacheFile)) {
cachePath = path;
}
@@ -1000,7 +1000,7 @@ int cmake::AddCMakePaths()
this->AddCacheEntry("CMAKE_COMMAND",
cmSystemTools::GetCMakeCommand().c_str(),
"Path to CMake executable.", cmStateEnums::INTERNAL);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->AddCacheEntry(
"CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand().c_str(),
"Path to ctest program executable.", cmStateEnums::INTERNAL);
@@ -1026,7 +1026,7 @@ int cmake::AddCMakePaths()
void cmake::AddDefaultExtraGenerators()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
@@ -1100,20 +1100,18 @@ createExtraGenerator(
const std::vector<std::string> generators =
i->GetSupportedGlobalGenerators();
if (i->GetName() == name) { // Match aliases
- return std::make_pair(i->CreateExternalMakefileProjectGenerator(),
- generators.at(0));
+ return { i->CreateExternalMakefileProjectGenerator(), generators.at(0) };
}
for (std::string const& g : generators) {
const std::string fullName =
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
g, i->GetName());
if (fullName == name) {
- return std::make_pair(i->CreateExternalMakefileProjectGenerator(), g);
+ return { i->CreateExternalMakefileProjectGenerator(), g };
}
}
}
- return std::make_pair(
- static_cast<cmExternalMakefileProjectGenerator*>(nullptr), name);
+ return { nullptr, name };
}
cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
@@ -1170,12 +1168,10 @@ std::string cmake::FindCacheFile(const std::string& binaryDir)
{
std::string cachePath = binaryDir;
cmSystemTools::ConvertToUnixSlashes(cachePath);
- std::string cacheFile = cachePath;
- cacheFile += "/CMakeCache.txt";
+ std::string cacheFile = cmStrCat(cachePath, "/CMakeCache.txt");
if (!cmSystemTools::FileExists(cacheFile)) {
// search in parent directories for cache
- std::string cmakeFiles = cachePath;
- cmakeFiles += "/CMakeFiles";
+ std::string cmakeFiles = cmStrCat(cachePath, "/CMakeFiles");
if (cmSystemTools::FileExists(cmakeFiles)) {
std::string cachePathFound =
cmSystemTools::FileExistsInParentDirectories("CMakeCache.txt",
@@ -1230,8 +1226,7 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
int cmake::DoPreConfigureChecks()
{
// Make sure the Source directory contains a CMakeLists.txt file.
- std::string srcList = this->GetHomeDirectory();
- srcList += "/CMakeLists.txt";
+ std::string srcList = cmStrCat(this->GetHomeDirectory(), "/CMakeLists.txt");
if (!cmSystemTools::FileExists(srcList)) {
std::ostringstream err;
if (cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) {
@@ -1253,17 +1248,16 @@ int cmake::DoPreConfigureChecks()
// do a sanity check on some values
if (this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY")) {
std::string cacheStart =
- *this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
- cacheStart += "/CMakeLists.txt";
- std::string currentStart = this->GetHomeDirectory();
- currentStart += "/CMakeLists.txt";
+ cmStrCat(*this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"),
+ "/CMakeLists.txt");
+ std::string currentStart =
+ cmStrCat(this->GetHomeDirectory(), "/CMakeLists.txt");
if (!cmSystemTools::SameFile(cacheStart, currentStart)) {
- std::string message = "The source \"";
- message += currentStart;
- message += "\" does not match the source \"";
- message += cacheStart;
- message += "\" used to generate cache. ";
- message += "Re-run cmake with a different source directory.";
+ std::string message =
+ cmStrCat("The source \"", currentStart,
+ "\" does not match the source \"", cacheStart,
+ "\" used to generate cache. Re-run cmake with a different "
+ "source directory.");
cmSystemTools::Error(message);
return -2;
}
@@ -1282,8 +1276,7 @@ struct SaveCacheEntry
int cmake::HandleDeleteCacheVariables(const std::string& var)
{
- std::vector<std::string> argsSplit;
- cmSystemTools::ExpandListArgument(std::string(var), argsSplit, true);
+ std::vector<std::string> argsSplit = cmExpandedList(std::string(var), true);
// erase the property to avoid infinite recursion
this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
if (this->State->GetIsInTryCompile()) {
@@ -1297,8 +1290,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
<< "Configure will be re-run and you may have to reset some variables.\n"
<< "The following variables have changed:\n";
/* clang-format on */
- for (std::vector<std::string>::iterator i = argsSplit.begin();
- i != argsSplit.end(); ++i) {
+ for (auto i = argsSplit.begin(); i != argsSplit.end(); ++i) {
SaveCacheEntry save;
save.key = *i;
warning << *i << "= ";
@@ -1397,18 +1389,16 @@ int cmake::Configure()
// 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 &&
- cmSystemTools::IsOff(value));
+ this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
- this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value));
+ this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value));
+ this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
- this->Messenger->SetDevWarningsAsErrors(value &&
- cmSystemTools::IsOff(value));
+ this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
int ret = this->ActualConfigure();
const char* delCacheVars =
@@ -1468,12 +1458,11 @@ int cmake::ActualConfigure()
this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
if (genName) {
if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) {
- std::string message = "Error: generator : ";
- message += this->GlobalGenerator->GetName();
- message += "\nDoes not match the generator used previously: ";
- message += *genName;
- message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
- "directory or choose a different binary directory.";
+ std::string message =
+ cmStrCat("Error: generator : ", this->GlobalGenerator->GetName(),
+ "\nDoes not match the generator used previously: ", *genName,
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.");
cmSystemTools::Error(message);
return -2;
}
@@ -1491,12 +1480,11 @@ int cmake::ActualConfigure()
if (const std::string* instance =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) {
- std::string message = "Error: generator instance: ";
- message += this->GeneratorInstance;
- message += "\nDoes not match the instance used previously: ";
- message += *instance;
- message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
- "directory or choose a different binary directory.";
+ std::string message =
+ cmStrCat("Error: generator instance: ", this->GeneratorInstance,
+ "\nDoes not match the instance used previously: ", *instance,
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.");
cmSystemTools::Error(message);
return -2;
}
@@ -1510,12 +1498,11 @@ int cmake::ActualConfigure()
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
if (this->GeneratorPlatformSet &&
this->GeneratorPlatform != *platformName) {
- std::string message = "Error: generator platform: ";
- message += this->GeneratorPlatform;
- message += "\nDoes not match the platform used previously: ";
- message += *platformName;
- message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
- "directory or choose a different binary directory.";
+ std::string message = cmStrCat(
+ "Error: generator platform: ", this->GeneratorPlatform,
+ "\nDoes not match the platform used previously: ", *platformName,
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.");
cmSystemTools::Error(message);
return -2;
}
@@ -1528,12 +1515,11 @@ int cmake::ActualConfigure()
if (const std::string* tsName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) {
if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) {
- std::string message = "Error: generator toolset: ";
- message += this->GeneratorToolset;
- message += "\nDoes not match the toolset used previously: ";
- message += *tsName;
- message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
- "directory or choose a different binary directory.";
+ std::string message =
+ cmStrCat("Error: generator toolset: ", this->GeneratorToolset,
+ "\nDoes not match the toolset used previously: ", *tsName,
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.");
cmSystemTools::Error(message);
return -2;
}
@@ -1553,7 +1539,7 @@ int cmake::ActualConfigure()
this->TruncateOutputLog("CMakeError.log");
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI = cm::make_unique<cmFileAPI>(this);
this->FileAPI->ReadQueries();
#endif
@@ -1780,7 +1766,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
cmGlobalVisualStudioGenerator* gg =
static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
- this->VSSolutionFile.c_str());
+ this->VSSolutionFile);
}
#endif
return ret;
@@ -1791,8 +1777,8 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
"Build files cannot be regenerated correctly.");
return ret;
}
- std::string message = "Build files have been written to: ";
- message += this->GetHomeOutputDirectory();
+ std::string message = cmStrCat("Build files have been written to: ",
+ this->GetHomeOutputDirectory());
this->UpdateProgress(message, -1);
return ret;
}
@@ -1821,7 +1807,7 @@ int cmake::Generate()
// for the Visual Studio and Xcode generators.)
this->SaveCache(this->GetHomeOutputDirectory());
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI->WriteReplies();
#endif
@@ -1836,15 +1822,13 @@ void cmake::AddCacheEntry(const std::string& key, const char* value,
this->UnwatchUnusedCli(key);
if (key == "CMAKE_WARN_DEPRECATED") {
- this->Messenger->SetSuppressDeprecatedWarnings(
- value && cmSystemTools::IsOff(value));
+ this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
} else if (key == "CMAKE_ERROR_DEPRECATED") {
- this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value));
+ this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
} else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") {
- this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value));
+ this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
} else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") {
- this->Messenger->SetDevWarningsAsErrors(value &&
- cmSystemTools::IsOff(value));
+ this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
}
}
@@ -1898,12 +1882,12 @@ const char* cmake::GetCacheDefinition(const std::string& name) const
void cmake::AddScriptingCommands()
{
- GetScriptingCommands(this->State);
+ GetScriptingCommands(this->GetState());
}
void cmake::AddProjectCommands()
{
- GetProjectCommands(this->State);
+ GetProjectCommands(this->GetState());
}
void cmake::AddDefaultGenerators()
@@ -1927,7 +1911,7 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory());
#endif
this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# if defined(__linux__) || defined(_WIN32)
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
# endif
@@ -1953,8 +1937,8 @@ int cmake::LoadCache()
// could we not read the cache
if (!this->LoadCache(this->GetHomeOutputDirectory())) {
// if it does exist, but isn't readable then warn the user
- std::string cacheFile = this->GetHomeOutputDirectory();
- cacheFile += "/CMakeCache.txt";
+ std::string cacheFile =
+ cmStrCat(this->GetHomeOutputDirectory(), "/CMakeCache.txt");
if (cmSystemTools::FileExists(cacheFile)) {
cmSystemTools::Error(
"There is a CMakeCache.txt file for the current binary tree but "
@@ -2040,8 +2024,7 @@ void cmake::AppendGlobalGeneratorsDocumentation(
for (cmGlobalGeneratorFactory* g : this->Generators) {
cmDocumentationEntry e;
g->GetDocumentation(e);
- if (!foundDefaultOne &&
- cmSystemTools::StringStartsWith(e.Name, defaultName.c_str())) {
+ if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
e.CustomNamePrefix = '*';
foundDefaultOne = true;
}
@@ -2087,7 +2070,7 @@ std::vector<cmDocumentationEntry> cmake::GetGeneratorsDocumentation()
void cmake::PrintGeneratorList()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDocumentation doc;
auto generators = this->GetGeneratorsDocumentation();
doc.AppendSection("Generators", generators);
@@ -2109,7 +2092,8 @@ void cmake::UpdateConversionPathTable()
". CMake can not open file.");
cmSystemTools::ReportLastSystemError("CMake can not open file.");
} else {
- std::string a, b;
+ std::string a;
+ std::string b;
while (!table.eof()) {
// two entries per line
table >> a;
@@ -2132,9 +2116,7 @@ int cmake::CheckBuildSystem()
// If no file is provided for the check, we have to rerun.
if (this->CheckBuildSystemArgument.empty()) {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake no build system arguments\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout("Re-run cmake no build system arguments\n");
}
return 1;
}
@@ -2192,7 +2174,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")) {
- cmSystemTools::ExpandListArgument(productStr, products);
+ cmExpandList(productStr, products);
}
for (std::string const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
@@ -2211,22 +2193,20 @@ int cmake::CheckBuildSystem()
const char* dependsStr = mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS");
const char* outputsStr = mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
if (dependsStr && outputsStr) {
- cmSystemTools::ExpandListArgument(dependsStr, depends);
- cmSystemTools::ExpandListArgument(outputsStr, outputs);
+ cmExpandList(dependsStr, depends);
+ cmExpandList(outputsStr, outputs);
}
if (depends.empty() || outputs.empty()) {
// Not enough information was provided to do the test. Just rerun.
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
- "or CMAKE_MAKEFILE_OUTPUTS :\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout("Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
+ "or CMAKE_MAKEFILE_OUTPUTS :\n");
}
return 1;
}
// Find the newest dependency.
- std::vector<std::string>::iterator dep = depends.begin();
+ auto dep = depends.begin();
std::string dep_newest = *dep++;
for (; dep != depends.end(); ++dep) {
int result = 0;
@@ -2236,16 +2216,15 @@ int cmake::CheckBuildSystem()
}
} else {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake: build system dependency is missing\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ "Re-run cmake: build system dependency is missing\n");
}
return 1;
}
}
// Find the oldest output.
- std::vector<std::string>::iterator out = outputs.begin();
+ auto out = outputs.begin();
std::string out_oldest = *out++;
for (; out != outputs.end(); ++out) {
int result = 0;
@@ -2255,9 +2234,8 @@ int cmake::CheckBuildSystem()
}
} else {
if (verbose) {
- std::ostringstream msg;
- msg << "Re-run cmake: build system output is missing\n";
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ "Re-run cmake: build system output is missing\n");
}
return 1;
}
@@ -2284,9 +2262,7 @@ int cmake::CheckBuildSystem()
void cmake::TruncateOutputLog(const char* fname)
{
- std::string fullPath = this->GetHomeOutputDirectory();
- fullPath += "/";
- fullPath += fname;
+ std::string fullPath = cmStrCat(this->GetHomeOutputDirectory(), '/', fname);
struct stat st;
if (::stat(fullPath.c_str(), &st)) {
return;
@@ -2303,14 +2279,6 @@ void cmake::TruncateOutputLog(const char* fname)
}
}
-inline std::string removeQuotes(const std::string& s)
-{
- if (s.front() == '\"' && s.back() == '\"') {
- return s.substr(1, s.size() - 2);
- }
- return s;
-}
-
void cmake::MarkCliAsUsed(const std::string& variable)
{
this->UsedCliVariables[variable] = true;
@@ -2318,13 +2286,13 @@ void cmake::MarkCliAsUsed(const std::string& variable)
void cmake::GenerateGraphViz(const std::string& fileName) const
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmGraphVizWriter gvWriter(this->GetGlobalGenerator());
- std::string settingsFile = this->GetHomeOutputDirectory();
- settingsFile += "/CMakeGraphVizOptions.cmake";
- std::string fallbackSettingsFile = this->GetHomeDirectory();
- fallbackSettingsFile += "/CMakeGraphVizOptions.cmake";
+ std::string settingsFile =
+ cmStrCat(this->GetHomeOutputDirectory(), "/CMakeGraphVizOptions.cmake");
+ std::string fallbackSettingsFile =
+ cmStrCat(this->GetHomeDirectory(), "/CMakeGraphVizOptions.cmake");
gvWriter.ReadSettings(settingsFile, fallbackSettingsFile);
gvWriter.WritePerTargetFiles(fileName);
@@ -2358,8 +2326,7 @@ bool cmake::GetPropertyAsBool(const std::string& prop)
cmInstalledFile* cmake::GetOrCreateInstalledFile(cmMakefile* mf,
const std::string& name)
{
- std::map<std::string, cmInstalledFile>::iterator i =
- this->InstalledFiles.find(name);
+ auto i = this->InstalledFiles.find(name);
if (i != this->InstalledFiles.end()) {
cmInstalledFile& file = i->second;
@@ -2372,8 +2339,7 @@ cmInstalledFile* cmake::GetOrCreateInstalledFile(cmMakefile* mf,
cmInstalledFile const* cmake::GetInstalledFile(const std::string& name) const
{
- std::map<std::string, cmInstalledFile>::const_iterator i =
- this->InstalledFiles.find(name);
+ auto i = this->InstalledFiles.find(name);
if (i != this->InstalledFiles.end()) {
cmInstalledFile const& file = i->second;
@@ -2421,8 +2387,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// no option assume it is the output file
else {
if (!cmSystemTools::FileIsFullPath(arg)) {
- resultFile = cwd;
- resultFile += "/";
+ resultFile = cmStrCat(cwd, '/');
}
resultFile += arg;
writeToStdout = false;
@@ -2431,12 +2396,10 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// we have to find the module directory, so we can copy the files
this->AddCMakePaths();
- std::string modulesPath = cmSystemTools::GetCMakeRoot();
- modulesPath += "/Modules";
- std::string inFile = modulesPath;
- inFile += "/SystemInformation.cmake";
- std::string outFile = destPath;
- outFile += "/CMakeLists.txt";
+ std::string modulesPath =
+ cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules");
+ std::string inFile = cmStrCat(modulesPath, "/SystemInformation.cmake");
+ std::string outFile = cmStrCat(destPath, "/CMakeLists.txt");
// Copy file
if (!cmsys::SystemTools::CopyFileAlways(inFile, outFile)) {
@@ -2447,8 +2410,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// do we write to a file or to stdout?
if (resultFile.empty()) {
- resultFile = cwd;
- resultFile += "/__cmake_systeminformation/results.txt";
+ resultFile = cmStrCat(cwd, "/__cmake_systeminformation/results.txt");
}
{
@@ -2504,8 +2466,7 @@ static bool cmakeCheckStampFile(const std::string& stampName)
// conjunction with cmLocalVisualStudio7Generator to avoid
// repeatedly re-running CMake when the user rebuilds the entire
// solution.
- std::string stampDepends = stampName;
- stampDepends += ".depend";
+ std::string stampDepends = cmStrCat(stampName, ".depend");
#if defined(_WIN32) || defined(__CYGWIN__)
cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
#else
@@ -2596,7 +2557,7 @@ std::vector<std::string> cmake::GetDebugConfigs()
if (const char* config_list =
this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
// Expand the specified list and convert to upper-case.
- cmSystemTools::ExpandListArgument(config_list, configs);
+ cmExpandList(config_list, configs);
std::transform(configs.begin(), configs.end(), configs.begin(),
cmSystemTools::UpperCase);
}
@@ -2607,11 +2568,6 @@ std::vector<std::string> cmake::GetDebugConfigs()
return configs;
}
-cmMessenger* cmake::GetMessenger() const
-{
- return this->Messenger;
-}
-
int cmake::Build(int jobs, const std::string& dir,
const std::vector<std::string>& targets,
const std::string& config,
@@ -2672,7 +2628,7 @@ int cmake::Build(int jobs, const std::string& dir,
const char* cachedVerbose =
this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
- if (cmSystemTools::IsOn(cachedVerbose)) {
+ if (cmIsOn(cachedVerbose)) {
verbose = true;
}
@@ -2720,8 +2676,8 @@ int cmake::Build(int jobs, const std::string& dir,
"Build files cannot be regenerated correctly.");
return ret;
}
- std::string message = "Build files have been written to: ";
- message += this->GetHomeOutputDirectory();
+ std::string message = cmStrCat("Build files have been written to: ",
+ this->GetHomeOutputDirectory());
this->UpdateProgress(message, -1);
// Restore the previously set directories to their original value.
@@ -2782,9 +2738,9 @@ bool cmake::Open(const std::string& dir, bool dryRun)
void cmake::WatchUnusedCli(const std::string& var)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
- if (this->UsedCliVariables.find(var) == this->UsedCliVariables.end()) {
+ if (!cmContains(this->UsedCliVariables, var)) {
this->UsedCliVariables[var] = false;
}
#endif
@@ -2792,7 +2748,7 @@ void cmake::WatchUnusedCli(const std::string& var)
void cmake::UnwatchUnusedCli(const std::string& var)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning);
this->UsedCliVariables.erase(var);
#endif
@@ -2800,7 +2756,7 @@ void cmake::UnwatchUnusedCli(const std::string& var)
void cmake::RunCheckForUnusedVariables()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
bool haveUnused = false;
std::ostringstream msg;
msg << "Manually-specified variables were not used by the project:";
diff --git a/Source/cmake.h b/Source/cmake.h
index fa4409aeb..687c1056b 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -7,12 +7,13 @@
#include <functional>
#include <map>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>
+#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
@@ -20,7 +21,7 @@
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_jsoncpp_value.h"
#endif
@@ -121,7 +122,18 @@ public:
bool isAlias;
};
- typedef std::map<std::string, cmInstalledFile> InstalledFilesMap;
+ struct FileExtensions
+ {
+ bool Test(std::string const& ext) const
+ {
+ return (this->unordered.find(ext) != this->unordered.end());
+ }
+
+ std::vector<std::string> ordered;
+ std::unordered_set<std::string> unordered;
+ };
+
+ using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
static const int NO_BUILD_PARALLEL_LEVEL = -1;
static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;
@@ -134,7 +146,7 @@ public:
cmake(cmake const&) = delete;
cmake& operator=(cmake const&) = delete;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value ReportVersionJson() const;
Json::Value ReportCapabilitiesJson() const;
#endif
@@ -233,24 +245,42 @@ public:
const std::vector<std::string>& GetSourceExtensions() const
{
- return this->SourceFileExtensions;
+ return this->SourceFileExtensions.ordered;
}
bool IsSourceExtension(const std::string& ext) const
{
- return this->SourceFileExtensionsSet.find(ext) !=
- this->SourceFileExtensionsSet.end();
+ return this->SourceFileExtensions.Test(ext);
}
const std::vector<std::string>& GetHeaderExtensions() const
{
- return this->HeaderFileExtensions;
+ return this->HeaderFileExtensions.ordered;
}
bool IsHeaderExtension(const std::string& ext) const
{
- return this->HeaderFileExtensionsSet.find(ext) !=
- this->HeaderFileExtensionsSet.end();
+ return this->HeaderFileExtensions.Test(ext);
+ }
+
+ const std::vector<std::string>& GetCudaExtensions() const
+ {
+ return this->CudaFileExtensions.ordered;
+ }
+
+ bool IsCudaExtension(const std::string& ext) const
+ {
+ return this->CudaFileExtensions.Test(ext);
+ }
+
+ const std::vector<std::string>& GetFortranExtensions() const
+ {
+ return this->FortranFileExtensions.ordered;
+ }
+
+ bool IsFortranExtension(const std::string& ext) const
+ {
+ return this->FortranFileExtensions.Test(ext);
}
// Strips the extension (if present and known) from a filename
@@ -305,9 +335,9 @@ public:
//! this is called by generators to update the progress
void UpdateProgress(const std::string& msg, float prog);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
//! Get the variable watch object
- cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
+ cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
#endif
std::vector<cmDocumentationEntry> GetGeneratorsDocumentation();
@@ -348,18 +378,18 @@ public:
/**
* Get the file comparison class
*/
- cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache; }
+ cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
- // Get the selected log level for `message()` commands during the cmake run.
+ //! Get the selected log level for `message()` commands during the cmake run.
LogLevel GetLogLevel() const { return this->MessageLogLevel; }
void SetLogLevel(LogLevel level) { this->MessageLogLevel = level; }
static LogLevel StringToLogLevel(const std::string& levelStr);
- // Do we want debug output during the cmake run.
+ //! Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
- // Do we want trace output during the cmake run.
+ //! Do we want trace output during the cmake run.
bool GetTrace() { return this->Trace; }
void SetTrace(bool b) { this->Trace = b; }
bool GetTraceExpand() { return this->TraceExpand; }
@@ -372,6 +402,9 @@ public:
{
return this->TraceOnlyThisSources;
}
+ cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
+ void SetTraceFile(std::string const& file);
+
bool GetWarnUninitialized() { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
bool GetWarnUnused() { return this->WarnUnused; }
@@ -396,31 +429,31 @@ public:
return this->CMakeEditCommand;
}
- cmMessenger* GetMessenger() const;
+ cmMessenger* GetMessenger() const { return this->Messenger.get(); }
- /*
+ /**
* Get the state of the suppression of developer (author) warnings.
* Returns false, by default, if developer warnings should be shown, true
* otherwise.
*/
bool GetSuppressDevWarnings() const;
- /*
+ /**
* Set the state of the suppression of developer (author) warnings.
*/
void SetSuppressDevWarnings(bool v);
- /*
+ /**
* Get the state of the suppression of deprecated warnings.
* Returns false, by default, if deprecated warnings should be shown, true
* otherwise.
*/
bool GetSuppressDeprecatedWarnings() const;
- /*
+ /**
* Set the state of the suppression of deprecated warnings.
*/
void SetSuppressDeprecatedWarnings(bool v);
- /*
+ /**
* Get the state of treating developer (author) warnings as errors.
* Returns false, by default, if warnings should not be treated as errors,
* true otherwise.
@@ -431,7 +464,7 @@ public:
*/
void SetDevWarningsAsErrors(bool v);
- /*
+ /**
* Get the state of treating deprecated warnings as errors.
* Returns false, by default, if warnings should not be treated as errors,
* true otherwise.
@@ -459,7 +492,7 @@ public:
void UnwatchUnusedCli(const std::string& var);
void WatchUnusedCli(const std::string& var);
- cmState* GetState() const { return this->State; }
+ cmState* GetState() const { return this->State.get(); }
void SetCurrentSnapshot(cmStateSnapshot const& snapshot)
{
this->CurrentSnapshot = snapshot;
@@ -470,24 +503,24 @@ protected:
void RunCheckForUnusedVariables();
int HandleDeleteCacheVariables(const std::string& var);
- typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector;
+ using RegisteredGeneratorsVector = std::vector<cmGlobalGeneratorFactory*>;
RegisteredGeneratorsVector Generators;
- typedef std::vector<cmExternalMakefileProjectGeneratorFactory*>
- RegisteredExtraGeneratorsVector;
+ using RegisteredExtraGeneratorsVector =
+ std::vector<cmExternalMakefileProjectGeneratorFactory*>;
RegisteredExtraGeneratorsVector ExtraGenerators;
void AddScriptingCommands();
void AddProjectCommands();
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator* GlobalGenerator = nullptr;
std::map<std::string, DiagLevel> DiagLevels;
std::string GeneratorInstance;
std::string GeneratorPlatform;
std::string GeneratorToolset;
- bool GeneratorInstanceSet;
- bool GeneratorPlatformSet;
- bool GeneratorToolsetSet;
+ bool GeneratorInstanceSet = false;
+ bool GeneratorPlatformSet = false;
+ bool GeneratorToolsetSet = false;
//! read in a cmake list file to initialize the cache
void ReadListFile(const std::vector<std::string>& args,
@@ -514,14 +547,15 @@ protected:
private:
ProgressCallbackType ProgressCallback;
- WorkingMode CurrentWorkingMode;
- bool DebugOutput;
- bool Trace;
- bool TraceExpand;
- bool WarnUninitialized;
- bool WarnUnused;
- bool WarnUnusedCli;
- bool CheckSystemVars;
+ WorkingMode CurrentWorkingMode = NORMAL_MODE;
+ bool DebugOutput = false;
+ bool Trace = false;
+ bool TraceExpand = false;
+ cmGeneratedFileStream TraceFile;
+ bool WarnUninitialized = false;
+ bool WarnUnused = false;
+ bool WarnUnusedCli = true;
+ bool CheckSystemVars = false;
std::map<std::string, bool> UsedCliVariables;
std::string CMakeEditCommand;
std::string CXXEnvironment;
@@ -531,24 +565,24 @@ private:
std::string CheckStampList;
std::string VSSolutionFile;
std::string EnvironmentGenerator;
- std::vector<std::string> SourceFileExtensions;
- std::unordered_set<std::string> SourceFileExtensionsSet;
- std::vector<std::string> HeaderFileExtensions;
- std::unordered_set<std::string> HeaderFileExtensionsSet;
- bool ClearBuildSystem;
- bool DebugTryCompile;
- cmFileTimeCache* FileTimeCache;
+ FileExtensions SourceFileExtensions;
+ FileExtensions HeaderFileExtensions;
+ FileExtensions CudaFileExtensions;
+ FileExtensions FortranFileExtensions;
+ bool ClearBuildSystem = false;
+ bool DebugTryCompile = false;
+ std::unique_ptr<cmFileTimeCache> FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- cmVariableWatch* VariableWatch;
+#if !defined(CMAKE_BOOTSTRAP)
+ std::unique_ptr<cmVariableWatch> VariableWatch;
std::unique_ptr<cmFileAPI> FileAPI;
#endif
- cmState* State;
+ std::unique_ptr<cmState> State;
cmStateSnapshot CurrentSnapshot;
- cmMessenger* Messenger;
+ std::unique_ptr<cmMessenger> Messenger;
std::vector<std::string> TraceOnlyThisSources;
@@ -556,7 +590,7 @@ private:
void UpdateConversionPathTable();
- // Print a list of valid generators to stderr.
+ //! Print a list of valid generators to stderr.
void PrintGeneratorList();
std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator();
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index a6348b39e..6d3e6ee30 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -7,37 +7,39 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
#include "cmcmd.h"
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmDocumentation.h"
# include "cmDynamicLoader.h"
#endif
-#include "cm_uv.h"
-
#include "cmsys/Encoding.hxx"
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+
+#include "cm_uv.h"
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
#include <cassert>
+#include <cctype>
#include <climits>
-#include <ctype.h>
+#include <cstring>
#include <iostream>
-#include <string.h>
#include <string>
#include <vector>
-#ifdef CMAKE_BUILD_WITH_CMAKE
-static const char* cmDocumentationName[][2] = {
+namespace {
+#ifndef CMAKE_BOOTSTRAP
+const char* cmDocumentationName[][2] = {
{ nullptr, " cmake - Cross-Platform Makefile Generator." },
{ nullptr, nullptr }
};
-static const char* cmDocumentationUsage[][2] = {
+const char* cmDocumentationUsage[][2] = {
{ nullptr,
" cmake [options] <path-to-source>\n"
" cmake [options] <path-to-existing-build>\n"
@@ -49,40 +51,12 @@ static const char* cmDocumentationUsage[][2] = {
{ nullptr, nullptr }
};
-static const char* cmDocumentationUsageNote[][2] = {
+const char* cmDocumentationUsageNote[][2] = {
{ nullptr, "Run 'cmake --help' for more information." },
{ nullptr, nullptr }
};
-# define CMAKE_BUILD_OPTIONS \
- " <dir> = Project binary directory to be built.\n" \
- " --parallel [<jobs>], -j [<jobs>]\n" \
- " = Build in parallel using the given number of jobs. \n" \
- " If <jobs> is omitted the native build tool's \n" \
- " default number is used.\n" \
- " The CMAKE_BUILD_PARALLEL_LEVEL environment " \
- "variable\n" \
- " specifies a default parallel level when this " \
- "option\n" \
- " is not given.\n" \
- " --target <tgt>..., -t <tgt>... \n" \
- " = Build <tgt> instead of default targets.\n" \
- " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
- " --clean-first = Build target 'clean' first, then build.\n" \
- " (To clean only, use --target 'clean'.)\n" \
- " --verbose, -v = Enable verbose output - if supported - including\n" \
- " the build commands to be executed. \n" \
- " -- = Pass remaining options to the native tool.\n"
-
-# define CMAKE_INSTALL_OPTIONS \
- " <dir> = Project binary directory to install.\n" \
- " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
- " --component <comp> = Component-based install. Only install <comp>.\n" \
- " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" \
- " --strip = Performing install/strip.\n" \
- " -v --verbose = Enable verbose output.\n"
-
-static const char* cmDocumentationOptions[][2] = {
+const char* cmDocumentationOptions[][2] = {
CMAKE_STANDARD_OPTIONS_TABLE,
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
@@ -96,8 +70,9 @@ static const char* cmDocumentationOptions[][2] = {
"Generate graphviz of dependencies, see "
"CMakeGraphVizOptions.cmake for more." },
{ "--system-information [file]", "Dump information about this system." },
- { "--loglevel=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
- "Set the verbosity of messages from CMake files." },
+ { "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
+ "Set the verbosity of messages from CMake files. "
+ "--loglevel is also accepted for backward compatibility reasons." },
{ "--debug-trycompile",
"Do not delete the try_compile build tree. Only "
"useful on one try_compile at a time." },
@@ -106,6 +81,8 @@ static const char* cmDocumentationOptions[][2] = {
{ "--trace-expand", "Put cmake in trace mode with variable expansion." },
{ "--trace-source=<file>",
"Trace only this CMake file/module. Multiple options allowed." },
+ { "--trace-redirect=<file>",
+ "Redirect trace output to a file instead of stderr." },
{ "--warn-uninitialized", "Warn about uninitialized values." },
{ "--warn-unused-vars", "Warn about unused variables." },
{ "--no-warn-unused-cli", "Don't warn about command line options." },
@@ -117,7 +94,7 @@ static const char* cmDocumentationOptions[][2] = {
#endif
-static int do_command(int ac, char const* const* av)
+int do_command(int ac, char const* const* av)
{
std::vector<std::string> args;
args.reserve(ac - 1);
@@ -126,12 +103,7 @@ static int do_command(int ac, char const* const* av)
return cmcmd::ExecuteCMakeCommand(args);
}
-int do_cmake(int ac, char const* const* av);
-static int do_build(int ac, char const* const* av);
-static int do_install(int ac, char const* const* av);
-static int do_open(int ac, char const* const* av);
-
-static cmMakefile* cmakemainGetMakefile(cmake* cm)
+cmMakefile* cmakemainGetMakefile(cmake* cm)
{
if (cm && cm->GetDebugOutput()) {
cmGlobalGenerator* gg = cm->GetGlobalGenerator();
@@ -142,7 +114,7 @@ static cmMakefile* cmakemainGetMakefile(cmake* cm)
return nullptr;
}
-static std::string cmakemainGetStack(cmake* cm)
+std::string cmakemainGetStack(cmake* cm)
{
std::string msg;
cmMakefile* mf = cmakemainGetMakefile(cm);
@@ -156,70 +128,25 @@ static std::string cmakemainGetStack(cmake* cm)
return msg;
}
-static void cmakemainMessageCallback(const std::string& m,
- const char* /*unused*/, cmake* cm)
+void cmakemainMessageCallback(const std::string& m, const char* /*unused*/,
+ cmake* cm)
{
- std::cerr << m << cmakemainGetStack(cm) << std::endl << std::flush;
+ std::cerr << m << cmakemainGetStack(cm) << std::endl;
}
-static void cmakemainProgressCallback(const std::string& m, float prog,
- cmake* cm)
+void cmakemainProgressCallback(const std::string& m, float prog, cmake* cm)
{
cmMakefile* mf = cmakemainGetMakefile(cm);
std::string dir;
if (mf && cmHasLiteralPrefix(m, "Configuring") && (prog < 0)) {
- dir = " ";
- dir += mf->GetCurrentSourceDirectory();
+ dir = cmStrCat(' ', mf->GetCurrentSourceDirectory());
} else if (mf && cmHasLiteralPrefix(m, "Generating")) {
- dir = " ";
- dir += mf->GetCurrentBinaryDirectory();
+ dir = cmStrCat(' ', mf->GetCurrentBinaryDirectory());
}
if ((prog < 0) || (!dir.empty())) {
std::cout << "-- " << m << dir << cmakemainGetStack(cm) << std::endl;
}
-
- std::cout.flush();
-}
-
-int main(int ac, char const* const* av)
-{
- cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
- // Replace streambuf so we can output Unicode to console
- cmsys::ConsoleBuf::Manager consoleOut(std::cout);
- consoleOut.SetUTF8Pipes();
- cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
- consoleErr.SetUTF8Pipes();
-#endif
- cmsys::Encoding::CommandLineArguments args =
- cmsys::Encoding::CommandLineArguments::Main(ac, av);
- ac = args.argc();
- av = args.argv();
-
- cmSystemTools::EnableMSVCDebugHook();
- cmSystemTools::InitializeLibUV();
- cmSystemTools::FindCMakeResources(av[0]);
- if (ac > 1) {
- if (strcmp(av[1], "--build") == 0) {
- return do_build(ac, av);
- }
- if (strcmp(av[1], "--install") == 0) {
- return do_install(ac, av);
- }
- if (strcmp(av[1], "--open") == 0) {
- return do_open(ac, av);
- }
- if (strcmp(av[1], "-E") == 0) {
- return do_command(ac, av);
- }
- }
- int ret = do_cmake(ac, av);
-#ifdef CMAKE_BUILD_WITH_CMAKE
- cmDynamicLoader::FlushCache();
-#endif
- uv_loop_close(uv_default_loop());
- return ret;
}
int do_cmake(int ac, char const* const* av)
@@ -230,7 +157,7 @@ int do_cmake(int ac, char const* const* av)
return 1;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(ac, av)) {
@@ -381,7 +308,6 @@ int do_cmake(int ac, char const* const* av)
return 0;
}
-namespace {
int extract_job_number(int& index, char const* current, char const* next,
int len_of_flag)
{
@@ -396,7 +322,7 @@ int extract_job_number(int& index, char const* current, char const* next,
unsigned long numJobs = 0;
if (jobString.empty()) {
jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
- } else if (cmSystemTools::StringToULong(jobString.c_str(), &numJobs)) {
+ } else if (cmStrToULong(jobString, &numJobs)) {
if (numJobs == 0) {
std::cerr
<< "The <jobs> value requires a positive integer argument.\n\n";
@@ -411,11 +337,10 @@ int extract_job_number(int& index, char const* current, char const* next,
}
return jobs;
}
-}
-static int do_build(int ac, char const* const* av)
+int do_build(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --build\n";
return -1;
#else
@@ -515,7 +440,7 @@ static int do_build(int ac, char const* const* av)
jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL;
} else {
unsigned long numJobs = 0;
- if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) {
+ if (cmStrToULong(parallel, &numJobs)) {
if (numJobs == 0) {
std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable "
"requires a positive integer argument.\n\n";
@@ -541,7 +466,24 @@ static int do_build(int ac, char const* const* av)
std::cerr <<
"Usage: cmake --build <dir> [options] [-- [native-options]]\n"
"Options:\n"
- CMAKE_BUILD_OPTIONS
+ " <dir> = Project binary directory to be built.\n"
+ " --parallel [<jobs>], -j [<jobs>]\n"
+ " = Build in parallel using the given number of jobs. \n"
+ " If <jobs> is omitted the native build tool's \n"
+ " default number is used.\n"
+ " The CMAKE_BUILD_PARALLEL_LEVEL environment "
+ "variable\n"
+ " specifies a default parallel level when this "
+ "option\n"
+ " is not given.\n"
+ " --target <tgt>..., -t <tgt>... \n"
+ " = Build <tgt> instead of default targets.\n"
+ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
+ " --clean-first = Build target 'clean' first, then build.\n"
+ " (To clean only, use --target 'clean'.)\n"
+ " --verbose, -v = Enable verbose output - if supported - including\n"
+ " the build commands to be executed. \n"
+ " -- = Pass remaining options to the native tool.\n"
;
/* clang-format on */
return 1;
@@ -560,9 +502,9 @@ static int do_build(int ac, char const* const* av)
#endif
}
-static int do_install(int ac, char const* const* av)
+int do_install(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --install\n";
return -1;
#else
@@ -627,8 +569,18 @@ static int do_install(int ac, char const* const* av)
}
if (dir.empty()) {
- std::cerr << "Usage: cmake --install <dir> "
- "[options]\nOptions:\n" CMAKE_INSTALL_OPTIONS;
+ /* clang-format off */
+ std::cerr <<
+ "Usage: cmake --install <dir> [options]\n"
+ "Options:\n"
+ " <dir> = Project binary directory to install.\n"
+ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
+ " --component <comp> = Component-based install. Only install <comp>.\n"
+ " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n"
+ " --strip = Performing install/strip.\n"
+ " -v --verbose = Enable verbose output.\n"
+ ;
+ /* clang-format on */
return 1;
}
@@ -671,9 +623,9 @@ static int do_install(int ac, char const* const* av)
#endif
}
-static int do_open(int ac, char const* const* av)
+int do_open(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --open\n";
return -1;
#else
@@ -713,3 +665,44 @@ static int do_open(int ac, char const* const* av)
return cm.Open(dir, false) ? 0 : 1;
#endif
}
+} // namespace
+
+int main(int ac, char const* const* av)
+{
+ cmSystemTools::EnsureStdPipes();
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+ // Replace streambuf so we can output Unicode to console
+ cmsys::ConsoleBuf::Manager consoleOut(std::cout);
+ consoleOut.SetUTF8Pipes();
+ cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
+ consoleErr.SetUTF8Pipes();
+#endif
+ cmsys::Encoding::CommandLineArguments args =
+ cmsys::Encoding::CommandLineArguments::Main(ac, av);
+ ac = args.argc();
+ av = args.argv();
+
+ cmSystemTools::EnableMSVCDebugHook();
+ cmSystemTools::InitializeLibUV();
+ cmSystemTools::FindCMakeResources(av[0]);
+ if (ac > 1) {
+ if (strcmp(av[1], "--build") == 0) {
+ return do_build(ac, av);
+ }
+ if (strcmp(av[1], "--install") == 0) {
+ return do_install(ac, av);
+ }
+ if (strcmp(av[1], "--open") == 0) {
+ return do_open(ac, av);
+ }
+ if (strcmp(av[1], "-E") == 0) {
+ return do_command(ac, av);
+ }
+ }
+ int ret = do_cmake(ac, av);
+#ifndef CMAKE_BOOTSTRAP
+ cmDynamicLoader::FlushCache();
+#endif
+ uv_loop_close(uv_default_loop());
+ return ret;
+}
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 19d0d3843..caf645301 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -18,13 +18,15 @@
// /showIncludes is equivalent to -MD, not -MMD, that is, system headers are
// included.
-#include "cmSystemTools.h"
-#include "cmsys/Encoding.hxx"
-
#include <algorithm>
#include <sstream>
+
#include <windows.h>
+#include "cmsys/Encoding.hxx"
+
+#include "cmSystemTools.h"
+
// We don't want any wildcard expansion.
// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx
void _setargv()
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 86082e517..d05e3c81b 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -13,42 +13,47 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmServer.h"
# include "cmServerConnection.h"
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
-# include "bindexplib.h"
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "cmsys/ConsoleBuf.hxx"
+
+# include "cmFileTime.h"
+
+# include "bindexplib.h"
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
# include "cmVisualStudioWCEPlatformParser.h"
#endif
-#include "cmsys/Directory.hxx"
-#include "cmsys/FStream.hxx"
-#include "cmsys/Process.h"
-#include "cmsys/Terminal.h"
-#include <algorithm>
#include <array>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#include <iostream>
-#include <iterator>
-#include <memory> // IWYU pragma: keep
+#include <memory>
#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
#include <utility>
+#include <cm/string_view>
+
+#include "cmsys/Directory.hxx"
+#include "cmsys/FStream.hxx"
+#include "cmsys/Process.h"
+#include "cmsys/Terminal.h"
+
class cmConnection;
int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
@@ -60,7 +65,7 @@ void CMakeCommandUsage(const char* program)
{
std::ostringstream errorStream;
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
/* clang-format off */
errorStream
<< "cmake version " << cmVersion::GetCMakeVersion() << "\n";
@@ -114,6 +119,8 @@ void CMakeCommandUsage(const char* program)
<< " touch <file>... - touch a <file>.\n"
<< " touch_nocreate <file>... - touch a <file> but do not create it.\n"
<< " create_symlink old new - create a symbolic link new -> old\n"
+ << " true - do nothing with an exit code of 0\n"
+ << " false - do nothing with an exit code of 1\n"
#if defined(_WIN32) && !defined(__CYGWIN__)
<< "Available on Windows only:\n"
<< " delete_regv key - delete registry value\n"
@@ -171,8 +178,7 @@ static int HandleIWYU(const std::string& runCmd,
{
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
- std::vector<std::string> iwyu_cmd;
- cmSystemTools::ExpandListArgument(runCmd, iwyu_cmd, true);
+ std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
// Ignore its return code because the tool always returns non-zero.
@@ -201,8 +207,7 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
// automatically skip over the compiler itself and extract the
// options.
int ret;
- std::vector<std::string> tidy_cmd =
- cmSystemTools::ExpandedListArgument(runCmd, true);
+ std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
tidy_cmd.push_back(sourceFile);
tidy_cmd.emplace_back("--");
cmAppend(tidy_cmd, orig_cmd);
@@ -262,8 +267,7 @@ static int HandleCppLint(const std::string& runCmd,
const std::vector<std::string>&)
{
// Construct the cpplint command line.
- std::vector<std::string> cpplint_cmd;
- cmSystemTools::ExpandListArgument(runCmd, cpplint_cmd, true);
+ std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
cpplint_cmd.push_back(sourceFile);
// Run the cpplint command line. Capture its output.
@@ -291,8 +295,7 @@ static int HandleCppCheck(const std::string& runCmd,
const std::vector<std::string>& orig_cmd)
{
// Construct the cpplint command line.
- std::vector<std::string> cppcheck_cmd;
- cmSystemTools::ExpandListArgument(runCmd, cppcheck_cmd, true);
+ std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
// extract all the -D, -U, and -I options from the compile line
for (auto const& opt : orig_cmd) {
if (opt.size() > 2) {
@@ -342,8 +345,8 @@ static int HandleCppCheck(const std::string& runCmd,
return ret;
}
-typedef int (*CoCompileHandler)(const std::string&, const std::string&,
- const std::vector<std::string>&);
+using CoCompileHandler = int (*)(const std::string&, const std::string&,
+ const std::vector<std::string>&);
struct CoCompiler
{
@@ -405,7 +408,7 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
if (cmHasLiteralPrefix(arg, "--source=")) {
sourceFile = arg.substr(9);
} else if (cmHasLiteralPrefix(arg, "--launcher=")) {
- cmSystemTools::ExpandListArgument(arg.substr(11), launchers, true);
+ cmExpandList(arg.substr(11), launchers, true);
} else {
// if it was not a co-compiler or --source/--launcher then error
std::cerr << "__run_co_compile given unknown argument: " << arg
@@ -558,17 +561,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
else if (args[1] == "__create_def") {
if (args.size() < 4) {
- std::cerr
- << "__create_def Usage: -E __create_def outfile.def objlistfile\n";
- return 1;
- }
- FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
- if (!fout) {
- std::cerr << "could not open output .def file: " << args[2].c_str()
- << "\n";
+ std::cerr << "__create_def Usage: -E __create_def outfile.def "
+ "objlistfile [-nm=nm-path]\n";
return 1;
}
cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
@@ -577,9 +574,41 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
<< "\n";
return 1;
}
- std::string file;
+ std::vector<std::string> files;
+ {
+ std::string file;
+ cmFileTime outTime;
+ bool outValid = outTime.Load(args[2]);
+ while (cmSystemTools::GetLineFromStream(fin, file)) {
+ files.push_back(file);
+ if (outValid) {
+ cmFileTime inTime;
+ outValid = inTime.Load(file) && inTime.Older(outTime);
+ }
+ }
+ if (outValid) {
+ // The def file already exists and all input files are older than the
+ // existing def file.
+ return 0;
+ }
+ }
+ FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+ if (!fout) {
+ std::cerr << "could not open output .def file: " << args[2].c_str()
+ << "\n";
+ return 1;
+ }
bindexplib deffile;
- while (cmSystemTools::GetLineFromStream(fin, file)) {
+ if (args.size() >= 5) {
+ auto a = args[4];
+ if (cmHasLiteralPrefix(a, "--nm=")) {
+ deffile.SetNmPath(a.substr(5));
+ std::cerr << a.substr(5) << "\n";
+ } else {
+ std::cerr << "unknown argument: " << a << "\n";
+ }
+ }
+ for (auto const& file : files) {
std::string const& ext = cmSystemTools::GetFilenameLastExtension(file);
if (cmSystemTools::LowerCase(ext) == ".def") {
if (!deffile.AddDefinitionFile(file.c_str())) {
@@ -651,7 +680,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 1;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args[1] == "environment") {
for (auto const& env : cmSystemTools::GetEnvironmentVariables()) {
std::cout << env << std::endl;
@@ -676,10 +705,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
// If an error occurs, we want to continue removing directories.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (cmSystemTools::FileIsDirectory(arg) &&
- !cmSystemTools::RemoveADirectory(arg)) {
- std::cerr << "Error removing directory \"" << arg << "\".\n";
- return_value = true;
+ if (cmSystemTools::FileIsDirectory(arg)) {
+ if (cmSystemTools::FileIsSymlink(arg)) {
+ if (!cmSystemTools::RemoveFile(arg)) {
+ std::cerr << "Error removing directory symlink \"" << arg
+ << "\".\n";
+ return_value = true;
+ }
+ } else if (!cmSystemTools::RemoveADirectory(arg)) {
+ std::cerr << "Error removing directory \"" << arg << "\".\n";
+ return_value = true;
+ }
}
}
return return_value;
@@ -763,8 +799,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
if (args[1] == "time" && args.size() > 2) {
std::vector<std::string> command(args.begin() + 2, args.end());
- clock_t clock_start, clock_finish;
- time_t time_start, time_finish;
+ clock_t clock_start;
+ clock_t clock_finish;
+ time_t time_start;
+ time_t time_finish;
time(&time_start);
clock_start = clock();
@@ -835,8 +873,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
// Command to start progress for a build
if (args[1] == "cmake_progress_start" && args.size() == 4) {
// basically remove the directory
- std::string dirName = args[2];
- dirName += "/Progress";
+ std::string dirName = cmStrCat(args[2], "/Progress");
cmSystemTools::RemoveADirectory(dirName);
// is the last argument a filename that exists?
@@ -853,8 +890,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
if (count) {
cmSystemTools::MakeDirectory(dirName);
// write the count into the directory
- std::string fName = dirName;
- fName += "/count.txt";
+ std::string fName = cmStrCat(dirName, "/count.txt");
FILE* progFile = cmsys::SystemTools::Fopen(fName, "w");
if (progFile) {
fprintf(progFile, "%i\n", count);
@@ -891,6 +927,16 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
+ // Command to do nothing with an exit code of 0.
+ if (args[1] == "true") {
+ return 0;
+ }
+
+ // Command to do nothing with an exit code of 1.
+ if (args[1] == "false") {
+ return 1;
+ }
+
// Internal CMake shared library support.
if (args[1] == "cmake_symlink_library" && args.size() == 5) {
return cmcmd::SymlinkLibrary(args);
@@ -933,8 +979,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
if (args.size() >= 9 && args[8].length() >= 8 &&
args[8].substr(0, 8) == "--color=") {
// Enable or disable color based on the switch value.
- color =
- (args[8].size() == 8 || cmSystemTools::IsOn(args[8].substr(8)));
+ color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
}
} else {
// Support older signature for existing makefiles:
@@ -981,7 +1026,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return cmcmd::ExecuteLinkScript(args);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Internal CMake ninja dependency scanning support.
if (args[1] == "cmake_ninja_depends") {
return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
@@ -1016,21 +1061,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return cmcmd::ExecuteEchoColor(args);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
- cmQtAutoMocUic autoGen;
- std::string const& infoDir = args[2];
- std::string const& config = args[3];
- return autoGen.Run(infoDir, config) ? 0 : 1;
+ cm::string_view const infoFile = args[2];
+ cm::string_view const config = args[3];
+ return cmQtAutoMocUic(infoFile, config) ? 0 : 1;
}
if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) {
- cmQtAutoRcc autoGen;
- std::string const& infoFile = args[2];
- std::string config;
- if (args.size() > 3) {
- config = args[3];
- }
- return autoGen.Run(infoFile, config) ? 0 : 1;
+ cm::string_view const infoFile = args[2];
+ cm::string_view const config =
+ (args.size() > 3) ? cm::string_view(args[3]) : cm::string_view();
+ return cmQtAutoRcc(infoFile, config) ? 0 : 1;
}
#endif
@@ -1063,11 +1104,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
}
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
- bool isKnown =
- std::find(cm::cbegin(knownFormats), cm::cend(knownFormats),
- format) != cm::cend(knownFormats);
-
- if (!isKnown) {
+ if (!cmContains(knownFormats, format)) {
cmSystemTools::Error("Unknown -E tar --format= argument: " +
format);
return 1;
@@ -1197,7 +1234,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 1;
}
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmConnection* conn;
if (isDebug) {
conn = new cmServerStdIoConnection;
@@ -1218,7 +1255,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 1;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Internal CMake Fortran module support.
if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) {
return cmDependsFortran::CopyModule(args) ? 0 : 1;
@@ -1339,14 +1376,12 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link)
static void cmcmdProgressReport(std::string const& dir, std::string const& num)
{
- std::string dirName = dir;
- dirName += "/Progress";
+ std::string dirName = cmStrCat(dir, "/Progress");
std::string fName;
FILE* progFile;
// read the count
- fName = dirName;
- fName += "/count.txt";
+ fName = cmStrCat(dirName, "/count.txt");
progFile = cmsys::SystemTools::Fopen(fName, "r");
int count = 0;
if (!progFile) {
@@ -1361,8 +1396,7 @@ static void cmcmdProgressReport(std::string const& dir, std::string const& num)
for (const char* c = last;; ++c) {
if (*c == ',' || *c == '\0') {
if (c != last) {
- fName = dirName;
- fName += "/";
+ fName = cmStrCat(dirName, '/');
fName.append(last, c - last);
progFile = cmsys::SystemTools::Fopen(fName, "w");
if (progFile) {
@@ -1399,7 +1433,7 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
// Enable or disable color based on the switch value.
std::string value = arg.substr(9);
if (!value.empty()) {
- enabled = cmSystemTools::IsOn(value);
+ enabled = cmIsOn(value);
}
} else if (cmHasLiteralPrefix(arg, "--progress-dir=")) {
progressDir = arg.substr(15);
@@ -1451,7 +1485,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
bool verbose = false;
if (args.size() >= 4) {
if (args[3].find("--verbose=") == 0) {
- if (!cmSystemTools::IsOff(args[3].substr(10))) {
+ if (!cmIsOff(args[3].substr(10))) {
verbose = true;
}
}
@@ -1534,7 +1568,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
cmVisualStudioWCEPlatformParser parser(name.c_str());
parser.ParseVersion(version);
if (parser.Found()) {
@@ -1592,7 +1626,7 @@ private:
// still works.
int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
{
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we output in the system codepage. CMake is set up
// to output in Unicode (see SetUTF8Pipes) but the Visual Studio linker
// outputs using the system codepage so we need to change behavior when
@@ -1698,7 +1732,7 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
{
// Parse our own arguments.
std::string intDir;
- std::vector<std::string>::const_iterator arg = argBeg;
+ auto arg = argBeg;
while (arg != argEnd && cmHasLiteralPrefix(*arg, "-")) {
if (*arg == "--") {
++arg;
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 69a7ecbb1..17f2f9a52 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -4,11 +4,12 @@
#define cmcmd_h
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmCryptoHash.h"
#include <string>
#include <vector>
+#include "cmCryptoHash.h"
+
class cmcmd
{
public:
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 3b3630fc9..0d65902ef 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -1,18 +1,19 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "CTest/cmCTestLaunch.h"
-#include "CTest/cmCTestScriptHandler.h"
+#include "cmsys/Encoding.hxx"
+
#include "cmCTest.h"
#include "cmDocumentation.h"
#include "cmSystemTools.h"
-#include "cmsys/Encoding.hxx"
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#include "CTest/cmCTestLaunch.h"
+#include "CTest/cmCTestScriptHandler.h"
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
+#include <cstring>
#include <iostream>
-#include <string.h>
#include <string>
#include <vector>
@@ -83,7 +84,9 @@ static const char* cmDocumentationOptions[][2] = {
{ "-T <action>, --test-action <action>",
"Sets the dashboard action to "
"perform" },
- { "--track <track>", "Specify the track to submit dashboard to" },
+ { "--group <group>",
+ "Specify what build group on the dashboard you'd like to "
+ "submit results to." },
{ "-S <script>, --script <script>",
"Execute a dashboard for a "
"configuration" },
@@ -100,6 +103,7 @@ static const char* cmDocumentationOptions[][2] = {
"times without failing in order to pass" },
{ "--max-width <width>", "Set the max width for a test name to output" },
{ "--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1." },
+ { "--resource-spec-file <file>", "Set the resource spec file to use." },
{ "--no-label-summary", "Disable timing summary information for labels." },
{ "--no-subproject-summary",
"Disable timing summary information for "
@@ -144,7 +148,7 @@ static const char* cmDocumentationOptions[][2] = {
int main(int argc, char const* const* argv)
{
cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we can output Unicode to console
cmsys::ConsoleBuf::Manager consoleOut(std::cout);
consoleOut.SetUTF8Pipes();
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 79e813eef..09bcdb943 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -121,8 +121,8 @@ if(KWSYS_CXX_STANDARD)
set(CMAKE_CXX_STANDARD "${KWSYS_CXX_STANDARD}")
elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
- AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"
- AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU"
+ AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"
+ AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU"
)
set(CMAKE_CXX_STANDARD 14)
else()
@@ -1013,7 +1013,7 @@ 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
- (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"))))
+ (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))))
ADD_DEFINITIONS(
-D_CRT_NONSTDC_NO_DEPRECATE
-D_CRT_SECURE_NO_DEPRECATE
@@ -1104,7 +1104,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf.cxx
)
- IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" 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()
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index a97f7a836..3fd195561 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -67,10 +67,10 @@ class CommandLineArgumentsInternal
{
public:
CommandLineArgumentsInternal()
+ : UnknownArgumentCallback{ nullptr }
+ , ClientData{ nullptr }
+ , LastArgument{ 0 }
{
- this->UnknownArgumentCallback = KWSYS_NULLPTR;
- this->ClientData = KWSYS_NULLPTR;
- this->LastArgument = 0;
}
typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
@@ -187,7 +187,7 @@ int CommandLineArguments::Parse()
switch (cs->ArgumentType) {
case NO_ARGUMENT:
// No value
- if (!this->PopulateVariable(cs, KWSYS_NULLPTR)) {
+ if (!this->PopulateVariable(cs, nullptr)) {
return 0;
}
break;
@@ -340,7 +340,7 @@ void CommandLineArguments::AddCallback(const char* argument,
s.Callback = callback;
s.CallData = call_data;
s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
- s.Variable = KWSYS_NULLPTR;
+ s.Variable = nullptr;
s.Help = help;
this->Internals->Callbacks[argument] = s;
@@ -355,8 +355,8 @@ void CommandLineArguments::AddArgument(const char* argument,
CommandLineArgumentsCallbackStructure s;
s.Argument = argument;
s.ArgumentType = type;
- s.Callback = KWSYS_NULLPTR;
- s.CallData = KWSYS_NULLPTR;
+ s.Callback = nullptr;
+ s.CallData = nullptr;
s.VariableType = vtype;
s.Variable = variable;
s.Help = help;
@@ -427,7 +427,7 @@ const char* CommandLineArguments::GetHelp(const char* arg)
CommandLineArguments::Internal::CallbacksMap::iterator it =
this->Internals->Callbacks.find(arg);
if (it == this->Internals->Callbacks.end()) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
// Since several arguments may point to the same argument, find the one this
@@ -621,7 +621,7 @@ void CommandLineArguments::PopulateVariable(bool* variable,
void CommandLineArguments::PopulateVariable(int* variable,
const std::string& value)
{
- char* res = KWSYS_NULLPTR;
+ char* res = nullptr;
*variable = static_cast<int>(strtol(value.c_str(), &res, 10));
// if ( res && *res )
// {
@@ -632,7 +632,7 @@ void CommandLineArguments::PopulateVariable(int* variable,
void CommandLineArguments::PopulateVariable(double* variable,
const std::string& value)
{
- char* res = KWSYS_NULLPTR;
+ char* res = nullptr;
*variable = strtod(value.c_str(), &res);
// if ( res && *res )
// {
@@ -669,7 +669,7 @@ void CommandLineArguments::PopulateVariable(std::vector<bool>* variable,
void CommandLineArguments::PopulateVariable(std::vector<int>* variable,
const std::string& value)
{
- char* res = KWSYS_NULLPTR;
+ char* res = nullptr;
variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
// if ( res && *res )
// {
@@ -680,7 +680,7 @@ void CommandLineArguments::PopulateVariable(std::vector<int>* variable,
void CommandLineArguments::PopulateVariable(std::vector<double>* variable,
const std::string& value)
{
- char* res = KWSYS_NULLPTR;
+ char* res = nullptr;
variable->push_back(strtod(value.c_str(), &res));
// if ( res && *res )
// {
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 92ffea3c9..29a2dd11e 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -58,7 +58,6 @@
# define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
# define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH
-# define KWSYS_NULLPTR @KWSYS_NAMESPACE@_NULLPTR
# define KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP \
@KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP
#endif
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
index 73a1efb25..49dbdf7ea 100644
--- a/Source/kwsys/ConsoleBuf.hxx.in
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -116,7 +116,7 @@ protected:
DWORD charsWritten;
success =
::WriteConsoleW(m_hOutput, wbuffer.c_str(), (DWORD)wbuffer.size(),
- &charsWritten, NULL) == 0
+ &charsWritten, nullptr) == 0
? false
: true;
} else {
@@ -124,8 +124,9 @@ protected:
std::string buffer;
success = encodeOutputBuffer(wbuffer, buffer);
if (success) {
- success = ::WriteFile(m_hOutput, buffer.c_str(),
- (DWORD)buffer.size(), &bytesWritten, NULL) == 0
+ success =
+ ::WriteFile(m_hOutput, buffer.c_str(), (DWORD)buffer.size(),
+ &bytesWritten, nullptr) == 0
? false
: true;
}
@@ -152,7 +153,7 @@ protected:
DWORD charsRead;
if (ReadConsoleW(m_hInput, wbuffer,
(sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead,
- NULL) == 0 ||
+ nullptr) == 0 ||
charsRead == 0) {
_setg(true);
return Traits::eof();
@@ -168,7 +169,7 @@ protected:
return Traits::eof();
}
char* buffer = new char[size.LowPart];
- while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, NULL) ==
+ while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) ==
0) {
if (GetLastError() == ERROR_MORE_DATA) {
strbuffer += std::string(buffer, bytesRead);
@@ -327,11 +328,12 @@ private:
}
const int length =
WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
- (int)wbuffer.size(), NULL, 0, NULL, NULL);
+ (int)wbuffer.size(), nullptr, 0, nullptr, nullptr);
char* buf = new char[length];
const bool success =
WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(),
- (int)wbuffer.size(), buf, length, NULL, NULL) > 0
+ (int)wbuffer.size(), buf, length, nullptr,
+ nullptr) > 0
? true
: false;
buffer = std::string(buf, length);
@@ -356,7 +358,7 @@ private:
length -= BOMsize;
}
const size_t wlength = static_cast<size_t>(MultiByteToWideChar(
- actualCodepage, 0, data, static_cast<int>(length), NULL, 0));
+ actualCodepage, 0, data, static_cast<int>(length), nullptr, 0));
wchar_t* wbuf = new wchar_t[wlength];
const bool success =
MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length),
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index 59530a43f..e3791826b 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -48,7 +48,7 @@ unsigned long Directory::GetNumberOfFiles() const
const char* Directory::GetFile(unsigned long dindex) const
{
if (dindex >= this->Internal->Files.size()) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
return this->Internal->Files[dindex].c_str();
}
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index b93a215cc..a4b864118 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -223,15 +223,15 @@ namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
const std::string& libname, int flags)
{
- CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, NULL);
+ CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, nullptr);
DWORD llFlags = 0;
if (flags & SearchBesideLibrary) {
llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH;
}
- return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), NULL,
- llFlags);
+ return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(),
+ nullptr, llFlags);
}
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
@@ -289,9 +289,9 @@ const char* DynamicLoader::LastError()
DWORD error = GetLastError();
DWORD length = FormatMessageW(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL);
+ lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, nullptr);
static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1];
@@ -305,7 +305,7 @@ const char* DynamicLoader::LastError()
}
if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str,
- DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) {
+ DYNLOAD_ERROR_BUFFER_SIZE, nullptr, nullptr)) {
/* WideCharToMultiByte failed. Use a default message. */
_snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE,
"DynamicLoader encountered error 0x%X. "
@@ -372,7 +372,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
DynamicLoader::SymbolPointer psym;
} result;
- result.psym = NULL;
+ result.psym = nullptr;
if (!lib) {
last_dynamic_err = B_BAD_VALUE;
@@ -384,7 +384,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid);
if (rc != B_OK) {
last_dynamic_err = rc;
- result.psym = NULL;
+ result.psym = nullptr;
}
}
return result.psym;
@@ -412,7 +412,7 @@ namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
const std::string& libname, int flags)
{
- CHECK_OPEN_FLAGS(flags, 0, NULL);
+ CHECK_OPEN_FLAGS(flags, 0, nullptr);
char* name = (char*)calloc(1, libname.size() + 1);
dld_init(program_invocation_name);
@@ -458,7 +458,7 @@ namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
const std::string& libname, int flags)
{
- CHECK_OPEN_FLAGS(flags, 0, NULL);
+ CHECK_OPEN_FLAGS(flags, 0, nullptr);
return dlopen(libname.c_str(), RTLD_LAZY);
}
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 251deef3d..4593c9251 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -65,7 +65,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac,
for (int i = 0; i < ac; i++) {
this->argv_[i] = strdup(av[i]);
}
- this->argv_[ac] = KWSYS_NULLPTR;
+ this->argv_[ac] = nullptr;
}
Encoding::CommandLineArguments::CommandLineArguments(int ac,
@@ -75,7 +75,7 @@ Encoding::CommandLineArguments::CommandLineArguments(int ac,
for (int i = 0; i < ac; i++) {
this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
}
- this->argv_[ac] = KWSYS_NULLPTR;
+ this->argv_[ac] = nullptr;
}
Encoding::CommandLineArguments::~CommandLineArguments()
@@ -90,7 +90,7 @@ Encoding::CommandLineArguments::CommandLineArguments(
{
this->argv_.resize(other.argv_.size());
for (size_t i = 0; i < this->argv_.size(); i++) {
- this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR;
+ this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr;
}
}
@@ -105,7 +105,7 @@ Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=(
this->argv_.resize(other.argv_.size());
for (i = 0; i < this->argv_.size(); i++) {
- this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : KWSYS_NULLPTR;
+ this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr;
}
}
@@ -128,8 +128,9 @@ std::wstring Encoding::ToWide(const std::string& str)
{
std::wstring wstr;
# if defined(_WIN32)
- const int wlength = MultiByteToWideChar(
- KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), int(str.size()), NULL, 0);
+ const int wlength =
+ MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
+ int(str.size()), nullptr, 0);
if (wlength > 0) {
wchar_t* wdata = new wchar_t[wlength];
int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
@@ -162,12 +163,12 @@ std::string Encoding::ToNarrow(const std::wstring& str)
# if defined(_WIN32)
int length =
WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
- int(str.size()), NULL, 0, NULL, NULL);
+ int(str.size()), nullptr, 0, nullptr, nullptr);
if (length > 0) {
char* data = new char[length];
int r =
WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
- int(str.size()), data, length, NULL, NULL);
+ int(str.size()), data, length, nullptr, nullptr);
if (r > 0) {
nstr = std::string(data, length);
}
@@ -193,7 +194,7 @@ std::string Encoding::ToNarrow(const std::wstring& str)
std::wstring Encoding::ToWide(const char* cstr)
{
std::wstring wstr;
- size_t length = kwsysEncoding_mbstowcs(KWSYS_NULLPTR, cstr, 0) + 1;
+ size_t length = kwsysEncoding_mbstowcs(nullptr, cstr, 0) + 1;
if (length > 0) {
std::vector<wchar_t> wchars(length);
if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) {
@@ -206,7 +207,7 @@ std::wstring Encoding::ToWide(const char* cstr)
std::string Encoding::ToNarrow(const wchar_t* wcstr)
{
std::string str;
- size_t length = kwsysEncoding_wcstombs(KWSYS_NULLPTR, wcstr, 0) + 1;
+ size_t length = kwsysEncoding_wcstombs(nullptr, wcstr, 0) + 1;
if (length > 0) {
std::vector<char> chars(length);
if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) {
@@ -227,9 +228,9 @@ std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
/* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
* won't return a large enough buffer size if the input is too small */
- wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, nullptr, nullptr) + 3;
std::vector<wchar_t> wfull(wfull_len);
- GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], nullptr);
/* This should get the correct size without any extra padding from the
* previous size workaround. */
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 829c1389f..34bb0d0fe 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -431,7 +431,7 @@ void Glob::SetRelative(const char* dir)
const char* Glob::GetRelative()
{
if (this->Relative.empty()) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
return this->Relative.c_str();
}
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 4c3bde167..170766f4b 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -54,7 +54,7 @@ public:
~Glob();
//! Find all files that match the pattern.
- bool FindFiles(const std::string& inexpr, GlobMessages* messages = 0);
+ bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr);
//! Return the list of files that matched.
std::vector<std::string>& GetFiles();
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 5f84b1946..5e6f8da50 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -37,7 +37,7 @@ namespace KWSYS_NAMESPACE {
RegularExpression::RegularExpression(const RegularExpression& rxp)
{
if (!rxp.program) {
- this->program = KWSYS_NULLPTR;
+ this->program = nullptr;
return;
}
int ind;
@@ -48,7 +48,7 @@ RegularExpression::RegularExpression(const RegularExpression& rxp)
// Copy pointers into last successful "find" operation
this->regmatch = rxp.regmatch;
this->regmust = rxp.regmust; // Copy field
- if (rxp.regmust != KWSYS_NULLPTR) {
+ if (rxp.regmust != nullptr) {
char* dum = rxp.program;
ind = 0;
while (dum != rxp.regmust) {
@@ -69,7 +69,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp)
return *this;
}
if (!rxp.program) {
- this->program = KWSYS_NULLPTR;
+ this->program = nullptr;
return *this;
}
int ind;
@@ -81,7 +81,7 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp)
// Copy pointers into last successful "find" operation
this->regmatch = rxp.regmatch;
this->regmust = rxp.regmust; // Copy field
- if (rxp.regmust != KWSYS_NULLPTR) {
+ if (rxp.regmust != nullptr) {
char* dum = rxp.program;
ind = 0;
while (dum != rxp.regmust) {
@@ -164,8 +164,8 @@ bool RegularExpression::deep_equal(const RegularExpression& rxp) const
*
* regstart char that must begin a match; '\0' if none obvious
* reganch is the match anchored (at beginning-of-line only)?
- * regmust string (pointer into program) that match must include, or NULL
- * regmlen length of regmust string
+ * regmust string (pointer into program) that match must include, or
+ * nullptr regmlen length of regmust string
*
* Regstart and reganch permit very fast decisions on suitable starting points
* for a match, cutting down the work a lot. Regmust permits fast rejection
@@ -337,10 +337,9 @@ bool RegularExpression::compile(const char* exp)
{
const char* scan;
const char* longest;
- size_t len;
int flags;
- if (exp == KWSYS_NULLPTR) {
+ if (exp == nullptr) {
// RAISE Error, SYM(RegularExpression), SYM(No_Expr),
printf("RegularExpression::compile(): No expression supplied.\n");
return false;
@@ -368,13 +367,13 @@ bool RegularExpression::compile(const char* exp)
// Allocate space.
//#ifndef _WIN32
- if (this->program != KWSYS_NULLPTR)
+ if (this->program != nullptr)
delete[] this->program;
//#endif
this->program = new char[comp.regsize];
this->progsize = static_cast<int>(comp.regsize);
- if (this->program == KWSYS_NULLPTR) {
+ if (this->program == nullptr) {
// RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
printf("RegularExpression::compile(): Out of memory.\n");
return false;
@@ -390,7 +389,7 @@ bool RegularExpression::compile(const char* exp)
// Dig out information for optimizations.
this->regstart = '\0'; // Worst-case defaults.
this->reganch = 0;
- this->regmust = KWSYS_NULLPTR;
+ this->regmust = nullptr;
this->regmlen = 0;
scan = this->program + 1; // First BRANCH.
if (OP(regnext(scan)) == END) { // Only one top-level choice.
@@ -411,9 +410,9 @@ bool RegularExpression::compile(const char* exp)
// absence of others.
//
if (flags & SPSTART) {
- longest = KWSYS_NULLPTR;
- len = 0;
- for (; scan != KWSYS_NULLPTR; scan = regnext(scan))
+ longest = nullptr;
+ size_t len = 0;
+ for (; scan != nullptr; scan = regnext(scan))
if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
longest = OPERAND(scan);
len = strlen(OPERAND(scan));
@@ -449,19 +448,19 @@ char* RegExpCompile::reg(int paren, int* flagp)
if (regnpar >= RegularExpressionMatch::NSUBEXP) {
// RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
printf("RegularExpression::compile(): Too many parentheses.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
parno = regnpar;
regnpar++;
ret = regnode(static_cast<char>(OPEN + parno));
} else
- ret = KWSYS_NULLPTR;
+ ret = nullptr;
// Pick up the branches, linking them together.
br = regbranch(&flags);
- if (br == KWSYS_NULLPTR)
- return (KWSYS_NULLPTR);
- if (ret != KWSYS_NULLPTR)
+ if (br == nullptr)
+ return (nullptr);
+ if (ret != nullptr)
regtail(ret, br); // OPEN -> first.
else
ret = br;
@@ -471,8 +470,8 @@ char* RegExpCompile::reg(int paren, int* flagp)
while (*regparse == '|') {
regparse++;
br = regbranch(&flags);
- if (br == KWSYS_NULLPTR)
- return (KWSYS_NULLPTR);
+ if (br == nullptr)
+ return (nullptr);
regtail(ret, br); // BRANCH -> BRANCH.
if (!(flags & HASWIDTH))
*flagp &= ~HASWIDTH;
@@ -484,23 +483,23 @@ char* RegExpCompile::reg(int paren, int* flagp)
regtail(ret, ender);
// Hook the tails of the branches to the closing node.
- for (br = ret; br != KWSYS_NULLPTR; br = regnext(br))
+ for (br = ret; br != nullptr; br = regnext(br))
regoptail(br, ender);
// Check for proper termination.
if (paren && *regparse++ != ')') {
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
printf("RegularExpression::compile(): Unmatched parentheses.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
} else if (!paren && *regparse != '\0') {
if (*regparse == ')') {
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
printf("RegularExpression::compile(): Unmatched parentheses.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
} else {
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf("RegularExpression::compile(): Internal error.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
// NOTREACHED
}
@@ -522,19 +521,19 @@ char* RegExpCompile::regbranch(int* flagp)
*flagp = WORST; // Tentatively.
ret = regnode(BRANCH);
- chain = KWSYS_NULLPTR;
+ chain = nullptr;
while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
latest = regpiece(&flags);
- if (latest == KWSYS_NULLPTR)
- return (KWSYS_NULLPTR);
+ if (latest == nullptr)
+ return (nullptr);
*flagp |= flags & HASWIDTH;
- if (chain == KWSYS_NULLPTR) // First piece.
+ if (chain == nullptr) // First piece.
*flagp |= flags & SPSTART;
else
regtail(chain, latest);
chain = latest;
}
- if (chain == KWSYS_NULLPTR) // Loop ran zero times.
+ if (chain == nullptr) // Loop ran zero times.
regnode(NOTHING);
return (ret);
@@ -557,8 +556,8 @@ char* RegExpCompile::regpiece(int* flagp)
int flags;
ret = regatom(&flags);
- if (ret == KWSYS_NULLPTR)
- return (KWSYS_NULLPTR);
+ if (ret == nullptr)
+ return (nullptr);
op = *regparse;
if (!ISMULT(op)) {
@@ -569,7 +568,7 @@ char* RegExpCompile::regpiece(int* flagp)
if (!(flags & HASWIDTH) && op != '?') {
// RAISE Error, SYM(RegularExpression), SYM(Empty_Operand),
printf("RegularExpression::compile() : *+ operand could be empty.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
*flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
@@ -603,7 +602,7 @@ char* RegExpCompile::regpiece(int* flagp)
if (ISMULT(*regparse)) {
// RAISE Error, SYM(RegularExpression), SYM(Nested_Operand),
printf("RegularExpression::compile(): Nested *?+.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
return (ret);
}
@@ -656,7 +655,7 @@ char* RegExpCompile::regatom(int* flagp)
if (rxpclass > rxpclassend + 1) {
// RAISE Error, SYM(RegularExpression), SYM(Invalid_Range),
printf("RegularExpression::compile(): Invalid range in [].\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
for (; rxpclass <= rxpclassend; rxpclass++)
regc(static_cast<char>(rxpclass));
@@ -669,15 +668,15 @@ char* RegExpCompile::regatom(int* flagp)
if (*regparse != ']') {
// RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket),
printf("RegularExpression::compile(): Unmatched [].\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
regparse++;
*flagp |= HASWIDTH | SIMPLE;
} break;
case '(':
ret = reg(1, &flags);
- if (ret == KWSYS_NULLPTR)
- return (KWSYS_NULLPTR);
+ if (ret == nullptr)
+ return (nullptr);
*flagp |= flags & (HASWIDTH | SPSTART);
break;
case '\0':
@@ -685,18 +684,18 @@ char* RegExpCompile::regatom(int* flagp)
case ')':
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf("RegularExpression::compile(): Internal error.\n"); // Never here
- return KWSYS_NULLPTR;
+ return nullptr;
case '?':
case '+':
case '*':
// RAISE Error, SYM(RegularExpression), SYM(No_Operand),
printf("RegularExpression::compile(): ?+* follows nothing.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
case '\\':
if (*regparse == '\0') {
// RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash),
printf("RegularExpression::compile(): Trailing backslash.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
ret = regnode(EXACTLY);
regc(*regparse++);
@@ -712,7 +711,7 @@ char* RegExpCompile::regatom(int* flagp)
if (len <= 0) {
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf("RegularExpression::compile(): Internal error.\n");
- return KWSYS_NULLPTR;
+ return nullptr;
}
ender = *(regparse + len);
if (len > 1 && ISMULT(ender))
@@ -810,7 +809,7 @@ void RegExpCompile::regtail(char* p, const char* val)
scan = p;
for (;;) {
temp = regnext(scan);
- if (temp == KWSYS_NULLPTR)
+ if (temp == nullptr)
break;
scan = temp;
}
@@ -829,7 +828,7 @@ void RegExpCompile::regtail(char* p, const char* val)
void RegExpCompile::regoptail(char* p, const char* val)
{
// "Operandless" and "op != BRANCH" are synonymous in practice.
- if (p == KWSYS_NULLPTR || p == regdummyptr || OP(p) != BRANCH)
+ if (p == nullptr || p == regdummyptr || OP(p) != BRANCH)
return;
regtail(OPERAND(p), val);
}
@@ -879,14 +878,14 @@ bool RegularExpression::find(char const* string,
}
// If there is a "must appear" string, look for it.
- if (this->regmust != KWSYS_NULLPTR) {
+ if (this->regmust != nullptr) {
s = string;
- while ((s = strchr(s, this->regmust[0])) != KWSYS_NULLPTR) {
+ while ((s = strchr(s, this->regmust[0])) != nullptr) {
if (strncmp(s, this->regmust, this->regmlen) == 0)
break; // Found it.
s++;
}
- if (s == KWSYS_NULLPTR) // Not present.
+ if (s == nullptr) // Not present.
return false;
}
@@ -904,7 +903,7 @@ bool RegularExpression::find(char const* string,
s = string;
if (this->regstart != '\0')
// We know what char it must start with.
- while ((s = strchr(s, this->regstart)) != KWSYS_NULLPTR) {
+ while ((s = strchr(s, this->regstart)) != nullptr) {
if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program))
return true;
s++;
@@ -938,8 +937,8 @@ int RegExpFind::regtry(const char* string, const char** start,
sp1 = start;
ep = end;
for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) {
- *sp1++ = KWSYS_NULLPTR;
- *ep++ = KWSYS_NULLPTR;
+ *sp1++ = nullptr;
+ *ep++ = nullptr;
}
if (regmatch(prog + 1)) {
start[0] = string;
@@ -967,7 +966,7 @@ int RegExpFind::regmatch(const char* prog)
scan = prog;
- while (scan != KWSYS_NULLPTR) {
+ while (scan != nullptr) {
next = regnext(scan);
@@ -999,14 +998,12 @@ int RegExpFind::regmatch(const char* prog)
reginput += len;
} break;
case ANYOF:
- if (*reginput == '\0' ||
- strchr(OPERAND(scan), *reginput) == KWSYS_NULLPTR)
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == nullptr)
return (0);
reginput++;
break;
case ANYBUT:
- if (*reginput == '\0' ||
- strchr(OPERAND(scan), *reginput) != KWSYS_NULLPTR)
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != nullptr)
return (0);
reginput++;
break;
@@ -1035,7 +1032,7 @@ int RegExpFind::regmatch(const char* prog)
// Don't set startp if some later invocation of the
// same parentheses already has.
//
- if (regstartp[no] == KWSYS_NULLPTR)
+ if (regstartp[no] == nullptr)
regstartp[no] = save;
return (1);
} else
@@ -1063,7 +1060,7 @@ int RegExpFind::regmatch(const char* prog)
// Don't set endp if some later invocation of the
// same parentheses already has.
//
- if (regendp[no] == KWSYS_NULLPTR)
+ if (regendp[no] == nullptr)
regendp[no] = save;
return (1);
} else
@@ -1083,7 +1080,7 @@ int RegExpFind::regmatch(const char* prog)
return (1);
reginput = save;
scan = regnext(scan);
- } while (scan != KWSYS_NULLPTR && OP(scan) == BRANCH);
+ } while (scan != nullptr && OP(scan) == BRANCH);
return (0);
// NOTREACHED
}
@@ -1161,13 +1158,13 @@ int RegExpFind::regrepeat(const char* p)
}
break;
case ANYOF:
- while (*scan != '\0' && strchr(opnd, *scan) != KWSYS_NULLPTR) {
+ while (*scan != '\0' && strchr(opnd, *scan) != nullptr) {
count++;
scan++;
}
break;
case ANYBUT:
- while (*scan != '\0' && strchr(opnd, *scan) == KWSYS_NULLPTR) {
+ while (*scan != '\0' && strchr(opnd, *scan) == nullptr) {
count++;
scan++;
}
@@ -1189,11 +1186,11 @@ static const char* regnext(const char* p)
int offset;
if (p == regdummyptr)
- return (KWSYS_NULLPTR);
+ return (nullptr);
offset = NEXT(p);
if (offset == 0)
- return (KWSYS_NULLPTR);
+ return (nullptr);
if (OP(p) == BACK)
return (p - offset);
@@ -1206,11 +1203,11 @@ static char* regnext(char* p)
int offset;
if (p == regdummyptr)
- return (KWSYS_NULLPTR);
+ return (nullptr);
offset = NEXT(p);
if (offset == 0)
- return (KWSYS_NULLPTR);
+ return (nullptr);
if (OP(p) == BACK)
return (p - offset);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index b7b93f962..df7eb4558 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -71,9 +71,9 @@ private:
*/
inline RegularExpressionMatch::RegularExpressionMatch()
{
- startp[0] = 0;
- endp[0] = 0;
- searchstring = 0;
+ startp[0] = nullptr;
+ endp[0] = nullptr;
+ searchstring = nullptr;
}
/**
@@ -81,7 +81,7 @@ inline RegularExpressionMatch::RegularExpressionMatch()
*/
inline bool RegularExpressionMatch::isValid() const
{
- return (this->startp[0] != 0);
+ return (this->startp[0] != nullptr);
}
/**
@@ -89,9 +89,9 @@ inline bool RegularExpressionMatch::isValid() const
*/
inline void RegularExpressionMatch::clear()
{
- startp[0] = 0;
- endp[0] = 0;
- searchstring = 0;
+ startp[0] = nullptr;
+ endp[0] = nullptr;
+ searchstring = nullptr;
}
/**
@@ -135,7 +135,7 @@ inline std::string::size_type RegularExpressionMatch::end(int n) const
*/
inline std::string RegularExpressionMatch::match(int n) const
{
- if (this->startp[n] == 0) {
+ if (this->startp[n] == nullptr) {
return std::string();
} else {
return std::string(
@@ -230,10 +230,11 @@ inline std::string RegularExpressionMatch::match(int n) const
* into the object's private data fields. The == and != operators only check
* the to see if the compiled regular expression is the same, and the
* deep_equal functions also checks to see if the start and end pointers are
- * the same. The is_valid function returns false if program is set to NULL,
- * (i.e. there is no valid compiled expression). The set_invalid function
- * sets the program to NULL (Warning: this deletes the compiled expression).
- * The following examples may help clarify regular expression usage:
+ * the same. The is_valid function returns false if program is set to
+ * nullptr, (i.e. there is no valid compiled expression). The set_invalid
+ * function sets the program to nullptr (Warning: this deletes the compiled
+ * expression). The following examples may help clarify regular expression
+ * usage:
*
* * The regular expression "^hello" matches a "hello" only at the
* beginning of a line. It would match "hello there" but not "hi,
@@ -288,7 +289,7 @@ class @KWSYS_NAMESPACE@_EXPORT RegularExpression
{
public:
/**
- * Instantiate RegularExpression with program=NULL.
+ * Instantiate RegularExpression with program=nullptr.
*/
inline RegularExpression();
@@ -407,8 +408,12 @@ private:
* Create an empty regular expression.
*/
inline RegularExpression::RegularExpression()
+ : regstart{}
+ , reganch{}
+ , regmust{}
+ , program{ nullptr }
+ , progsize{}
{
- this->program = 0;
}
/**
@@ -416,8 +421,12 @@ inline RegularExpression::RegularExpression()
* compiles s.
*/
inline RegularExpression::RegularExpression(const char* s)
+ : regstart{}
+ , reganch{}
+ , regmust{}
+ , program{ nullptr }
+ , progsize{}
{
- this->program = 0;
if (s) {
this->compile(s);
}
@@ -428,8 +437,12 @@ inline RegularExpression::RegularExpression(const char* s)
* compiles s.
*/
inline RegularExpression::RegularExpression(const std::string& s)
+ : regstart{}
+ , reganch{}
+ , regmust{}
+ , program{ nullptr }
+ , progsize{}
{
- this->program = 0;
this->compile(s);
}
@@ -533,7 +546,7 @@ inline bool RegularExpression::operator!=(const RegularExpression& r) const
*/
inline bool RegularExpression::is_valid() const
{
- return (this->program != 0);
+ return (this->program != nullptr);
}
inline void RegularExpression::set_invalid()
@@ -541,7 +554,7 @@ inline void RegularExpression::set_invalid()
//#ifndef _WIN32
delete[] this->program;
//#endif
- this->program = 0;
+ this->program = nullptr;
}
} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 7dc6cf4b0..6ec6e48ff 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -847,31 +847,16 @@ void SystemInformation::RunMemoryCheck()
// SystemInformationImplementation starts here
-#define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x
-#define TLBCACHE_INFO_UNITS (15)
-#define CLASSICAL_CPU_FREQ_LOOP 10000000
-#define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31
-
-// Status Flag
-#define HT_NOT_CAPABLE 0
-#define HT_ENABLED 1
-#define HT_DISABLED 2
-#define HT_SUPPORTED_NOT_ENABLED 3
-#define HT_CANNOT_DETECT 4
-
-// EDX[28] Bit 28 is set if HT is supported
-#define HT_BIT 0x10000000
-
-// EAX[11:8] Bit 8-11 contains family processor ID.
-#define FAMILY_ID 0x0F00
-#define PENTIUM4_ID 0x0F00
-// EAX[23:20] Bit 20-23 contains extended family processor ID
-#define EXT_FAMILY_ID 0x0F00000
-// EBX[23:16] Bit 16-23 in ebx contains the number of logical
-#define NUM_LOGICAL_BITS 0x00FF0000
-// processors per physical processor when execute cpuid with
-// eax set to 1
-// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique
+#if USE_CPUID
+# define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x
+# define TLBCACHE_INFO_UNITS (15)
+#endif
+
+#if USE_ASM_INSTRUCTIONS
+# define CLASSICAL_CPU_FREQ_LOOP 10000000
+# define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31
+#endif
+
#define INITIAL_APIC_ID_BITS 0xFF000000
// initial APIC ID for the processor this code is running on.
// Default value = 0xff if HT is not supported
@@ -888,7 +873,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines)
char buf[bufSize] = { '\0' };
while (!feof(file) && !ferror(file)) {
errno = 0;
- if (fgets(buf, bufSize, file) == KWSYS_NULLPTR) {
+ if (fgets(buf, bufSize, file) == nullptr) {
if (ferror(file) && (errno == EINTR)) {
clearerr(file);
}
@@ -952,7 +937,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values)
return -1;
}
int i = 0;
- while (fieldNames[i] != NULL) {
+ while (fieldNames[i] != nullptr) {
int ierr = NameValue(fields, fieldNames[i], values[i]);
if (ierr) {
return -(i + 2);
@@ -966,7 +951,7 @@ int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values)
template <typename T>
int GetFieldFromFile(const char* fileName, const char* fieldName, T& value)
{
- const char* fieldNames[2] = { fieldName, NULL };
+ const char* fieldNames[2] = { fieldName, nullptr };
T values[1] = { T(0) };
int ierr = GetFieldsFromFile(fileName, fieldNames, values);
if (ierr) {
@@ -984,7 +969,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames,
T* values)
{
FILE* file = popen(command, "r");
- if (file == KWSYS_NULLPTR) {
+ if (file == nullptr) {
return -1;
}
std::vector<std::string> fields;
@@ -994,7 +979,7 @@ int GetFieldsFromCommand(const char* command, const char** fieldNames,
return -1;
}
int i = 0;
- while (fieldNames[i] != KWSYS_NULLPTR) {
+ while (fieldNames[i] != nullptr) {
int ierr = NameValue(fields, fieldNames[i], values[i]);
if (ierr) {
return -(i + 2);
@@ -1030,8 +1015,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo,
break;
case SIGFPE:
- oss << "Caught SIGFPE at "
- << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "")
+ oss << "Caught SIGFPE at " << (sigInfo->si_addr == nullptr ? "0x" : "")
<< sigInfo->si_addr << " ";
switch (sigInfo->si_code) {
# if defined(FPE_INTDIV)
@@ -1079,8 +1063,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo,
break;
case SIGSEGV:
- oss << "Caught SIGSEGV at "
- << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "")
+ oss << "Caught SIGSEGV at " << (sigInfo->si_addr == nullptr ? "0x" : "")
<< sigInfo->si_addr << " ";
switch (sigInfo->si_code) {
case SEGV_MAPERR:
@@ -1098,8 +1081,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo,
break;
case SIGBUS:
- oss << "Caught SIGBUS at "
- << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "")
+ oss << "Caught SIGBUS at " << (sigInfo->si_addr == nullptr ? "0x" : "")
<< sigInfo->si_addr << " ";
switch (sigInfo->si_code) {
case BUS_ADRALN:
@@ -1139,8 +1121,7 @@ void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo,
break;
case SIGILL:
- oss << "Caught SIGILL at "
- << (sigInfo->si_addr == KWSYS_NULLPTR ? "0x" : "")
+ oss << "Caught SIGILL at " << (sigInfo->si_addr == nullptr ? "0x" : "")
<< sigInfo->si_addr << " ";
switch (sigInfo->si_code) {
case ILL_ILLOPC:
@@ -1324,8 +1305,8 @@ SymbolProperties::SymbolProperties()
// not using an initializer list
// to avoid some PGI compiler warnings
this->SetBinary("???");
- this->SetBinaryBaseAddress(KWSYS_NULLPTR);
- this->Address = KWSYS_NULLPTR;
+ this->SetBinaryBaseAddress(nullptr);
+ this->Address = nullptr;
this->SetSourceFile("???");
this->SetFunction("???");
this->SetLineNumber(-1);
@@ -1682,7 +1663,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
return -2;
}
- for (ifa = ifas; ifa != KWSYS_NULLPTR; ifa = ifa->ifa_next) {
+ for (ifa = ifas; ifa != nullptr; ifa = ifa->ifa_next) {
int fam = ifa->ifa_addr ? ifa->ifa_addr->sa_family : -1;
// Skip Loopback interfaces
if (((fam == AF_INET) || (fam == AF_INET6)) &&
@@ -1693,7 +1674,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
: sizeof(struct sockaddr_in6));
ierr = getnameinfo(ifa->ifa_addr, static_cast<socklen_t>(addrlen), host,
- NI_MAXHOST, KWSYS_NULLPTR, 0, NI_NAMEREQD);
+ NI_MAXHOST, nullptr, 0, NI_NAMEREQD);
if (ierr) {
// don't report the failure now since we may succeed on another
// interface. If all attempts fail then return the failure code.
@@ -2577,7 +2558,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
// If RDTSC is not supported, we fallback to trying to read this value
// from the registry:
if (!retrieved) {
- HKEY hKey = NULL;
+ HKEY hKey = nullptr;
LONG err =
RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
@@ -2597,7 +2578,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
}
RegCloseKey(hKey);
- hKey = NULL;
+ hKey = nullptr;
}
}
#endif
@@ -3628,7 +3609,7 @@ SystemInformationImplementation::GetHostMemoryTotal()
#elif defined(__APPLE__)
uint64_t mem;
size_t len = sizeof(mem);
- int ierr = sysctlbyname("hw.memsize", &mem, &len, KWSYS_NULLPTR, 0);
+ int ierr = sysctlbyname("hw.memsize", &mem, &len, nullptr, 0);
if (ierr) {
return -1;
}
@@ -3745,12 +3726,12 @@ SystemInformationImplementation::GetHostMemoryUsed()
# endif
#elif defined(__linux)
// First try to use MemAvailable, but it only works on newer kernels
- const char* names2[3] = { "MemTotal:", "MemAvailable:", NULL };
+ const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr };
SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) };
int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2);
if (ierr) {
const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:",
- NULL };
+ nullptr };
SystemInformation::LongLong values4[4] = { SystemInformation::LongLong(
0) };
ierr = GetFieldsFromFile("/proc/meminfo", names4, values4);
@@ -3771,8 +3752,7 @@ SystemInformationImplementation::GetHostMemoryUsed()
if (psz < 1) {
return -1;
}
- const char* names[3] = { "Pages wired down:", "Pages active:",
- KWSYS_NULLPTR };
+ const char* names[3] = { "Pages wired down:", "Pages active:", nullptr };
SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) };
int ierr = GetFieldsFromCommand("vm_stat", names, values);
if (ierr) {
@@ -3820,7 +3800,7 @@ SystemInformationImplementation::GetProcMemoryUsed()
std::ostringstream oss;
oss << "ps -o rss= -p " << pid;
FILE* file = popen(oss.str().c_str(), "r");
- if (file == KWSYS_NULLPTR) {
+ if (file == nullptr) {
return -1;
}
oss.str("");
@@ -3920,9 +3900,9 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
void* stack[TRACE_MAX_STACK_FRAMES];
HANDLE process = GetCurrentProcess();
- SymInitialize(process, NULL, TRUE);
+ SymInitialize(process, nullptr, TRUE);
WORD numberOfFrames =
- CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, NULL);
+ CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, nullptr);
SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>(
malloc(sizeof(SYMBOL_INFO) +
(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)));
@@ -3933,7 +3913,7 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++) {
DWORD64 address = reinterpret_cast<DWORD64>(stack[i]);
- SymFromAddr(process, address, NULL, symbol);
+ SymFromAddr(process, address, nullptr, symbol);
if (SymGetLineFromAddr64(process, address, &displacement, &line)) {
oss << " at " << symbol->Name << " in " << line.FileName << " line "
<< line.LineNumber << std::endl;
@@ -4000,13 +3980,13 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable)
if (enable && !saOrigValid) {
// save the current actions
- sigaction(SIGABRT, KWSYS_NULLPTR, &saABRTOrig);
- sigaction(SIGSEGV, KWSYS_NULLPTR, &saSEGVOrig);
- sigaction(SIGTERM, KWSYS_NULLPTR, &saTERMOrig);
- sigaction(SIGINT, KWSYS_NULLPTR, &saINTOrig);
- sigaction(SIGILL, KWSYS_NULLPTR, &saILLOrig);
- sigaction(SIGBUS, KWSYS_NULLPTR, &saBUSOrig);
- sigaction(SIGFPE, KWSYS_NULLPTR, &saFPEOrig);
+ sigaction(SIGABRT, nullptr, &saABRTOrig);
+ sigaction(SIGSEGV, nullptr, &saSEGVOrig);
+ sigaction(SIGTERM, nullptr, &saTERMOrig);
+ sigaction(SIGINT, nullptr, &saINTOrig);
+ sigaction(SIGILL, nullptr, &saILLOrig);
+ sigaction(SIGBUS, nullptr, &saBUSOrig);
+ sigaction(SIGFPE, nullptr, &saFPEOrig);
// enable read, disable write
saOrigValid = 1;
@@ -4020,22 +4000,22 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable)
# endif
sigemptyset(&sa.sa_mask);
- sigaction(SIGABRT, &sa, KWSYS_NULLPTR);
- sigaction(SIGSEGV, &sa, KWSYS_NULLPTR);
- sigaction(SIGTERM, &sa, KWSYS_NULLPTR);
- sigaction(SIGINT, &sa, KWSYS_NULLPTR);
- sigaction(SIGILL, &sa, KWSYS_NULLPTR);
- sigaction(SIGBUS, &sa, KWSYS_NULLPTR);
- sigaction(SIGFPE, &sa, KWSYS_NULLPTR);
+ sigaction(SIGABRT, &sa, nullptr);
+ sigaction(SIGSEGV, &sa, nullptr);
+ sigaction(SIGTERM, &sa, nullptr);
+ sigaction(SIGINT, &sa, nullptr);
+ sigaction(SIGILL, &sa, nullptr);
+ sigaction(SIGBUS, &sa, nullptr);
+ sigaction(SIGFPE, &sa, nullptr);
} else if (!enable && saOrigValid) {
// restore previous actions
- sigaction(SIGABRT, &saABRTOrig, KWSYS_NULLPTR);
- sigaction(SIGSEGV, &saSEGVOrig, KWSYS_NULLPTR);
- sigaction(SIGTERM, &saTERMOrig, KWSYS_NULLPTR);
- sigaction(SIGINT, &saINTOrig, KWSYS_NULLPTR);
- sigaction(SIGILL, &saILLOrig, KWSYS_NULLPTR);
- sigaction(SIGBUS, &saBUSOrig, KWSYS_NULLPTR);
- sigaction(SIGFPE, &saFPEOrig, KWSYS_NULLPTR);
+ sigaction(SIGABRT, &saABRTOrig, nullptr);
+ sigaction(SIGSEGV, &saSEGVOrig, nullptr);
+ sigaction(SIGTERM, &saTERMOrig, nullptr);
+ sigaction(SIGINT, &saINTOrig, nullptr);
+ sigaction(SIGILL, &saILLOrig, nullptr);
+ sigaction(SIGBUS, &saBUSOrig, nullptr);
+ sigaction(SIGFPE, &saFPEOrig, nullptr);
// enable write, disable read
saOrigValid = 0;
@@ -4417,7 +4397,7 @@ void SystemInformationImplementation::CPUCountWindows()
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo;
{
DWORD Length = 0;
- DWORD rc = pGetLogicalProcessorInformation(NULL, &Length);
+ DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length);
assert(FALSE == rc);
(void)rc; // Silence unused variable warning in Borland C++ 5.81
assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
@@ -4471,7 +4451,7 @@ bool SystemInformationImplementation::ParseSysCtl()
int err = 0;
uint64_t value = 0;
size_t len = sizeof(value);
- sysctlbyname("hw.memsize", &value, &len, KWSYS_NULLPTR, 0);
+ sysctlbyname("hw.memsize", &value, &len, nullptr, 0);
this->TotalPhysicalMemory = static_cast<size_t>(value / 1048576);
// Parse values for Mac
@@ -4481,7 +4461,7 @@ bool SystemInformationImplementation::ParseSysCtl()
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat,
&count) == KERN_SUCCESS) {
len = sizeof(value);
- err = sysctlbyname("hw.pagesize", &value, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("hw.pagesize", &value, &len, nullptr, 0);
int64_t available_memory =
(vmstat.free_count + vmstat.inactive_count) * value;
this->AvailablePhysicalMemory =
@@ -4491,10 +4471,11 @@ bool SystemInformationImplementation::ParseSysCtl()
# ifdef VM_SWAPUSAGE
// Virtual memory.
int mib[2] = { CTL_VM, VM_SWAPUSAGE };
- size_t miblen = sizeof(mib) / sizeof(mib[0]);
+ unsigned int miblen =
+ static_cast<unsigned int>(sizeof(mib) / sizeof(mib[0]));
struct xsw_usage swap;
len = sizeof(swap);
- err = sysctl(mib, miblen, &swap, &len, KWSYS_NULLPTR, 0);
+ err = sysctl(mib, miblen, &swap, &len, nullptr, 0);
if (err == 0) {
this->AvailableVirtualMemory =
static_cast<size_t>(swap.xsu_avail / 1048576);
@@ -4507,75 +4488,72 @@ bool SystemInformationImplementation::ParseSysCtl()
// CPU Info
len = sizeof(this->NumberOfPhysicalCPU);
- sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len,
- KWSYS_NULLPTR, 0);
+ sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, nullptr, 0);
len = sizeof(this->NumberOfLogicalCPU);
- sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, KWSYS_NULLPTR,
- 0);
+ sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, nullptr, 0);
int cores_per_package = 0;
len = sizeof(cores_per_package);
err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len,
- KWSYS_NULLPTR, 0);
+ nullptr, 0);
// That name was not found, default to 1
this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
err != 0 ? 1 : static_cast<unsigned char>(cores_per_package);
len = sizeof(value);
- sysctlbyname("hw.cpufrequency", &value, &len, KWSYS_NULLPTR, 0);
+ sysctlbyname("hw.cpufrequency", &value, &len, nullptr, 0);
this->CPUSpeedInMHz = static_cast<float>(value) / 1000000;
// Chip family
len = sizeof(this->ChipID.Family);
// Seems only the intel chips will have this name so if this fails it is
// probably a PPC machine
- err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len,
- KWSYS_NULLPTR, 0);
+ err =
+ sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, nullptr, 0);
if (err != 0) // Go back to names we know but are less descriptive
{
this->ChipID.Family = 0;
::memset(retBuf, 0, 128);
len = 32;
- err = sysctlbyname("hw.machine", &retBuf, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("hw.machine", &retBuf, &len, nullptr, 0);
std::string machineBuf(retBuf);
if (machineBuf.find_first_of("Power") != std::string::npos) {
this->ChipID.Vendor = "IBM";
len = sizeof(this->ChipID.Family);
- err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len,
- KWSYS_NULLPTR, 0);
+ err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, nullptr, 0);
len = sizeof(this->ChipID.Model);
- err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len,
- KWSYS_NULLPTR, 0);
+ err =
+ sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, nullptr, 0);
this->FindManufacturer();
}
} else // Should be an Intel Chip.
{
len = sizeof(this->ChipID.Family);
err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len,
- KWSYS_NULLPTR, 0);
+ nullptr, 0);
::memset(retBuf, 0, 128);
len = 128;
- err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, nullptr, 0);
// Chip Vendor
this->ChipID.Vendor = retBuf;
this->FindManufacturer();
// Chip Model
len = sizeof(value);
- err = sysctlbyname("machdep.cpu.model", &value, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("machdep.cpu.model", &value, &len, nullptr, 0);
this->ChipID.Model = static_cast<int>(value);
// Chip Stepping
len = sizeof(value);
value = 0;
- err = sysctlbyname("machdep.cpu.stepping", &value, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("machdep.cpu.stepping", &value, &len, nullptr, 0);
if (!err) {
this->ChipID.Revision = static_cast<int>(value);
}
// feature string
- char* buf = KWSYS_NULLPTR;
+ char* buf = nullptr;
size_t allocSize = 128;
err = 0;
@@ -4592,8 +4570,7 @@ bool SystemInformationImplementation::ParseSysCtl()
}
buf[0] = ' ';
len = allocSize - 2; // keep space for leading and trailing space
- err =
- sysctlbyname("machdep.cpu.features", buf + 1, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("machdep.cpu.features", buf + 1, &len, nullptr, 0);
}
if (!err && buf && len) {
// now we can match every flags as space + flag + space
@@ -4634,8 +4611,7 @@ bool SystemInformationImplementation::ParseSysCtl()
// brand string
::memset(retBuf, 0, sizeof(retBuf));
len = sizeof(retBuf);
- err =
- sysctlbyname("machdep.cpu.brand_string", retBuf, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, nullptr, 0);
if (!err) {
this->ChipID.ProcessorName = retBuf;
this->ChipID.ModelName = retBuf;
@@ -4643,10 +4619,10 @@ bool SystemInformationImplementation::ParseSysCtl()
// Cache size
len = sizeof(value);
- err = sysctlbyname("hw.l1icachesize", &value, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("hw.l1icachesize", &value, &len, nullptr, 0);
this->Features.L1CacheSize = static_cast<int>(value);
len = sizeof(value);
- err = sysctlbyname("hw.l2cachesize", &value, &len, KWSYS_NULLPTR, 0);
+ err = sysctlbyname("hw.l2cachesize", &value, &len, nullptr, 0);
this->Features.L2CacheSize = static_cast<int>(value);
return true;
@@ -4683,7 +4659,7 @@ std::string SystemInformationImplementation::RunProcess(
kwsysProcess_Execute(gp);
- char* data = KWSYS_NULLPTR;
+ char* data = nullptr;
int length;
double timeout = 255;
int pipe; // pipe id as returned by kwsysProcess_WaitForData()
@@ -4695,7 +4671,7 @@ std::string SystemInformationImplementation::RunProcess(
{
buffer.append(data, length);
}
- kwsysProcess_WaitForExit(gp, KWSYS_NULLPTR);
+ kwsysProcess_WaitForExit(gp, nullptr);
int result = 0;
switch (kwsysProcess_GetState(gp)) {
@@ -4766,7 +4742,7 @@ std::string SystemInformationImplementation::ParseValueFromKStat(
for (size_t i = 0; i < args_string.size(); ++i) {
args.push_back(args_string[i].c_str());
}
- args.push_back(KWSYS_NULLPTR);
+ args.push_back(nullptr);
std::string buffer = this->RunProcess(args);
@@ -4965,7 +4941,7 @@ bool SystemInformationImplementation::QueryBSDMemory()
# endif
size_t sz = sizeof(k);
- if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5036,7 +5012,7 @@ bool SystemInformationImplementation::QueryBSDProcessor()
size_t sz = sizeof(k);
int ctrl[2] = { CTL_HW, HW_NCPU };
- if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5046,7 +5022,7 @@ bool SystemInformationImplementation::QueryBSDProcessor()
# if defined(HW_CPUSPEED)
ctrl[1] = HW_CPUSPEED;
- if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5057,7 +5033,7 @@ bool SystemInformationImplementation::QueryBSDProcessor()
ctrl[0] = CTL_MACHDEP;
ctrl[1] = CPU_SSE;
- if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5068,7 +5044,7 @@ bool SystemInformationImplementation::QueryBSDProcessor()
ctrl[0] = CTL_MACHDEP;
ctrl[1] = CPU_SSE2;
- if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5081,7 +5057,7 @@ bool SystemInformationImplementation::QueryBSDProcessor()
char vbuf[25];
::memset(vbuf, 0, sizeof(vbuf));
sz = sizeof(vbuf) - 1;
- if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0) {
+ if (sysctl(ctrl, 2, vbuf, &sz, nullptr, 0) != 0) {
return false;
}
@@ -5293,7 +5269,7 @@ bool SystemInformationImplementation::QueryOSInformation()
RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0,
KEY_QUERY_VALUE, &hKey);
- RegQueryValueExW(hKey, L"ProductType", NULL, NULL,
+ RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr,
(LPBYTE)szProductType, &dwBufLen);
RegCloseKey(hKey);
@@ -5335,13 +5311,13 @@ bool SystemInformationImplementation::QueryOSInformation()
// Load the Kernel32 DLL.
hKernelDLL = LoadLibraryW(L"kernel32");
- if (hKernelDLL != NULL) {
+ if (hKernelDLL != nullptr) {
// Only XP and .NET Server support IsWOW64Process so... Load
// dynamically!
DLLProc = (LPFNPROC)GetProcAddress(hKernelDLL, "IsWow64Process");
// If the function address is valid, call the function.
- if (DLLProc != NULL)
+ if (DLLProc != nullptr)
(DLLProc)(GetCurrentProcess(), &bIsWindows64Bit);
else
bIsWindows64Bit = false;
@@ -5456,7 +5432,7 @@ int SystemInformationImplementation::CallSwVers(const char* arg,
std::vector<const char*> args;
args.push_back("sw_vers");
args.push_back(arg);
- args.push_back(KWSYS_NULLPTR);
+ args.push_back(nullptr);
ver = this->RunProcess(args);
this->TrimNewline(ver);
#else
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index 5e93878fa..fc42e9dc7 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -115,8 +115,8 @@ public:
// returns an informative general description if the installed and
// available ram on this system. See the GetHostMemoryTotal, and
// Get{Host,Proc}MemoryAvailable methods for more information.
- std::string GetMemoryDescription(const char* hostLimitEnvVarName = NULL,
- const char* procLimitEnvVarName = NULL);
+ std::string GetMemoryDescription(const char* hostLimitEnvVarName = nullptr,
+ const char* procLimitEnvVarName = nullptr);
// Retrieve amount of physical memory installed on the system in KiB
// units.
@@ -128,7 +128,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 = NULL);
+ LongLong 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,8 +136,8 @@ 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 = NULL,
- const char* procLimitEnvVarName = NULL);
+ LongLong 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();
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ae7a18a8c..ce4d6ef95 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -192,15 +192,15 @@ static inline char* realpath(const char* path, char* resolved_path)
{
const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH;
snprintf(resolved_path, maxlen, "%s", path);
- BPath normalized(resolved_path, NULL, true);
+ BPath normalized(resolved_path, nullptr, true);
const char* resolved = normalized.Path();
- if (resolved != NULL) // NULL == No such file.
+ if (resolved != nullptr) // nullptr == No such file.
{
if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) {
return resolved_path;
}
}
- return NULL; // something went wrong.
+ return nullptr; // something went wrong.
}
#endif
@@ -273,12 +273,12 @@ inline void Realpath(const std::string& path, std::string& resolved_path,
if (bufferLen) {
*errorMessage = "Destination path buffer size too small.";
} else if (unsigned int errorId = GetLastError()) {
- LPSTR message = NULL;
+ LPSTR message = nullptr;
DWORD size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&message, 0, NULL);
+ nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&message, 0, nullptr);
*errorMessage = std::string(message, size);
LocalFree(message);
} else {
@@ -313,7 +313,7 @@ inline int Chdir(const std::string& dir)
return chdir(dir.c_str());
}
inline void Realpath(const std::string& path, std::string& resolved_path,
- std::string* errorMessage = KWSYS_NULLPTR)
+ std::string* errorMessage = nullptr)
{
char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
@@ -359,7 +359,7 @@ double SystemTools::GetTime(void)
11644473600.0);
#else
struct timeval t;
- gettimeofday(&t, KWSYS_NULLPTR);
+ gettimeofday(&t, nullptr);
return 1.0 * double(t.tv_sec) + 0.000001 * double(t.tv_usec);
#endif
}
@@ -389,8 +389,8 @@ struct kwsysEnvCompare
#else
const char* leq = strchr(l, '=');
const char* req = strchr(r, '=');
- size_t llen = leq ? (leq - l) : strlen(l);
- size_t rlen = req ? (req - r) : strlen(r);
+ size_t llen = leq ? static_cast<size_t>(leq - l) : strlen(l);
+ size_t rlen = req ? static_cast<size_t>(req - r) : strlen(r);
if (llen == rlen) {
return strncmp(l, r, llen) < 0;
} else {
@@ -420,7 +420,7 @@ public:
const envchar* Release(const envchar* env)
{
- const envchar* old = KWSYS_NULLPTR;
+ const envchar* old = nullptr;
iterator i = this->find(env);
if (i != this->end()) {
old = *i;
@@ -630,7 +630,7 @@ const char* SystemToolsStatic::GetEnvBuffered(const char* key)
}
return menv.c_str();
}
- return KWSYS_NULLPTR;
+ return nullptr;
}
#endif
@@ -684,7 +684,7 @@ bool SystemTools::HasEnv(const char* key)
#else
const char* v = getenv(key);
#endif
- return v != KWSYS_NULLPTR;
+ return v != nullptr;
}
bool SystemTools::HasEnv(const std::string& key)
@@ -915,7 +915,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
while ((pos = dir.find('/', pos)) != std::string::npos) {
topdir = dir.substr(0, pos);
- if (Mkdir(topdir) == 0 && mode != KWSYS_NULLPTR) {
+ if (Mkdir(topdir) == 0 && mode != nullptr) {
SystemTools::SetPermissions(topdir, *mode);
}
@@ -934,7 +934,7 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
) {
return false;
}
- } else if (mode != KWSYS_NULLPTR) {
+ } else if (mode != nullptr) {
SystemTools::SetPermissions(topdir, *mode);
}
@@ -1055,7 +1055,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode,
// only add the modes when on a system that supports Wow64.
static FARPROC wow64p =
GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process");
- if (wow64p == NULL) {
+ if (wow64p == nullptr) {
return mode;
}
@@ -1136,7 +1136,7 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value,
DWORD dwType, dwSize;
dwSize = 1023;
wchar_t data[1024];
- if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), NULL,
+ if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), nullptr,
&dwType, (BYTE*)data, &dwSize) == ERROR_SUCCESS) {
if (dwType == REG_SZ) {
value = Encoding::ToNarrow(data);
@@ -1186,7 +1186,7 @@ bool SystemTools::WriteRegistryValue(const std::string& key,
wchar_t lpClass[] = L"";
if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass,
REG_OPTION_NON_VOLATILE,
- SystemToolsMakeRegistryMode(KEY_WRITE, view), NULL,
+ SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr,
&hKey, &dwDummy) != ERROR_SUCCESS) {
return false;
}
@@ -1252,10 +1252,10 @@ bool SystemTools::SameFile(const std::string& file1, const std::string& file2)
hFile1 =
CreateFileW(Encoding::ToWide(file1).c_str(), GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
hFile2 =
CreateFileW(Encoding::ToWide(file2).c_str(), GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE) {
if (hFile1 != INVALID_HANDLE_VALUE) {
CloseHandle(hFile1);
@@ -1347,7 +1347,7 @@ bool SystemTools::FileExists(const std::string& filename)
// even if we do not have permission to read the file itself
HANDLE handle =
CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(), 0, 0,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (handle == INVALID_HANDLE_VALUE) {
return false;
@@ -1493,12 +1493,12 @@ bool SystemTools::Touch(const std::string& filename, bool create)
CloseHandle(h);
#elif KWSYS_CXX_HAS_UTIMENSAT
// utimensat is only available on newer Unixes and macOS 10.13+
- if (utimensat(AT_FDCWD, filename.c_str(), NULL, 0) < 0) {
+ if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) {
return false;
}
#else
// fall back to utimes
- if (utimes(filename.c_str(), NULL) < 0) {
+ if (utimes(filename.c_str(), nullptr) < 0) {
return false;
}
#endif
@@ -1653,7 +1653,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2)
size_t len1 = strlen(str1);
char* newstr = new char[len1 + strlen(str2) + 1];
if (!newstr) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
strcpy(newstr, str1);
strcat(newstr + len1, str2);
@@ -1676,7 +1676,7 @@ char* SystemTools::AppendStrings(const char* str1, const char* str2,
size_t len1 = strlen(str1), len2 = strlen(str2);
char* newstr = new char[len1 + len2 + strlen(str3) + 1];
if (!newstr) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
strcpy(newstr, str1);
strcat(newstr + len1, str2);
@@ -1726,7 +1726,7 @@ size_t SystemTools::CountChar(const char* str, char c)
char* SystemTools::RemoveChars(const char* str, const char* toremove)
{
if (!str) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
char* clean_str = new char[strlen(str) + 1];
char* ptr = clean_str;
@@ -1748,7 +1748,7 @@ char* SystemTools::RemoveChars(const char* str, const char* toremove)
char* SystemTools::RemoveCharsButUpperHex(const char* str)
{
if (!str) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
char* clean_str = new char[strlen(str) + 1];
char* ptr = clean_str;
@@ -1829,7 +1829,7 @@ bool SystemTools::StringEndsWith(const std::string& str1, const char* str2)
const char* SystemTools::FindLastString(const char* str1, const char* str2)
{
if (!str1 || !str2) {
- return KWSYS_NULLPTR;
+ return nullptr;
}
size_t len1 = strlen(str1), len2 = strlen(str2);
@@ -1842,7 +1842,7 @@ const char* SystemTools::FindLastString(const char* str1, const char* str2)
} while (ptr-- != str1);
}
- return KWSYS_NULLPTR;
+ return nullptr;
}
// Duplicate string
@@ -1852,7 +1852,7 @@ char* SystemTools::DuplicateString(const char* str)
char* newstr = new char[strlen(str) + 1];
return strcpy(newstr, str);
}
- return KWSYS_NULLPTR;
+ return nullptr;
}
// Return a cropped string
@@ -2169,24 +2169,24 @@ std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path)
return ret;
}
+/**
+ * Append the filename from the path source to the directory name dir.
+ */
+static std::string FileInDir(const std::string& source, const std::string& dir)
+{
+ std::string new_destination = dir;
+ SystemTools::ConvertToUnixSlashes(new_destination);
+ return new_destination + '/' + SystemTools::GetFilenameName(source);
+}
+
bool SystemTools::CopyFileIfDifferent(const std::string& source,
const std::string& destination)
{
// special check for a destination that is a directory
// FilesDiffer does not handle file to directory compare
if (SystemTools::FileIsDirectory(destination)) {
- std::string new_destination = destination;
- SystemTools::ConvertToUnixSlashes(new_destination);
- new_destination += '/';
- std::string source_name = source;
- new_destination += SystemTools::GetFilenameName(source_name);
- if (SystemTools::FilesDiffer(source, new_destination)) {
- return SystemTools::CopyFileAlways(source, destination);
- } else {
- // the files are the same so the copy is done return
- // true
- return true;
- }
+ const std::string new_destination = FileInDir(source, destination);
+ return SystemTools::CopyFileIfDifferent(source, new_destination);
}
// source and destination are files so do a copy if they
// are different
@@ -2612,101 +2612,6 @@ std::string SystemTools::GetLastSystemError()
return strerror(e);
}
-#ifdef _WIN32
-
-static bool IsJunction(const std::wstring& source)
-{
-# ifdef FSCTL_GET_REPARSE_POINT
- const DWORD JUNCTION_ATTRS =
- FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
- DWORD attrs = GetFileAttributesW(source.c_str());
- if (attrs == INVALID_FILE_ATTRIBUTES) {
- return false;
- }
- if ((attrs & JUNCTION_ATTRS) != JUNCTION_ATTRS) {
- return false;
- }
-
- // Adjust privileges so that we can succefully open junction points.
- HANDLE token;
- TOKEN_PRIVILEGES privs;
- OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
- LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &privs.Privileges[0].Luid);
- privs.PrivilegeCount = 1;
- privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL,
- NULL);
- CloseHandle(token);
-
- HANDLE dir = CreateFileW(
- source.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (dir == INVALID_HANDLE_VALUE) {
- return false;
- }
-
- // Query whether this is a reparse point or not.
- BYTE buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- REPARSE_GUID_DATA_BUFFER* reparse_buffer = (REPARSE_GUID_DATA_BUFFER*)buffer;
- DWORD sentinel;
-
- BOOL success =
- DeviceIoControl(dir, FSCTL_GET_REPARSE_POINT, NULL, 0, reparse_buffer,
- MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &sentinel, NULL);
-
- CloseHandle(dir);
-
- return (success &&
- (reparse_buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT));
-# else
- return false;
-# endif
-}
-
-static bool DeleteJunction(const std::wstring& source)
-{
-# ifdef FSCTL_DELETE_REPARSE_POINT
- // Adjust privileges so that we can succefully open junction points as
- // read/write.
- HANDLE token;
- TOKEN_PRIVILEGES privs;
- OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
- LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &privs.Privileges[0].Luid);
- privs.PrivilegeCount = 1;
- privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL,
- NULL);
- CloseHandle(token);
-
- HANDLE dir = CreateFileW(
- source.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (dir == INVALID_HANDLE_VALUE) {
- return false;
- }
-
- // Set up the structure so that we can delete the junction.
- std::vector<BYTE> buffer(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0);
- REPARSE_GUID_DATA_BUFFER* reparse_buffer =
- (REPARSE_GUID_DATA_BUFFER*)&buffer[0];
- DWORD sentinel;
-
- reparse_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
-
- BOOL success = DeviceIoControl(
- dir, FSCTL_DELETE_REPARSE_POINT, reparse_buffer,
- REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0, &sentinel, NULL);
-
- CloseHandle(dir);
-
- return !!success;
-# else
- return false;
-# endif
-}
-
-#endif
-
bool SystemTools::RemoveFile(const std::string& source)
{
#ifdef _WIN32
@@ -2728,9 +2633,7 @@ bool SystemTools::RemoveFile(const std::string& source)
SetLastError(err);
return false;
}
- if (IsJunction(ws) && DeleteJunction(ws)) {
- return true;
- }
+
const DWORD DIRECTORY_SOFT_LINK_ATTRS =
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
DWORD attrs = GetFileAttributesW(ws.c_str());
@@ -3115,16 +3018,16 @@ bool SystemTools::FileIsSymlink(const std::string& name)
// * a file or directory that has an associated reparse point, or
// * a file that is a symbolic link.
HANDLE hFile = CreateFileW(
- path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
DWORD bytesReturned = 0;
- if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer,
+ if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer,
MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned,
- NULL)) {
+ nullptr)) {
CloseHandle(hFile);
// Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be
// a symbolic link if it is not a reparse point.
@@ -3155,7 +3058,7 @@ bool SystemTools::FileIsFIFO(const std::string& name)
#if defined(_WIN32)
HANDLE hFile =
CreateFileW(Encoding::ToWide(name).c_str(), GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
@@ -3316,7 +3219,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
std::string SystemTools::CollapseFullPath(const std::string& in_relative)
{
- return SystemTools::CollapseFullPath(in_relative, KWSYS_NULLPTR);
+ return SystemTools::CollapseFullPath(in_relative, nullptr);
}
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
@@ -3403,11 +3306,7 @@ static void SystemToolsAppendComponents(
out_components.emplace_back(std::move(*i));
}
} else if (!i->empty() && *i != cur) {
-#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
- out_components.push_back(std::move(*i));
-#else
- out_components.push_back(*i);
-#endif
+ out_components.emplace_back(std::move(*i));
}
}
}
@@ -4114,7 +4013,7 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
}
std::wstring wtempPath = Encoding::ToWide(tempPath);
- DWORD ret = GetShortPathNameW(wtempPath.c_str(), NULL, 0);
+ DWORD ret = GetShortPathNameW(wtempPath.c_str(), nullptr, 0);
std::vector<wchar_t> buffer(ret);
if (ret != 0) {
ret = GetShortPathNameW(wtempPath.c_str(), &buffer[0],
@@ -4522,7 +4421,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion()
return 0;
}
- lRet = RegQueryValueExW(hKey, L"ProductType", NULL, NULL,
+ lRet = RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr,
(LPBYTE)szProductType, &dwBufLen);
if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE)) {
@@ -4743,7 +4642,7 @@ void SystemTools::ClassInitialize()
// Test progressively shorter logical-to-physical mappings.
std::string cwd_str = cwd;
std::string pwd_path;
- Realpath(pwd_str.c_str(), pwd_path);
+ Realpath(pwd_str, pwd_path);
while (cwd_str == pwd_path && cwd_str != pwd_str) {
// The current pair of paths is a working logical mapping.
cwd_changed = cwd_str;
@@ -4753,7 +4652,7 @@ void SystemTools::ClassInitialize()
// mapping still works.
pwd_str = SystemTools::GetFilenamePath(pwd_str);
cwd_str = SystemTools::GetFilenamePath(cwd_str);
- Realpath(pwd_str.c_str(), pwd_path);
+ Realpath(pwd_str, pwd_path);
}
// Add the translation to keep the logical path name.
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index dd1266bee..c4ab9d4f3 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -400,9 +400,10 @@ public:
* installPrefix is a possibly null pointer to the install directory.
*/
static bool FindProgramPath(const char* argv0, std::string& pathOut,
- std::string& errorMsg, const char* exeName = 0,
- const char* buildDir = 0,
- const char* installPrefix = 0);
+ std::string& errorMsg,
+ const char* exeName = nullptr,
+ const char* buildDir = nullptr,
+ const char* installPrefix = nullptr);
/**
* Given a path to a file or directory, convert it to a full path.
@@ -420,11 +421,11 @@ public:
* Get the real path for a given path, removing all symlinks. In
* the event of an error (non-existent path, permissions issue,
* etc.) the original path is returned if errorMessage pointer is
- * NULL. Otherwise empty string is returned and errorMessage
+ * nullptr. Otherwise empty string is returned and errorMessage
* contains error description.
*/
static std::string GetRealPath(const std::string& path,
- std::string* errorMessage = 0);
+ std::string* errorMessage = nullptr);
/**
* Split a path name into its root component and the rest of the
@@ -442,7 +443,7 @@ public:
* given.
*/
static const char* SplitPathRootComponent(const std::string& p,
- std::string* root = 0);
+ std::string* root = nullptr);
/**
* Split a path name into its basic components. The first component
@@ -528,7 +529,8 @@ public:
* be true when the line read had a newline character.
*/
static bool GetLineFromStream(std::istream& istr, std::string& line,
- bool* has_newline = 0, long sizeLimit = -1);
+ bool* has_newline = nullptr,
+ long sizeLimit = -1);
/**
* Get the parent directory of the directory or file
@@ -563,8 +565,9 @@ public:
* can make a full path even if none of the directories existed
* prior to calling this function.
*/
- static bool MakeDirectory(const char* path, const mode_t* mode = 0);
- static bool MakeDirectory(const std::string& path, const mode_t* mode = 0);
+ static bool MakeDirectory(const char* path, const mode_t* mode = nullptr);
+ static bool MakeDirectory(const std::string& path,
+ const mode_t* mode = nullptr);
/**
* Copy the source file to the destination file only
@@ -842,7 +845,8 @@ public:
* string vector passed in. If env is set then the value
* of env will be used instead of PATH.
*/
- static void GetPath(std::vector<std::string>& path, const char* env = 0);
+ static void GetPath(std::vector<std::string>& path,
+ const char* env = nullptr);
/**
* Read an environment variable
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
index 0981c66ff..8c4b0025f 100644
--- a/Source/kwsys/hashtable.hxx.in
+++ b/Source/kwsys/hashtable.hxx.in
@@ -354,7 +354,7 @@ public:
return end();
}
- iterator end() { return iterator(0, this); }
+ iterator end() { return iterator(nullptr, this); }
const_iterator begin() const
{
@@ -364,7 +364,7 @@ public:
return end();
}
- const_iterator end() const { return const_iterator(0, this); }
+ const_iterator end() const { return const_iterator(nullptr, this); }
friend bool operator==<>(const hashtable&, const hashtable&);
@@ -510,7 +510,7 @@ private:
{
const size_type __n_buckets = _M_next_size(__n);
_M_buckets.reserve(__n_buckets);
- _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)0);
+ _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr);
_M_num_elements = 0;
}
@@ -544,7 +544,7 @@ private:
_Node* _M_new_node(const value_type& __obj)
{
_Node* __n = _M_get_node();
- __n->_M_next = 0;
+ __n->_M_next = nullptr;
try {
construct(&__n->_M_val, __obj);
return __n;
@@ -839,9 +839,9 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first,
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, 0);
+ _M_erase_bucket(__f_bucket, __first._M_cur, nullptr);
for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
- _M_erase_bucket(__n, 0);
+ _M_erase_bucket(__n, nullptr);
if (__l_bucket != _M_buckets.size())
_M_erase_bucket(__l_bucket, __last._M_cur);
}
@@ -873,7 +873,8 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(
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*)(0), _M_buckets.get_allocator());
+ _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];
@@ -940,12 +941,12 @@ 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 != 0) {
+ while (__cur != nullptr) {
_Node* __next = __cur->_M_next;
_M_delete_node(__cur);
__cur = __next;
}
- _M_buckets[__i] = 0;
+ _M_buckets[__i] = nullptr;
}
_M_num_elements = 0;
}
@@ -956,7 +957,7 @@ void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(
{
_M_buckets.clear();
_M_buckets.reserve(__ht._M_buckets.size());
- _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)0);
+ _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];
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 15f9c02ba..1778a9ba8 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -76,7 +76,7 @@ int testCommandLineArguments(int argc, char* argv[])
int some_int_variable = 10;
double some_double_variable = 10.10;
- char* some_string_variable = KWSYS_NULLPTR;
+ char* some_string_variable = nullptr;
std::string some_stl_string_variable;
bool some_bool_variable = false;
bool some_bool_variable1 = false;
@@ -203,7 +203,7 @@ int testCommandLineArguments(int argc, char* argv[])
for (cc = 0; cc < strings_argument.size(); ++cc) {
delete[] strings_argument[cc];
- strings_argument[cc] = KWSYS_NULLPTR;
+ strings_argument[cc] = nullptr;
}
return res;
}
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 9895008f0..64561b1e3 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -21,7 +21,7 @@ int testCommandLineArguments1(int argc, char* argv[])
arg.Initialize(argc, argv);
int n = 0;
- char* m = KWSYS_NULLPTR;
+ char* m = nullptr;
std::string p;
int res = 0;
@@ -55,11 +55,11 @@ int testCommandLineArguments1(int argc, char* argv[])
delete[] m;
}
- char** newArgv = KWSYS_NULLPTR;
+ char** newArgv = nullptr;
int newArgc = 0;
arg.GetUnusedArguments(&newArgc, &newArgv);
int cc;
- const char* valid_unused_args[9] = { KWSYS_NULLPTR,
+ const char* valid_unused_args[9] = { nullptr,
"--ignored",
"--second-ignored",
"third-ignored",
diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx
index b6ad1188d..4b7ddf053 100644
--- a/Source/kwsys/testConsoleBuf.cxx
+++ b/Source/kwsys/testConsoleBuf.cxx
@@ -51,7 +51,7 @@ static void displayError(DWORD errorCode)
LPWSTR message;
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, errorCode, 0, (LPWSTR)&message, 0, NULL)) {
+ nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) {
std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message)
<< std::endl;
HeapFree(GetProcessHeap(), 0, message);
@@ -124,7 +124,7 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
}
WCHAR cmd[MAX_PATH];
- if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) {
+ if (GetModuleFileNameW(nullptr, cmd, MAX_PATH) == 0) {
std::cerr << "GetModuleFileName failed!" << std::endl;
return false;
}
@@ -136,14 +136,14 @@ static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
wcscat(cmd, L".exe");
bool success =
- CreateProcessW(NULL, // No module name (use command line)
+ CreateProcessW(nullptr, // No module name (use command line)
cmd, // Command line
- NULL, // Process handle not inheritable
- NULL, // Thread handle not inheritable
+ nullptr, // Process handle not inheritable
+ nullptr, // Thread handle not inheritable
bInheritHandles, // Set handle inheritance
dwCreationFlags,
- NULL, // Use parent's environment block
- NULL, // Use parent's starting directory
+ nullptr, // Use parent's environment block
+ nullptr, // Use parent's starting directory
&startupInfo, // Pointer to STARTUPINFO structure
&processInfo) !=
0; // Pointer to PROCESS_INFORMATION structure
@@ -174,7 +174,7 @@ static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = TRUE;
- securityAttributes.lpSecurityDescriptor = NULL;
+ securityAttributes.lpSecurityDescriptor = nullptr;
return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0 ? false
: true;
}
@@ -194,7 +194,7 @@ static HANDLE createFile(LPCWSTR fileName)
SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = TRUE;
- securityAttributes.lpSecurityDescriptor = NULL;
+ securityAttributes.lpSecurityDescriptor = nullptr;
HANDLE file =
CreateFileW(fileName, GENERIC_READ | GENERIC_WRITE,
@@ -202,7 +202,7 @@ static HANDLE createFile(LPCWSTR fileName)
&securityAttributes,
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
- NULL); // no template
+ nullptr); // no template
if (file == INVALID_HANDLE_VALUE) {
DWORD lastError = GetLastError();
std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")"
@@ -288,7 +288,7 @@ static int testPipe()
DWORD bytesWritten = 0;
if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
(DWORD)encodedInputTestString.size(), &bytesWritten,
- NULL) ||
+ nullptr) ||
bytesWritten == 0) {
throw std::runtime_error("WriteFile failed!");
}
@@ -305,7 +305,8 @@ static int testPipe()
throw std::runtime_error("WaitForSingleObject failed!");
}
DWORD bytesRead = 0;
- if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL) ||
+ if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead,
+ nullptr) ||
bytesRead == 0) {
throw std::runtime_error("ReadFile#1 failed!");
}
@@ -313,7 +314,7 @@ static int testPipe()
if ((bytesRead <
encodedTestString.size() + 1 + encodedInputTestString.size() &&
!ReadFile(outPipeRead, buffer + bytesRead,
- sizeof(buffer) - bytesRead, &bytesRead, NULL)) ||
+ sizeof(buffer) - bytesRead, &bytesRead, nullptr)) ||
bytesRead == 0) {
throw std::runtime_error("ReadFile#2 failed!");
}
@@ -324,7 +325,7 @@ static int testPipe()
encodedInputTestString.size()) == 0) {
bytesRead = 0;
if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead,
- NULL) ||
+ nullptr) ||
bytesRead == 0) {
throw std::runtime_error("ReadFile#3 failed!");
}
@@ -383,13 +384,13 @@ static int testFile()
char buffer2[200];
int length;
- if ((length =
- WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
- buffer, sizeof(buffer), NULL, NULL)) == 0) {
+ if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString,
+ -1, buffer, sizeof(buffer), nullptr,
+ nullptr)) == 0) {
throw std::runtime_error("WideCharToMultiByte failed!");
}
buffer[length - 1] = '\n';
- if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL) ||
+ if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) ||
bytesWritten == 0) {
throw std::runtime_error("WriteFile failed!");
}
@@ -413,7 +414,7 @@ static int testFile()
INVALID_SET_FILE_POINTER) {
throw std::runtime_error("SetFilePointer#1 failed!");
}
- if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL) ||
+ if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) ||
bytesRead == 0) {
throw std::runtime_error("ReadFile#1 failed!");
}
@@ -429,7 +430,8 @@ static int testFile()
throw std::runtime_error("SetFilePointer#2 failed!");
}
- if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL) ||
+ if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead,
+ nullptr) ||
bytesRead == 0) {
throw std::runtime_error("ReadFile#2 failed!");
}
@@ -519,12 +521,12 @@ static int testConsole()
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
&hConsoleKey) == ERROR_SUCCESS) {
DWORD dwordSize = sizeof(DWORD);
- if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL,
+ if (RegQueryValueExW(hConsoleKey, L"FontFamily", nullptr, nullptr,
(LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
if (FontFamily != TestFontFamily) {
- RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL,
+ RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr,
(LPBYTE)FaceName, &FaceNameSize);
- RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL,
+ RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr,
(LPBYTE)&FontSize, &dwordSize);
RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
@@ -557,10 +559,10 @@ static int testConsole()
SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = TRUE;
- securityAttributes.lpSecurityDescriptor = NULL;
+ securityAttributes.lpSecurityDescriptor = nullptr;
hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
- OPEN_EXISTING, 0, NULL);
+ OPEN_EXISTING, 0, nullptr);
if (hIn == INVALID_HANDLE_VALUE) {
DWORD lastError = GetLastError();
std::cerr << "CreateFile(CONIN$)" << std::endl;
@@ -568,7 +570,7 @@ static int testConsole()
}
hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes,
- OPEN_EXISTING, 0, NULL);
+ OPEN_EXISTING, 0, nullptr);
if (hOut == INVALID_HANDLE_VALUE) {
DWORD lastError = GetLastError();
std::cerr << "CreateFile(CONOUT$)" << std::endl;
@@ -630,7 +632,7 @@ static int testConsole()
}
# endif
- if (createProcess(NULL, NULL, NULL)) {
+ if (createProcess(nullptr, nullptr, nullptr)) {
try {
DWORD status;
if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) !=
@@ -746,7 +748,7 @@ int testConsoleBuf(int, char* [])
int ret = 0;
#if defined(_WIN32)
- beforeInputEvent = CreateEventW(NULL,
+ beforeInputEvent = CreateEventW(nullptr,
FALSE, // auto-reset event
FALSE, // initial state is nonsignaled
BeforeInputEventName); // object name
@@ -755,7 +757,7 @@ int testConsoleBuf(int, char* [])
return 1;
}
- afterOutputEvent = CreateEventW(NULL, FALSE, FALSE, AfterOutputEventName);
+ afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName);
if (!afterOutputEvent) {
std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl;
return 1;
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index eff2ed7ee..2421ac0e1 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -21,7 +21,7 @@
// left on disk.
#include <testSystemTools.h>
-static std::string GetLibName(const char* lname, const char* subdir = NULL)
+static std::string GetLibName(const char* lname, const char* subdir = nullptr)
{
// Construct proper name of lib
std::string slname;
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index fdad1cdff..988697bff 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -84,7 +84,7 @@ static int testRobustEncoding()
// this conversion could fail
std::wstring wstr = kwsys::Encoding::ToWide(cstr);
- wstr = kwsys::Encoding::ToWide(KWSYS_NULLPTR);
+ wstr = kwsys::Encoding::ToWide(nullptr);
if (wstr != L"") {
const wchar_t* wcstr = wstr.c_str();
std::cout << "ToWide(NULL) returned";
@@ -112,7 +112,7 @@ static int testRobustEncoding()
std::string win_str = kwsys::Encoding::ToNarrow(cwstr);
#endif
- std::string str = kwsys::Encoding::ToNarrow(KWSYS_NULLPTR);
+ std::string str = kwsys::Encoding::ToNarrow(nullptr);
if (str != "") {
std::cout << "ToNarrow(NULL) returned " << str << std::endl;
ret++;
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index f139f5860..39aaa23ba 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -477,7 +477,7 @@ static int runChild2(kwsysProcess* kp, const char* cmd[], int state,
printf("Error in administrating child process: [%s]\n",
kwsysProcess_GetErrorString(kp));
break;
- };
+ }
if (result) {
if (exception != kwsysProcess_GetExitException(kp)) {
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index ffa6a297d..1f3a15b59 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -52,7 +52,7 @@ static const char* toUnixPaths[][2] = {
{ "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
{ "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
{ "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo/ cal/bin/pa/ sswd" },
- { KWSYS_NULLPTR, KWSYS_NULLPTR }
+ { nullptr, nullptr }
};
static bool CheckConvertToUnixSlashes(std::string const& input,
@@ -71,7 +71,7 @@ static bool CheckConvertToUnixSlashes(std::string const& input,
static const char* checkEscapeChars[][4] = {
{ "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2" },
{ " {} ", "{}", "#", " #{#} " },
- { KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR, KWSYS_NULLPTR }
+ { nullptr, nullptr, nullptr, nullptr }
};
static bool CheckEscapeChars(std::string const& input,
@@ -160,7 +160,7 @@ static bool CheckFileOperations()
res = false;
}
// calling with 0 pointer should return false
- if (kwsys::SystemTools::MakeDirectory(KWSYS_NULLPTR)) {
+ if (kwsys::SystemTools::MakeDirectory(nullptr)) {
std::cerr << "Problem with MakeDirectory(0)" << std::endl;
res = false;
}
@@ -218,11 +218,11 @@ static bool CheckFileOperations()
}
// calling with 0 pointer should return false
- if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR)) {
+ if (kwsys::SystemTools::FileExists(nullptr)) {
std::cerr << "Problem with FileExists(0)" << std::endl;
res = false;
}
- if (kwsys::SystemTools::FileExists(KWSYS_NULLPTR, true)) {
+ if (kwsys::SystemTools::FileExists(nullptr, true)) {
std::cerr << "Problem with FileExists(0) as file" << std::endl;
res = false;
}
@@ -999,30 +999,45 @@ static bool writeFile(const char* fileName, const char* data)
return true;
}
+static std::string readFile(const char* fileName)
+{
+ kwsys::ifstream in(fileName, std::ios::binary);
+ std::stringstream sstr;
+ sstr << in.rdbuf();
+ std::string data = sstr.str();
+ if (!in) {
+ std::cerr << "Failed to read file: " << fileName << std::endl;
+ return std::string();
+ }
+ return data;
+}
+
+struct
+{
+ const char* a;
+ const char* b;
+ bool differ;
+} diff_test_cases[] = { { "one", "one", false },
+ { "one", "two", true },
+ { "", "", false },
+ { "\n", "\r\n", false },
+ { "one\n", "one\n", false },
+ { "one\r\n", "one\n", false },
+ { "one\n", "one", false },
+ { "one\ntwo", "one\ntwo", false },
+ { "one\ntwo", "one\r\ntwo", false } };
+
static bool CheckTextFilesDiffer()
{
- struct
- {
- const char* a;
- const char* b;
- bool differ;
- } test_cases[] = { { "one", "one", false },
- { "one", "two", true },
- { "", "", false },
- { "\n", "\r\n", false },
- { "one\n", "one\n", false },
- { "one\r\n", "one\n", false },
- { "one\n", "one", false },
- { "one\ntwo", "one\ntwo", false },
- { "one\ntwo", "one\r\ntwo", false } };
- const int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+ const int num_test_cases =
+ sizeof(diff_test_cases) / sizeof(diff_test_cases[0]);
for (int i = 0; i < num_test_cases; ++i) {
- if (!writeFile("file_a", test_cases[i].a) ||
- !writeFile("file_b", test_cases[i].b)) {
+ if (!writeFile("file_a", diff_test_cases[i].a) ||
+ !writeFile("file_b", diff_test_cases[i].b)) {
return false;
}
if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") !=
- test_cases[i].differ) {
+ diff_test_cases[i].differ) {
std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1
<< "." << std::endl;
return false;
@@ -1032,6 +1047,36 @@ static bool CheckTextFilesDiffer()
return true;
}
+static bool CheckCopyFileIfDifferent()
+{
+ bool ret = true;
+ const int num_test_cases =
+ sizeof(diff_test_cases) / sizeof(diff_test_cases[0]);
+ for (int i = 0; i < num_test_cases; ++i) {
+ if (!writeFile("file_a", diff_test_cases[i].a) ||
+ !writeFile("file_b", diff_test_cases[i].b)) {
+ return false;
+ }
+ const char* cptarget =
+ i < 4 ? TEST_SYSTEMTOOLS_BINARY_DIR "/file_b" : "file_b";
+ if (!kwsys::SystemTools::CopyFileIfDifferent("file_a", cptarget)) {
+ std::cerr << "CopyFileIfDifferent() returned false for test case "
+ << i + 1 << "." << std::endl;
+ ret = false;
+ continue;
+ }
+ std::string bdata = readFile("file_b");
+ if (diff_test_cases[i].a != bdata) {
+ std::cerr << "Incorrect CopyFileIfDifferent file contents in test case "
+ << i + 1 << "." << std::endl;
+ ret = false;
+ continue;
+ }
+ }
+
+ return ret;
+}
+
int testSystemTools(int, char* [])
{
bool res = true;
@@ -1077,5 +1122,7 @@ int testSystemTools(int, char* [])
res &= CheckTextFilesDiffer();
+ res &= CheckCopyFileIfDifferent();
+
return res ? 0 : 1;
}