summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt17
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx51
-rw-r--r--Source/CPack/cmCPackGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx50
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx3
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx66
-rw-r--r--Source/CPack/cmCPackPKGGenerator.h8
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx5
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx9
-rw-r--r--Source/CTest/cmCTestBZR.cxx5
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx8
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx11
-rw-r--r--Source/CTest/cmCTestBuildCommand.h2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx5
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx7
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx13
-rw-r--r--Source/CTest/cmCTestCurl.cxx9
-rw-r--r--Source/CTest/cmCTestHG.cxx5
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx182
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h4
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx92
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h22
-rw-r--r--Source/CTest/cmCTestP4.cxx5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx34
-rw-r--r--Source/CTest/cmCTestRunTest.h23
-rw-r--r--Source/CTest/cmCTestSVN.cxx7
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx7
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx5
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx18
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx4
-rw-r--r--Source/CTest/cmCTestTestCommand.h1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx44
-rw-r--r--Source/CTest/cmCTestTestHandler.h5
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx6
-rw-r--r--Source/CTest/cmProcess.cxx29
-rw-r--r--Source/CTest/cmProcess.h1
-rw-r--r--Source/Checks/Curses.cmake9
-rw-r--r--Source/Checks/cm_c11_thread_local.cmake10
-rw-r--r--Source/Checks/cm_cxx14_check.cmake12
-rw-r--r--Source/Checks/cm_cxx17_check.cmake12
-rw-r--r--Source/Checks/cm_cxx17_check.cpp10
-rw-r--r--Source/Checks/cm_cxx_features.cmake14
-rw-r--r--Source/Checks/cm_message_checks_compat.cmake13
-rw-r--r--Source/CursesDialog/CMakeLists.txt25
-rw-r--r--Source/CursesDialog/ccmake.cxx24
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx15
-rw-r--r--Source/CursesDialog/cmCursesColor.cxx29
-rw-r--r--Source/CursesDialog/cmCursesColor.h24
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx26
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h9
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx271
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h25
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.cxx10
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx8
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx10
-rw-r--r--Source/LexerParser/.gitattributes2
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.cxx121
-rw-r--r--Source/LexerParser/cmCommandArgumentParserTokens.h2
-rw-r--r--Source/LexerParser/cmDependsJavaParser.cxx1381
-rw-r--r--Source/LexerParser/cmDependsJavaParserTokens.h2
-rw-r--r--Source/LexerParser/cmExprParser.cxx121
-rw-r--r--Source/LexerParser/cmExprParserTokens.h2
-rw-r--r--Source/LexerParser/cmFortranParser.cxx372
-rw-r--r--Source/LexerParser/cmFortranParser.y1
-rw-r--r--Source/LexerParser/cmFortranParserTokens.h9
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.cxx2210
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.h687
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.in.l72
-rw-r--r--Source/QtDialog/CMakeLists.txt4
-rw-r--r--Source/QtDialog/QCMake.cxx3
-rw-r--r--Source/bindexplib.cxx53
-rw-r--r--Source/cmAddCustomCommandCommand.cxx11
-rw-r--r--Source/cmAddCustomTargetCommand.cxx7
-rw-r--r--Source/cmAddDependenciesCommand.cxx2
-rw-r--r--Source/cmAddLibraryCommand.cxx5
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx3
-rw-r--r--Source/cmAddTestCommand.cxx6
-rw-r--r--Source/cmAlgorithms.h64
-rw-r--r--Source/cmArchiveWrite.cxx10
-rw-r--r--Source/cmCPluginAPI.cxx6
-rw-r--r--Source/cmCPluginAPI.h4
-rw-r--r--Source/cmCTest.cxx85
-rw-r--r--Source/cmCTest.h20
-rw-r--r--Source/cmCacheManager.cxx25
-rw-r--r--Source/cmCacheManager.h30
-rw-r--r--Source/cmCommands.cxx3
-rw-r--r--Source/cmCommonTargetGenerator.cxx96
-rw-r--r--Source/cmCommonTargetGenerator.h41
-rw-r--r--Source/cmComputeComponentGraph.cxx2
-rw-r--r--Source/cmComputeLinkDepends.cxx6
-rw-r--r--Source/cmComputeLinkDepends.h3
-rw-r--r--Source/cmComputeLinkInformation.cxx63
-rw-r--r--Source/cmComputeLinkInformation.h11
-rw-r--r--Source/cmComputeTargetDepends.cxx51
-rw-r--r--Source/cmComputeTargetDepends.h4
-rw-r--r--Source/cmConditionEvaluator.cxx4
-rw-r--r--Source/cmCoreTryCompile.cxx7
-rw-r--r--Source/cmCustomCommand.cxx18
-rw-r--r--Source/cmCustomCommand.h8
-rw-r--r--Source/cmCustomCommandGenerator.cxx20
-rw-r--r--Source/cmDependsC.h3
-rw-r--r--Source/cmDocumentationSection.h5
-rw-r--r--Source/cmELF.cxx5
-rw-r--r--Source/cmExecuteProcessCommand.cxx5
-rw-r--r--Source/cmExportBuildFileGenerator.cxx6
-rw-r--r--Source/cmExportBuildFileGenerator.h5
-rw-r--r--Source/cmExportCommand.cxx14
-rw-r--r--Source/cmExportFileGenerator.cxx14
-rw-r--r--Source/cmExportFileGenerator.h2
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx2
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx13
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx3
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h9
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx30
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx21
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx63
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h2
-rw-r--r--Source/cmExtraKateGenerator.cxx47
-rw-r--r--Source/cmExtraKateGenerator.h8
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx15
-rw-r--r--Source/cmExtraSublimeTextGenerator.h3
-rw-r--r--Source/cmFLTKWrapUICommand.cxx16
-rw-r--r--Source/cmFileAPICMakeFiles.cxx3
-rw-r--r--Source/cmFileAPICodemodel.cxx20
-rw-r--r--Source/cmFileCommand.cxx14
-rw-r--r--Source/cmFileLock.cxx25
-rw-r--r--Source/cmFileLock.h2
-rw-r--r--Source/cmFileLockPool.cxx52
-rw-r--r--Source/cmFileLockPool.h14
-rw-r--r--Source/cmFileMonitor.cxx35
-rw-r--r--Source/cmFileMonitor.h3
-rw-r--r--Source/cmFindBase.cxx136
-rw-r--r--Source/cmFindBase.h32
-rw-r--r--Source/cmFindCommon.cxx22
-rw-r--r--Source/cmFindCommon.h9
-rw-r--r--Source/cmFindLibraryCommand.cxx68
-rw-r--r--Source/cmFindPackageCommand.cxx155
-rw-r--r--Source/cmFindPackageCommand.h2
-rw-r--r--Source/cmFindPathCommand.cxx17
-rw-r--r--Source/cmFindPathCommand.h4
-rw-r--r--Source/cmFindProgramCommand.cxx19
-rw-r--r--Source/cmForEachCommand.cxx422
-rw-r--r--Source/cmFunctionCommand.cxx80
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx126
-rw-r--r--Source/cmGccDepfileLexerHelper.h40
-rw-r--r--Source/cmGccDepfileReader.cxx18
-rw-r--r--Source/cmGccDepfileReader.h10
-rw-r--r--Source/cmGccDepfileReaderTypes.h17
-rw-r--r--Source/cmGeneratorExpression.cxx24
-rw-r--r--Source/cmGeneratorExpression.h5
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx21
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h16
-rw-r--r--Source/cmGeneratorExpressionNode.cxx2
-rw-r--r--Source/cmGeneratorExpressionParser.cxx66
-rw-r--r--Source/cmGeneratorExpressionParser.h10
-rw-r--r--Source/cmGeneratorTarget.cxx404
-rw-r--r--Source/cmGeneratorTarget.h77
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx6
-rw-r--r--Source/cmGlobVerificationManager.cxx2
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx13
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h10
-rw-r--r--Source/cmGlobalCommonGenerator.cxx9
-rw-r--r--Source/cmGlobalGenerator.cxx292
-rw-r--r--Source/cmGlobalGenerator.h67
-rw-r--r--Source/cmGlobalGeneratorFactory.h14
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx14
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h12
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx2
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h6
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h7
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h8
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx2
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h7
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx1006
-rw-r--r--Source/cmGlobalNinjaGenerator.h268
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx322
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h19
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx80
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h15
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx24
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx31
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx15
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h12
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx27
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h19
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx52
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx46
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx46
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h5
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h6
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx134
-rw-r--r--Source/cmGlobalXCodeGenerator.h9
-rw-r--r--Source/cmGraphAdjacencyList.h6
-rw-r--r--Source/cmGraphVizWriter.cxx723
-rw-r--r--Source/cmGraphVizWriter.h93
-rw-r--r--Source/cmIDEOptions.cxx6
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx7
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx17
-rw-r--r--Source/cmInstallCommand.cxx161
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx16
-rw-r--r--Source/cmInstallDirectoryGenerator.h21
-rw-r--r--Source/cmInstallExportGenerator.cxx14
-rw-r--r--Source/cmInstallExportGenerator.h20
-rw-r--r--Source/cmInstallFilesCommand.cxx22
-rw-r--r--Source/cmInstallFilesGenerator.cxx15
-rw-r--r--Source/cmInstallFilesGenerator.h18
-rw-r--r--Source/cmInstallGenerator.cxx15
-rw-r--r--Source/cmInstallGenerator.h14
-rw-r--r--Source/cmInstallProgramsCommand.cxx22
-rw-r--r--Source/cmInstallScriptGenerator.cxx12
-rw-r--r--Source/cmInstallScriptGenerator.h9
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx12
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h6
-rw-r--r--Source/cmInstallTargetGenerator.cxx14
-rw-r--r--Source/cmInstallTargetGenerator.h20
-rw-r--r--Source/cmInstalledFile.cxx17
-rw-r--r--Source/cmInstalledFile.h4
-rw-r--r--Source/cmJsonObjects.cxx22
-rw-r--r--Source/cmLinkItem.cxx15
-rw-r--r--Source/cmLinkItem.h5
-rw-r--r--Source/cmLinkItemGraphVisitor.cxx142
-rw-r--r--Source/cmLinkItemGraphVisitor.h75
-rw-r--r--Source/cmLinkLibrariesCommand.cxx2
-rw-r--r--Source/cmLinkLineComputer.cxx38
-rw-r--r--Source/cmLinkLineComputer.h2
-rw-r--r--Source/cmLoadCacheCommand.cxx8
-rw-r--r--Source/cmLoadCommandCommand.cxx9
-rw-r--r--Source/cmLocalCommonGenerator.cxx10
-rw-r--r--Source/cmLocalCommonGenerator.h8
-rw-r--r--Source/cmLocalGenerator.cxx807
-rw-r--r--Source/cmLocalGenerator.h121
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx7
-rw-r--r--Source/cmLocalNinjaGenerator.cxx143
-rw-r--r--Source/cmLocalNinjaGenerator.h24
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx103
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h4
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx11
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx123
-rw-r--r--Source/cmLocalVisualStudio7Generator.h6
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx4
-rw-r--r--Source/cmLocalXCodeGenerator.cxx4
-rw-r--r--Source/cmMacroCommand.cxx6
-rw-r--r--Source/cmMakefile.cxx858
-rw-r--r--Source/cmMakefile.h194
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx74
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx117
-rw-r--r--Source/cmMakefileTargetGenerator.cxx204
-rw-r--r--Source/cmMakefileTargetGenerator.h25
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx3
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx62
-rw-r--r--Source/cmMessageCommand.cxx135
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx549
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h27
-rw-r--r--Source/cmNinjaTargetGenerator.cxx360
-rw-r--r--Source/cmNinjaTargetGenerator.h112
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx51
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.h4
-rw-r--r--Source/cmOSXBundleGenerator.cxx71
-rw-r--r--Source/cmOSXBundleGenerator.h21
-rw-r--r--Source/cmOrderDirectories.cxx29
-rw-r--r--Source/cmOrderDirectories.h6
-rw-r--r--Source/cmOutputConverter.cxx23
-rw-r--r--Source/cmOutputConverter.h9
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx54
-rw-r--r--Source/cmPolicies.h20
-rw-r--r--Source/cmProjectCommand.cxx5
-rw-r--r--Source/cmPropertyMap.cxx6
-rw-r--r--Source/cmPropertyMap.h2
-rw-r--r--Source/cmQtAutoGen.cxx6
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx36
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h2
-rw-r--r--Source/cmQtAutoGenInitializer.cxx297
-rw-r--r--Source/cmQtAutoGenInitializer.h5
-rw-r--r--Source/cmQtAutoMocUic.cxx222
-rw-r--r--Source/cmQtAutoRcc.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmScriptGenerator.h2
-rw-r--r--Source/cmSearchPath.cxx8
-rw-r--r--Source/cmSearchPath.h2
-rw-r--r--Source/cmServerProtocol.cxx4
-rw-r--r--Source/cmSetCommand.cxx2
-rw-r--r--Source/cmSetPropertyCommand.cxx117
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx7
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx5
-rw-r--r--Source/cmSourceFile.cxx14
-rw-r--r--Source/cmSourceFile.h7
-rw-r--r--Source/cmSourceFileLocation.cxx3
-rw-r--r--Source/cmState.cxx88
-rw-r--r--Source/cmState.h14
-rw-r--r--Source/cmStateDirectory.cxx5
-rw-r--r--Source/cmStateDirectory.h2
-rw-r--r--Source/cmStateSnapshot.cxx4
-rw-r--r--Source/cmString.hxx212
-rw-r--r--Source/cmSystemTools.cxx19
-rw-r--r--Source/cmTarget.cxx140
-rw-r--r--Source/cmTarget.h18
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx2
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx11
-rw-r--r--Source/cmTargetDepend.h4
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx204
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx5
-rw-r--r--Source/cmTargetPropCommandBase.cxx9
-rw-r--r--Source/cmTargetPropertyComputer.cxx1
-rw-r--r--Source/cmTargetPropertyComputer.h12
-rw-r--r--Source/cmTargetSourcesCommand.cxx3
-rw-r--r--Source/cmTest.cxx2
-rw-r--r--Source/cmTest.h2
-rw-r--r--Source/cmVariableWatch.cxx14
-rw-r--r--Source/cmVariableWatch.h4
-rw-r--r--Source/cmVariableWatchCommand.cxx71
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx148
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h3
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx44
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h13
-rw-r--r--Source/cmXCodeScheme.cxx28
-rw-r--r--Source/cmXCodeScheme.h6
-rw-r--r--Source/cmake.cxx292
-rw-r--r--Source/cmake.h84
-rw-r--r--Source/cmakemain.cxx27
-rw-r--r--Source/cmcmd.cxx243
-rw-r--r--Source/cmcmd.h3
-rw-r--r--Source/ctest.cxx12
-rw-r--r--Source/kwsys/CTestCustom.cmake.in4
-rw-r--r--Source/kwsys/Encoding.hxx.in2
-rw-r--r--Source/kwsys/EncodingCXX.cxx14
-rw-r--r--Source/kwsys/FStream.hxx.in14
-rw-r--r--Source/kwsys/RegularExpression.hxx.in17
-rw-r--r--Source/kwsys/SystemTools.cxx35
-rw-r--r--Source/kwsys/Terminal.c9
-rw-r--r--Source/kwsys/testSystemTools.cxx9
343 files changed, 14453 insertions, 6107 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b1f7b29e58..c57f71347d 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -134,6 +134,9 @@ set(SRCS
LexerParser/cmFortranParser.cxx
LexerParser/cmFortranParserTokens.h
LexerParser/cmFortranParser.y
+ LexerParser/cmGccDepfileLexer.cxx
+ LexerParser/cmGccDepfileLexer.h
+ LexerParser/cmGccDepfileLexer.in.l
LexerParser/cmListFileLexer.c
LexerParser/cmListFileLexer.in.l
@@ -270,6 +273,10 @@ set(SRCS
cmFortranParserImpl.cxx
cmFSPermissions.cxx
cmFSPermissions.h
+ cmGccDepfileLexerHelper.cxx
+ cmGccDepfileLexerHelper.h
+ cmGccDepfileReader.cxx
+ cmGccDepfileReader.h
cmGeneratedFileStream.cxx
cmGeneratorExpressionContext.cxx
cmGeneratorExpressionContext.h
@@ -289,6 +296,8 @@ set(SRCS
cmGeneratorExpression.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
+ cmLinkItemGraphVisitor.cxx
+ cmLinkItemGraphVisitor.h
cmGetPipes.cxx
cmGetPipes.h
cmGlobalCommonGenerator.cxx
@@ -691,6 +700,8 @@ set(SRCS
cmDuration.h
cmDuration.cxx
+
+ bindexplib.cxx
)
SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
@@ -713,7 +724,6 @@ if (WIN32)
set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h
- bindexplib.cxx
)
if(NOT UNIX)
@@ -1193,6 +1203,11 @@ if(WIN32)
endforeach()
endif()
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET ${_tools} PROPERTY JOB_POOL_LINK "link-bin")
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS "link-bin=${CMake_JOB_POOL_LINK_BIN}")
+endif()
+
# Install tools
foreach(_tool ${_tools})
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 6a8d2fcdd8..de3f0507d7 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 16)
-set(CMake_VERSION_PATCH 5)
+set(CMake_VERSION_MINOR 17)
+set(CMake_VERSION_PATCH 0)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index ea7100708f..fe7abf4223 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -138,11 +138,16 @@ int cmCPackDragNDropGenerator::InitializeInternal()
}
for (auto const& language : languages) {
std::string license = slaDirectory + "/" + language + ".license.txt";
- if (!singleLicense && !cmSystemTools::FileExists(license)) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Missing license file " << language << ".license.txt"
- << std::endl);
- return 0;
+ std::string license_rtf = slaDirectory + "/" + language + ".license.rtf";
+ if (!singleLicense) {
+ if (!cmSystemTools::FileExists(license) &&
+ !cmSystemTools::FileExists(license_rtf)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing license file "
+ << language << ".license.txt"
+ << " / " << language << ".license.rtf" << std::endl);
+ return 0;
+ }
}
std::string menu = slaDirectory + "/" + language + ".menu.txt";
if (!cmSystemTools::FileExists(menu)) {
@@ -775,6 +780,11 @@ std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
}
}
+ std::string componentFileName =
+ "CPACK_DMG_" + cmSystemTools::UpperCase(componentName) + "_FILE_NAME";
+ if (this->IsSet(componentFileName)) {
+ return this->GetOption(componentFileName);
+ }
return GetComponentPackageFileName(package_file_name, componentName, false);
}
@@ -788,13 +798,29 @@ bool cmCPackDragNDropGenerator::WriteLicense(
licenseLanguage = "English";
}
+ // License file
+ std::string license_format = "TEXT";
+ std::string actual_license;
+ if (!licenseFile.empty()) {
+ if (cmHasLiteralSuffix(licenseFile, ".rtf")) {
+ license_format = "RTF ";
+ }
+ actual_license = licenseFile;
+ } else {
+ std::string license_wo_ext =
+ slaDirectory + "/" + licenseLanguage + ".license";
+ if (cmSystemTools::FileExists(license_wo_ext + ".txt")) {
+ actual_license = license_wo_ext + ".txt";
+ } else {
+ license_format = "RTF ";
+ actual_license = license_wo_ext + ".rtf";
+ }
+ }
+
// License header
- outputStream << "data 'TEXT' (" << licenseNumber << ", \"" << licenseLanguage
- << "\") {\n";
+ outputStream << "data '" << license_format << "' (" << licenseNumber
+ << ", \"" << licenseLanguage << "\") {\n";
// License body
- std::string actual_license = !licenseFile.empty()
- ? licenseFile
- : (slaDirectory + "/" + licenseLanguage + ".license.txt");
cmsys::ifstream license_ifs;
license_ifs.open(actual_license.c_str());
if (license_ifs.is_open()) {
@@ -873,8 +899,9 @@ bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
std::string* error)
{
const size_t max_line_length = 512;
- for (size_t i = 0; i < line.size(); i += max_line_length) {
- size_t line_length = max_line_length;
+ size_t line_length = max_line_length;
+ for (size_t i = 0; i < line.size(); i += line_length) {
+ line_length = max_line_length;
if (i + line_length > line.size()) {
line_length = line.size() - i;
} else {
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 6698f3c11c..712eb779cd 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -621,9 +621,9 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
buildConfigs.emplace_back();
}
- std::unique_ptr<cmGlobalGenerator> globalGenerator(
+ std::unique_ptr<cmGlobalGenerator> globalGenerator =
this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
- cmakeGenerator));
+ cmakeGenerator);
if (!globalGenerator) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Specified package generator not found. "
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 9bf72dfb88..363f536822 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -128,22 +128,26 @@ int cmCPackNSISGenerator::PackageFiles()
this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
std::string installerIconCode;
if (this->IsSet("CPACK_NSIS_MUI_ICON")) {
- installerIconCode += "!define MUI_ICON \"";
- installerIconCode += this->GetOption("CPACK_NSIS_MUI_ICON");
- installerIconCode += "\"\n";
+ installerIconCode += cmStrCat(
+ "!define MUI_ICON \"", this->GetOption("CPACK_NSIS_MUI_ICON"), "\"\n");
}
if (this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
- installerIconCode += "!define MUI_UNICON \"";
- installerIconCode += this->GetOption("CPACK_NSIS_MUI_UNIICON");
- installerIconCode += "\"\n";
+ installerIconCode +=
+ cmStrCat("!define MUI_UNICON \"",
+ this->GetOption("CPACK_NSIS_MUI_UNIICON"), "\"\n");
}
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
installerIconCode.c_str());
}
- if (this->IsSet("CPACK_PACKAGE_ICON")) {
- std::string installerIconCode =
- cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"",
- this->GetOption("CPACK_PACKAGE_ICON"), "\"\n");
+ std::string installerHeaderImage;
+ if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) {
+ installerHeaderImage = this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE");
+ } else if (this->IsSet("CPACK_PACKAGE_ICON")) {
+ installerHeaderImage = this->GetOption("CPACK_PACKAGE_ICON");
+ }
+ if (!installerHeaderImage.empty()) {
+ std::string installerIconCode = cmStrCat(
+ "!define MUI_HEADERIMAGE_BITMAP \"", installerHeaderImage, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
installerIconCode.c_str());
}
@@ -173,6 +177,32 @@ int cmCPackNSISGenerator::PackageFiles()
installerRunCode.c_str());
}
+ if (this->IsSet("CPACK_NSIS_WELCOME_TITLE")) {
+ std::string welcomeTitleCode =
+ cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"",
+ this->GetOption("CPACK_NSIS_WELCOME_TITLE"), "\"");
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE",
+ welcomeTitleCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_WELCOME_TITLE_3LINES")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE",
+ "!define MUI_WELCOMEPAGE_TITLE_3LINES");
+ }
+
+ if (this->IsSet("CPACK_NSIS_FINISH_TITLE")) {
+ std::string finishTitleCode =
+ cmStrCat("!define MUI_FINISHPAGE_TITLE \"",
+ this->GetOption("CPACK_NSIS_FINISH_TITLE"), "\"");
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE",
+ finishTitleCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_FINISH_TITLE_3LINES")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE",
+ "!define MUI_FINISHPAGE_TITLE_3LINES");
+ }
+
// Setup all of the component sections
if (this->Components.empty()) {
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 951c65f4d3..5de4a6f3fe 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -178,6 +178,9 @@ int cmCPackOSXX11Generator::PackageFiles()
int cmCPackOSXX11Generator::InitializeInternal()
{
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "The OSXX11 generator is deprecated "
+ "and will be removed in a future version.\n");
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"cmCPackOSXX11Generator::Initialize()" << std::endl);
std::vector<std::string> path;
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index dae5ec9d4b..ac3d64d9ae 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -46,7 +46,66 @@ std::string cmCPackPKGGenerator::GetPackageName(
return component.ArchiveFile + ".pkg";
}
-void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
+void cmCPackPKGGenerator::CreateBackground(const char* themeName,
+ const char* metapackageFile,
+ cm::string_view genName,
+ cmXMLWriter& xout)
+{
+ std::string paramSuffix =
+ (themeName == nullptr) ? "" : cmSystemTools::UpperCase(themeName);
+ std::string opt = (themeName == nullptr)
+ ? cmStrCat("CPACK_", genName, "_BACKGROUND")
+ : cmStrCat("CPACK_", genName, "_BACKGROUND_", paramSuffix);
+ const char* bgFileName = this->GetOption(opt);
+ if (bgFileName == nullptr) {
+ return;
+ }
+
+ std::string bgFilePath = cmStrCat(metapackageFile, "/Contents/", bgFileName);
+
+ if (!cmSystemTools::FileExists(bgFilePath)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Background image doesn't exist in the resource directory: "
+ << bgFileName << std::endl);
+ return;
+ }
+
+ if (themeName == nullptr) {
+ xout.StartElement("background");
+ } else {
+ xout.StartElement(cmStrCat("background-", themeName));
+ }
+
+ xout.Attribute("file", bgFileName);
+
+ const char* param = this->GetOption(cmStrCat(opt, "_ALIGNMENT"));
+ if (param != nullptr) {
+ xout.Attribute("alignment", param);
+ }
+
+ param = this->GetOption(cmStrCat(opt, "_SCALING"));
+ if (param != nullptr) {
+ xout.Attribute("scaling", param);
+ }
+
+ // Apple docs say that you must provide either mime-type or uti
+ // attribute for the background, but I've seen examples that
+ // doesn't have them, so don't make them mandatory.
+ param = this->GetOption(cmStrCat(opt, "_MIME_TYPE"));
+ if (param != nullptr) {
+ xout.Attribute("mime-type", param);
+ }
+
+ param = this->GetOption(cmStrCat(opt, "_UTI"));
+ if (param != nullptr) {
+ xout.Attribute("uti", param);
+ }
+
+ xout.EndElement();
+}
+
+void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile,
+ const char* genName)
{
std::string distributionTemplate =
this->FindTemplate("CPack.distribution.dist.in");
@@ -102,6 +161,11 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
CreateChoice(PostFlightComponent, xout);
}
+ // default background
+ this->CreateBackground(nullptr, metapackageFile, genName, xout);
+ // Dark Aqua
+ this->CreateBackground("darkAqua", metapackageFile, genName, xout);
+
this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
// Create the distribution.dist file in the metapackage to turn it
diff --git a/Source/CPack/cmCPackPKGGenerator.h b/Source/CPack/cmCPackPKGGenerator.h
index 69286ffde6..be730abddf 100644
--- a/Source/CPack/cmCPackPKGGenerator.h
+++ b/Source/CPack/cmCPackPKGGenerator.h
@@ -9,6 +9,8 @@
#include <sstream>
#include <string>
+#include <cm/string_view>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
@@ -57,7 +59,7 @@ protected:
// inter-component dependencies. metapackageFile is the name of the
// metapackage for the distribution. Only valid for a
// component-based install.
- void WriteDistributionFile(const char* metapackageFile);
+ void WriteDistributionFile(const char* metapackageFile, const char* genName);
// Subroutine of WriteDistributionFile that writes out the
// dependency attributes for inter-component dependencies.
@@ -85,6 +87,10 @@ protected:
/// installer GUI.
void CreateChoice(const cmCPackComponent& component, cmXMLWriter& xout);
+ /// Creates a background in the distribution XML.
+ void CreateBackground(const char* themeName, const char* metapackageFile,
+ cm::string_view genName, cmXMLWriter& xout);
+
// The PostFlight component when creating a metapackage
cmCPackComponent PostFlightComponent;
};
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index c5ba726d50..f51ea42de9 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -279,7 +279,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
} else {
// We have built the package in place. Generate the
// distribution.dist file to describe it for the installer.
- WriteDistributionFile(packageDirFileName.c_str());
+ WriteDistributionFile(packageDirFileName.c_str(), "PACKAGEMAKER");
}
std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
@@ -321,6 +321,9 @@ int cmCPackPackageMakerGenerator::PackageFiles()
int cmCPackPackageMakerGenerator::InitializeInternal()
{
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "The PackageMaker generator is deprecated "
+ "and will be removed in a future version.\n");
this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
// Starting with Xcode 4.3, PackageMaker is a separate app, and you
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index dae268c5ce..a3e55de5c2 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -81,7 +81,7 @@ int cmCPackProductBuildGenerator::PackageFiles()
}
// combine package(s) into a distribution
- WriteDistributionFile(packageDirFileName.c_str());
+ WriteDistributionFile(packageDirFileName.c_str(), "PRODUCTBUILD");
std::ostringstream pkgCmd;
std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 58956522f4..dc316233c9 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -115,7 +115,6 @@ int main(int argc, char const* const* argv)
argc = args.argc();
argv = args.argv();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(argv[0]);
cmCPackLog log;
@@ -314,7 +313,7 @@ int main(int argc, char const* const* argv)
else {
// get a default value (current working directory)
cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
- // use default value iff no value has been provided by the config file
+ // use default value if no value has been provided by the config file
if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
cpackProjectDirectory);
@@ -324,6 +323,12 @@ int main(int argc, char const* const* argv)
globalMF.AddDefinition(cd.first, cd.second);
}
+ // Force CPACK_PACKAGE_DIRECTORY as absolute path
+ cpackProjectDirectory = globalMF.GetDefinition("CPACK_PACKAGE_DIRECTORY");
+ cpackProjectDirectory =
+ cmSystemTools::CollapseFullPath(cpackProjectDirectory);
+ globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
+
const char* cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH");
if (cpackModulesPath) {
globalMF.AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 8640c46f84..c87fb83b31 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -8,11 +8,12 @@
#include <ostream>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
#include "cm_expat.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -245,7 +246,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 2ad661cf04..5e29386c76 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -215,11 +215,11 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
if (this->BuildNoCMake) {
// Make the generator available for the Build call below.
- cmGlobalGenerator* gen = cm.CreateGlobalGenerator(this->BuildGenerator);
- cm.SetGlobalGenerator(gen);
+ cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator));
if (!this->BuildGeneratorPlatform.empty()) {
- cmMakefile mf(gen, cm.GetCurrentSnapshot());
- if (!gen->SetGeneratorPlatform(this->BuildGeneratorPlatform, &mf)) {
+ cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot());
+ if (!cm.GetGlobalGenerator()->SetGeneratorPlatform(
+ this->BuildGeneratorPlatform, &mf)) {
return 1;
}
}
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 18df2141ec..d1b7701ec6 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -29,13 +29,7 @@ void cmCTestBuildCommand::BindArguments()
this->Bind("PROJECT_NAME"_s, this->ProjectName);
}
-cmCTestBuildCommand::~cmCTestBuildCommand()
-{
- if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
- }
-}
+cmCTestBuildCommand::~cmCTestBuildCommand() = default;
cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
{
@@ -79,8 +73,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
}
if (this->GlobalGenerator) {
if (this->GlobalGenerator->GetName() != cmakeGeneratorName) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
+ this->GlobalGenerator.reset();
}
}
if (!this->GlobalGenerator) {
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index da00a43c64..0f82817589 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -48,7 +48,7 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- cmGlobalGenerator* GlobalGenerator = nullptr;
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
protected:
cmCTestBuildHandler* Handler;
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 9cb5449d96..03a3fd306b 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -7,11 +7,12 @@
#include <set>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmFileTimeCache.h"
@@ -969,7 +970,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, size_t length,
if (it != queue->end()) {
// Create a contiguous array for the line
this->CurrentProcessingLine.clear();
- cmAppend(this->CurrentProcessingLine, queue->begin(), it);
+ cm::append(this->CurrentProcessingLine, queue->begin(), it);
this->CurrentProcessingLine.push_back(0);
const char* line = this->CurrentProcessingLine.data();
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index f2f42b4f2d..3854710819 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -69,12 +69,11 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
bool multiConfig = false;
bool cmakeBuildTypeInOptions = false;
- cmGlobalGenerator* gg =
- this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
- cmakeGeneratorName);
+ auto gg = this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
+ cmakeGeneratorName);
if (gg) {
multiConfig = gg->IsMultiConfig();
- delete gg;
+ gg.reset();
}
std::string cmakeConfigureCommand =
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 4cd783fd6b..2c8f119378 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -12,12 +12,13 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#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"
#include "cmGeneratedFileStream.h"
@@ -819,7 +820,7 @@ int cmCTestCoverageHandler::HandleJacocoCoverage(
std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory");
std::string binCoverageFile = binaryDir + "/*jacoco.xml";
g2.FindFiles(binCoverageFile);
- cmAppend(files, g2.GetFiles());
+ cm::append(files, g2.GetFiles());
if (!files.empty()) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -1462,7 +1463,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
" looking for LCOV files in: " << daGlob << std::endl, this->Quiet);
gl.FindFiles(daGlob);
// Keep a list of all LCOV files
- cmAppend(lcovFiles, gl.GetFiles());
+ cm::append(lcovFiles, gl.GetFiles());
for (std::string const& file : lcovFiles) {
lcovFile = file;
@@ -1599,10 +1600,10 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
" globbing for coverage in: " << lm.first << std::endl, this->Quiet);
std::string daGlob = cmStrCat(lm.first, "/*.da");
gl.FindFiles(daGlob);
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
daGlob = cmStrCat(lm.first, "/*.gcda");
gl.FindFiles(daGlob);
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
}
}
@@ -1638,7 +1639,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
"Error while finding files matching " << daGlob << std::endl);
return false;
}
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Now searching in: " << daGlob << std::endl, this->Quiet);
return true;
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index ccac832f06..69c57938fe 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -5,7 +5,8 @@
#include <cstdio>
#include <ostream>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCTest.h"
#include "cmCurl.h"
#include "cmStringAlgorithms.h"
@@ -46,15 +47,15 @@ size_t curlWriteMemoryCallback(void* ptr, size_t size, size_t nmemb,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + realsize);
+ cm::append(*static_cast<std::vector<char>*>(data), chPtr, chPtr + realsize);
return realsize;
}
size_t curlDebugCallback(CURL* /*unused*/, curl_infotype /*unused*/,
char* chPtr, size_t size, void* data)
{
- cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size);
- return size;
+ cm::append(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size);
+ return 0;
}
}
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 3265498c08..5f4581eff7 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -5,9 +5,10 @@
#include <ostream>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -204,7 +205,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index a5ec1ae81e..c1ecaf125d 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -2,9 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckHandler.h"
+#include <algorithm>
#include <chrono>
#include <cstring>
#include <iostream>
+#include <iterator>
#include <sstream>
#include <utility>
@@ -12,6 +14,7 @@
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmSystemTools.h"
@@ -162,12 +165,13 @@ int cmCTestMemCheckHandler::PostProcessHandler()
void cmCTestMemCheckHandler::GenerateTestCommand(
std::vector<std::string>& args, int test)
{
- std::string index;
- std::ostringstream stream;
+ std::string index = std::to_string(test);
std::string memcheckcommand =
cmSystemTools::ConvertToOutputPath(this->MemoryTester);
- stream << test;
- index = stream.str();
+
+ std::vector<std::string> dirs;
+ bool nextArgIsDir = false;
+
for (std::string arg : this->MemoryTesterDynamicOptions) {
std::string::size_type pos = arg.find("??");
if (pos != std::string::npos) {
@@ -177,6 +181,16 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += " \"";
memcheckcommand += arg;
memcheckcommand += "\"";
+
+ if (nextArgIsDir) {
+ nextArgIsDir = false;
+ dirs.push_back(arg);
+ }
+
+ if (this->MemoryTesterStyle == cmCTestMemCheckHandler::DRMEMORY &&
+ (arg == "-logdir" || arg == "-symcache_dir")) {
+ nextArgIsDir = true;
+ }
}
// Create a copy of the memory tester environment variable.
// This is used for memory testing programs that pass options
@@ -208,6 +222,11 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += " " + memTesterEnvironmentVariable;
args.push_back(memTesterEnvironmentVariable);
}
+
+ for (std::string const& dir : dirs) {
+ cmSystemTools::MakeDirectory(dir);
+ }
+
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Memory check command: " << memcheckcommand << std::endl,
this->Quiet);
@@ -300,6 +319,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
case cmCTestMemCheckHandler::VALGRIND:
xml.Attribute("Checker", "Valgrind");
break;
+ case cmCTestMemCheckHandler::DRMEMORY:
+ xml.Attribute("Checker", "DrMemory");
+ break;
case cmCTestMemCheckHandler::PURIFY:
xml.Attribute("Checker", "Purify");
break;
@@ -387,11 +409,11 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
}
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
"MemCheck log files can be found here: "
- "( * corresponds to test number)"
+ "(<#> corresponds to test number)"
<< std::endl,
this->Quiet);
std::string output = this->MemoryTesterOutputFile;
- cmSystemTools::ReplaceString(output, "??", "*");
+ cmSystemTools::ReplaceString(output, "??", "<#>");
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, output << std::endl,
this->Quiet);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
@@ -437,6 +459,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
if (testerName.find("valgrind") != std::string::npos ||
this->CTest->GetCTestConfiguration("MemoryCheckType") == "Valgrind") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ } else if (testerName.find("drmemory") != std::string::npos ||
+ this->CTest->GetCTestConfiguration("MemoryCheckType") ==
+ "DrMemory") {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
} else if (testerName.find("purify") != std::string::npos) {
this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
} else if (testerName.find("BC") != std::string::npos) {
@@ -453,6 +479,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTester = this->CTest->GetCTestConfiguration("ValgrindCommand");
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
} else if (cmSystemTools::FileExists(
+ this->CTest->GetCTestConfiguration("DrMemoryCommand"))) {
+ this->MemoryTester = this->CTest->GetCTestConfiguration("DrMemoryCommand");
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
+ } else if (cmSystemTools::FileExists(
this->CTest->GetCTestConfiguration("BoundsCheckerCommand"))) {
this->MemoryTester =
this->CTest->GetCTestConfiguration("BoundsCheckerCommand");
@@ -498,6 +528,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
} else if (checkType == "Valgrind") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ } else if (checkType == "DrMemory") {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
}
}
if (this->MemoryTester.empty()) {
@@ -519,6 +551,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
.empty()) {
memoryTesterOptions =
this->CTest->GetCTestConfiguration("ValgrindCommandOptions");
+ } else if (!this->CTest->GetCTestConfiguration("DrMemoryCommandOptions")
+ .empty()) {
+ memoryTesterOptions =
+ this->CTest->GetCTestConfiguration("DrMemoryCommandOptions");
}
this->MemoryTesterOptions =
cmSystemTools::ParseArguments(memoryTesterOptions);
@@ -554,6 +590,64 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOutputFile);
break;
}
+ case cmCTestMemCheckHandler::DRMEMORY: {
+ std::string tempDrMemoryDir =
+ this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
+
+ if (!cmContains(this->MemoryTesterOptions, "-quiet")) {
+ this->MemoryTesterOptions.emplace_back("-quiet");
+ }
+
+ if (!cmContains(this->MemoryTesterOptions, "-batch")) {
+ this->MemoryTesterOptions.emplace_back("-batch");
+ }
+
+ this->MemoryTesterDynamicOptions.emplace_back("-logdir");
+ auto logdirOption =
+ std::find(this->MemoryTesterOptions.begin(),
+ this->MemoryTesterOptions.end(), "-logdir");
+ if (logdirOption == this->MemoryTesterOptions.end()) {
+ // No logdir found in memory tester options
+ std::string drMemoryLogDir = tempDrMemoryDir + "/??";
+ this->MemoryTesterDynamicOptions.push_back(drMemoryLogDir);
+ this->MemoryTesterOutputFile = drMemoryLogDir;
+ } else {
+ // Use logdir found in memory tester options
+ auto logdirLocation = std::next(logdirOption);
+ this->MemoryTesterOutputFile = *logdirLocation;
+ this->MemoryTesterDynamicOptions.push_back(*logdirLocation);
+ this->MemoryTesterOptions.erase(logdirOption, logdirLocation + 1);
+ }
+ this->MemoryTesterOutputFile += "/*/results.txt";
+
+ if (std::find(this->MemoryTesterOptions.begin(),
+ this->MemoryTesterOptions.end(),
+ "-symcache_dir") == this->MemoryTesterOptions.end()) {
+ this->MemoryTesterDynamicOptions.emplace_back("-symcache_dir");
+ std::string drMemoryCacheDir = tempDrMemoryDir + "/cache";
+ this->MemoryTesterDynamicOptions.push_back(drMemoryCacheDir);
+ }
+
+ if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile")
+ .empty()) {
+ if (!cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile"))) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find memory checker suppression file: "
+ << this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile")
+ << std::endl);
+ return false;
+ }
+ this->MemoryTesterOptions.emplace_back("-suppress");
+ this->MemoryTesterOptions.push_back(
+ this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"));
+ }
+
+ this->MemoryTesterOptions.emplace_back("--");
+
+ break;
+ }
case cmCTestMemCheckHandler::PURIFY: {
std::string outputFile;
#ifdef _WIN32
@@ -667,6 +761,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
switch (this->MemoryTesterStyle) {
case cmCTestMemCheckHandler::VALGRIND:
return this->ProcessMemCheckValgrindOutput(str, log, results);
+ case cmCTestMemCheckHandler::DRMEMORY:
+ return this->ProcessMemCheckDrMemoryOutput(str, log, results);
case cmCTestMemCheckHandler::PURIFY:
return this->ProcessMemCheckPurifyOutput(str, log, results);
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
@@ -932,6 +1028,47 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
return defects == 0;
}
+bool cmCTestMemCheckHandler::ProcessMemCheckDrMemoryOutput(
+ const std::string& str, std::string& log, std::vector<int>& results)
+{
+ std::vector<std::string> lines;
+ cmsys::SystemTools::Split(str, lines);
+
+ cmsys::RegularExpression drMemoryError("^Error #[0-9]+");
+
+ cmsys::RegularExpression unaddressableAccess("UNADDRESSABLE ACCESS");
+ cmsys::RegularExpression uninitializedRead("UNINITIALIZED READ");
+ cmsys::RegularExpression invalidHeapArgument("INVALID HEAP ARGUMENT");
+ cmsys::RegularExpression leak("LEAK");
+ cmsys::RegularExpression handleLeak("HANDLE LEAK");
+
+ int defects = 0;
+
+ std::ostringstream ostr;
+ for (const auto& l : lines) {
+ ostr << l << std::endl;
+ if (drMemoryError.find(l)) {
+ defects++;
+ if (unaddressableAccess.find(l)) {
+ results[cmCTestMemCheckHandler::UMR]++;
+ } else if (uninitializedRead.find(l)) {
+ results[cmCTestMemCheckHandler::UMR]++;
+ } else if (leak.find(l)) {
+ results[cmCTestMemCheckHandler::MLK]++;
+ } else if (handleLeak.find(l)) {
+ results[cmCTestMemCheckHandler::MLK]++;
+ } else if (invalidHeapArgument.find(l)) {
+ results[cmCTestMemCheckHandler::FMM]++;
+ }
+ }
+ }
+
+ log = ostr.str();
+
+ this->DefectCount += defects;
+ return defects == 0;
+}
+
bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
const std::string& str, std::string& log, std::vector<int>& results)
{
@@ -991,6 +1128,8 @@ void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test)
this->Quiet);
if (this->MemoryTesterStyle == cmCTestMemCheckHandler::BOUNDS_CHECKER) {
this->PostProcessBoundsCheckerTest(res, test);
+ } else if (this->MemoryTesterStyle == cmCTestMemCheckHandler::DRMEMORY) {
+ this->PostProcessDrMemoryTest(res, test);
} else {
std::vector<std::string> files;
this->TestOutputFileNames(test, files);
@@ -1045,6 +1184,37 @@ void cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(
this->Quiet);
}
+void cmCTestMemCheckHandler::PostProcessDrMemoryTest(
+ cmCTestTestHandler::cmCTestTestResult& res, int test)
+{
+ std::string drMemoryLogDir = this->MemoryTesterOutputFile.substr(
+ 0, this->MemoryTesterOutputFile.find("/*/results.txt"));
+
+ // replace placeholder of test
+ std::string::size_type pos = drMemoryLogDir.find("??");
+ if (pos != std::string::npos) {
+ drMemoryLogDir.replace(pos, 2, std::to_string(test));
+ }
+
+ cmsys::Glob g;
+ g.FindFiles(drMemoryLogDir + "/resfile.*");
+ const std::vector<std::string>& files = g.GetFiles();
+
+ for (const std::string& f : files) {
+ cmsys::ifstream ifs(f.c_str());
+ if (!ifs) {
+ std::string log = "Cannot read memory tester output file: " + f;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log << std::endl);
+ return;
+ }
+ std::string resultFileLocation;
+ cmSystemTools::GetLineFromStream(ifs, resultFileLocation);
+ this->AppendMemTesterOutput(res, resultFileLocation);
+ ifs.close();
+ cmSystemTools::RemoveFile(f);
+ }
+}
+
void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
std::string const& ofile)
{
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index eda65f7b98..52667f8cfe 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -43,6 +43,7 @@ private:
UNKNOWN = 0,
VALGRIND,
PURIFY,
+ DRMEMORY,
BOUNDS_CHECKER,
// checkers after here do not use the standard error list
ADDRESS_SANITIZER,
@@ -132,6 +133,8 @@ private:
std::vector<int>& results);
bool ProcessMemCheckValgrindOutput(const std::string& str, std::string& log,
std::vector<int>& results);
+ bool ProcessMemCheckDrMemoryOutput(const std::string& str, std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
std::vector<int>& results);
bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
@@ -142,6 +145,7 @@ private:
void PostProcessTest(cmCTestTestResult& res, int test);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
+ void PostProcessDrMemoryTest(cmCTestTestResult& res, int test);
//! append MemoryTesterOutputFile to the test log
void AppendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 02d396ebdc..2192843ecd 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -19,6 +19,8 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
@@ -171,9 +173,9 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->RunningCount += GetProcessorsUsed(test);
cmCTestRunTest* testRun = new cmCTestRunTest(*this);
- if (this->CTest->GetRepeatUntilFail()) {
- testRun->SetRunUntilFailOn();
- testRun->SetNumberOfRuns(this->CTest->GetTestRepeat());
+ if (this->RepeatMode != cmCTest::Repeat::Never) {
+ testRun->SetRepeatMode(this->RepeatMode);
+ testRun->SetNumberOfRuns(this->RepeatCount);
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
@@ -194,8 +196,40 @@ 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");
+ if (!this->ResourceAllocationErrors[test].empty()) {
+ std::ostringstream e;
+ e << "Insufficient resources for test " << this->Properties[test]->Name
+ << ":\n\n";
+ for (auto const& it : this->ResourceAllocationErrors[test]) {
+ switch (it.second) {
+ case ResourceAllocationError::NoResourceType:
+ e << " Test requested resources of type '" << it.first
+ << "' which does not exist\n";
+ break;
+
+ case ResourceAllocationError::InsufficientResources:
+ e << " Test requested resources of type '" << it.first
+ << "' in the following amounts:\n";
+ for (auto const& group : this->Properties[test]->ResourceGroups) {
+ for (auto const& requirement : group) {
+ if (requirement.ResourceType == it.first) {
+ e << " " << requirement.SlotsNeeded
+ << (requirement.SlotsNeeded == 1 ? " slot\n" : " slots\n");
+ }
+ }
+ }
+ e << " but only the following units were available:\n";
+ for (auto const& res :
+ this->ResourceAllocator.GetResources().at(it.first)) {
+ e << " '" << res.first << "': " << res.second.Total
+ << (res.second.Total == 1 ? " slot\n" : " slots\n");
+ }
+ break;
+ }
+ e << "\n";
+ }
+ e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
+ testRun->StartFailure(e.str(), "Insufficient resources");
this->FinishTestProcess(testRun, false);
return false;
}
@@ -203,8 +237,9 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
testRun->StartFailure("Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()));
+ this->Properties[test]->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
} else {
if (testRun->StartTest(this->Completed, this->Total)) {
// Ownership of 'testRun' has moved to another structure.
@@ -247,7 +282,8 @@ bool cmCTestMultiProcessHandler::AllocateResources(int index)
bool cmCTestMultiProcessHandler::TryAllocateResources(
int index,
- std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations)
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations,
+ std::map<std::string, ResourceAllocationError>* errors)
{
allocations.clear();
@@ -262,18 +298,28 @@ bool cmCTestMultiProcessHandler::TryAllocateResources(
++processIndex;
}
+ bool result = true;
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;
+ if (errors) {
+ (*errors)[it.first] = ResourceAllocationError::NoResourceType;
+ result = false;
+ } else {
+ return false;
+ }
+ } else if (!cmAllocateCTestResourcesRoundRobin(
+ availableResources.at(it.first), it.second)) {
+ if (errors) {
+ (*errors)[it.first] = ResourceAllocationError::InsufficientResources;
+ result = false;
+ } else {
+ return false;
+ }
}
}
- return true;
+ return result;
}
void cmCTestMultiProcessHandler::DeallocateResources(int index)
@@ -314,11 +360,13 @@ bool cmCTestMultiProcessHandler::AllResourcesAvailable()
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);
+ if (this->TestHandler->UseResourceSpec) {
+ for (auto test : this->SortedTests) {
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>
+ allocations;
+ this->TryAllocateResources(test, allocations,
+ &this->ResourceAllocationErrors[test]);
+ }
}
}
@@ -405,7 +453,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
}
// Allocate resources
- if (this->TestsHaveSufficientResources[test] &&
+ if (this->ResourceAllocationErrors[test].empty() &&
!this->AllocateResources(test)) {
this->DeallocateResources(test);
return false;
@@ -788,7 +836,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// Sort tests within each level by COST and append them to the cost list.
for (TestSet const& currentSet : cmReverseRange(priorityStack)) {
TestList sortedCopy;
- cmAppend(sortedCopy, currentSet);
+ cm::append(sortedCopy, currentSet);
std::stable_sort(sortedCopy.begin(), sortedCopy.end(),
TestComparator(this));
@@ -1154,7 +1202,7 @@ static Json::Value DumpCTestInfo(
const std::vector<std::string>& args = testRun.GetArguments();
if (!args.empty()) {
commandAndArgs.reserve(args.size() + 1);
- cmAppend(commandAndArgs, args);
+ cm::append(commandAndArgs, args);
}
testInfo["command"] = DumpToJsonArray(commandAndArgs);
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 1db4bfdd1b..5b429d4ae8 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -14,11 +14,11 @@
#include "cm_uv.h"
+#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
-class cmCTest;
struct cmCTestBinPackerAllocation;
class cmCTestResourceSpec;
class cmCTestRunTest;
@@ -85,6 +85,12 @@ public:
cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }
+ void SetRepeatMode(cmCTest::Repeat mode, int count)
+ {
+ this->RepeatMode = mode;
+ this->RepeatCount = count;
+ }
+
void SetQuiet(bool b) { this->Quiet = b; }
void InitResourceAllocator(const cmCTestResourceSpec& spec)
@@ -137,11 +143,18 @@ protected:
void LockResources(int index);
void UnlockResources(int index);
+ enum class ResourceAllocationError
+ {
+ NoResourceType,
+ InsufficientResources,
+ };
+
bool AllocateResources(int index);
bool TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
- allocations);
+ allocations,
+ std::map<std::string, ResourceAllocationError>* errors = nullptr);
void DeallocateResources(int index);
bool AllResourcesAvailable();
@@ -168,7 +181,8 @@ protected:
std::map<int,
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
AllocatedResources;
- std::map<int, bool> TestsHaveSufficientResources;
+ std::map<int, std::map<std::string, ResourceAllocationError>>
+ ResourceAllocationErrors;
cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
@@ -179,6 +193,8 @@ protected:
cmCTestTestHandler* TestHandler;
cmCTest* CTest;
bool HasCycles;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int RepeatCount = 1;
bool Quiet;
bool SerialTestRunning;
};
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index e2063e1786..1375be406c 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -7,9 +7,10 @@
#include <ostream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -326,7 +327,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
// The CTEST_P4_OPTIONS variable adds additional Perforce command line
// options before the main command
std::string opts = this->CTest->GetCTestConfiguration("P4Options");
- cmAppend(P4Options, cmSystemTools::ParseArguments(opts));
+ cm::append(P4Options, cmSystemTools::ParseArguments(opts));
}
CommandOptions.clear();
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 3091050f38..ec549606fd 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -34,9 +34,6 @@ cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler)
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = 0;
this->TestResult.Properties = nullptr;
- this->NumberOfRunsLeft = 1; // default to 1 run of the test
- this->RunUntilFail = false; // default to run the test once
- this->RunAgain = false; // default to not having to run again
}
void cmCTestRunTest::CheckOutput(std::string const& line)
@@ -310,7 +307,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
// If the test does not need to rerun push the current TestResult onto the
// TestHandler vector
- if (!this->NeedsToRerun()) {
+ if (!this->NeedsToRepeat()) {
this->TestHandler->TestResults.push_back(this->TestResult);
}
this->TestProcess.reset();
@@ -327,8 +324,9 @@ bool cmCTestRunTest::StartAgain(size_t completed)
cmWorkingDirectory workdir(this->TestProperties->Directory);
if (workdir.Failed()) {
this->StartFailure("Failed to change working directory to " +
- this->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()));
+ this->TestProperties->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
return true;
}
@@ -336,17 +334,21 @@ bool cmCTestRunTest::StartAgain(size_t completed)
return true;
}
-bool cmCTestRunTest::NeedsToRerun()
+bool cmCTestRunTest::NeedsToRepeat()
{
this->NumberOfRunsLeft--;
if (this->NumberOfRunsLeft == 0) {
return false;
}
// if number of runs left is not 0, and we are running until
- // we find a failed test, then return true so the test can be
+ // we find a failed (or passed) test, then return true so the test can be
// restarted
- if (this->RunUntilFail &&
- this->TestResult.Status == cmCTestTestHandler::COMPLETED) {
+ if ((this->RepeatMode == cmCTest::Repeat::UntilFail &&
+ this->TestResult.Status == cmCTestTestHandler::COMPLETED) ||
+ (this->RepeatMode == cmCTest::Repeat::UntilPass &&
+ this->TestResult.Status != cmCTestTestHandler::COMPLETED) ||
+ (this->RepeatMode == cmCTest::Repeat::AfterTimeout &&
+ this->TestResult.Status == cmCTestTestHandler::TIMEOUT)) {
this->RunAgain = true;
return true;
}
@@ -380,7 +382,8 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index);
}
-void cmCTestRunTest::StartFailure(std::string const& output)
+void cmCTestRunTest::StartFailure(std::string const& output,
+ std::string const& detail)
{
// Still need to log the Start message so the test summary records our
// attempt to start this test
@@ -403,7 +406,7 @@ void cmCTestRunTest::StartFailure(std::string const& output)
this->TestResult.ExecutionTime = cmDuration::zero();
this->TestResult.CompressOutput = false;
this->TestResult.ReturnValue = -1;
- this->TestResult.CompletionStatus = "Failed to start";
+ this->TestResult.CompletionStatus = detail;
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
@@ -746,7 +749,12 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
// then it will never print out the completed / total, same would
// got for run until pass. Trick is when this is called we don't
// yet know if we are passing or failing.
- if (this->NumberOfRunsLeft == 1 || this->CTest->GetTestProgressOutput()) {
+ bool const progressOnLast =
+ (this->RepeatMode != cmCTest::Repeat::UntilPass &&
+ this->RepeatMode != cmCTest::Repeat::AfterTimeout);
+ if ((progressOnLast && this->NumberOfRunsLeft == 1) ||
+ (!progressOnLast && this->NumberOfRunsLeft == this->NumberOfRunsTotal) ||
+ this->CTest->GetTestProgressOutput()) {
outputStream << std::setw(getNumWidth(total)) << completed << "/";
outputStream << std::setw(getNumWidth(total)) << total << " ";
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index f781c7ab0d..4988839b0f 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -13,13 +13,12 @@
#include <stddef.h>
+#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
#include "cmProcess.h"
-class cmCTest;
-
/** \class cmRunTest
* \brief represents a single test to be run
*
@@ -30,8 +29,13 @@ class cmCTestRunTest
public:
explicit cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler);
- void SetNumberOfRuns(int n) { this->NumberOfRunsLeft = n; }
- void SetRunUntilFailOn() { this->RunUntilFail = true; }
+ void SetNumberOfRuns(int n)
+ {
+ this->NumberOfRunsLeft = n;
+ this->NumberOfRunsTotal = n;
+ }
+
+ void SetRepeatMode(cmCTest::Repeat r) { this->RepeatMode = r; }
void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties* prop)
{
this->TestProperties = prop;
@@ -72,7 +76,7 @@ public:
bool StartAgain(size_t completed);
- void StartFailure(std::string const& output);
+ void StartFailure(std::string const& output, std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
@@ -98,7 +102,7 @@ public:
}
private:
- bool NeedsToRerun();
+ bool NeedsToRepeat();
void DartProcessing();
void ExeNotFound(std::string exe);
bool ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
@@ -132,9 +136,10 @@ private:
std::vector<std::map<
std::string, std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>
AllocatedResources;
- bool RunUntilFail;
- int NumberOfRunsLeft;
- bool RunAgain;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int NumberOfRunsLeft = 1; // default to 1 run of the test
+ int NumberOfRunsTotal = 1; // default to 1 run of the test
+ bool RunAgain = false; // default to not having to run again
size_t TotalNumberOfTests;
};
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 34395c9fe0..44dfab2e60 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -7,9 +7,10 @@
#include <map>
#include <ostream>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -271,7 +272,7 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::vector<char const*> args;
args.push_back(this->CommandLineTool.c_str());
- cmAppend(args, parameters);
+ cm::append(args, parameters);
args.push_back("--non-interactive");
std::string userOptions = this->CTest->GetCTestConfiguration("SVNOptions");
@@ -344,7 +345,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 60facbdf53..7803e3764a 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -340,6 +340,13 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
this->SetRunCurrentScript(true);
this->UpdateElapsedTime();
+ // set the CTEST_CONFIGURATION_TYPE variable to the current value of the
+ // the -C argument on the command line.
+ if (!this->CTest->GetConfigType().empty()) {
+ this->Makefile->AddDefinition("CTEST_CONFIGURATION_TYPE",
+ this->CTest->GetConfigType());
+ }
+
// add the script arg if defined
if (!script_arg.empty()) {
this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg);
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 46b00b1685..acb75b2edd 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -7,6 +7,7 @@
#include <utility>
#include <cm/memory>
+#include <cm/vector>
#include "cm_static_string_view.hxx"
@@ -174,7 +175,7 @@ void cmCTestSubmitCommand::CheckArguments(
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 {
+ cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
if (p == cmCTest::PartCount) {
std::ostringstream e;
@@ -185,7 +186,7 @@ void cmCTestSubmitCommand::CheckArguments(
return false;
});
- cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 2ac5af691a..22ab48f57e 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -7,6 +7,8 @@
#include <cstdlib>
#include <sstream>
+#include <cmext/algorithm>
+
#include "cm_curl.h"
#include "cm_jsoncpp_reader.h"
#include "cm_jsoncpp_value.h"
@@ -65,7 +67,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CurrentValue, data, data + length);
+ cm::append(this->CurrentValue, data, data + length);
}
void EndElement(const std::string& name) override
@@ -96,8 +98,8 @@ static size_t cmCTestSubmitHandlerWriteMemoryCallback(void* ptr, size_t size,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
- chPtr + realsize);
+ cm::append(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
+ chPtr + realsize);
return realsize;
}
@@ -106,9 +108,9 @@ static size_t cmCTestSubmitHandlerCurlDebugCallback(CURL* /*unused*/,
char* chPtr, size_t size,
void* data)
{
- cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
- chPtr + size);
- return size;
+ cm::append(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
+ chPtr + size);
+ return 0;
}
cmCTestSubmitHandler::cmCTestSubmitHandler()
@@ -768,7 +770,7 @@ int cmCTestSubmitHandler::ProcessHandler()
if (!this->Files.empty()) {
// Submit the explicitly selected files:
- cmAppend(files, this->Files);
+ cm::append(files, this->Files);
}
// Add to the list of files to submit from any selected, existing parts:
@@ -814,7 +816,7 @@ int cmCTestSubmitHandler::ProcessHandler()
}
// Submit files from this part.
- cmAppend(files, this->CTest->GetSubmitFiles(p));
+ cm::append(files, this->CTest->GetSubmitFiles(p));
}
// Make sure files are unique, but preserve order.
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 9784214053..0f9b6958df 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -29,6 +29,7 @@ void cmCTestTestCommand::BindArguments()
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("REPEAT"_s, this->Repeat);
this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
this->Bind("STOP_TIME"_s, this->StopTime);
this->Bind("TEST_LOAD"_s, this->TestLoad);
@@ -85,6 +86,9 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
if (!this->ParallelLevel.empty()) {
handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
+ if (!this->Repeat.empty()) {
+ handler->SetOption("Repeat", this->Repeat.c_str());
+ }
if (!this->ScheduleRandom.empty()) {
handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str());
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 4019694b2e..2345afbcfe 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -55,6 +55,7 @@ protected:
std::string ExcludeFixtureSetup;
std::string ExcludeFixtureCleanup;
std::string ParallelLevel;
+ std::string Repeat;
std::string ScheduleRandom;
std::string StopTime;
std::string TestLoad;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index c8bbb0b137..4f324ea6d2 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -410,10 +410,15 @@ int cmCTestTestHandler::ProcessHandler()
auto clock_finish = std::chrono::steady_clock::now();
+ bool noTestsFoundError = false;
if (passed.size() + failed.size() == 0) {
- if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
+ if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() &&
+ this->CTest->GetNoTestsMode() != cmCTest::NoTests::Ignore) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"No tests were found!!!" << std::endl);
+ if (this->CTest->GetNoTestsMode() == cmCTest::NoTests::Error) {
+ noTestsFoundError = true;
+ }
}
} else {
if (this->HandlerVerbose && !passed.empty() &&
@@ -459,6 +464,12 @@ int cmCTestTestHandler::ProcessHandler()
this->LogFile = nullptr;
return -1;
}
+
+ if (noTestsFoundError) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+
this->LogFile = nullptr;
return 0;
}
@@ -471,6 +482,30 @@ bool cmCTestTestHandler::ProcessOptions()
if (cmIsOn(this->GetOption("ScheduleRandom"))) {
this->CTest->SetScheduleType("Random");
}
+ if (const char* repeat = this->GetOption("Repeat")) {
+ cmsys::RegularExpression repeatRegex(
+ "^(UNTIL_FAIL|UNTIL_PASS|AFTER_TIMEOUT):([0-9]+)$");
+ if (repeatRegex.find(repeat)) {
+ std::string const& count = repeatRegex.match(2);
+ unsigned long n = 1;
+ cmStrToULong(count, &n); // regex guarantees success
+ this->RepeatCount = static_cast<int>(n);
+ if (this->RepeatCount > 1) {
+ std::string const& mode = repeatRegex.match(1);
+ if (mode == "UNTIL_FAIL") {
+ this->RepeatMode = cmCTest::Repeat::UntilFail;
+ } else if (mode == "UNTIL_PASS") {
+ this->RepeatMode = cmCTest::Repeat::UntilPass;
+ } else if (mode == "AFTER_TIMEOUT") {
+ this->RepeatMode = cmCTest::Repeat::AfterTimeout;
+ }
+ }
+ } else {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Repeat option invalid value: " << repeat << std::endl);
+ return false;
+ }
+ }
if (this->GetOption("ParallelLevel")) {
this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
}
@@ -513,6 +548,7 @@ bool cmCTestTestHandler::ProcessOptions()
val = this->GetOption("ResourceSpecFile");
if (val) {
this->UseResourceSpec = true;
+ this->ResourceSpecFile = val;
auto result = this->ResourceSpec.ReadFromJSONFile(val);
if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -1235,6 +1271,12 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
+ if (this->RepeatMode != cmCTest::Repeat::Never) {
+ parallel->SetRepeatMode(this->RepeatMode, this->RepeatCount);
+ } else {
+ parallel->SetRepeatMode(this->CTest->GetRepeatMode(),
+ this->CTest->GetRepeatCount());
+ }
parallel->SetQuiet(this->Quiet);
if (this->TestLoad > 0) {
parallel->SetTestLoad(this->TestLoad);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index eab75d0eb8..b1c8755025 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -18,12 +18,12 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestResourceSpec.h"
#include "cmDuration.h"
#include "cmListFileCache.h"
-class cmCTest;
class cmMakefile;
class cmXMLWriter;
@@ -338,6 +338,7 @@ private:
bool UseResourceSpec;
cmCTestResourceSpec ResourceSpec;
+ std::string ResourceSpecFile;
void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
cmsys::RegularExpression DartStuff1;
@@ -353,6 +354,8 @@ private:
std::ostream* LogFile;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int RepeatCount = 1;
bool RerunFailed;
};
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index d0e3848a08..eaef1ca6af 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -4,11 +4,11 @@
#include <set>
#include <sstream>
-#include <vector>
+
+#include <cm/vector>
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
@@ -24,7 +24,7 @@ void cmCTestUploadCommand::BindArguments()
void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
{
- cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 87f7147bc9..6097aa5bdd 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -6,9 +6,10 @@
#include <iostream>
#include <string>
+#include <cmext/algorithm>
+
#include "cmsys/Process.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
@@ -218,7 +219,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
if (nread > 0) {
std::string strdata;
this->Conv.DecodeText(buf->base, static_cast<size_t>(nread), strdata);
- cmAppend(this->Output, strdata);
+ cm::append(this->Output, strdata);
while (this->Output.GetLine(line)) {
this->Runner.CheckOutput(line);
@@ -248,7 +249,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
this->PipeReader.reset();
if (this->ProcessHandleClosed) {
uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
+ this->Finish();
}
}
@@ -277,9 +278,6 @@ void cmProcess::OnTimeoutCB(uv_timer_t* timer)
void cmProcess::OnTimeout()
{
- if (this->ProcessState != cmProcess::State::Executing) {
- return;
- }
this->ProcessState = cmProcess::State::Expired;
bool const was_still_reading = !this->ReadHandleClosed;
if (!this->ReadHandleClosed) {
@@ -293,7 +291,7 @@ void cmProcess::OnTimeout()
// Our on-exit handler already ran but did not finish the test
// because we were still reading output. We've just dropped
// our read handler, so we need to finish the test now.
- this->Runner.FinalizeTest();
+ this->Finish();
}
}
@@ -323,6 +321,16 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal)
// Record exit information.
this->ExitValue = exit_status;
this->Signal = term_signal;
+
+ this->ProcessHandleClosed = true;
+ if (this->ReadHandleClosed) {
+ uv_timer_stop(this->Timer);
+ this->Finish();
+ }
+}
+
+void cmProcess::Finish()
+{
this->TotalTime = std::chrono::steady_clock::now() - this->StartTime;
// Because of a processor clock scew the runtime may become slightly
// negative. If someone changed the system clock while the process was
@@ -331,12 +339,7 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal)
if (this->TotalTime <= cmDuration::zero()) {
this->TotalTime = cmDuration::zero();
}
-
- this->ProcessHandleClosed = true;
- if (this->ReadHandleClosed) {
- uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
- }
+ this->Runner.FinalizeTest();
}
cmProcess::State cmProcess::GetProcessStatus()
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 2c24f2df02..ea72a26506 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -101,6 +101,7 @@ private:
void OnAllocate(size_t suggested_size, uv_buf_t* buf);
void StartTimer();
+ void Finish();
class Buffer : public std::vector<char>
{
diff --git a/Source/Checks/Curses.cmake b/Source/Checks/Curses.cmake
index 2942b666ae..d35dd2a6e1 100644
--- a/Source/Checks/Curses.cmake
+++ b/Source/Checks/Curses.cmake
@@ -1,4 +1,7 @@
-message(STATUS "Checking for curses support")
+include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+cm_message_checks_compat(
+ "Checking for curses support" __checkStart __checkPass __checkFail)
+message(${__checkStart})
# Try compiling a simple project using curses.
# Pass in any cache entries that the user may have set.
@@ -31,11 +34,11 @@ set(CMakeCheckCurses_COMPILED "${CMakeCheckCurses_COMPILED}")
unset(CMakeCheckCurses_COMPILED CACHE)
if(CMakeCheckCurses_COMPILED)
- message(STATUS "Checking for curses support - Success")
+ message(${__checkPass} "Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking for curses support passed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
else()
- message(STATUS "Checking for curses support - Failed")
+ message(${__checkFail} "Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Checking for curses support failed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
endif()
diff --git a/Source/Checks/cm_c11_thread_local.cmake b/Source/Checks/cm_c11_thread_local.cmake
index 6b8d10b2bd..2263be3bad 100644
--- a/Source/Checks/cm_c11_thread_local.cmake
+++ b/Source/Checks/cm_c11_thread_local.cmake
@@ -1,7 +1,11 @@
set(CMake_C11_THREAD_LOCAL_BROKEN 0)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
if(NOT DEFINED CMake_C11_THREAD_LOCAL_WORKS)
- message(STATUS "Checking if compiler supports C11 _Thread_local")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports C11 _Thread_local"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_C11_THREAD_LOCAL_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_c11_thread_local.c
@@ -12,14 +16,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
set_property(CACHE CMake_C11_THREAD_LOCAL_WORKS PROPERTY VALUE 0)
endif()
if(CMake_C11_THREAD_LOCAL_WORKS)
- message(STATUS "Checking if compiler supports C11 _Thread_local - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C11 _Thread_local passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports C11 _Thread_local - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C11 _Thread_local failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx14_check.cmake b/Source/Checks/cm_cxx14_check.cmake
index 38606b9c90..e5656bf4ed 100644
--- a/Source/Checks/cm_cxx14_check.cmake
+++ b/Source/Checks/cm_cxx14_check.cmake
@@ -1,10 +1,14 @@
set(CMake_CXX14_BROKEN 0)
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
if(NOT CMAKE_CXX14_STANDARD_COMPILE_OPTION)
set(CMake_CXX14_WORKS 0)
endif()
if(NOT DEFINED CMake_CXX14_WORKS)
- message(STATUS "Checking if compiler supports needed C++14 constructs")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports needed C++14 constructs"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_CXX14_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx14_check.cpp
@@ -15,14 +19,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
set_property(CACHE CMake_CXX14_WORKS PROPERTY VALUE 0)
endif()
if(CMake_CXX14_WORKS)
- message(STATUS "Checking if compiler supports needed C++14 constructs - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports needed C++14 constructs passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports needed C++14 constructs - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports needed C++14 constructs failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx17_check.cmake b/Source/Checks/cm_cxx17_check.cmake
index 4da2fd7cac..dba3eaf3b3 100644
--- a/Source/Checks/cm_cxx17_check.cmake
+++ b/Source/Checks/cm_cxx17_check.cmake
@@ -1,10 +1,14 @@
set(CMake_CXX17_BROKEN 0)
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
if(NOT CMAKE_CXX17_STANDARD_COMPILE_OPTION)
set(CMake_CXX17_WORKS 0)
endif()
if(NOT DEFINED CMake_CXX17_WORKS)
- message(STATUS "Checking if compiler supports needed C++17 constructs")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports needed C++17 constructs"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_CXX17_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx17_check.cpp
@@ -15,14 +19,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
set_property(CACHE CMake_CXX17_WORKS PROPERTY VALUE 0)
endif()
if(CMake_CXX17_WORKS)
- message(STATUS "Checking if compiler supports needed C++17 constructs - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports needed C++17 constructs passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports needed C++17 constructs - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports needed C++17 constructs failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx17_check.cpp b/Source/Checks/cm_cxx17_check.cpp
index 29863b136b..abbe22cf6f 100644
--- a/Source/Checks/cm_cxx17_check.cpp
+++ b/Source/Checks/cm_cxx17_check.cpp
@@ -8,6 +8,13 @@
# include <comdef.h>
#endif
+template <typename T,
+ typename std::invoke_result<decltype(&T::get), T>::type = nullptr>
+typename T::pointer get_ptr(T& item)
+{
+ return item.get();
+}
+
int main()
{
int a[] = { 0, 1, 2 };
@@ -20,6 +27,9 @@ int main()
std::unique_ptr<int> u(new int(0));
+ // Intel compiler do not handle correctly 'decltype' inside 'invoke_result'
+ get_ptr(u);
+
#ifdef _MSC_VER
// clang-cl has problems instantiating this constructor in C++17 mode
// error: indirection requires pointer operand ('const _GUID' invalid)
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index fb68ed78c9..c16286c7fd 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -1,8 +1,12 @@
+include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
function(cm_check_cxx_feature name)
string(TOUPPER ${name} FEATURE)
if(NOT DEFINED CMake_HAVE_CXX_${FEATURE})
- message(STATUS "Checking if compiler supports C++ ${name}")
+ cm_message_checks_compat(
+ "Checking if compiler supports C++ ${name}"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
if(CMAKE_CXX_STANDARD)
set(maybe_cxx_standard -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
else()
@@ -26,19 +30,23 @@ function(cm_check_cxx_feature name)
string(REGEX REPLACE "[^\n]*warning:[^\n]*sprintf\\(\\) is often misused, please use snprintf[^\n]*" "" check_output "${check_output}")
# Filter out xcodebuild warnings.
string(REGEX REPLACE "[^\n]* xcodebuild\\[[0-9]*:[0-9]*\\] warning: [^\n]*" "" check_output "${check_output}")
+ # Filter out ld warnings.
+ string(REGEX REPLACE "[^\n]*ld: warning: [^\n]*" "" check_output "${check_output}")
+ # Filter out CUDA installation warnings.
+ string(REGEX REPLACE "[^\n]*clang: warning: Unknown CUDA version[^\n]*" "" check_output "${check_output}")
# If using the feature causes warnings, treat it as broken/unavailable.
if(check_output MATCHES "(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]")
set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
endif()
if(CMake_HAVE_CXX_${FEATURE})
- message(STATUS "Checking if compiler supports C++ ${name} - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C++ ${name} passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports C++ ${name} - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C++ ${name} failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_message_checks_compat.cmake b/Source/Checks/cm_message_checks_compat.cmake
new file mode 100644
index 0000000000..024c397a8b
--- /dev/null
+++ b/Source/Checks/cm_message_checks_compat.cmake
@@ -0,0 +1,13 @@
+# Supporting using the CHECK_... message modes if available
+# and fall back to the older behavior if not
+macro(cm_message_checks_compat description startVar passVar failVar)
+ if(CMAKE_VERSION VERSION_GREATER 3.16.2019)
+ set(${startVar} CHECK_START "${description}")
+ set(${passVar} CHECK_PASS)
+ set(${failVar} CHECK_FAIL)
+ else()
+ set(${startVar} STATUS "${description}")
+ set(${passVar} STATUS "${description} - ")
+ set(${failVar} STATUS "${description} - ")
+ endif()
+endmacro()
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 7009717511..c24ee76216 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -5,6 +5,7 @@ add_executable(ccmake
ccmake.cxx
cmCursesBoolWidget.cxx
cmCursesCacheEntryComposite.cxx
+ cmCursesColor.cxx
cmCursesDummyWidget.cxx
cmCursesFilePathWidget.cxx
cmCursesForm.cxx
@@ -17,21 +18,45 @@ add_executable(ccmake
cmCursesWidget.cxx
)
target_include_directories(ccmake PRIVATE ${CURSES_INCLUDE_PATH})
+set(CMAKE_REQUIRED_INCLUDES ${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})
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${CURSES_FORM_INCLUDE_DIR})
endif()
target_link_libraries(ccmake
${CURSES_FORM_LIBRARY}
${CURSES_LIBRARY}
)
+ set(CMAKE_REQUIRED_LIBRARIES
+ ${CURSES_FORM_LIBRARY}
+ ${CURSES_LIBRARY}
+ )
if(CURSES_EXTRA_LIBRARY)
target_link_libraries(ccmake ${CURSES_EXTRA_LIBRARY})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_EXTRA_LIBRARY})
endif()
else()
target_link_libraries(ccmake cmForm)
+ get_target_property(cmFormIncludeDirs cmForm INTERFACE_INCLUDE_DIRECTORIES)
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${cmFormIncludeDirs})
+ get_target_property(cmFormLibraries cmForm INTERFACE_LINK_LIBRARIES)
+ set(CMAKE_REQUIRED_LIBRARIES ${cmFormLibraries})
+endif()
+
+include(CheckSymbolExists)
+check_symbol_exists(use_default_colors
+ "form.h"
+ HAVE_CURSES_USE_DEFAULT_COLORS)
+if(HAVE_CURSES_USE_DEFAULT_COLORS)
+ set_source_files_properties(cmCursesColor.cxx
+ PROPERTIES COMPILE_DEFINITIONS HAVE_CURSES_USE_DEFAULT_COLORS)
+endif()
+
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET ccmake PROPERTY JOB_POOL_LINK "link-bin")
endif()
CMake_OPTIONAL_COMPONENT(ccmake)
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 9e9dfbd195..01fce85454 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -9,6 +9,7 @@
#include "cmsys/Encoding.hxx"
+#include "cmCursesColor.h"
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
@@ -126,6 +127,7 @@ int main(int argc, char const* const* argv)
noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
+ cmCursesColor::InitColors();
signal(SIGWINCH, onsig);
@@ -153,10 +155,28 @@ int main(int argc, char const* const* argv)
return 1;
}
+ /*
+ * The message is stored in a list by the form which will be
+ * joined by '\n' before display.
+ * Removing any trailing '\n' avoid extra empty lines in the final results
+ */
+ auto cleanMessage = [](const std::string& message) -> std::string {
+ auto msg = message;
+ if (!msg.empty() && msg.back() == '\n') {
+ msg.pop_back();
+ }
+ return msg;
+ };
cmSystemTools::SetMessageCallback(
- [myform](const std::string& message, const char* title) {
- myform->AddError(message, title);
+ [&](const std::string& message, const char* title) {
+ myform->AddError(cleanMessage(message), title);
});
+ cmSystemTools::SetStderrCallback([&](const std::string& message) {
+ myform->AddError(cleanMessage(message), "");
+ });
+ cmSystemTools::SetStdoutCallback([&](const std::string& message) {
+ myform->UpdateProgress(cleanMessage(message), -1);
+ });
cmCursesForm::CurrentForm = myform;
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
index 97b0811288..c4dbed8350 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.cxx
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -4,6 +4,7 @@
#include <string>
+#include "cmCursesColor.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
@@ -12,8 +13,10 @@ cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, int left,
: cmCursesWidget(width, height, left, top)
{
this->Type = cmStateEnums::BOOL;
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (!cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
this->SetValueAsBool(false);
}
@@ -42,8 +45,16 @@ void cmCursesBoolWidget::SetValueAsBool(bool value)
{
if (value) {
this->SetValue("ON");
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::BoolOn));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::BoolOn));
+ }
} else {
this->SetValue("OFF");
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::BoolOff));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::BoolOff));
+ }
}
}
diff --git a/Source/CursesDialog/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx
new file mode 100644
index 0000000000..641d48ccec
--- /dev/null
+++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -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. */
+#include "cmCursesColor.h"
+
+#include "cmCursesStandardIncludes.h"
+
+bool cmCursesColor::HasColors()
+{
+#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
+ return has_colors();
+#else
+ return false;
+#endif
+}
+
+void cmCursesColor::InitColors()
+{
+#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
+ if (HasColors()) {
+ start_color();
+ use_default_colors();
+ init_pair(cmCursesColor::BoolOff, COLOR_RED, -1);
+ init_pair(cmCursesColor::BoolOn, COLOR_GREEN, -1);
+ init_pair(cmCursesColor::String, COLOR_BLUE, -1);
+ init_pair(cmCursesColor::Path, COLOR_YELLOW, -1);
+ init_pair(cmCursesColor::Options, COLOR_MAGENTA, -1);
+ }
+#endif
+}
diff --git a/Source/CursesDialog/cmCursesColor.h b/Source/CursesDialog/cmCursesColor.h
new file mode 100644
index 0000000000..78ca52cbb1
--- /dev/null
+++ b/Source/CursesDialog/cmCursesColor.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 cmCursesColor_h
+#define cmCursesColor_h
+
+class cmCursesColor
+{
+public:
+ enum Color
+ {
+ // Default color is pair 0
+ BoolOff = 1,
+ BoolOn,
+ String,
+ Path,
+ Options
+ };
+
+ static bool HasColors();
+
+ static void InitColors();
+};
+
+#endif // cmCursesColor_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index e2d8d06b49..806e663e9e 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -8,6 +8,7 @@
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
inline int ctrl(int z)
@@ -16,14 +17,12 @@ inline int ctrl(int z)
}
cmCursesLongMessageForm::cmCursesLongMessageForm(
- std::vector<std::string> const& messages, const char* title)
+ std::vector<std::string> const& messages, const char* title,
+ ScrollBehavior scrollBehavior)
+ : Scrolling(scrollBehavior)
{
// Append all messages into on big string
- for (std::string const& message : messages) {
- this->Messages += message;
- // Add one blank line after each message
- this->Messages += "\n\n";
- }
+ this->Messages = cmJoin(messages, "\n");
this->Title = title;
this->Fields[0] = nullptr;
this->Fields[1] = nullptr;
@@ -48,7 +47,7 @@ void cmCursesLongMessageForm::UpdateStatusBar()
size = cmCursesMainForm::MAX_WIDTH - 1;
}
strncpy(bar, this->Title.c_str(), size);
- for (size_t i = size - 1; i < cmCursesMainForm::MAX_WIDTH; i++) {
+ for (size_t i = size; i < cmCursesMainForm::MAX_WIDTH; i++) {
bar[i] = ' ';
}
int width;
@@ -89,7 +88,7 @@ void cmCursesLongMessageForm::PrintKeys()
return;
}
char firstLine[512];
- sprintf(firstLine, "Press [e] to exit help");
+ sprintf(firstLine, "Press [e] to exit screen");
char fmt_s[] = "%s";
curses_move(y - 2, 0);
@@ -112,8 +111,6 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
const char* msg = this->Messages.c_str();
- curses_clear();
-
if (this->Fields[0]) {
free_field(this->Fields[0]);
this->Fields[0] = nullptr;
@@ -136,10 +133,13 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
}
i++;
}
- form_driver(this->Form, REQ_BEG_FIELD);
+ if (this->Scrolling == ScrollBehavior::ScrollDown) {
+ form_driver(this->Form, REQ_END_FIELD);
+ } else {
+ form_driver(this->Form, REQ_BEG_FIELD);
+ }
this->UpdateStatusBar();
- this->PrintKeys();
touchwin(stdscr);
refresh();
}
@@ -153,6 +153,7 @@ void cmCursesLongMessageForm::HandleInput()
char debugMessage[128];
for (;;) {
+ this->PrintKeys();
int key = getch();
sprintf(debugMessage, "Message widget handling input, key: %d", key);
@@ -173,7 +174,6 @@ void cmCursesLongMessageForm::HandleInput()
}
this->UpdateStatusBar();
- this->PrintKeys();
touchwin(stdscr);
wrefresh(stdscr);
}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 42f9c710b7..88efe62173 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -14,8 +14,14 @@
class cmCursesLongMessageForm : public cmCursesForm
{
public:
+ enum class ScrollBehavior
+ {
+ NoScroll,
+ ScrollDown
+ };
+
cmCursesLongMessageForm(std::vector<std::string> const& messages,
- const char* title);
+ const char* title, ScrollBehavior scrollBehavior);
~cmCursesLongMessageForm() override;
cmCursesLongMessageForm(cmCursesLongMessageForm const&) = delete;
@@ -43,6 +49,7 @@ public:
protected:
std::string Messages;
std::string Title;
+ ScrollBehavior Scrolling;
FIELD* Fields[2];
};
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 6b71e8a10a..2c92835159 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -34,6 +34,7 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> args,
: Args(std::move(args))
, InitialWidth(initWidth)
{
+ this->HasNonStatusOutputs = false;
this->NumberOfPages = 0;
this->AdvancedMode = false;
this->NumberOfVisibleEntries = 0;
@@ -321,25 +322,25 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
} else {
if (this->OkToGenerate) {
sprintf(firstLine,
- "Press [c] to configure Press [g] to generate and exit");
+ " [l] Show log output [c] Configure"
+ " [g] Generate ");
} else {
sprintf(firstLine,
- "Press [c] to configure ");
+ " [l] Show log output [c] Configure"
+ " ");
}
{
const char* toggleKeyInstruction =
- "Press [t] to toggle advanced mode (Currently %s)";
+ " [t] Toggle advanced mode (currently %s)";
sprintf(thirdLine, toggleKeyInstruction,
- this->AdvancedMode ? "On" : "Off");
+ this->AdvancedMode ? "on" : "off");
}
sprintf(secondLine,
- "Press [h] for help "
- "Press [q] to quit without generating");
+ " [h] Help [q] Quit without generating");
}
curses_move(y - 4, 0);
- char fmt[512] =
- "Press [enter] to edit option Press [d] to delete an entry";
+ char fmt[512] = "Keys: [enter] Edit an entry [d] Delete an entry";
if (process) {
memset(fmt, ' ', 57);
}
@@ -364,7 +365,7 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
// Print the key of the current entry and the CMake version
// on the status bar. Designed for a width of 80 chars.
-void cmCursesMainForm::UpdateStatusBar(const char* message)
+void cmCursesMainForm::UpdateStatusBar(cm::optional<std::string> message)
{
int x;
int y;
@@ -385,119 +386,91 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
return;
}
- // Get the key of the current entry
- FIELD* cur = current_field(this->Form);
- int findex = field_index(cur);
- cmCursesWidget* lbl = nullptr;
- if (findex >= 0) {
- lbl = reinterpret_cast<cmCursesWidget*>(
- field_userptr(this->Fields[findex - 2]));
- }
- char help[128] = "";
- const char* curField = "";
- if (lbl) {
- curField = lbl->GetValue();
+ // Find the current label index
+ // Field are grouped by 3, the label should be 2 less than the current index
+ using size_type = decltype(this->Fields)::size_type;
+ size_type currentLabelIndex = field_index(current_field(this->Form)) - 2;
+
+ // Use the status message if any, otherwise join the key and help string
+ std::string bar;
+ if (message) {
+ bar = *message;
+ } else {
+ // Get the key of the current entry
+ cmCursesWidget* labelWidget = reinterpret_cast<cmCursesWidget*>(
+ field_userptr(this->Fields[currentLabelIndex]));
+ std::string labelValue = labelWidget->GetValue();
+ bar = labelValue + ": ";
// Get the help string of the current entry
// and add it to the help string
- const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
+ auto cmakeState = this->CMakeInstance->GetState();
+ const char* existingValue = cmakeState->GetCacheEntryValue(labelValue);
if (existingValue) {
- const char* hs = this->CMakeInstance->GetState()->GetCacheEntryProperty(
- curField, "HELPSTRING");
- if (hs) {
- strncpy(help, hs, 127);
- help[127] = '\0';
- } else {
- help[0] = 0;
+ auto help = cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
+ if (help) {
+ bar += help;
}
- } else {
- sprintf(help, " ");
}
}
+ // Pad with spaces to erase any previous text,
+ // or truncate as necessary to fit the screen
+ bar.resize(x, ' ');
+ curses_move(y - 5, 0);
+ attron(A_STANDOUT);
+ char fmt_s[] = "%s";
+ printw(fmt_s, bar.c_str());
+ attroff(A_STANDOUT);
- // Join the key, help string and pad with spaces
- // (or truncate) as necessary
- char bar[cmCursesMainForm::MAX_WIDTH];
- size_t curFieldLen = strlen(curField);
- size_t helpLen = strlen(help);
-
- size_t width = std::min<size_t>(x, cmCursesMainForm::MAX_WIDTH);
-
- if (message) {
- curField = message;
- curFieldLen = strlen(message);
- strncpy(bar, curField, width);
- if (curFieldLen < width) {
- memset(bar + curFieldLen, ' ', width - curFieldLen);
- }
- } else {
- strncpy(bar, curField, width);
- if (curFieldLen < width) {
- bar[curFieldLen] = ':';
- bar[curFieldLen + 1] = ' ';
- strncpy(bar + curFieldLen + 2, help, width - curFieldLen - 2);
- if (curFieldLen + helpLen + 2 < width) {
- memset(bar + curFieldLen + helpLen + 2, ' ',
- width - (curFieldLen + helpLen + 2));
- }
- }
+ // Highlight the current label, reset others
+ // Fields are grouped by 3, the first one being the label
+ // so start at 0 and move up by 3 avoiding the last null entry
+ for (size_type index = 0; index < this->Fields.size() - 1; index += 3) {
+ bool currentLabel = index == currentLabelIndex;
+ set_field_fore(this->Fields[index], currentLabel ? A_STANDOUT : A_NORMAL);
}
- bar[width] = '\0';
-
- // Display CMake version info on the next line
+ // Display CMake version under the status bar
// We want to display this on the right
- char version[cmCursesMainForm::MAX_WIDTH];
- char vertmp[128];
- sprintf(vertmp, "CMake Version %s", cmVersion::GetCMakeVersion());
- size_t sideSpace = (width - strlen(vertmp));
- memset(version, ' ', sideSpace);
- sprintf(version + sideSpace, "%s", vertmp);
- version[width] = '\0';
-
- // Now print both lines
- char fmt_s[] = "%s";
- curses_move(y - 5, 0);
- attron(A_STANDOUT);
- printw(fmt_s, bar);
- attroff(A_STANDOUT);
- curses_move(y - 4, 0);
- printw(fmt_s, version);
+ std::string version = "CMake Version ";
+ version += cmVersion::GetCMakeVersion();
+ version.resize(std::min<std::string::size_type>(x, version.size()));
+ curses_move(y - 4, x - static_cast<int>(version.size()));
+ printw(fmt_s, version.c_str());
+
pos_form_cursor(this->Form);
}
void cmCursesMainForm::UpdateProgress(const std::string& msg, float prog)
{
- char tmp[1024];
- const char* cmsg = tmp;
if (prog >= 0) {
- sprintf(tmp, "%s %i%%", msg.c_str(), static_cast<int>(100 * prog));
+ constexpr int progressBarWidth = 40;
+ int progressBarCompleted = static_cast<int>(progressBarWidth * prog);
+ int percentCompleted = static_cast<int>(100 * prog);
+ this->LastProgress = (percentCompleted < 100 ? " " : "");
+ this->LastProgress += (percentCompleted < 10 ? " " : "");
+ this->LastProgress += std::to_string(percentCompleted) + "% [";
+ this->LastProgress.append(progressBarCompleted, '#');
+ this->LastProgress.append(progressBarWidth - progressBarCompleted, ' ');
+ this->LastProgress += "] " + msg + "...";
} else {
- cmsg = msg.c_str();
+ this->Outputs.emplace_back(msg);
}
- this->UpdateStatusBar(cmsg);
- this->PrintKeys(1);
- curses_move(1, 1);
- touchwin(stdscr);
- refresh();
+
+ this->DisplayOutputs();
}
int cmCursesMainForm::Configure(int noconfigure)
{
- int xi;
- int yi;
- getmaxyx(stdscr, yi, xi);
-
- curses_move(1, 1);
- this->UpdateStatusBar("Configuring, please wait...");
- this->PrintKeys(1);
- touchwin(stdscr);
- refresh();
- this->CMakeInstance->SetProgressCallback(
- [this](const std::string& msg, float prog) {
- this->UpdateProgress(msg, prog);
- });
+ this->ResetOutputs();
+
+ if (noconfigure == 0) {
+ this->UpdateProgress("Configuring", 0);
+ this->CMakeInstance->SetProgressCallback(
+ [this](const std::string& msg, float prog) {
+ this->UpdateProgress(msg, prog);
+ });
+ }
// always save the current gui values to disk
this->FillCacheManagerFromUI();
@@ -505,9 +478,6 @@ int cmCursesMainForm::Configure(int noconfigure)
this->CMakeInstance->GetHomeOutputDirectory());
this->LoadCache(nullptr);
- // Get rid of previous errors
- this->Errors = std::vector<std::string>();
-
// run the generate process
this->OkToGenerate = true;
int retVal;
@@ -524,7 +494,7 @@ int cmCursesMainForm::Configure(int noconfigure)
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
- if (retVal != 0 || !this->Errors.empty()) {
+ if (retVal != 0 || this->HasNonStatusOutputs) {
// see if there was an error
if (cmSystemTools::GetErrorOccuredFlag()) {
this->OkToGenerate = false;
@@ -532,11 +502,13 @@ int cmCursesMainForm::Configure(int noconfigure)
int xx;
int yy;
getmaxyx(stdscr, yy, xx);
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->Errors,
- cmSystemTools::GetErrorOccuredFlag()
- ? "Errors occurred during the last pass."
- : "CMake produced the following output.");
+ const char* title = "Configure produced the following output";
+ if (cmSystemTools::GetErrorOccuredFlag()) {
+ title = "Configure failed with the following output";
+ }
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->Outputs, title,
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
// reset error condition
cmSystemTools::ResetErrorOccuredFlag();
CurrentForm = msgs;
@@ -547,11 +519,13 @@ int cmCursesMainForm::Configure(int noconfigure)
if (retVal == -2) {
return retVal;
}
- CurrentForm = this;
- this->Render(1, 1, xx, yy);
}
this->InitializeUI();
+ CurrentForm = this;
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
this->Render(1, 1, xi, yi);
return 0;
@@ -559,30 +533,21 @@ int cmCursesMainForm::Configure(int noconfigure)
int cmCursesMainForm::Generate()
{
- int xi;
- int yi;
- getmaxyx(stdscr, yi, xi);
+ this->ResetOutputs();
- curses_move(1, 1);
- this->UpdateStatusBar("Generating, please wait...");
- this->PrintKeys(1);
- touchwin(stdscr);
- refresh();
+ this->UpdateProgress("Generating", 0);
this->CMakeInstance->SetProgressCallback(
[this](const std::string& msg, float prog) {
this->UpdateProgress(msg, prog);
});
- // Get rid of previous errors
- this->Errors = std::vector<std::string>();
-
// run the generate process
int retVal = this->CMakeInstance->Generate();
this->CMakeInstance->SetProgressCallback(nullptr);
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
- if (retVal != 0 || !this->Errors.empty()) {
+ if (retVal != 0 || this->HasNonStatusOutputs) {
// see if there was an error
if (cmSystemTools::GetErrorOccuredFlag()) {
this->OkToGenerate = false;
@@ -592,12 +557,13 @@ int cmCursesMainForm::Generate()
int xx;
int yy;
getmaxyx(stdscr, yy, xx);
- const char* title = "Messages during last pass.";
+ const char* title = "Generate produced the following output";
if (cmSystemTools::GetErrorOccuredFlag()) {
- title = "Errors occurred during the last pass.";
+ title = "Generate failed with the following output";
}
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->Errors, title);
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->Outputs, title,
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
msgs->HandleInput();
@@ -606,11 +572,13 @@ int cmCursesMainForm::Generate()
if (retVal == -2) {
return retVal;
}
- CurrentForm = this;
- this->Render(1, 1, xx, yy);
}
this->InitializeUI();
+ CurrentForm = this;
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
this->Render(1, 1, xi, yi);
return 0;
@@ -619,7 +587,9 @@ int cmCursesMainForm::Generate()
void cmCursesMainForm::AddError(const std::string& message,
const char* /*unused*/)
{
- this->Errors.emplace_back(message);
+ this->Outputs.emplace_back(message);
+ this->HasNonStatusOutputs = true;
+ this->DisplayOutputs();
}
void cmCursesMainForm::RemoveEntry(const char* value)
@@ -704,7 +674,7 @@ void cmCursesMainForm::HandleInput()
this->PrintKeys();
if (this->SearchMode) {
std::string searchstr = "Search: " + this->SearchString;
- this->UpdateStatusBar(searchstr.c_str());
+ this->UpdateStatusBar(searchstr);
this->PrintKeys(1);
curses_move(y - 5, static_cast<unsigned int>(searchstr.size()));
// curses_move(1,1);
@@ -848,8 +818,9 @@ void cmCursesMainForm::HandleInput()
this->HelpMessage[1] = "";
}
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->HelpMessage, "Help.");
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->HelpMessage, "Help",
+ cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -861,7 +832,8 @@ void cmCursesMainForm::HandleInput()
else if (key == 'l') {
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
- this->Errors, "Errors occurred during the last pass.");
+ this->Outputs, "CMake produced the following output",
+ cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -1007,15 +979,6 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
} else {
form_driver(this->Form, REQ_NEXT_FIELD);
}
- /*
- char buffer[1024];
- sprintf(buffer, "Line: %d != %d / %d\n", findex, idx,
- this->NumberOfVisibleEntries);
- touchwin(stdscr);
- refresh();
- this->UpdateStatusBar( buffer );
- usleep(100000);
- */
cur = current_field(this->Form);
findex = field_index(cur);
if (findex == start_index) {
@@ -1024,6 +987,28 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
}
}
+void cmCursesMainForm::ResetOutputs()
+{
+ this->LogForm.reset();
+ this->Outputs.clear();
+ this->HasNonStatusOutputs = false;
+ this->LastProgress.clear();
+}
+
+void cmCursesMainForm::DisplayOutputs()
+{
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
+
+ auto newLogForm = new cmCursesLongMessageForm(
+ this->Outputs, this->LastProgress.c_str(),
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
+ CurrentForm = newLogForm;
+ this->LogForm.reset(newLogForm);
+ this->LogForm->Render(1, 1, xi, yi);
+}
+
const char* cmCursesMainForm::s_ConstHelpMessage =
"CMake is used to configure and generate build files for software projects. "
"The basic steps for configuring a project with ccmake are as follows:\n\n"
@@ -1080,7 +1065,7 @@ const char* cmCursesMainForm::s_ConstHelpMessage =
" c : process the configuration files with the current options\n"
" g : generate build files and exit, only available when there are no "
"new options and no errors have been detected during last configuration.\n"
- " l : shows last errors\n"
+ " l : shows cmake output\n"
" d : delete an option\n"
" t : toggles advanced mode. In normal mode, only the most important "
"options are shown. In advanced mode, all options are shown. We recommend "
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index b8769b7cf4..b7c204d64e 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -10,12 +10,15 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmStateTypes.h"
class cmake;
+class cmCursesLongMessageForm;
/** \class cmCursesMainForm
* \brief The main page of ccmake
@@ -66,8 +69,8 @@ public:
* exception is during a resize. The optional argument specifies the
* string to be displayed in the status bar.
*/
- void UpdateStatusBar() override { this->UpdateStatusBar(nullptr); }
- virtual void UpdateStatusBar(const char* message);
+ void UpdateStatusBar() override { this->UpdateStatusBar(cm::nullopt); }
+ void UpdateStatusBar(cm::optional<std::string> message);
/**
* Display current commands and their keys on the toolbar. This
@@ -122,10 +125,24 @@ protected:
// Jump to the cache entry whose name matches the string.
void JumpToCacheEntry(const char* str);
+ // Clear and reset the output log and state
+ void ResetOutputs();
+
+ // Display the current progress and output
+ void DisplayOutputs();
+
// Copies of cache entries stored in the user interface
std::vector<cmCursesCacheEntryComposite> Entries;
- // Errors produced during last run of cmake
- std::vector<std::string> Errors;
+
+ // The form used to display logs during processing
+ std::unique_ptr<cmCursesLongMessageForm> LogForm;
+ // Output produced by the last pass
+ std::vector<std::string> Outputs;
+ // Did the last pass produced outputs of interest (errors, warnings, ...)
+ bool HasNonStatusOutputs;
+ // Last progress bar
+ std::string LastProgress;
+
// Command line arguments to be passed to cmake each time
// it is run
std::vector<std::string> Args;
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
index eb773ad0fb..a15241faed 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.cxx
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesOptionsWidget.h"
+#include "cmCursesColor.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
@@ -15,8 +16,13 @@ cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left,
// there is no option type, and string type causes ccmake to cast
// the widget into a string widget at some point. BOOL is safe for
// now.
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Options));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Options));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
}
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
index bb3808e89c..8ed42dee75 100644
--- a/Source/CursesDialog/cmCursesPathWidget.cxx
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -4,6 +4,7 @@
#include <vector>
+#include "cmCursesColor.h"
#include "cmCursesMainForm.h"
#include "cmCursesStringWidget.h"
#include "cmStateTypes.h"
@@ -16,6 +17,13 @@ cmCursesPathWidget::cmCursesPathWidget(int width, int height, int left,
this->Type = cmStateEnums::PATH;
this->Cycle = false;
this->CurrentIndex = 0;
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Path));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Path));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
}
void cmCursesPathWidget::OnType(int& key, cmCursesMainForm* fm, WINDOW* w)
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index 6296af20ba..c62947836c 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -4,6 +4,7 @@
#include <cstdio>
+#include "cmCursesColor.h"
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
@@ -21,8 +22,13 @@ cmCursesStringWidget::cmCursesStringWidget(int width, int height, int left,
{
this->InEdit = false;
this->Type = cmStateEnums::STRING;
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::String));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::String));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
}
diff --git a/Source/LexerParser/.gitattributes b/Source/LexerParser/.gitattributes
index bf70249788..63d9afb263 100644
--- a/Source/LexerParser/.gitattributes
+++ b/Source/LexerParser/.gitattributes
@@ -16,4 +16,6 @@
/cmFortranLexer.h generated
/cmFortranParser.cxx generated
/cmFortranParserTokens.h generated
+/cmGccDepfileLexer.cxx generated
+/cmGccDepfileLexer.h generated
/cmListFileLexer.c generated
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index ae7fb42ea8..34dc8ecfea 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmCommandArgumentParser.y" /* yacc.c:337 */
+#line 1 "cmCommandArgumentParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -134,7 +134,8 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 138 "cmCommandArgumentParser.cxx" /* yacc.c:337 */
+#line 138 "cmCommandArgumentParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -155,8 +156,8 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmCommandArgumentParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
# define YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -310,6 +311,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -700,7 +703,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1138,6 +1143,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1200,8 +1207,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1269,7 +1274,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1304,193 +1308,194 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 99 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+ case 2:
+#line 99 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
-#line 1314 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1318 "cmCommandArgumentParser.cxx"
break;
case 3:
-#line 105 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 105 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1322 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1326 "cmCommandArgumentParser.cxx"
break;
case 4:
-#line 108 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 108 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1330 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1334 "cmCommandArgumentParser.cxx"
break;
case 5:
-#line 113 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 113 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1338 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1342 "cmCommandArgumentParser.cxx"
break;
case 6:
-#line 116 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 116 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1346 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1350 "cmCommandArgumentParser.cxx"
break;
case 7:
-#line 121 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 121 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1354 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1358 "cmCommandArgumentParser.cxx"
break;
case 8:
-#line 124 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 124 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1362 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1366 "cmCommandArgumentParser.cxx"
break;
case 9:
-#line 129 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 129 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1370 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1374 "cmCommandArgumentParser.cxx"
break;
case 10:
-#line 132 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 132 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1378 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1382 "cmCommandArgumentParser.cxx"
break;
case 11:
-#line 135 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 135 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1386 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1390 "cmCommandArgumentParser.cxx"
break;
case 12:
-#line 138 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 138 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1394 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1398 "cmCommandArgumentParser.cxx"
break;
case 13:
-#line 141 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 141 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1402 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1406 "cmCommandArgumentParser.cxx"
break;
case 14:
-#line 144 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 144 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1410 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1414 "cmCommandArgumentParser.cxx"
break;
case 15:
-#line 149 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 149 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1418 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1422 "cmCommandArgumentParser.cxx"
break;
case 16:
-#line 152 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 152 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1426 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1430 "cmCommandArgumentParser.cxx"
break;
case 17:
-#line 155 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 155 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
-#line 1434 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1438 "cmCommandArgumentParser.cxx"
break;
case 18:
-#line 158 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 158 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
-#line 1442 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1446 "cmCommandArgumentParser.cxx"
break;
case 19:
-#line 163 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 163 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1450 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1454 "cmCommandArgumentParser.cxx"
break;
case 20:
-#line 166 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 166 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[-1].str);
}
-#line 1458 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1462 "cmCommandArgumentParser.cxx"
break;
case 21:
-#line 171 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 171 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1466 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1470 "cmCommandArgumentParser.cxx"
break;
case 22:
-#line 174 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 174 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1474 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1478 "cmCommandArgumentParser.cxx"
break;
case 23:
-#line 179 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 179 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1482 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1486 "cmCommandArgumentParser.cxx"
break;
case 24:
-#line 182 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 182 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1490 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1494 "cmCommandArgumentParser.cxx"
break;
-#line 1494 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1498 "cmCommandArgumentParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1723,7 +1728,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 187 "cmCommandArgumentParser.y" /* yacc.c:1918 */
+#line 187 "cmCommandArgumentParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h
index 56c9794f9f..033b8994d1 100644
--- a/Source/LexerParser/cmCommandArgumentParserTokens.h
+++ b/Source/LexerParser/cmCommandArgumentParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index 6c1fb2cb37..b15082ddb2 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmDependsJavaParser.y" /* yacc.c:337 */
+#line 1 "cmDependsJavaParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -123,7 +123,8 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 127 "cmDependsJavaParser.cxx" /* yacc.c:337 */
+#line 127 "cmDependsJavaParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -144,8 +145,8 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmDependsJavaParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
# define YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -481,6 +482,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -1685,7 +1688,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -2123,6 +2128,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -2185,8 +2192,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -2254,7 +2259,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -2289,215 +2293,215 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 183 "cmDependsJavaParser.y" /* yacc.c:1652 */
+ case 2:
+#line 183 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2305 "cmDependsJavaParser.cxx"
break;
case 3:
-#line 192 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 192 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2312 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2316 "cmDependsJavaParser.cxx"
break;
case 4:
-#line 200 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 200 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2323 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2327 "cmDependsJavaParser.cxx"
break;
case 5:
-#line 208 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 208 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2334 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2338 "cmDependsJavaParser.cxx"
break;
case 6:
-#line 216 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 216 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2345 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2349 "cmDependsJavaParser.cxx"
break;
case 7:
-#line 224 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 224 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2356 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2360 "cmDependsJavaParser.cxx"
break;
case 8:
-#line 232 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 232 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2371 "cmDependsJavaParser.cxx"
break;
case 9:
-#line 241 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 241 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2382 "cmDependsJavaParser.cxx"
break;
case 10:
-#line 249 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 249 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2389 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2393 "cmDependsJavaParser.cxx"
break;
case 11:
-#line 258 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 258 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2400 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2404 "cmDependsJavaParser.cxx"
break;
case 12:
-#line 266 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 266 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2411 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2415 "cmDependsJavaParser.cxx"
break;
case 13:
-#line 275 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 275 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2419 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2423 "cmDependsJavaParser.cxx"
break;
case 14:
-#line 280 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 280 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2427 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2431 "cmDependsJavaParser.cxx"
break;
case 15:
-#line 285 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 285 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2439 "cmDependsJavaParser.cxx"
break;
case 16:
-#line 290 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 290 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2443 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2447 "cmDependsJavaParser.cxx"
break;
case 17:
-#line 295 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 295 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2451 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2455 "cmDependsJavaParser.cxx"
break;
case 18:
-#line 300 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 300 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2459 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2463 "cmDependsJavaParser.cxx"
break;
case 19:
-#line 305 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 305 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2467 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2471 "cmDependsJavaParser.cxx"
break;
case 20:
-#line 310 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 310 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2475 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2479 "cmDependsJavaParser.cxx"
break;
case 21:
-#line 316 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 316 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2486 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2490 "cmDependsJavaParser.cxx"
break;
case 22:
-#line 324 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 324 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2497 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2501 "cmDependsJavaParser.cxx"
break;
case 23:
-#line 333 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 333 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpStoreClass((yyvsp[0].str));
@@ -2505,44 +2509,44 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2513 "cmDependsJavaParser.cxx"
break;
case 24:
-#line 343 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 343 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2524 "cmDependsJavaParser.cxx"
break;
case 25:
-#line 352 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 352 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2531 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2535 "cmDependsJavaParser.cxx"
break;
case 26:
-#line 361 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 361 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2542 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2546 "cmDependsJavaParser.cxx"
break;
case 27:
-#line 369 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 369 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpStoreClass((yyvsp[-1].str));
@@ -2550,56 +2554,56 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2554 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2558 "cmDependsJavaParser.cxx"
break;
case 28:
-#line 379 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 379 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2567 "cmDependsJavaParser.cxx"
break;
case 29:
-#line 385 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 385 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2572 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2576 "cmDependsJavaParser.cxx"
break;
case 30:
-#line 392 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 392 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2581 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2585 "cmDependsJavaParser.cxx"
break;
case 31:
-#line 399 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 399 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2590 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2594 "cmDependsJavaParser.cxx"
break;
case 32:
-#line 405 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 405 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = (yyvsp[0].str);
}
-#line 2599 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2603 "cmDependsJavaParser.cxx"
break;
case 33:
-#line 412 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 412 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2607,11 +2611,11 @@ yyreduce:
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
(yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
}
-#line 2611 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2615 "cmDependsJavaParser.cxx"
break;
case 34:
-#line 421 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 421 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2620,11 +2624,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2624 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2628 "cmDependsJavaParser.cxx"
break;
case 35:
-#line 431 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 431 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2633,118 +2637,118 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2641 "cmDependsJavaParser.cxx"
break;
case 36:
-#line 441 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 441 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2648 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2652 "cmDependsJavaParser.cxx"
break;
case 37:
-#line 450 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 450 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2659 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2663 "cmDependsJavaParser.cxx"
break;
case 38:
-#line 458 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 458 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2674 "cmDependsJavaParser.cxx"
break;
case 39:
-#line 467 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 467 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2681 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2685 "cmDependsJavaParser.cxx"
break;
case 40:
-#line 475 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 475 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2695 "cmDependsJavaParser.cxx"
break;
case 41:
-#line 482 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 482 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2702 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2706 "cmDependsJavaParser.cxx"
break;
case 42:
-#line 490 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 490 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2712 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2716 "cmDependsJavaParser.cxx"
break;
case 43:
-#line 497 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 497 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2723 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2727 "cmDependsJavaParser.cxx"
break;
case 44:
-#line 505 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 505 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2733 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2737 "cmDependsJavaParser.cxx"
break;
case 45:
-#line 512 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 512 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2744 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2748 "cmDependsJavaParser.cxx"
break;
case 46:
-#line 521 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 521 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2754,33 +2758,33 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2758 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2762 "cmDependsJavaParser.cxx"
break;
case 47:
-#line 533 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 533 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2769 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2773 "cmDependsJavaParser.cxx"
break;
case 48:
-#line 541 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 541 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2780 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2784 "cmDependsJavaParser.cxx"
break;
case 49:
-#line 550 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 550 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2790,11 +2794,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2794 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2798 "cmDependsJavaParser.cxx"
break;
case 50:
-#line 562 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 562 "cmDependsJavaParser.y"
{
jpElementStart(5);
std::string str = (yyvsp[-3].str);
@@ -2805,77 +2809,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2809 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2813 "cmDependsJavaParser.cxx"
break;
case 51:
-#line 575 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 575 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2824 "cmDependsJavaParser.cxx"
break;
case 52:
-#line 583 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 583 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2831 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2835 "cmDependsJavaParser.cxx"
break;
case 53:
-#line 591 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 591 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2842 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2846 "cmDependsJavaParser.cxx"
break;
case 54:
-#line 600 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 600 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2853 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2857 "cmDependsJavaParser.cxx"
break;
case 55:
-#line 608 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 608 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2864 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2868 "cmDependsJavaParser.cxx"
break;
case 67:
-#line 623 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 623 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 2875 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2879 "cmDependsJavaParser.cxx"
break;
case 68:
-#line 633 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 633 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -2883,11 +2887,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2887 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2891 "cmDependsJavaParser.cxx"
break;
case 69:
-#line 642 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 642 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(2);
@@ -2895,11 +2899,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2899 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2903 "cmDependsJavaParser.cxx"
break;
case 70:
-#line 651 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 651 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -2907,11 +2911,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2911 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2915 "cmDependsJavaParser.cxx"
break;
case 71:
-#line 660 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 660 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -2919,226 +2923,226 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2923 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2927 "cmDependsJavaParser.cxx"
break;
case 72:
-#line 669 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 669 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2933 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2937 "cmDependsJavaParser.cxx"
break;
case 73:
-#line 676 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 676 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2944 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2948 "cmDependsJavaParser.cxx"
break;
case 74:
-#line 685 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 685 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2955 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2959 "cmDependsJavaParser.cxx"
break;
case 75:
-#line 694 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 694 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2966 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2970 "cmDependsJavaParser.cxx"
break;
case 76:
-#line 703 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 703 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2977 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2981 "cmDependsJavaParser.cxx"
break;
case 77:
-#line 711 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 711 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2992 "cmDependsJavaParser.cxx"
break;
case 78:
-#line 720 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 720 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2999 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3003 "cmDependsJavaParser.cxx"
break;
case 79:
-#line 728 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 728 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3009 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3013 "cmDependsJavaParser.cxx"
break;
case 80:
-#line 735 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 735 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3020 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3024 "cmDependsJavaParser.cxx"
break;
case 81:
-#line 744 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 744 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3035 "cmDependsJavaParser.cxx"
break;
case 82:
-#line 752 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 752 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3042 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3046 "cmDependsJavaParser.cxx"
break;
case 83:
-#line 760 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 760 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3053 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3057 "cmDependsJavaParser.cxx"
break;
case 84:
-#line 768 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 768 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3064 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3068 "cmDependsJavaParser.cxx"
break;
case 85:
-#line 777 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 777 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3075 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3079 "cmDependsJavaParser.cxx"
break;
case 86:
-#line 785 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 785 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3086 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3090 "cmDependsJavaParser.cxx"
break;
case 87:
-#line 794 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 794 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 3094 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3098 "cmDependsJavaParser.cxx"
break;
case 88:
-#line 800 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 800 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3109 "cmDependsJavaParser.cxx"
break;
case 89:
-#line 808 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 808 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3116 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3120 "cmDependsJavaParser.cxx"
break;
case 90:
-#line 817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 817 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3131 "cmDependsJavaParser.cxx"
break;
case 91:
-#line 825 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 825 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3138 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3142 "cmDependsJavaParser.cxx"
break;
case 92:
-#line 834 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 834 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3146,77 +3150,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3154 "cmDependsJavaParser.cxx"
break;
case 93:
-#line 843 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 843 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3161 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3165 "cmDependsJavaParser.cxx"
break;
case 94:
-#line 852 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 852 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3176 "cmDependsJavaParser.cxx"
break;
case 95:
-#line 860 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 860 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3183 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3187 "cmDependsJavaParser.cxx"
break;
case 96:
-#line 869 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 869 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3194 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3198 "cmDependsJavaParser.cxx"
break;
case 97:
-#line 877 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 877 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3209 "cmDependsJavaParser.cxx"
break;
case 98:
-#line 885 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 885 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3216 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3220 "cmDependsJavaParser.cxx"
break;
case 99:
-#line 894 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 894 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3224,11 +3228,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3228 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3232 "cmDependsJavaParser.cxx"
break;
case 100:
-#line 903 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 903 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3236,22 +3240,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3240 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3244 "cmDependsJavaParser.cxx"
break;
case 101:
-#line 912 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 912 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3255 "cmDependsJavaParser.cxx"
break;
case 102:
-#line 920 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 920 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3259,11 +3263,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3263 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3267 "cmDependsJavaParser.cxx"
break;
case 103:
-#line 930 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 930 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3272,40 +3276,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3276 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3280 "cmDependsJavaParser.cxx"
break;
case 104:
-#line 940 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 940 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 3285 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3289 "cmDependsJavaParser.cxx"
break;
case 105:
-#line 946 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 946 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3296 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3300 "cmDependsJavaParser.cxx"
break;
case 107:
-#line 957 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 957 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3305 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3309 "cmDependsJavaParser.cxx"
break;
case 108:
-#line 963 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 963 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3313,11 +3317,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3317 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3321 "cmDependsJavaParser.cxx"
break;
case 109:
-#line 973 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 973 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3325,11 +3329,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3329 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3333 "cmDependsJavaParser.cxx"
break;
case 110:
-#line 983 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 983 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3337,20 +3341,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3341 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3345 "cmDependsJavaParser.cxx"
break;
case 111:
-#line 993 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 993 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3350 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3354 "cmDependsJavaParser.cxx"
break;
case 112:
-#line 999 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 999 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3358,11 +3362,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3362 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3366 "cmDependsJavaParser.cxx"
break;
case 113:
-#line 1009 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1009 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3370,11 +3374,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3374 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3378 "cmDependsJavaParser.cxx"
break;
case 114:
-#line 1019 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1019 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3382,11 +3386,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3386 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3390 "cmDependsJavaParser.cxx"
break;
case 115:
-#line 1029 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1029 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3394,11 +3398,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3398 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3402 "cmDependsJavaParser.cxx"
break;
case 116:
-#line 1038 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1038 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3406,11 +3410,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3410 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3414 "cmDependsJavaParser.cxx"
break;
case 117:
-#line 1048 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1048 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3419,11 +3423,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3423 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3427 "cmDependsJavaParser.cxx"
break;
case 118:
-#line 1059 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1059 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3431,22 +3435,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3439 "cmDependsJavaParser.cxx"
break;
case 119:
-#line 1068 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1068 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3446 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3450 "cmDependsJavaParser.cxx"
break;
case 120:
-#line 1076 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1076 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3454,11 +3458,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3458 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3462 "cmDependsJavaParser.cxx"
break;
case 121:
-#line 1086 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1086 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3466,11 +3470,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3470 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3474 "cmDependsJavaParser.cxx"
break;
case 122:
-#line 1095 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1095 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3478,22 +3482,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3486 "cmDependsJavaParser.cxx"
break;
case 123:
-#line 1105 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1105 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3497 "cmDependsJavaParser.cxx"
break;
case 124:
-#line 1114 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1114 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3501,21 +3505,21 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3509 "cmDependsJavaParser.cxx"
break;
case 125:
-#line 1123 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1123 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3515 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3519 "cmDependsJavaParser.cxx"
break;
case 126:
-#line 1130 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1130 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3523,11 +3527,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3527 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3531 "cmDependsJavaParser.cxx"
break;
case 127:
-#line 1140 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1140 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3535,11 +3539,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3539 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3543 "cmDependsJavaParser.cxx"
break;
case 128:
-#line 1149 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1149 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3547,11 +3551,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3551 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3555 "cmDependsJavaParser.cxx"
break;
case 129:
-#line 1159 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1159 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3559,33 +3563,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3567 "cmDependsJavaParser.cxx"
break;
case 130:
-#line 1168 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1168 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3578 "cmDependsJavaParser.cxx"
break;
case 131:
-#line 1176 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1176 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3585 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3589 "cmDependsJavaParser.cxx"
break;
case 132:
-#line 1185 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1185 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3593,11 +3597,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3597 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3601 "cmDependsJavaParser.cxx"
break;
case 133:
-#line 1194 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1194 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3605,11 +3609,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3609 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3613 "cmDependsJavaParser.cxx"
break;
case 134:
-#line 1203 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1203 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3617,22 +3621,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3621 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3625 "cmDependsJavaParser.cxx"
break;
case 135:
-#line 1212 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1212 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3632 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3636 "cmDependsJavaParser.cxx"
break;
case 136:
-#line 1220 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1220 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3640,22 +3644,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3644 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3648 "cmDependsJavaParser.cxx"
break;
case 137:
-#line 1229 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1229 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3655 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3659 "cmDependsJavaParser.cxx"
break;
case 138:
-#line 1238 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1238 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3663,11 +3667,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3667 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3671 "cmDependsJavaParser.cxx"
break;
case 139:
-#line 1248 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1248 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3675,11 +3679,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3679 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3683 "cmDependsJavaParser.cxx"
break;
case 140:
-#line 1258 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1258 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3687,11 +3691,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3695 "cmDependsJavaParser.cxx"
break;
case 141:
-#line 1267 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1267 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3699,11 +3703,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3703 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3707 "cmDependsJavaParser.cxx"
break;
case 142:
-#line 1277 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1277 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3711,22 +3715,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3715 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3719 "cmDependsJavaParser.cxx"
break;
case 143:
-#line 1286 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1286 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3726 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3730 "cmDependsJavaParser.cxx"
break;
case 144:
-#line 1294 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1294 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3734,11 +3738,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3738 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3742 "cmDependsJavaParser.cxx"
break;
case 145:
-#line 1303 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1303 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3746,11 +3750,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3750 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3754 "cmDependsJavaParser.cxx"
break;
case 146:
-#line 1313 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1313 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3758,11 +3762,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3762 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3766 "cmDependsJavaParser.cxx"
break;
case 147:
-#line 1322 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1322 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3770,33 +3774,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3774 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3778 "cmDependsJavaParser.cxx"
break;
case 148:
-#line 1332 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1332 "cmDependsJavaParser.y"
{
jpElementStart(4);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3785 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3789 "cmDependsJavaParser.cxx"
break;
case 149:
-#line 1340 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1340 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3796 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3800 "cmDependsJavaParser.cxx"
break;
case 150:
-#line 1348 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1348 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3804,11 +3808,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3808 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3812 "cmDependsJavaParser.cxx"
break;
case 151:
-#line 1358 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1358 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3816,11 +3820,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3824 "cmDependsJavaParser.cxx"
break;
case 152:
-#line 1367 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1367 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3828,11 +3832,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3832 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3836 "cmDependsJavaParser.cxx"
break;
case 153:
-#line 1377 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1377 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3840,11 +3844,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3844 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3848 "cmDependsJavaParser.cxx"
break;
case 154:
-#line 1386 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1386 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3852,11 +3856,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3856 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3860 "cmDependsJavaParser.cxx"
break;
case 155:
-#line 1395 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1395 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3864,11 +3868,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3868 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3872 "cmDependsJavaParser.cxx"
break;
case 156:
-#line 1405 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1405 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3876,11 +3880,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3880 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3884 "cmDependsJavaParser.cxx"
break;
case 157:
-#line 1415 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1415 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(3);
@@ -3888,11 +3892,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3896 "cmDependsJavaParser.cxx"
break;
case 158:
-#line 1424 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1424 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3900,11 +3904,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3908 "cmDependsJavaParser.cxx"
break;
case 159:
-#line 1434 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1434 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3912,11 +3916,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3920 "cmDependsJavaParser.cxx"
break;
case 160:
-#line 1443 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1443 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3924,11 +3928,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3932 "cmDependsJavaParser.cxx"
break;
case 161:
-#line 1452 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1452 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3936,11 +3940,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3944 "cmDependsJavaParser.cxx"
break;
case 162:
-#line 1461 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1461 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3948,11 +3952,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3956 "cmDependsJavaParser.cxx"
break;
case 163:
-#line 1470 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1470 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3960,11 +3964,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3968 "cmDependsJavaParser.cxx"
break;
case 164:
-#line 1479 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1479 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3972,11 +3976,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3976 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3980 "cmDependsJavaParser.cxx"
break;
case 165:
-#line 1489 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1489 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3984,11 +3988,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3992 "cmDependsJavaParser.cxx"
break;
case 166:
-#line 1498 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1498 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3996,11 +4000,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4000 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4004 "cmDependsJavaParser.cxx"
break;
case 167:
-#line 1507 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1507 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4008,11 +4012,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4012 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4016 "cmDependsJavaParser.cxx"
break;
case 168:
-#line 1516 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1516 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4020,11 +4024,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4024 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4028 "cmDependsJavaParser.cxx"
break;
case 169:
-#line 1525 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1525 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4032,11 +4036,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4036 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4040 "cmDependsJavaParser.cxx"
break;
case 170:
-#line 1535 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1535 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4044,11 +4048,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4048 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4052 "cmDependsJavaParser.cxx"
break;
case 171:
-#line 1544 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1544 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4056,11 +4060,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4060 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4064 "cmDependsJavaParser.cxx"
break;
case 172:
-#line 1553 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1553 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4068,11 +4072,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4072 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4076 "cmDependsJavaParser.cxx"
break;
case 173:
-#line 1562 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1562 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4080,11 +4084,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4084 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4088 "cmDependsJavaParser.cxx"
break;
case 174:
-#line 1571 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1571 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4092,11 +4096,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4096 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4100 "cmDependsJavaParser.cxx"
break;
case 175:
-#line 1580 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1580 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4104,11 +4108,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4108 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4112 "cmDependsJavaParser.cxx"
break;
case 176:
-#line 1589 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1589 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4116,11 +4120,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4120 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4124 "cmDependsJavaParser.cxx"
break;
case 177:
-#line 1598 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1598 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4128,11 +4132,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4132 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4136 "cmDependsJavaParser.cxx"
break;
case 178:
-#line 1607 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1607 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4140,11 +4144,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4144 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4148 "cmDependsJavaParser.cxx"
break;
case 179:
-#line 1616 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1616 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4152,11 +4156,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4156 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4160 "cmDependsJavaParser.cxx"
break;
case 180:
-#line 1625 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1625 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4164,11 +4168,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4168 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4172 "cmDependsJavaParser.cxx"
break;
case 181:
-#line 1634 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1634 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4176,11 +4180,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4180 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4184 "cmDependsJavaParser.cxx"
break;
case 182:
-#line 1644 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1644 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4188,11 +4192,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4196 "cmDependsJavaParser.cxx"
break;
case 183:
-#line 1654 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1654 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4201,11 +4205,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4209 "cmDependsJavaParser.cxx"
break;
case 184:
-#line 1665 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1665 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4213,11 +4217,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4217 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4221 "cmDependsJavaParser.cxx"
break;
case 185:
-#line 1675 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1675 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4225,11 +4229,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4229 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4233 "cmDependsJavaParser.cxx"
break;
case 186:
-#line 1685 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1685 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4237,11 +4241,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4241 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4245 "cmDependsJavaParser.cxx"
break;
case 187:
-#line 1694 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1694 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4249,11 +4253,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4253 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4257 "cmDependsJavaParser.cxx"
break;
case 188:
-#line 1703 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1703 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4261,11 +4265,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4265 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4269 "cmDependsJavaParser.cxx"
break;
case 189:
-#line 1712 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1712 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4273,11 +4277,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4281 "cmDependsJavaParser.cxx"
break;
case 190:
-#line 1721 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1721 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4285,11 +4289,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4293 "cmDependsJavaParser.cxx"
break;
case 191:
-#line 1730 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1730 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4297,11 +4301,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4305 "cmDependsJavaParser.cxx"
break;
case 192:
-#line 1739 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1739 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4309,11 +4313,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4317 "cmDependsJavaParser.cxx"
break;
case 193:
-#line 1749 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1749 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4321,11 +4325,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4329 "cmDependsJavaParser.cxx"
break;
case 194:
-#line 1759 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1759 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4333,11 +4337,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4341 "cmDependsJavaParser.cxx"
break;
case 195:
-#line 1769 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1769 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4345,40 +4349,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4353 "cmDependsJavaParser.cxx"
break;
case 196:
-#line 1779 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1779 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4358 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4362 "cmDependsJavaParser.cxx"
break;
case 197:
-#line 1786 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1786 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 4367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4371 "cmDependsJavaParser.cxx"
break;
case 198:
-#line 1792 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1792 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4382 "cmDependsJavaParser.cxx"
break;
case 199:
-#line 1800 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1800 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4386,22 +4390,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4390 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4394 "cmDependsJavaParser.cxx"
break;
case 200:
-#line 1809 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1809 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4401 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4405 "cmDependsJavaParser.cxx"
break;
case 201:
-#line 1817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1817 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4409,11 +4413,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4413 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4417 "cmDependsJavaParser.cxx"
break;
case 202:
-#line 1827 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1827 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4421,11 +4425,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4425 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4429 "cmDependsJavaParser.cxx"
break;
case 203:
-#line 1837 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1837 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4433,11 +4437,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4437 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4441 "cmDependsJavaParser.cxx"
break;
case 204:
-#line 1846 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1846 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4445,11 +4449,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4449 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4453 "cmDependsJavaParser.cxx"
break;
case 205:
-#line 1856 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1856 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4457,11 +4461,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4461 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4465 "cmDependsJavaParser.cxx"
break;
case 206:
-#line 1865 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1865 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4469,58 +4473,58 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4473 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4477 "cmDependsJavaParser.cxx"
break;
case 207:
-#line 1875 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1875 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4486 "cmDependsJavaParser.cxx"
break;
case 208:
-#line 1882 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1882 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4491 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4495 "cmDependsJavaParser.cxx"
break;
case 209:
-#line 1889 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1889 "cmDependsJavaParser.y"
{
jpElementStart(7);
}
-#line 4500 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4504 "cmDependsJavaParser.cxx"
break;
case 210:
-#line 1897 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1897 "cmDependsJavaParser.y"
{
jpElementStart(9);
}
-#line 4509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4513 "cmDependsJavaParser.cxx"
break;
case 211:
-#line 1903 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1903 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4524 "cmDependsJavaParser.cxx"
break;
case 212:
-#line 1911 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1911 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4528,22 +4532,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4532 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4536 "cmDependsJavaParser.cxx"
break;
case 213:
-#line 1920 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1920 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4543 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4547 "cmDependsJavaParser.cxx"
break;
case 214:
-#line 1928 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1928 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4551,33 +4555,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4555 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4559 "cmDependsJavaParser.cxx"
break;
case 215:
-#line 1939 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1939 "cmDependsJavaParser.y"
{
jpElementStart(9);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4566 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4570 "cmDependsJavaParser.cxx"
break;
case 216:
-#line 1947 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1947 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4577 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4581 "cmDependsJavaParser.cxx"
break;
case 217:
-#line 1955 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1955 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4585,11 +4589,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4589 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4593 "cmDependsJavaParser.cxx"
break;
case 218:
-#line 1965 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1965 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4597,11 +4601,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4601 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4605 "cmDependsJavaParser.cxx"
break;
case 219:
-#line 1974 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1974 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4609,11 +4613,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4613 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4617 "cmDependsJavaParser.cxx"
break;
case 220:
-#line 1984 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1984 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4621,11 +4625,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4625 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4629 "cmDependsJavaParser.cxx"
break;
case 221:
-#line 1994 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1994 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4633,11 +4637,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4641 "cmDependsJavaParser.cxx"
break;
case 222:
-#line 2003 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2003 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4645,11 +4649,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4649 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4653 "cmDependsJavaParser.cxx"
break;
case 223:
-#line 2013 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2013 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4657,11 +4661,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4661 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4665 "cmDependsJavaParser.cxx"
break;
case 224:
-#line 2022 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2022 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4669,11 +4673,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4673 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4677 "cmDependsJavaParser.cxx"
break;
case 225:
-#line 2032 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2032 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4682,31 +4686,31 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4686 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4690 "cmDependsJavaParser.cxx"
break;
case 226:
-#line 2042 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2042 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4697 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4701 "cmDependsJavaParser.cxx"
break;
case 227:
-#line 2050 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2050 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4710 "cmDependsJavaParser.cxx"
break;
case 228:
-#line 2057 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2057 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4715,11 +4719,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4719 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4723 "cmDependsJavaParser.cxx"
break;
case 229:
-#line 2068 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2068 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4727,11 +4731,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4731 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4735 "cmDependsJavaParser.cxx"
break;
case 230:
-#line 2078 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2078 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4739,11 +4743,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4743 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4747 "cmDependsJavaParser.cxx"
break;
case 231:
-#line 2088 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2088 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4751,11 +4755,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4755 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4759 "cmDependsJavaParser.cxx"
break;
case 232:
-#line 2098 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2098 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4763,11 +4767,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4767 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4771 "cmDependsJavaParser.cxx"
break;
case 233:
-#line 2107 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2107 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -4775,22 +4779,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4779 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4783 "cmDependsJavaParser.cxx"
break;
case 234:
-#line 2116 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2116 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4794 "cmDependsJavaParser.cxx"
break;
case 235:
-#line 2124 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2124 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4798,11 +4802,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4806 "cmDependsJavaParser.cxx"
break;
case 236:
-#line 2134 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2134 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4810,11 +4814,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4818 "cmDependsJavaParser.cxx"
break;
case 237:
-#line 2143 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2143 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4822,20 +4826,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4830 "cmDependsJavaParser.cxx"
break;
case 238:
-#line 2153 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2153 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4835 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4839 "cmDependsJavaParser.cxx"
break;
case 239:
-#line 2160 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2160 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4843,11 +4847,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4847 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4851 "cmDependsJavaParser.cxx"
break;
case 240:
-#line 2170 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2170 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4855,11 +4859,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4859 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4863 "cmDependsJavaParser.cxx"
break;
case 241:
-#line 2179 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2179 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4867,11 +4871,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4871 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4875 "cmDependsJavaParser.cxx"
break;
case 242:
-#line 2189 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2189 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4879,20 +4883,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4883 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4887 "cmDependsJavaParser.cxx"
break;
case 243:
-#line 2198 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2198 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4896 "cmDependsJavaParser.cxx"
break;
case 244:
-#line 2204 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2204 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4900,11 +4904,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4908 "cmDependsJavaParser.cxx"
break;
case 245:
-#line 2213 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2213 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4912,11 +4916,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4920 "cmDependsJavaParser.cxx"
break;
case 246:
-#line 2222 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2222 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4924,11 +4928,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4932 "cmDependsJavaParser.cxx"
break;
case 247:
-#line 2231 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2231 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4936,11 +4940,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4944 "cmDependsJavaParser.cxx"
break;
case 248:
-#line 2240 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2240 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4948,11 +4952,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4956 "cmDependsJavaParser.cxx"
break;
case 249:
-#line 2250 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2250 "cmDependsJavaParser.y"
{
jpElementStart(6);
jpCheckEmpty(6);
@@ -4960,22 +4964,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4968 "cmDependsJavaParser.cxx"
break;
case 250:
-#line 2259 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2259 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4975 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4979 "cmDependsJavaParser.cxx"
break;
case 251:
-#line 2267 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2267 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4983,22 +4987,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4987 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4991 "cmDependsJavaParser.cxx"
break;
case 252:
-#line 2276 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2276 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4998 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5002 "cmDependsJavaParser.cxx"
break;
case 253:
-#line 2284 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2284 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5006,11 +5010,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5010 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5014 "cmDependsJavaParser.cxx"
break;
case 254:
-#line 2294 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2294 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5018,11 +5022,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5022 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5026 "cmDependsJavaParser.cxx"
break;
case 255:
-#line 2303 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2303 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5030,11 +5034,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5034 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5038 "cmDependsJavaParser.cxx"
break;
case 256:
-#line 2313 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2313 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5042,11 +5046,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5046 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5050 "cmDependsJavaParser.cxx"
break;
case 257:
-#line 2322 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2322 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5054,11 +5058,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5058 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5062 "cmDependsJavaParser.cxx"
break;
case 258:
-#line 2331 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2331 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5066,11 +5070,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5070 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5074 "cmDependsJavaParser.cxx"
break;
case 259:
-#line 2340 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2340 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5078,22 +5082,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5082 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5086 "cmDependsJavaParser.cxx"
break;
case 260:
-#line 2349 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2349 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5093 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5097 "cmDependsJavaParser.cxx"
break;
case 261:
-#line 2357 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2357 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5101,11 +5105,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5109 "cmDependsJavaParser.cxx"
break;
case 262:
-#line 2367 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2367 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5113,11 +5117,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5117 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5121 "cmDependsJavaParser.cxx"
break;
case 263:
-#line 2376 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2376 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5125,11 +5129,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5129 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5133 "cmDependsJavaParser.cxx"
break;
case 264:
-#line 2386 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2386 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5137,29 +5141,29 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5141 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5145 "cmDependsJavaParser.cxx"
break;
case 265:
-#line 2396 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2396 "cmDependsJavaParser.y"
{
jpElementStart(2);
}
-#line 5150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5154 "cmDependsJavaParser.cxx"
break;
case 266:
-#line 2402 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2402 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 5159 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5163 "cmDependsJavaParser.cxx"
break;
case 267:
-#line 2409 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2409 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5168,11 +5172,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5176 "cmDependsJavaParser.cxx"
break;
case 268:
-#line 2419 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2419 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5181,11 +5185,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5185 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5189 "cmDependsJavaParser.cxx"
break;
case 269:
-#line 2429 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2429 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5194,11 +5198,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5198 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5202 "cmDependsJavaParser.cxx"
break;
case 270:
-#line 2439 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2439 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5207,11 +5211,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5211 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5215 "cmDependsJavaParser.cxx"
break;
case 271:
-#line 2450 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2450 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5220,11 +5224,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5224 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5228 "cmDependsJavaParser.cxx"
break;
case 272:
-#line 2460 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2460 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5234,11 +5238,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5238 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5242 "cmDependsJavaParser.cxx"
break;
case 273:
-#line 2471 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2471 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5247,11 +5251,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5255 "cmDependsJavaParser.cxx"
break;
case 274:
-#line 2481 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2481 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5260,11 +5264,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5264 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5268 "cmDependsJavaParser.cxx"
break;
case 275:
-#line 2492 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2492 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5273,11 +5277,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5281 "cmDependsJavaParser.cxx"
break;
case 276:
-#line 2502 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2502 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5285,11 +5289,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5293 "cmDependsJavaParser.cxx"
break;
case 277:
-#line 2512 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2512 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5297,11 +5301,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5305 "cmDependsJavaParser.cxx"
break;
case 278:
-#line 2521 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2521 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5309,11 +5313,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5317 "cmDependsJavaParser.cxx"
break;
case 279:
-#line 2530 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2530 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5321,11 +5325,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5329 "cmDependsJavaParser.cxx"
break;
case 280:
-#line 2539 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2539 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5333,11 +5337,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5341 "cmDependsJavaParser.cxx"
break;
case 281:
-#line 2548 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2548 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5345,11 +5349,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5353 "cmDependsJavaParser.cxx"
break;
case 282:
-#line 2558 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2558 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5357,11 +5361,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5361 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5365 "cmDependsJavaParser.cxx"
break;
case 283:
-#line 2568 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2568 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5369,11 +5373,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5373 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5377 "cmDependsJavaParser.cxx"
break;
case 284:
-#line 2578 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2578 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5381,11 +5385,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5385 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5389 "cmDependsJavaParser.cxx"
break;
case 285:
-#line 2587 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2587 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5393,11 +5397,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5397 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5401 "cmDependsJavaParser.cxx"
break;
case 286:
-#line 2596 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2596 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5405,11 +5409,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5409 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5413 "cmDependsJavaParser.cxx"
break;
case 287:
-#line 2605 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2605 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5417,11 +5421,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5421 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5425 "cmDependsJavaParser.cxx"
break;
case 288:
-#line 2614 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2614 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5429,11 +5433,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5433 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5437 "cmDependsJavaParser.cxx"
break;
case 289:
-#line 2624 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2624 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5441,11 +5445,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5445 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5449 "cmDependsJavaParser.cxx"
break;
case 290:
-#line 2634 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2634 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5453,11 +5457,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5457 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5461 "cmDependsJavaParser.cxx"
break;
case 291:
-#line 2644 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2644 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5465,11 +5469,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5469 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5473 "cmDependsJavaParser.cxx"
break;
case 292:
-#line 2653 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2653 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5477,11 +5481,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5481 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5485 "cmDependsJavaParser.cxx"
break;
case 293:
-#line 2662 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2662 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5489,11 +5493,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5497 "cmDependsJavaParser.cxx"
break;
case 294:
-#line 2671 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2671 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5501,11 +5505,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5509 "cmDependsJavaParser.cxx"
break;
case 295:
-#line 2681 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2681 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5513,11 +5517,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5517 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5521 "cmDependsJavaParser.cxx"
break;
case 296:
-#line 2690 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2690 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5525,20 +5529,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5529 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5533 "cmDependsJavaParser.cxx"
break;
case 297:
-#line 2699 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2699 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5538 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5542 "cmDependsJavaParser.cxx"
break;
case 298:
-#line 2706 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2706 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5546,11 +5550,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5550 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5554 "cmDependsJavaParser.cxx"
break;
case 299:
-#line 2715 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2715 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5558,11 +5562,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5562 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5566 "cmDependsJavaParser.cxx"
break;
case 300:
-#line 2724 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2724 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5570,11 +5574,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5578 "cmDependsJavaParser.cxx"
break;
case 301:
-#line 2733 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2733 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5582,11 +5586,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5586 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5590 "cmDependsJavaParser.cxx"
break;
case 302:
-#line 2743 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2743 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5594,11 +5598,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5598 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5602 "cmDependsJavaParser.cxx"
break;
case 303:
-#line 2752 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2752 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5606,11 +5610,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5610 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5614 "cmDependsJavaParser.cxx"
break;
case 304:
-#line 2761 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2761 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5618,11 +5622,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5622 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5626 "cmDependsJavaParser.cxx"
break;
case 305:
-#line 2771 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2771 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5630,11 +5634,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5634 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5638 "cmDependsJavaParser.cxx"
break;
case 306:
-#line 2780 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2780 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5642,11 +5646,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5646 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5650 "cmDependsJavaParser.cxx"
break;
case 307:
-#line 2789 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2789 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5654,11 +5658,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5658 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5662 "cmDependsJavaParser.cxx"
break;
case 308:
-#line 2798 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2798 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5666,11 +5670,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5674 "cmDependsJavaParser.cxx"
break;
case 309:
-#line 2808 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2808 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5678,11 +5682,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5682 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5686 "cmDependsJavaParser.cxx"
break;
case 310:
-#line 2817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2817 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5690,11 +5694,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5694 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5698 "cmDependsJavaParser.cxx"
break;
case 311:
-#line 2826 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2826 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5702,11 +5706,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5710 "cmDependsJavaParser.cxx"
break;
case 312:
-#line 2835 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2835 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5714,11 +5718,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5718 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5722 "cmDependsJavaParser.cxx"
break;
case 313:
-#line 2844 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2844 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5726,11 +5730,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5730 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5734 "cmDependsJavaParser.cxx"
break;
case 314:
-#line 2853 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2853 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5738,11 +5742,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5742 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5746 "cmDependsJavaParser.cxx"
break;
case 315:
-#line 2863 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2863 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5750,11 +5754,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5754 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5758 "cmDependsJavaParser.cxx"
break;
case 316:
-#line 2872 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2872 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5762,11 +5766,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5766 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5770 "cmDependsJavaParser.cxx"
break;
case 317:
-#line 2881 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2881 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5774,11 +5778,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5778 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5782 "cmDependsJavaParser.cxx"
break;
case 318:
-#line 2891 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2891 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5786,11 +5790,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5794 "cmDependsJavaParser.cxx"
break;
case 319:
-#line 2900 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2900 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5798,11 +5802,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5806 "cmDependsJavaParser.cxx"
break;
case 320:
-#line 2910 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2910 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5810,11 +5814,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5818 "cmDependsJavaParser.cxx"
break;
case 321:
-#line 2919 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2919 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5822,11 +5826,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5830 "cmDependsJavaParser.cxx"
break;
case 322:
-#line 2929 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2929 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5834,11 +5838,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5838 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5842 "cmDependsJavaParser.cxx"
break;
case 323:
-#line 2938 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2938 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5846,11 +5850,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5850 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5854 "cmDependsJavaParser.cxx"
break;
case 324:
-#line 2948 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2948 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5858,11 +5862,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5862 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5866 "cmDependsJavaParser.cxx"
break;
case 325:
-#line 2957 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2957 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5870,11 +5874,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5874 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5878 "cmDependsJavaParser.cxx"
break;
case 326:
-#line 2967 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2967 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5882,11 +5886,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5886 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5890 "cmDependsJavaParser.cxx"
break;
case 327:
-#line 2976 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2976 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5894,11 +5898,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5898 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5902 "cmDependsJavaParser.cxx"
break;
case 328:
-#line 2986 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2986 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5906,11 +5910,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5910 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5914 "cmDependsJavaParser.cxx"
break;
case 329:
-#line 2995 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2995 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5918,11 +5922,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5922 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5926 "cmDependsJavaParser.cxx"
break;
case 330:
-#line 3005 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3005 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5930,11 +5934,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5934 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5938 "cmDependsJavaParser.cxx"
break;
case 331:
-#line 3014 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3014 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5942,11 +5946,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5946 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5950 "cmDependsJavaParser.cxx"
break;
case 332:
-#line 3024 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3024 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5954,11 +5958,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5958 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5962 "cmDependsJavaParser.cxx"
break;
case 333:
-#line 3034 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3034 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5967,11 +5971,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5971 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5975 "cmDependsJavaParser.cxx"
break;
case 334:
-#line 3044 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3044 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5979,11 +5983,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5983 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5987 "cmDependsJavaParser.cxx"
break;
case 335:
-#line 3053 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3053 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5991,11 +5995,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5995 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5999 "cmDependsJavaParser.cxx"
break;
case 336:
-#line 3063 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3063 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6003,11 +6007,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6007 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6011 "cmDependsJavaParser.cxx"
break;
case 337:
-#line 3072 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3072 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6015,11 +6019,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6019 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6023 "cmDependsJavaParser.cxx"
break;
case 338:
-#line 3081 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3081 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6027,11 +6031,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6035 "cmDependsJavaParser.cxx"
break;
case 339:
-#line 3090 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3090 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6039,11 +6043,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6043 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6047 "cmDependsJavaParser.cxx"
break;
case 340:
-#line 3099 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3099 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6051,11 +6055,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6055 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6059 "cmDependsJavaParser.cxx"
break;
case 341:
-#line 3108 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3108 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6063,11 +6067,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6067 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6071 "cmDependsJavaParser.cxx"
break;
case 342:
-#line 3117 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3117 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6075,11 +6079,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6079 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6083 "cmDependsJavaParser.cxx"
break;
case 343:
-#line 3126 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3126 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6087,11 +6091,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6091 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6095 "cmDependsJavaParser.cxx"
break;
case 344:
-#line 3135 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3135 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6099,11 +6103,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6103 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6107 "cmDependsJavaParser.cxx"
break;
case 345:
-#line 3144 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3144 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6111,11 +6115,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6115 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6119 "cmDependsJavaParser.cxx"
break;
case 346:
-#line 3153 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3153 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6123,11 +6127,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6131 "cmDependsJavaParser.cxx"
break;
case 347:
-#line 3162 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3162 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6135,11 +6139,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6139 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6143 "cmDependsJavaParser.cxx"
break;
case 348:
-#line 3172 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3172 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6147,11 +6151,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6151 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6155 "cmDependsJavaParser.cxx"
break;
case 349:
-#line 3182 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3182 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6159,11 +6163,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6163 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6167 "cmDependsJavaParser.cxx"
break;
case 350:
-#line 3192 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3192 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6171,11 +6175,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6175 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6179 "cmDependsJavaParser.cxx"
break;
case 351:
-#line 3201 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3201 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -6184,11 +6188,12 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6188 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6192 "cmDependsJavaParser.cxx"
break;
-#line 6192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6196 "cmDependsJavaParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -6421,7 +6426,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 3210 "cmDependsJavaParser.y" /* yacc.c:1918 */
+#line 3210 "cmDependsJavaParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h
index 6bbc0848d4..e0dfa01cc5 100644
--- a/Source/LexerParser/cmDependsJavaParserTokens.h
+++ b/Source/LexerParser/cmDependsJavaParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index 8416e7249c..562b35bf71 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmExprParser.y" /* yacc.c:337 */
+#line 1 "cmExprParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -116,7 +116,8 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 120 "cmExprParser.cxx" /* yacc.c:337 */
+#line 120 "cmExprParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -137,8 +138,8 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmExprParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
# define YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -296,6 +297,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -688,7 +691,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1126,6 +1131,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1188,8 +1195,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1257,7 +1262,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1292,195 +1296,196 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 77 "cmExprParser.y" /* yacc.c:1652 */
+ case 2:
+#line 77 "cmExprParser.y"
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
-#line 1301 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1305 "cmExprParser.cxx"
break;
case 3:
-#line 82 "cmExprParser.y" /* yacc.c:1652 */
+#line 82 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1309 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1313 "cmExprParser.cxx"
break;
case 4:
-#line 85 "cmExprParser.y" /* yacc.c:1652 */
+#line 85 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
-#line 1317 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1321 "cmExprParser.cxx"
break;
case 5:
-#line 90 "cmExprParser.y" /* yacc.c:1652 */
+#line 90 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1325 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1329 "cmExprParser.cxx"
break;
case 6:
-#line 93 "cmExprParser.y" /* yacc.c:1652 */
+#line 93 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
-#line 1333 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1337 "cmExprParser.cxx"
break;
case 7:
-#line 98 "cmExprParser.y" /* yacc.c:1652 */
+#line 98 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1341 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1345 "cmExprParser.cxx"
break;
case 8:
-#line 101 "cmExprParser.y" /* yacc.c:1652 */
+#line 101 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
-#line 1349 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1353 "cmExprParser.cxx"
break;
case 9:
-#line 106 "cmExprParser.y" /* yacc.c:1652 */
+#line 106 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1357 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1361 "cmExprParser.cxx"
break;
case 10:
-#line 109 "cmExprParser.y" /* yacc.c:1652 */
+#line 109 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
-#line 1365 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1369 "cmExprParser.cxx"
break;
case 11:
-#line 112 "cmExprParser.y" /* yacc.c:1652 */
+#line 112 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
-#line 1373 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1377 "cmExprParser.cxx"
break;
case 12:
-#line 117 "cmExprParser.y" /* yacc.c:1652 */
+#line 117 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1381 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1385 "cmExprParser.cxx"
break;
case 13:
-#line 120 "cmExprParser.y" /* yacc.c:1652 */
+#line 120 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
-#line 1389 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1393 "cmExprParser.cxx"
break;
case 14:
-#line 123 "cmExprParser.y" /* yacc.c:1652 */
+#line 123 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
-#line 1397 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1401 "cmExprParser.cxx"
break;
case 15:
-#line 128 "cmExprParser.y" /* yacc.c:1652 */
+#line 128 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1405 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1409 "cmExprParser.cxx"
break;
case 16:
-#line 131 "cmExprParser.y" /* yacc.c:1652 */
+#line 131 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
-#line 1413 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1417 "cmExprParser.cxx"
break;
case 17:
-#line 134 "cmExprParser.y" /* yacc.c:1652 */
+#line 134 "cmExprParser.y"
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
-#line 1424 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1428 "cmExprParser.cxx"
break;
case 18:
-#line 140 "cmExprParser.y" /* yacc.c:1652 */
+#line 140 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
-#line 1432 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1436 "cmExprParser.cxx"
break;
case 19:
-#line 145 "cmExprParser.y" /* yacc.c:1652 */
+#line 145 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1440 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1444 "cmExprParser.cxx"
break;
case 20:
-#line 148 "cmExprParser.y" /* yacc.c:1652 */
+#line 148 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
}
-#line 1448 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1452 "cmExprParser.cxx"
break;
case 21:
-#line 151 "cmExprParser.y" /* yacc.c:1652 */
+#line 151 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
}
-#line 1456 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1460 "cmExprParser.cxx"
break;
case 22:
-#line 154 "cmExprParser.y" /* yacc.c:1652 */
+#line 154 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
}
-#line 1464 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1468 "cmExprParser.cxx"
break;
case 23:
-#line 159 "cmExprParser.y" /* yacc.c:1652 */
+#line 159 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1472 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1476 "cmExprParser.cxx"
break;
case 24:
-#line 162 "cmExprParser.y" /* yacc.c:1652 */
+#line 162 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
}
-#line 1480 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1484 "cmExprParser.cxx"
break;
-#line 1484 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1488 "cmExprParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1713,7 +1718,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 167 "cmExprParser.y" /* yacc.c:1918 */
+#line 167 "cmExprParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h
index 5ffd7c5100..e30a832572 100644
--- a/Source/LexerParser/cmExprParserTokens.h
+++ b/Source/LexerParser/cmExprParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 2ca79276d8..2494aadcc7 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmFortranParser.y" /* yacc.c:337 */
+#line 1 "cmFortranParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -135,7 +135,8 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 139 "cmFortranParser.cxx" /* yacc.c:337 */
+#line 139 "cmFortranParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -156,8 +157,8 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmFortranParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -255,16 +256,15 @@ extern int cmFortran_yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:352 */
+#line 73 "cmFortranParser.y"
char* string;
-#line 266 "cmFortranParser.cxx" /* yacc.c:352 */
-};
+#line 266 "cmFortranParser.cxx"
+};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
@@ -378,6 +378,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -509,16 +511,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 593
+#define YYLAST 594
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 41
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 14
/* YYNRULES -- Number of rules. */
-#define YYNRULES 63
+#define YYNRULES 64
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 126
+#define YYNSTATES 127
#define YYUNDEFTOK 2
#define YYMAXUTOK 295
@@ -574,7 +576,7 @@ static const yytype_uint8 yyrline[] =
220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
225, 225, 226, 226, 227, 227, 228, 228, 231, 232,
233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
- 243, 244, 245, 246
+ 243, 244, 245, 246, 247
};
#endif
@@ -626,16 +628,16 @@ static const yytype_int16 yypact[] =
-39, 21, -39, 1, -39, -20, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -24, -18, 20, -8,
- -3, 39, -39, 15, 16, 18, 19, 33, -39, -39,
+ -3, 40, -39, 15, 16, 17, 19, 34, -39, -39,
-39, -39, -39, -39, 59, -39, -39, -39, -39, -39,
- 35, 36, 37, -39, -39, -39, -39, -39, -39, 76,
- 114, 129, 167, 182, -39, -39, -39, -39, -39, -39,
+ 36, 37, 38, -39, -39, -39, -39, -39, -39, 77,
+ 115, 130, 168, 183, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, 220, 235, 273, 288, -21, 26, -39, 326,
- 341, 379, 394, 432, 447, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, 38, 40, 41, 485, -39, -39,
- -39, -39, -39, -39, 45, -39, -39, -39, 43, 500,
- 538, -39, -39, -39, 553, -39
+ -39, -39, -39, 221, 236, 274, 289, -21, 26, -39,
+ 327, 342, 380, 395, 433, 448, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, 39, 41, 42, 486, -39,
+ -39, -39, -39, -39, -39, 18, -39, -39, -39, 43,
+ 501, 539, -39, -39, -39, 554, -39
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -649,13 +651,13 @@ static const yytype_uint8 yydefact[] =
0, 0, 3, 0, 0, 0, 0, 0, 46, 46,
46, 46, 26, 46, 0, 46, 46, 4, 46, 46,
0, 0, 0, 46, 46, 46, 46, 46, 46, 0,
- 0, 0, 0, 0, 15, 57, 56, 62, 58, 59,
- 60, 61, 63, 55, 48, 49, 50, 51, 52, 53,
- 54, 47, 0, 0, 0, 0, 0, 0, 46, 0,
- 0, 0, 0, 0, 0, 21, 22, 23, 24, 14,
- 10, 13, 9, 6, 0, 0, 0, 0, 5, 16,
- 17, 18, 19, 20, 0, 46, 46, 11, 0, 0,
- 0, 46, 7, 12, 0, 8
+ 0, 0, 0, 0, 15, 57, 56, 64, 62, 58,
+ 59, 60, 61, 63, 55, 48, 49, 50, 51, 52,
+ 53, 54, 47, 0, 0, 0, 0, 0, 0, 46,
+ 0, 0, 0, 0, 0, 0, 21, 22, 23, 24,
+ 14, 10, 13, 9, 6, 0, 0, 0, 0, 5,
+ 16, 17, 18, 19, 20, 0, 46, 46, 11, 0,
+ 0, 0, 46, 7, 12, 0, 8
};
/* YYPGOTO[NTERM-NUM]. */
@@ -669,7 +671,7 @@ static const yytype_int8 yypgoto[] =
static const yytype_int8 yydefgoto[] =
{
-1, 1, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 44, 81
+ 40, 41, 44, 82
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -677,66 +679,66 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 59, 60, 61, 62, 42, 63, 104, 82, 83, 105,
- 84, 85, 43, 45, 46, 89, 90, 91, 92, 93,
- 94, 2, 3, 47, 4, 49, 50, 5, 6, 7,
+ 59, 60, 61, 62, 42, 63, 105, 83, 84, 106,
+ 85, 86, 43, 45, 46, 90, 91, 92, 93, 94,
+ 95, 2, 3, 47, 4, 49, 50, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 54, 0, 55,
- 107, 56, 57, 48, 106, 25, 26, 27, 28, 29,
- 30, 31, 64, 65, 66, 51, 58, 52, 86, 87,
- 88, 114, 53, 115, 116, 118, 121, 119, 120, 95,
- 65, 66, 0, 124, 0, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
- 0, 75, 76, 77, 78, 79, 80, 96, 65, 66,
+ 18, 19, 20, 21, 22, 23, 24, 54, 119, 55,
+ 56, 108, 57, 48, 107, 25, 26, 27, 28, 29,
+ 30, 31, 64, 65, 66, 67, 51, 58, 52, 87,
+ 88, 89, 115, 53, 116, 117, 122, 0, 120, 121,
+ 96, 65, 66, 67, 125, 68, 69, 70, 71, 72,
+ 73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
+ 0, 0, 0, 68, 69, 70, 71, 72, 73, 74,
+ 75, 0, 76, 77, 78, 79, 80, 81, 97, 65,
+ 66, 67, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 98, 65, 66, 67, 0, 0, 0,
+ 0, 68, 69, 70, 71, 72, 73, 74, 75, 0,
+ 76, 77, 78, 79, 80, 81, 68, 69, 70, 71,
+ 72, 73, 74, 75, 0, 76, 77, 78, 79, 80,
+ 81, 99, 65, 66, 67, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 100, 65, 66, 67,
+ 0, 0, 0, 0, 68, 69, 70, 71, 72, 73,
+ 74, 75, 0, 76, 77, 78, 79, 80, 81, 68,
+ 69, 70, 71, 72, 73, 74, 75, 0, 76, 77,
+ 78, 79, 80, 81, 101, 65, 66, 67, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 102,
+ 65, 66, 67, 0, 0, 0, 0, 68, 69, 70,
+ 71, 72, 73, 74, 75, 0, 76, 77, 78, 79,
+ 80, 81, 68, 69, 70, 71, 72, 73, 74, 75,
+ 0, 76, 77, 78, 79, 80, 81, 103, 65, 66,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 104, 65, 66, 67, 0, 0, 0, 0,
+ 68, 69, 70, 71, 72, 73, 74, 75, 0, 76,
+ 77, 78, 79, 80, 81, 68, 69, 70, 71, 72,
+ 73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
+ 109, 65, 66, 67, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 110, 65, 66, 67, 0,
+ 0, 0, 0, 68, 69, 70, 71, 72, 73, 74,
+ 75, 0, 76, 77, 78, 79, 80, 81, 68, 69,
+ 70, 71, 72, 73, 74, 75, 0, 76, 77, 78,
+ 79, 80, 81, 111, 65, 66, 67, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 112, 65,
+ 66, 67, 0, 0, 0, 0, 68, 69, 70, 71,
+ 72, 73, 74, 75, 0, 76, 77, 78, 79, 80,
+ 81, 68, 69, 70, 71, 72, 73, 74, 75, 0,
+ 76, 77, 78, 79, 80, 81, 113, 65, 66, 67,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 97, 65, 66, 0, 0, 0, 0, 0,
- 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
- 76, 77, 78, 79, 80, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 98, 65, 66, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 99, 65, 66, 0, 0,
- 0, 0, 0, 67, 68, 69, 70, 71, 72, 73,
- 74, 0, 75, 76, 77, 78, 79, 80, 67, 68,
- 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
- 78, 79, 80, 100, 65, 66, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 101, 65,
- 66, 0, 0, 0, 0, 0, 67, 68, 69, 70,
- 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
- 80, 67, 68, 69, 70, 71, 72, 73, 74, 0,
- 75, 76, 77, 78, 79, 80, 102, 65, 66, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 103, 65, 66, 0, 0, 0, 0, 0, 67,
- 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
- 77, 78, 79, 80, 67, 68, 69, 70, 71, 72,
- 73, 74, 0, 75, 76, 77, 78, 79, 80, 108,
- 65, 66, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 109, 65, 66, 0, 0, 0,
- 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
- 0, 75, 76, 77, 78, 79, 80, 67, 68, 69,
- 70, 71, 72, 73, 74, 0, 75, 76, 77, 78,
- 79, 80, 110, 65, 66, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 111, 65, 66,
- 0, 0, 0, 0, 0, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
- 76, 77, 78, 79, 80, 112, 65, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 113, 65, 66, 0, 0, 0, 0, 0, 67, 68,
- 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
- 78, 79, 80, 67, 68, 69, 70, 71, 72, 73,
- 74, 0, 75, 76, 77, 78, 79, 80, 117, 65,
- 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 122, 65, 66, 0, 0, 0, 0,
- 0, 67, 68, 69, 70, 71, 72, 73, 74, 0,
- 75, 76, 77, 78, 79, 80, 67, 68, 69, 70,
- 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
- 80, 123, 65, 66, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 125, 65, 66, 0,
- 0, 0, 0, 0, 67, 68, 69, 70, 71, 72,
- 73, 74, 0, 75, 76, 77, 78, 79, 80, 67,
- 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
- 77, 78, 79, 80
+ 0, 114, 65, 66, 67, 0, 0, 0, 0, 68,
+ 69, 70, 71, 72, 73, 74, 75, 0, 76, 77,
+ 78, 79, 80, 81, 68, 69, 70, 71, 72, 73,
+ 74, 75, 0, 76, 77, 78, 79, 80, 81, 118,
+ 65, 66, 67, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 123, 65, 66, 67, 0, 0,
+ 0, 0, 68, 69, 70, 71, 72, 73, 74, 75,
+ 0, 76, 77, 78, 79, 80, 81, 68, 69, 70,
+ 71, 72, 73, 74, 75, 0, 76, 77, 78, 79,
+ 80, 81, 124, 65, 66, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 126, 65, 66,
+ 67, 0, 0, 0, 0, 68, 69, 70, 71, 72,
+ 73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
+ 68, 69, 70, 71, 72, 73, 74, 75, 0, 76,
+ 77, 78, 79, 80, 81
};
static const yytype_int8 yycheck[] =
@@ -745,62 +747,62 @@ static const yytype_int8 yycheck[] =
48, 49, 32, 37, 32, 53, 54, 55, 56, 57,
58, 0, 1, 3, 3, 33, 29, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 32, -1, 33,
- 88, 33, 33, 33, 28, 34, 35, 36, 37, 38,
- 39, 40, 3, 4, 5, 26, 33, 28, 33, 33,
- 33, 33, 33, 33, 33, 30, 33, 115, 116, 3,
- 4, 5, -1, 121, -1, 26, 27, 28, 29, 30,
+ 19, 20, 21, 22, 23, 24, 25, 32, 30, 33,
+ 33, 89, 33, 33, 28, 34, 35, 36, 37, 38,
+ 39, 40, 3, 4, 5, 6, 26, 33, 28, 33,
+ 33, 33, 33, 33, 33, 33, 33, -1, 116, 117,
+ 3, 4, 5, 6, 122, 26, 27, 28, 29, 30,
31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
- -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
+ -1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, -1, 35, 36, 37, 38, 39, 40, 3, 4,
+ 5, 6, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 3, 4, 5, 6, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, -1,
+ 35, 36, 37, 38, 39, 40, 26, 27, 28, 29,
+ 30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
+ 40, 3, 4, 5, 6, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
+ -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
+ 32, 33, -1, 35, 36, 37, 38, 39, 40, 26,
+ 27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
+ 37, 38, 39, 40, 3, 4, 5, 6, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 3,
+ 4, 5, 6, -1, -1, -1, -1, 26, 27, 28,
+ 29, 30, 31, 32, 33, -1, 35, 36, 37, 38,
+ 39, 40, 26, 27, 28, 29, 30, 31, 32, 33,
-1, 35, 36, 37, 38, 39, 40, 3, 4, 5,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 3, 4, 5, -1, -1, -1, -1, -1,
+ 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3, 4, 5, 6, -1, -1, -1, -1,
26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
36, 37, 38, 39, 40, 26, 27, 28, 29, 30,
31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
- 3, 4, 5, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 3, 4, 5, -1, -1,
+ 3, 4, 5, 6, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 3, 4, 5, 6, -1,
-1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
33, -1, 35, 36, 37, 38, 39, 40, 26, 27,
28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
- 38, 39, 40, 3, 4, 5, -1, -1, -1, -1,
+ 38, 39, 40, 3, 4, 5, 6, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
- 5, -1, -1, -1, -1, -1, 26, 27, 28, 29,
+ 5, 6, -1, -1, -1, -1, 26, 27, 28, 29,
30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
40, 26, 27, 28, 29, 30, 31, 32, 33, -1,
- 35, 36, 37, 38, 39, 40, 3, 4, 5, -1,
+ 35, 36, 37, 38, 39, 40, 3, 4, 5, 6,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, -1, -1, -1, -1, -1, 26,
+ -1, 3, 4, 5, 6, -1, -1, -1, -1, 26,
27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
37, 38, 39, 40, 26, 27, 28, 29, 30, 31,
32, 33, -1, 35, 36, 37, 38, 39, 40, 3,
- 4, 5, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, 4, 5, -1, -1, -1,
+ 4, 5, 6, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 3, 4, 5, 6, -1, -1,
-1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
-1, 35, 36, 37, 38, 39, 40, 26, 27, 28,
29, 30, 31, 32, 33, -1, 35, 36, 37, 38,
- 39, 40, 3, 4, 5, -1, -1, -1, -1, -1,
+ 39, 40, 3, 4, 5, 6, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
- -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+ 6, -1, -1, -1, -1, 26, 27, 28, 29, 30,
31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
- 36, 37, 38, 39, 40, 3, 4, 5, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 3, 4, 5, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
- 38, 39, 40, 26, 27, 28, 29, 30, 31, 32,
- 33, -1, 35, 36, 37, 38, 39, 40, 3, 4,
- 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 3, 4, 5, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, -1,
- 35, 36, 37, 38, 39, 40, 26, 27, 28, 29,
- 30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
- 40, 3, 4, 5, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
- 32, 33, -1, 35, 36, 37, 38, 39, 40, 26,
- 27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
- 37, 38, 39, 40
+ 36, 37, 38, 39, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -813,13 +815,13 @@ static const yytype_uint8 yystos[] =
39, 40, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 3, 32, 53, 37, 32, 3, 33, 33,
29, 26, 28, 33, 32, 33, 33, 33, 33, 53,
- 53, 53, 53, 53, 3, 4, 5, 26, 27, 28,
- 29, 30, 31, 32, 33, 35, 36, 37, 38, 39,
- 40, 54, 53, 53, 53, 53, 33, 33, 33, 53,
- 53, 53, 53, 53, 53, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 27, 30, 28, 53, 3, 3,
- 3, 3, 3, 3, 33, 33, 33, 3, 30, 53,
- 53, 33, 3, 3, 53, 3
+ 53, 53, 53, 53, 3, 4, 5, 6, 26, 27,
+ 28, 29, 30, 31, 32, 33, 35, 36, 37, 38,
+ 39, 40, 54, 53, 53, 53, 53, 33, 33, 33,
+ 53, 53, 53, 53, 53, 53, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 27, 30, 28, 53, 3,
+ 3, 3, 3, 3, 3, 33, 33, 33, 3, 30,
+ 53, 53, 33, 3, 3, 53, 3
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -831,7 +833,7 @@ static const yytype_uint8 yyr1[] =
45, 45, 46, 46, 47, 47, 48, 48, 49, 49,
50, 50, 51, 51, 52, 52, 53, 53, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54
+ 54, 54, 54, 54, 54
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -843,7 +845,7 @@ static const yytype_uint8 yyr2[] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1
+ 1, 1, 1, 1, 1
};
@@ -930,7 +932,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1368,6 +1372,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1430,8 +1436,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1499,7 +1503,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1534,27 +1537,27 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 4:
-#line 104 "cmFortranParser.y" /* yacc.c:1652 */
+ case 4:
+#line 104 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1544 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1547 "cmFortranParser.cxx"
break;
case 5:
-#line 108 "cmFortranParser.y" /* yacc.c:1652 */
+#line 108 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1554 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1557 "cmFortranParser.cxx"
break;
case 6:
-#line 113 "cmFortranParser.y" /* yacc.c:1652 */
+#line 113 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1564,22 +1567,22 @@ yyreduce:
}
free((yyvsp[-2].string));
}
-#line 1568 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1571 "cmFortranParser.cxx"
break;
case 7:
-#line 122 "cmFortranParser.y" /* yacc.c:1652 */
+#line 122 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1579 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1582 "cmFortranParser.cxx"
break;
case 8:
-#line 128 "cmFortranParser.y" /* yacc.c:1652 */
+#line 128 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1587,40 +1590,40 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1591 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1594 "cmFortranParser.cxx"
break;
case 9:
-#line 135 "cmFortranParser.y" /* yacc.c:1652 */
+#line 135 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
-#line 1601 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1604 "cmFortranParser.cxx"
break;
case 10:
-#line 140 "cmFortranParser.y" /* yacc.c:1652 */
+#line 140 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
-#line 1610 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1613 "cmFortranParser.cxx"
break;
case 11:
-#line 144 "cmFortranParser.y" /* yacc.c:1652 */
+#line 144 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1620 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1623 "cmFortranParser.cxx"
break;
case 12:
-#line 149 "cmFortranParser.y" /* yacc.c:1652 */
+#line 149 "cmFortranParser.y"
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1629,139 +1632,140 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1633 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1636 "cmFortranParser.cxx"
break;
case 13:
-#line 157 "cmFortranParser.y" /* yacc.c:1652 */
+#line 157 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1643 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1646 "cmFortranParser.cxx"
break;
case 14:
-#line 162 "cmFortranParser.y" /* yacc.c:1652 */
+#line 162 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1653 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1656 "cmFortranParser.cxx"
break;
case 15:
-#line 167 "cmFortranParser.y" /* yacc.c:1652 */
+#line 167 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1663 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1666 "cmFortranParser.cxx"
break;
case 16:
-#line 172 "cmFortranParser.y" /* yacc.c:1652 */
+#line 172 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1673 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1676 "cmFortranParser.cxx"
break;
case 17:
-#line 177 "cmFortranParser.y" /* yacc.c:1652 */
+#line 177 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1683 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1686 "cmFortranParser.cxx"
break;
case 18:
-#line 182 "cmFortranParser.y" /* yacc.c:1652 */
+#line 182 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1693 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1696 "cmFortranParser.cxx"
break;
case 19:
-#line 187 "cmFortranParser.y" /* yacc.c:1652 */
+#line 187 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1703 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1706 "cmFortranParser.cxx"
break;
case 20:
-#line 192 "cmFortranParser.y" /* yacc.c:1652 */
+#line 192 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1713 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1716 "cmFortranParser.cxx"
break;
case 21:
-#line 197 "cmFortranParser.y" /* yacc.c:1652 */
+#line 197 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1722 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1725 "cmFortranParser.cxx"
break;
case 22:
-#line 201 "cmFortranParser.y" /* yacc.c:1652 */
+#line 201 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1731 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1734 "cmFortranParser.cxx"
break;
case 23:
-#line 205 "cmFortranParser.y" /* yacc.c:1652 */
+#line 205 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1740 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1743 "cmFortranParser.cxx"
break;
case 24:
-#line 209 "cmFortranParser.y" /* yacc.c:1652 */
+#line 209 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1749 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1752 "cmFortranParser.cxx"
break;
case 48:
-#line 231 "cmFortranParser.y" /* yacc.c:1652 */
+#line 231 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1755 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1758 "cmFortranParser.cxx"
break;
case 55:
-#line 238 "cmFortranParser.y" /* yacc.c:1652 */
+#line 238 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1761 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1764 "cmFortranParser.cxx"
break;
-#line 1765 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1768 "cmFortranParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1994,6 +1998,6 @@ yyreturn:
#endif
return yyresult;
}
-#line 249 "cmFortranParser.y" /* yacc.c:1918 */
+#line 250 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index 87f3e0a16e..1b54dd9f7d 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -244,6 +244,7 @@ misc_code:
| RPAREN
| COMMA
| UNTERMINATED_STRING
+| CPP_LINE_DIRECTIVE
;
%%
diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h
index 0da4c1c43e..f66a15cf87 100644
--- a/Source/LexerParser/cmFortranParserTokens.h
+++ b/Source/LexerParser/cmFortranParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
@@ -131,16 +131,15 @@ extern int cmFortran_yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:1921 */
+#line 73 "cmFortranParser.y"
char* string;
-#line 142 "cmFortranParserTokens.h" /* yacc.c:1921 */
-};
+#line 141 "cmFortranParserTokens.h"
+};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
new file mode 100644
index 0000000000..a98969d591
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -0,0 +1,2210 @@
+#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 cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmGccDepfile_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmGccDepfile_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmGccDepfile_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmGccDepfile_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmGccDepfile_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmGccDepfile_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmGccDepfile_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmGccDepfile_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmGccDepfile_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmGccDepfile_yylex_ALREADY_DEFINED
+#else
+#define yylex cmGccDepfile_yylex
+#endif
+
+#ifdef yyrestart
+#define cmGccDepfile_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmGccDepfile_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmGccDepfile_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmGccDepfile_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmGccDepfile_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmGccDepfile_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmGccDepfile_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmGccDepfile_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmGccDepfile_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmGccDepfile_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmGccDepfile_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmGccDepfile_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmGccDepfile_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmGccDepfile_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmGccDepfile_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmGccDepfile_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmGccDepfile_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmGccDepfile_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmGccDepfile_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmGccDepfile_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmGccDepfile_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmGccDepfile_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmGccDepfile_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmGccDepfile_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmGccDepfile_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmGccDepfile_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmGccDepfile_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmGccDepfile_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmGccDepfile_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmGccDepfile_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmGccDepfile_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmGccDepfile_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmGccDepfile_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmGccDepfile_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 cmGccDepfile_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 11
+#define YY_END_OF_BUFFER 12
+/* 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[26] =
+ { 0,
+ 0, 0, 12, 10, 8, 6, 10, 9, 10, 10,
+ 10, 8, 0, 6, 9, 1, 7, 5, 0, 3,
+ 2, 0, 4, 0, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 6, 1, 7, 8, 6, 1, 1, 6,
+ 6, 1, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 9, 1, 1,
+ 6, 1, 1, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 10, 6, 1, 6, 1, 6, 6, 6, 6,
+
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 1, 6, 6, 1, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6
+ } ;
+
+static const YY_CHAR yy_meta[11] =
+ { 0,
+ 1, 2, 1, 1, 2, 1, 1, 1, 1, 3
+ } ;
+
+static const flex_int16_t yy_base[28] =
+ { 0,
+ 0, 0, 29, 35, 18, 35, 22, 18, 15, 0,
+ 8, 12, 16, 35, 11, 35, 0, 35, 13, 35,
+ 35, 16, 35, 22, 35, 31, 12
+ } ;
+
+static const flex_int16_t yy_def[28] =
+ { 0,
+ 25, 1, 25, 25, 26, 25, 25, 25, 25, 27,
+ 25, 26, 25, 25, 25, 25, 27, 25, 25, 25,
+ 25, 25, 25, 25, 0, 25, 25
+ } ;
+
+static const flex_int16_t yy_nxt[46] =
+ { 0,
+ 4, 5, 6, 7, 5, 8, 4, 9, 10, 11,
+ 18, 19, 20, 17, 21, 18, 15, 22, 18, 19,
+ 23, 13, 16, 15, 14, 24, 20, 13, 25, 25,
+ 25, 22, 12, 12, 3, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25
+ } ;
+
+static const flex_int16_t yy_chk[46] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 11, 11, 11, 27, 11, 19, 15, 11, 13, 13,
+ 22, 12, 9, 8, 7, 22, 24, 5, 3, 0,
+ 0, 24, 26, 26, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25
+ } ;
+
+/* 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. */
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include <cmGccDepfileLexerHelper.h>
+#include <string>
+
+#define INITIAL 0
+
+#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 >= 26 )
+ 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] != 35 );
+
+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
+{
+ // Unescape the dollar sign.
+ yyextra->addToCurrentPath("$");
+ }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+{
+ // Unescape the hash.
+ yyextra->addToCurrentPath("#");
+ }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+{
+ // 2N+1 backslashes plus space -> N backslashes plus space.
+ size_t c = (strlen(yytext) - 1) / 2;
+ std::string s(c, '\\');
+ s.push_back(' ');
+ yyextra->addToCurrentPath(s.c_str());
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+ // 2N backslashes plus space -> 2N backslashes, end of filename.
+ yytext[strlen(yytext) - 1] = 0;
+ yyextra->addToCurrentPath(yytext);
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+{
+ // A line continuation ends the current file name.
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+{
+ // A newline ends the current file name and the current rule.
+ yyextra->newEntry();
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+{
+ // A colon followed by space ends the rules and starts a new dependency.
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+{
+ // Rules and dependencies are separated by blocks of whitespace.
+ yyextra->newRuleOrDependency();
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+{
+ // Got a span of plain text.
+ yyextra->addToCurrentPath(yytext);
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+{
+ // Got an otherwise unmatched character.
+ yyextra->addToCurrentPath(yytext);
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ 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 >= 26 )
+ 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 >= 26 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 25);
+
+ (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/cmGccDepfileLexer.h b/Source/LexerParser/cmGccDepfileLexer.h
new file mode 100644
index 0000000000..7d34060a10
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.h
@@ -0,0 +1,687 @@
+#ifndef cmGccDepfile_yyHEADER_H
+#define cmGccDepfile_yyHEADER_H 1
+#define cmGccDepfile_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 cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmGccDepfile_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmGccDepfile_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmGccDepfile_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmGccDepfile_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmGccDepfile_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmGccDepfile_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmGccDepfile_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmGccDepfile_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmGccDepfile_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmGccDepfile_yylex_ALREADY_DEFINED
+#else
+#define yylex cmGccDepfile_yylex
+#endif
+
+#ifdef yyrestart
+#define cmGccDepfile_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmGccDepfile_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmGccDepfile_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmGccDepfile_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmGccDepfile_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmGccDepfile_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmGccDepfile_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmGccDepfile_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmGccDepfile_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmGccDepfile_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmGccDepfile_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmGccDepfile_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmGccDepfile_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmGccDepfile_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmGccDepfile_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmGccDepfile_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmGccDepfile_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmGccDepfile_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmGccDepfile_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmGccDepfile_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmGccDepfile_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmGccDepfile_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmGccDepfile_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmGccDepfile_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmGccDepfile_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmGccDepfile_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmGccDepfile_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmGccDepfile_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmGccDepfile_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmGccDepfile_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmGccDepfile_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmGccDepfile_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmGccDepfile_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmGccDepfile_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 cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+
+#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 cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#undef yy_create_buffer
+#endif
+#ifndef cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#undef yy_delete_buffer
+#endif
+#ifndef cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#undef yy_scan_buffer
+#endif
+#ifndef cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#undef yy_scan_string
+#endif
+#ifndef cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#undef yy_scan_bytes
+#endif
+#ifndef cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#undef yy_init_buffer
+#endif
+#ifndef cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#undef yy_flush_buffer
+#endif
+#ifndef cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#undef yy_load_buffer_state
+#endif
+#ifndef cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#undef yy_switch_to_buffer
+#endif
+#ifndef cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#undef yypush_buffer_state
+#endif
+#ifndef cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#undef yypop_buffer_state
+#endif
+#ifndef cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#undef yyensure_buffer_stack
+#endif
+#ifndef cmGccDepfile_yylex_ALREADY_DEFINED
+#undef yylex
+#endif
+#ifndef cmGccDepfile_yyrestart_ALREADY_DEFINED
+#undef yyrestart
+#endif
+#ifndef cmGccDepfile_yylex_init_ALREADY_DEFINED
+#undef yylex_init
+#endif
+#ifndef cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#undef yylex_init_extra
+#endif
+#ifndef cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#undef yylex_destroy
+#endif
+#ifndef cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#undef yyget_debug
+#endif
+#ifndef cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#undef yyset_debug
+#endif
+#ifndef cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#undef yyget_extra
+#endif
+#ifndef cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#undef yyset_extra
+#endif
+#ifndef cmGccDepfile_yyget_in_ALREADY_DEFINED
+#undef yyget_in
+#endif
+#ifndef cmGccDepfile_yyset_in_ALREADY_DEFINED
+#undef yyset_in
+#endif
+#ifndef cmGccDepfile_yyget_out_ALREADY_DEFINED
+#undef yyget_out
+#endif
+#ifndef cmGccDepfile_yyset_out_ALREADY_DEFINED
+#undef yyset_out
+#endif
+#ifndef cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#undef yyget_leng
+#endif
+#ifndef cmGccDepfile_yyget_text_ALREADY_DEFINED
+#undef yyget_text
+#endif
+#ifndef cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#undef yyget_lineno
+#endif
+#ifndef cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#undef yyset_lineno
+#endif
+#ifndef cmGccDepfile_yyget_column_ALREADY_DEFINED
+#undef yyget_column
+#endif
+#ifndef cmGccDepfile_yyset_column_ALREADY_DEFINED
+#undef yyset_column
+#endif
+#ifndef cmGccDepfile_yywrap_ALREADY_DEFINED
+#undef yywrap
+#endif
+#ifndef cmGccDepfile_yyget_lval_ALREADY_DEFINED
+#undef yyget_lval
+#endif
+#ifndef cmGccDepfile_yyset_lval_ALREADY_DEFINED
+#undef yyset_lval
+#endif
+#ifndef cmGccDepfile_yyget_lloc_ALREADY_DEFINED
+#undef yyget_lloc
+#endif
+#ifndef cmGccDepfile_yyset_lloc_ALREADY_DEFINED
+#undef yyset_lloc
+#endif
+#ifndef cmGccDepfile_yyalloc_ALREADY_DEFINED
+#undef yyalloc
+#endif
+#ifndef cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#undef yyrealloc
+#endif
+#ifndef cmGccDepfile_yyfree_ALREADY_DEFINED
+#undef yyfree
+#endif
+#ifndef cmGccDepfile_yytext_ALREADY_DEFINED
+#undef yytext
+#endif
+#ifndef cmGccDepfile_yyleng_ALREADY_DEFINED
+#undef yyleng
+#endif
+#ifndef cmGccDepfile_yyin_ALREADY_DEFINED
+#undef yyin
+#endif
+#ifndef cmGccDepfile_yyout_ALREADY_DEFINED
+#undef yyout
+#endif
+#ifndef cmGccDepfile_yy_flex_debug_ALREADY_DEFINED
+#undef yy_flex_debug
+#endif
+#ifndef cmGccDepfile_yylineno_ALREADY_DEFINED
+#undef yylineno
+#endif
+#ifndef cmGccDepfile_yytables_fload_ALREADY_DEFINED
+#undef yytables_fload
+#endif
+#ifndef cmGccDepfile_yytables_destroy_ALREADY_DEFINED
+#undef yytables_destroy
+#endif
+#ifndef cmGccDepfile_yyTABLES_NAME_ALREADY_DEFINED
+#undef yyTABLES_NAME
+#endif
+
+#undef cmGccDepfile_yyIN_HEADER
+#endif /* cmGccDepfile_yyHEADER_H */
diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l
new file mode 100644
index 0000000000..08f8577fc2
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.in.l
@@ -0,0 +1,72 @@
+%{
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include <cmGccDepfileLexerHelper.h>
+#include <string>
+%}
+
+%option prefix="cmGccDepfile_yy"
+%option noyywrap
+%option reentrant
+%pointer
+
+WSPACE [ \t]
+NEWLINE \r?\n
+
+%%
+\${2} {
+ // Unescape the dollar sign.
+ yyextra->addToCurrentPath("$");
+ }
+\\# {
+ // Unescape the hash.
+ yyextra->addToCurrentPath("#");
+ }
+(\\\\)*\\[ ] {
+ // 2N+1 backslashes plus space -> N backslashes plus space.
+ size_t c = (strlen(yytext) - 1) / 2;
+ std::string s(c, '\\');
+ s.push_back(' ');
+ yyextra->addToCurrentPath(s.c_str());
+ }
+(\\\\)+[ ] {
+ // 2N backslashes plus space -> 2N backslashes, end of filename.
+ yytext[strlen(yytext) - 1] = 0;
+ yyextra->addToCurrentPath(yytext);
+ yyextra->newDependency();
+ }
+{WSPACE}*\\{NEWLINE} {
+ // A line continuation ends the current file name.
+ yyextra->newDependency();
+ }
+{NEWLINE} {
+ // A newline ends the current file name and the current rule.
+ yyextra->newEntry();
+ }
+:{WSPACE}+ {
+ // A colon followed by space ends the rules and starts a new dependency.
+ yyextra->newDependency();
+ }
+{WSPACE}+ {
+ // Rules and dependencies are separated by blocks of whitespace.
+ yyextra->newRuleOrDependency();
+ }
+[a-zA-Z0-9+,/_.~()}{%=@\x5B\x5D!\x80-\xFF-]+ {
+ // Got a span of plain text.
+ yyextra->addToCurrentPath(yytext);
+ }
+. {
+ // Got an otherwise unmatched character.
+ yyextra->addToCurrentPath(yytext);
+ }
+
+%%
+
+/*--------------------------------------------------------------------------*/
+
+#endif /* __clang_analyzer__ */
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index cb89d19fd9..98dd0e212b 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -178,6 +178,10 @@ if(WIN32)
target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
endif()
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET cmake-gui PROPERTY JOB_POOL_LINK "link-bin")
+endif()
+
# cmake-gui has not been updated for `include-what-you-use`.
# Block the tool until this is done.
set_target_properties(cmake-gui PROPERTIES
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index b608fcbfc6..a9089e52f2 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -6,6 +6,7 @@
#include <QDir>
#include "cmExternalMakefileProjectGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -485,7 +486,7 @@ void QCMake::setWarnUnusedMode(bool value)
void QCMake::checkOpenPossible()
{
- auto data = this->BinaryDirectory.toLocal8Bit().data();
+ std::string data = this->BinaryDirectory.toLocal8Bit().data();
auto possible = this->CMakeInstance->Open(data, true);
emit openPossible(possible);
}
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index b85cc33590..0b2750d854 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -64,32 +64,36 @@
*/
#include "bindexplib.h"
-#include <iostream>
+#include <cstddef>
#include <sstream>
#include <vector>
-#include <windows.h>
+#ifdef _WIN32
+# include <windows.h>
+
+# include "cmsys/Encoding.hxx"
+#endif
-#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
+#ifdef _WIN32
+# ifndef IMAGE_FILE_MACHINE_ARM
+# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_THUMB
-# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_THUMB
+# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_ARMNT
-# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_ARMNT
+# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_ARM64
-# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_ARM64
+# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
+# endif
typedef struct cmANON_OBJECT_HEADER_BIGOBJ
{
@@ -306,6 +310,7 @@ private:
SymbolTableType* SymbolTable;
bool IsI386;
};
+#endif
bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols,
@@ -315,15 +320,15 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
// 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);
+ command.emplace_back("--no-weak");
+ command.emplace_back("--defined-only");
+ command.emplace_back("--format=posix");
+ command.emplace_back(filename);
// run the command
int exit_code = 0;
- cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "",
- cmSystemTools::OUTPUT_NONE);
+ cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code,
+ nullptr, cmSystemTools::OUTPUT_NONE);
if (exit_code != 0) {
fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str());
@@ -336,7 +341,7 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
if (line.empty()) { // last line
continue;
}
- size_t sym_end = line.find(" ");
+ 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());
@@ -366,6 +371,9 @@ bool DumpFile(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols,
std::set<std::string>& dataSymbols)
{
+#ifndef _WIN32
+ return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols);
+#else
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
@@ -446,6 +454,7 @@ bool DumpFile(std::string const& nmPath, const char* filename,
CloseHandle(hFileMapping);
CloseHandle(hFile);
return true;
+#endif
}
bool bindexplib::AddObjectFile(const char* filename)
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 6e04ce5829..231a2d6303 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -174,7 +174,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
doing = doing_comment;
} else if (copy == keyDEPFILE) {
doing = doing_depfile;
- if (mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ if (!mf.GetGlobalGenerator()->SupportsCustomCommandDepfile()) {
status.SetError("Option DEPFILE not supported by " +
mf.GetGlobalGenerator()->GetName());
return false;
@@ -215,7 +215,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
}
if (cmSystemTools::FileIsFullPath(filename)) {
- filename = cmSystemTools::CollapseFullPath(filename);
+ filename = cmSystemTools::CollapseFullPath(
+ filename, status.GetMakefile().GetHomeOutputDirectory());
}
switch (doing) {
case doing_depfile:
@@ -261,9 +262,9 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
case doing_target:
target = copy;
break;
- case doing_depends: {
+ case doing_depends:
depends.push_back(copy);
- } break;
+ break;
case doing_outputs:
outputs.push_back(filename);
break;
@@ -343,7 +344,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
// Target is empty, use the output.
mf.AddCustomCommandToOutput(
output, byproducts, depends, main_dependency, implicit_depends,
- commandLines, comment, working.c_str(), false, escapeOldStyle,
+ commandLines, comment, working.c_str(), nullptr, false, escapeOldStyle,
uses_terminal, command_expand_lists, depfile, job_pool);
} else if (!byproducts.empty()) {
status.SetError("BYPRODUCTS may not be specified with SOURCE signatures");
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index e27b126dd8..aa98d8949a 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -6,7 +6,6 @@
#include "cmCheckCustomOutputs.h"
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -215,9 +214,9 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = mf.AddUtilityCommand(
- targetName, cmCommandOrigin::Project, excludeFromAll,
- working_directory.c_str(), byproducts, depends, commandLines,
- escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool);
+ targetName, excludeFromAll, working_directory.c_str(), byproducts, depends,
+ commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
+ job_pool);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index b1fc89341f..2d55a5a4b9 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -29,7 +29,7 @@ bool cmAddDependenciesCommand(std::vector<std::string> const& args,
// skip over target_name
for (std::string const& arg : cmMakeRange(args).advance(1)) {
- target->AddUtility(arg, &mf);
+ target->AddUtility(arg, false, &mf);
}
} else {
mf.IssueMessage(
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 0439c518c0..f443fc664a 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLibraryCommand.h"
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -309,7 +310,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
return true;
}
- cmAppend(srclists, s, args.end());
+ cm::append(srclists, s, args.end());
mf.AddLibrary(libName, type, srclists, excludeFromAll);
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 6a1a514f76..35eabafcfa 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -53,7 +53,8 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
status.SetError(error);
return false;
}
- srcPath = cmSystemTools::CollapseFullPath(srcPath);
+ srcPath =
+ cmSystemTools::CollapseFullPath(srcPath, mf.GetHomeOutputDirectory());
// Compute the full path to the binary directory.
std::string binPath;
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index 89421131ab..205c1c7a51 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddTestCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -44,7 +46,7 @@ bool cmAddTestCommand(std::vector<std::string> const& args,
} else {
test = mf.CreateTest(args[0]);
test->SetOldStyle(true);
- mf.AddTestGenerator(new cmTestGenerator(test));
+ mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test));
}
test->SetCommand(command);
@@ -141,7 +143,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
}
test->SetCommandExpandLists(command_expand_lists);
- mf.AddTestGenerator(new cmTestGenerator(test, configurations));
+ mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations));
return true;
}
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index e0d27eedf9..c0ac5512a3 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -8,6 +8,7 @@
#include <algorithm>
#include <functional>
#include <iterator>
+#include <memory>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -36,12 +37,6 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
return first;
}
-template <typename Container, typename Predicate>
-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))
@@ -72,40 +67,6 @@ bool cmContains(Range const& range, Key const& key)
namespace ContainerAlgorithms {
-template <typename T>
-struct cmIsPair
-{
- enum
- {
- value = false
- };
-};
-
-template <typename K, typename V>
-struct cmIsPair<std::pair<K, V>>
-{
- enum
- {
- value = true
- };
-};
-
-template <typename Range,
- bool valueTypeIsPair = cmIsPair<typename Range::value_type>::value>
-struct DefaultDeleter
-{
- void operator()(typename Range::value_type value) const { delete value; }
-};
-
-template <typename Range>
-struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
-{
- void operator()(typename Range::value_type value) const
- {
- delete value.second;
- }
-};
-
template <typename FwdIt>
FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
{
@@ -138,25 +99,6 @@ using cmBacktraceRange =
cmRange<std::vector<cmListFileBacktrace>::const_iterator>;
template <typename Range>
-void cmDeleteAll(Range const& r)
-{
- std::for_each(r.begin(), r.end(),
- ContainerAlgorithms::DefaultDeleter<Range>());
-}
-
-template <typename T, typename Range>
-void cmAppend(std::vector<T>& v, Range const& r)
-{
- v.insert(v.end(), r.begin(), r.end());
-}
-
-template <typename T, typename InputIt>
-void cmAppend(std::vector<T>& v, InputIt first, InputIt last)
-{
- v.insert(v.end(), first, last);
-}
-
-template <typename Range>
typename Range::const_iterator cmRemoveN(Range& r, size_t n)
{
return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
@@ -197,7 +139,7 @@ template <typename ForwardIterator>
ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
{
using Value = typename std::iterator_traits<ForwardIterator>::value_type;
- using Hash = struct
+ struct Hash
{
std::size_t operator()(ForwardIterator it) const
{
@@ -205,7 +147,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
}
};
- using Equal = struct
+ struct Equal
{
bool operator()(ForwardIterator it1, ForwardIterator it2) const
{
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index e5eea795dd..d29b2acf62 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -200,8 +200,11 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix,
bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
bool recursive)
{
- if (!this->AddFile(path, skip, prefix)) {
- return false;
+ if (strcmp(path, ".") != 0 ||
+ (this->Format != "zip" && this->Format != "7zip")) {
+ if (!this->AddFile(path, skip, prefix)) {
+ return false;
+ }
}
if ((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
cmSystemTools::FileIsSymlink(path)) {
@@ -210,6 +213,9 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
cmsys::Directory d;
if (d.Load(path)) {
std::string next = cmStrCat(path, '/');
+ if (next == "./" && (this->Format == "zip" || this->Format == "7zip")) {
+ next.clear();
+ }
std::string::size_type end = next.size();
unsigned long n = d.GetNumberOfFiles();
for (unsigned long i = 0; i < n; ++i) {
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 177bca889a..b5c7e9693a 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -221,10 +221,10 @@ void CCONV cmAddUtilityCommand(void* arg, const char* utilityName,
// Pass the call to the makefile instance.
std::vector<std::string> no_byproducts;
- mf->AddUtilityCommand(utilityName, cmCommandOrigin::Project,
- (all ? false : true), nullptr, no_byproducts, depends2,
- commandLines);
+ mf->AddUtilityCommand(utilityName, (all ? false : true), nullptr,
+ no_byproducts, depends2, commandLines);
}
+
void CCONV cmAddCustomCommand(void* arg, const char* source,
const char* command, int numArgs,
const char** args, int numDepends,
diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h
index 6a9514869c..19626f0b87 100644
--- a/Source/cmCPluginAPI.h
+++ b/Source/cmCPluginAPI.h
@@ -36,7 +36,7 @@ typedef struct
of functions are utility functions that are specific to the plugin API
=========================================================================*/
/* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
- information is passed from the InitialPass to FInalPass for commands
+ information is passed from the InitialPass to FinalPass for commands
that need a FinalPass and need information from the InitialPass */
void*(CCONV* GetClientData)(void* info);
/* return the summed size in characters of all the arguments */
@@ -44,7 +44,7 @@ typedef struct
/* free all the memory associated with an argc, argv pair */
void(CCONV* FreeArguments)(int argc, char** argv);
/* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
- information is passed from the InitialPass to FInalPass for commands
+ information is passed from the InitialPass to FinalPass for commands
that need a FinalPass and need information from the InitialPass */
void(CCONV* SetClientData)(void* info, void* cd);
/* when an error occurs, call this function to set the error string */
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 6eae26e4c7..04f75bd506 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -21,6 +21,7 @@
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/Process.h"
+#include "cmsys/RegularExpression.hxx"
#include "cmsys/SystemInformation.hxx"
#include "cm_curl.h"
@@ -32,8 +33,8 @@
#endif
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestConfigureHandler.h"
@@ -83,8 +84,8 @@ struct cmCTest::Private
std::string Name;
};
- int RepeatTests = 1; // default to run each test once
- bool RepeatUntilFail = false;
+ int RepeatCount = 1; // default to run each test once
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
std::string ConfigType;
std::string ScheduleType;
std::chrono::system_clock::time_point StopTime;
@@ -207,6 +208,8 @@ struct cmCTest::Private
bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole();
std::map<std::string, std::string> Definitions;
+
+ cmCTest::NoTests NoTestsMode = cmCTest::NoTests::Legacy;
};
struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag)
@@ -1279,7 +1282,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
processOutput.DecodeText(data, length, strdata);
if (output) {
- cmAppend(tempOutput, data, data + length);
+ cm::append(tempOutput, data, data + length);
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
cmCTestLogWrite(strdata.c_str(), strdata.size()));
@@ -1839,11 +1842,16 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->SetParallelLevel(plevel);
this->Impl->ParallelLevelSetInCli = true;
}
+
if (this->CheckArgument(arg, "--repeat-until-fail")) {
if (i >= args.size() - 1) {
errormsg = "'--repeat-until-fail' requires an argument";
return false;
}
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ errormsg = "At most one '--repeat' option may be used.";
+ return false;
+ }
i++;
long repeat = 1;
if (!cmStrToLong(args[i], &repeat)) {
@@ -1851,9 +1859,42 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"'--repeat-until-fail' given non-integer value '" + args[i] + "'";
return false;
}
- this->Impl->RepeatTests = static_cast<int>(repeat);
+ this->Impl->RepeatCount = static_cast<int>(repeat);
if (repeat > 1) {
- this->Impl->RepeatUntilFail = true;
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ }
+ }
+
+ if (this->CheckArgument(arg, "--repeat")) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--repeat' requires an argument";
+ return false;
+ }
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ errormsg = "At most one '--repeat' option may be used.";
+ return false;
+ }
+ i++;
+ cmsys::RegularExpression repeatRegex(
+ "^(until-fail|until-pass|after-timeout):([0-9]+)$");
+ if (repeatRegex.find(args[i])) {
+ std::string const& count = repeatRegex.match(2);
+ unsigned long n = 1;
+ cmStrToULong(count, &n); // regex guarantees success
+ this->Impl->RepeatCount = static_cast<int>(n);
+ if (this->Impl->RepeatCount > 1) {
+ std::string const& mode = repeatRegex.match(1);
+ if (mode == "until-fail") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ } else if (mode == "until-pass") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilPass;
+ } else if (mode == "after-timeout") {
+ this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout;
+ }
+ }
+ } else {
+ errormsg = "'--repeat' given invalid value '" + args[i] + "'";
+ return false;
}
}
@@ -2020,6 +2061,19 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
this->SetNotesFiles(args[i].c_str());
}
+ const std::string noTestsPrefix = "--no-tests=";
+ if (cmHasPrefix(arg, noTestsPrefix)) {
+ const std::string noTestsMode = arg.substr(noTestsPrefix.length());
+ if (noTestsMode == "error") {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Error;
+ } else if (noTestsMode != "ignore") {
+ errormsg = "'--no-tests=' given unknown value '" + noTestsMode + "'";
+ return false;
+ } else {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
+ }
+ }
+
// options that control what tests are run
if (this->CheckArgument(arg, "-I", "--tests-information") &&
i < args.size() - 1) {
@@ -2204,7 +2258,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
bool SRArgumentSpecified = false;
// copy the command line
- cmAppend(this->Impl->InitialCommandLineArguments, args);
+ cm::append(this->Impl->InitialCommandLineArguments, args);
// process the command line arguments
for (size_t i = 1; i < args.size(); ++i) {
@@ -2847,14 +2901,19 @@ const std::map<std::string, std::string>& cmCTest::GetDefinitions() const
return this->Impl->Definitions;
}
-int cmCTest::GetTestRepeat() const
+int cmCTest::GetRepeatCount() const
+{
+ return this->Impl->RepeatCount;
+}
+
+cmCTest::Repeat cmCTest::GetRepeatMode() const
{
- return this->Impl->RepeatTests;
+ return this->Impl->RepeatMode;
}
-bool cmCTest::GetRepeatUntilFail() const
+cmCTest::NoTests cmCTest::GetNoTestsMode() const
{
- return this->Impl->RepeatUntilFail;
+ return this->Impl->NoTestsMode;
}
void cmCTest::SetBuildID(const std::string& id)
@@ -2964,10 +3023,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
res = cmsysProcess_WaitForData(cp, &data, &length, nullptr);
switch (res) {
case cmsysProcess_Pipe_STDOUT:
- cmAppend(tempOutput, data, data + length);
+ cm::append(tempOutput, data, data + length);
break;
case cmsysProcess_Pipe_STDERR:
- cmAppend(tempError, data, data + length);
+ cm::append(tempError, data, data + length);
break;
default:
done = true;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 82a6f4cbd3..7f8f913a93 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -431,10 +431,24 @@ public:
const std::map<std::string, std::string>& GetDefinitions() const;
/** Return the number of times a test should be run */
- int GetTestRepeat() const;
+ int GetRepeatCount() const;
- /** Return true if test should run until fail */
- bool GetRepeatUntilFail() const;
+ enum class Repeat
+ {
+ Never,
+ UntilFail,
+ UntilPass,
+ AfterTimeout,
+ };
+ Repeat GetRepeatMode() const;
+
+ enum class NoTests
+ {
+ Legacy,
+ Error,
+ Ignore
+ };
+ NoTests GetNoTestsMode() const;
void GenerateSubprojectsOutput(cmXMLWriter& xml);
std::vector<std::string> GetLabelsForSubprojects();
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index d627465c76..dc9aba187f 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -190,7 +190,7 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
if (entryKey.size() > plen && *(end - plen) == '-' &&
strcmp(end - plen + 1, *p) == 0) {
std::string key = entryKey.substr(0, entryKey.size() - plen);
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
if (it.IsAtEnd()) {
// Create an entry and store the property.
CacheEntry& ne = this->Cache[key];
@@ -497,9 +497,15 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
return nullptr;
}
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key)
+cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
+ const std::string& key)
{
- return { *this, key };
+ return { *this, key.c_str() };
+}
+
+cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator()
+{
+ return { *this, nullptr };
}
const std::string* cmCacheManager::GetInitializedCacheValue(
@@ -617,7 +623,7 @@ const char* cmCacheManager::CacheEntry::GetProperty(
const std::string& prop) const
{
if (prop == "TYPE") {
- return cmState::CacheEntryTypeToString(this->Type);
+ return cmState::CacheEntryTypeToString(this->Type).c_str();
}
if (prop == "VALUE") {
return this->Value.c_str();
@@ -638,14 +644,15 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
}
void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
- const char* value,
+ const std::string& value,
bool asString)
{
if (prop == "TYPE") {
- this->Type = cmState::StringToCacheEntryType(value ? value : "STRING");
+ this->Type =
+ cmState::StringToCacheEntryType(!value.empty() ? value : "STRING");
} else if (prop == "VALUE") {
- if (value) {
- if (!this->Value.empty() && *value && !asString) {
+ if (!value.empty()) {
+ if (!this->Value.empty() && !asString) {
this->Value += ";";
}
this->Value += value;
@@ -673,7 +680,7 @@ void cmCacheManager::CacheIterator::SetProperty(const std::string& p,
}
void cmCacheManager::CacheIterator::AppendProperty(const std::string& p,
- const char* v,
+ const std::string& v,
bool asString)
{
if (!this->IsAtEnd()) {
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index faa60c5287..d8be991cd9 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -39,7 +39,7 @@ private:
std::vector<std::string> GetPropertyList() const;
const char* GetProperty(const std::string&) const;
void SetProperty(const std::string& property, const char* value);
- void AppendProperty(const std::string& property, const char* value,
+ void AppendProperty(const std::string& property, const std::string& value,
bool asString = false);
bool Initialized = false;
};
@@ -58,10 +58,10 @@ public:
bool GetPropertyAsBool(const std::string&) const;
bool PropertyExists(const std::string&) const;
void SetProperty(const std::string& property, const char* value);
- void AppendProperty(const std::string& property, const char* value,
+ void AppendProperty(const std::string& property, const std::string& value,
bool asString = false);
void SetProperty(const std::string& property, bool value);
- const char* GetValue() const { return this->GetEntry().Value.c_str(); }
+ const std::string& GetValue() const { return this->GetEntry().Value; }
bool GetValueAsBool() const;
void SetValue(const char*);
cmStateEnums::CacheEntryType GetType() const
@@ -111,7 +111,8 @@ public:
void PrintCache(std::ostream&) const;
//! Get the iterator for an entry with a given key.
- cmCacheManager::CacheIterator GetCacheIterator(const char* key = nullptr);
+ cmCacheManager::CacheIterator GetCacheIterator(const std::string& key);
+ cmCacheManager::CacheIterator GetCacheIterator();
//! Remove an entry from the cache
void RemoveCacheEntry(const std::string& key);
@@ -124,52 +125,52 @@ public:
const char* GetCacheEntryValue(const std::string& key)
{
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
if (it.IsAtEnd()) {
return nullptr;
}
- return it.GetValue();
+ return it.GetValue().c_str();
}
const char* GetCacheEntryProperty(std::string const& key,
std::string const& propName)
{
- return this->GetCacheIterator(key.c_str()).GetProperty(propName);
+ return this->GetCacheIterator(key).GetProperty(propName);
}
cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key)
{
- return this->GetCacheIterator(key.c_str()).GetType();
+ return this->GetCacheIterator(key).GetType();
}
bool GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propName)
{
- return this->GetCacheIterator(key.c_str()).GetPropertyAsBool(propName);
+ return this->GetCacheIterator(key).GetPropertyAsBool(propName);
}
void SetCacheEntryProperty(std::string const& key,
std::string const& propName,
std::string const& value)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, value.c_str());
+ this->GetCacheIterator(key).SetProperty(propName, value.c_str());
}
void SetCacheEntryBoolProperty(std::string const& key,
std::string const& propName, bool value)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, value);
+ this->GetCacheIterator(key).SetProperty(propName, value);
}
void SetCacheEntryValue(std::string const& key, std::string const& value)
{
- this->GetCacheIterator(key.c_str()).SetValue(value.c_str());
+ this->GetCacheIterator(key).SetValue(value.c_str());
}
void RemoveCacheEntryProperty(std::string const& key,
std::string const& propName)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, nullptr);
+ this->GetCacheIterator(key).SetProperty(propName, nullptr);
}
void AppendCacheEntryProperty(std::string const& key,
@@ -177,8 +178,7 @@ public:
std::string const& value,
bool asString = false)
{
- this->GetCacheIterator(key.c_str())
- .AppendProperty(propName, value.c_str(), asString);
+ this->GetCacheIterator(key).AppendProperty(propName, value, asString);
}
std::vector<std::string> GetCacheEntryKeys()
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6f19697bc0..896b6a98de 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -198,6 +198,7 @@ void GetScriptingCommands(cmState* state)
#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("cmake_host_system_information",
cmCMakeHostSystemInformationCommand);
+ state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
state->AddBuiltinCommand("remove", cmRemoveCommand);
state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
state->AddBuiltinCommand("write_file", cmWriteFileCommand);
@@ -279,7 +280,6 @@ void GetProjectCommands(cmState* state)
state->AddBuiltinCommand("link_libraries", cmLinkLibrariesCommand);
state->AddBuiltinCommand("target_link_directories",
cmTargetLinkDirectoriesCommand);
- state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand);
state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand);
state->AddBuiltinCommand("remove_definitions", cmRemoveDefinitionsCommand);
@@ -339,7 +339,6 @@ void GetProjectCommandsInScriptMode(cmState* state)
CM_UNEXPECTED_PROJECT_COMMAND("install");
CM_UNEXPECTED_PROJECT_COMMAND("link_directories");
CM_UNEXPECTED_PROJECT_COMMAND("link_libraries");
- CM_UNEXPECTED_PROJECT_COMMAND("load_cache");
CM_UNEXPECTED_PROJECT_COMMAND("project");
CM_UNEXPECTED_PROJECT_COMMAND("qt_wrap_cpp");
CM_UNEXPECTED_PROJECT_COMMAND("qt_wrap_ui");
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 19a096bdf7..033cb6039f 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
+#include "cmTarget.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
: GeneratorTarget(gt)
@@ -25,27 +26,29 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
, GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
gt->LocalGenerator->GetGlobalGenerator()))
- , ConfigName(LocalCommonGenerator->GetConfigName())
+ , ConfigNames(LocalCommonGenerator->GetConfigNames())
{
}
cmCommonTargetGenerator::~cmCommonTargetGenerator() = default;
-std::string const& cmCommonTargetGenerator::GetConfigName() const
+std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
{
- return this->ConfigName;
+ return this->ConfigNames;
}
-const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
+ const std::string& config)
{
- return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+ return this->GeneratorTarget->GetFeature(feature, config);
}
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
- cmLinkLineComputer* linkLineComputer, std::string& flags)
+ cmLinkLineComputer* linkLineComputer, std::string& flags,
+ const std::string& config)
{
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ this->GeneratorTarget->GetModuleDefinitionInfo(config);
if (!mdi || mdi->DefFile.empty()) {
return;
}
@@ -94,57 +97,60 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
}
-std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
+std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
+ const std::string& config)
{
- auto i = this->FlagsByLanguage.find(l);
- if (i == this->FlagsByLanguage.end()) {
+ auto i = this->Configs[config].FlagsByLanguage.find(l);
+ if (i == this->Configs[config].FlagsByLanguage.end()) {
std::string flags;
- this->LocalCommonGenerator->GetTargetCompileFlags(
- this->GeneratorTarget, this->ConfigName, l, flags);
+ this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
+ config, l, flags);
ByLanguageMap::value_type entry(l, flags);
- i = this->FlagsByLanguage.insert(entry).first;
+ i = this->Configs[config].FlagsByLanguage.insert(entry).first;
}
return i->second;
}
-std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
+std::string cmCommonTargetGenerator::GetDefines(const std::string& l,
+ const std::string& config)
{
- auto i = this->DefinesByLanguage.find(l);
- if (i == this->DefinesByLanguage.end()) {
+ auto i = this->Configs[config].DefinesByLanguage.find(l);
+ if (i == this->Configs[config].DefinesByLanguage.end()) {
std::set<std::string> defines;
- this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget,
- this->ConfigName, l, defines);
+ this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, config,
+ l, defines);
std::string definesString;
this->LocalCommonGenerator->JoinDefines(defines, definesString, l);
ByLanguageMap::value_type entry(l, definesString);
- i = this->DefinesByLanguage.insert(entry).first;
+ i = this->Configs[config].DefinesByLanguage.insert(entry).first;
}
return i->second;
}
-std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
+ const std::string& config)
{
- auto i = this->IncludesByLanguage.find(l);
- if (i == this->IncludesByLanguage.end()) {
+ auto i = this->Configs[config].IncludesByLanguage.find(l);
+ if (i == this->Configs[config].IncludesByLanguage.end()) {
std::string includes;
- this->AddIncludeFlags(includes, l);
+ this->AddIncludeFlags(includes, l, config);
ByLanguageMap::value_type entry(l, includes);
- i = this->IncludesByLanguage.insert(entry).first;
+ i = this->Configs[config].IncludesByLanguage.insert(entry).first;
}
return i->second;
}
-std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
- const
+std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
+ const std::string& config) const
{
std::vector<std::string> dirs;
std::set<cmGeneratorTarget const*> emitted;
if (cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->ConfigName)) {
+ this->GeneratorTarget->GetLinkInformation(config)) {
cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
for (auto const& item : items) {
cmGeneratorTarget const* linkee = item.Target;
@@ -165,19 +171,24 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
return dirs;
}
-std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
+std::string cmCommonTargetGenerator::ComputeTargetCompilePDB(
+ const std::string& config) const
{
std::string compilePdbPath;
if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
return compilePdbPath;
}
- compilePdbPath =
- this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
+ compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(config);
if (compilePdbPath.empty()) {
// Match VS default: `$(IntDir)vc$(PlatformToolsetVersion).pdb`.
// A trailing slash tells the toolchain to add its default file name.
- compilePdbPath = this->GeneratorTarget->GetSupportDirectory() + "/";
+ compilePdbPath = this->GeneratorTarget->GetSupportDirectory();
+ if (this->GlobalCommonGenerator->IsMultiConfig()) {
+ compilePdbPath += "/";
+ compilePdbPath += config;
+ }
+ compilePdbPath += "/";
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
// Match VS default for static libs: `$(IntDir)$(ProjectName).pdb`.
compilePdbPath += this->GeneratorTarget->GetName();
@@ -188,10 +199,10 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
return compilePdbPath;
}
-std::string cmCommonTargetGenerator::GetManifests()
+std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
{
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
std::vector<std::string> manifests;
manifests.reserve(manifest_srcs.size());
@@ -206,6 +217,20 @@ std::string cmCommonTargetGenerator::GetManifests()
return cmJoin(manifests, " ");
}
+std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
+{
+ std::string aixExports;
+ if (this->GeneratorTarget->Target->IsAIX()) {
+ if (const char* exportAll =
+ this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
+ if (cmIsOff(exportAll)) {
+ aixExports = "-n";
+ }
+ }
+ }
+ return aixExports;
+}
+
void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
const std::string& lang,
const char* name, bool so)
@@ -223,7 +248,10 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
int major;
int minor;
int patch;
- this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
+ std::string prop = cmStrCat("MACHO_", name, "_VERSION");
+ std::string fallback_prop = so ? "SOVERSION" : "VERSION";
+ this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major,
+ minor, patch);
if (major > 0 || minor > 0 || patch > 0) {
// Append the flag since a non-zero version is specified.
std::ostringstream vflag;
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 17792d6ac3..b40a2edad4 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -25,42 +25,51 @@ public:
cmCommonTargetGenerator(cmGeneratorTarget* gt);
virtual ~cmCommonTargetGenerator();
- std::string const& GetConfigName() const;
+ std::vector<std::string> const& GetConfigNames() const;
protected:
// Feature query methods.
- const char* GetFeature(const std::string& feature);
+ const char* GetFeature(const std::string& feature,
+ const std::string& config);
// Helper to add flag for windows .def file.
void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
- std::string& flags);
+ std::string& flags, const std::string& config);
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator;
- std::string ConfigName;
+ std::vector<std::string> ConfigNames;
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
- virtual void AddIncludeFlags(std::string& flags,
- std::string const& lang) = 0;
+ virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
+ const std::string& config) = 0;
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
- using ByLanguageMap = std::map<std::string, std::string>;
- std::string GetFlags(const std::string& l);
- ByLanguageMap FlagsByLanguage;
- std::string GetDefines(const std::string& l);
- ByLanguageMap DefinesByLanguage;
- std::string GetIncludes(std::string const& l);
- ByLanguageMap IncludesByLanguage;
- std::string GetManifests();
+ std::string GetFlags(const std::string& l, const std::string& config);
+ std::string GetDefines(const std::string& l, const std::string& config);
+ std::string GetIncludes(std::string const& l, const std::string& config);
+ std::string GetManifests(const std::string& config);
+ std::string GetAIXExports(std::string const& config);
+
+ std::vector<std::string> GetLinkedTargetDirectories(
+ const std::string& config) const;
+ std::string ComputeTargetCompilePDB(const std::string& config) const;
- std::vector<std::string> GetLinkedTargetDirectories() const;
- std::string ComputeTargetCompilePDB() const;
+private:
+ using ByLanguageMap = std::map<std::string, std::string>;
+ struct ByConfig
+ {
+ ByLanguageMap FlagsByLanguage;
+ ByLanguageMap DefinesByLanguage;
+ ByLanguageMap IncludesByLanguage;
+ };
+ std::map<std::string, ByConfig> Configs;
};
#endif
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index af257ee03f..81cd8785bf 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -123,7 +123,7 @@ void cmComputeComponentGraph::TransferEdges()
// We do not attempt to combine duplicate edges, but instead
// store the inter-component edges with suitable multiplicity.
this->ComponentGraph[i_component].emplace_back(
- j_component, ni.IsStrong(), ni.GetBacktrace());
+ j_component, ni.IsStrong(), ni.IsCross(), ni.GetBacktrace());
}
}
}
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index ccef9c85fa..e9bf5a5cd0 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -412,7 +412,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// This shared library dependency must follow the item that listed
// it.
this->EntryConstraintGraph[dep.DependerIndex].emplace_back(
- index, true, cmListFileBacktrace());
+ index, true, false, cmListFileBacktrace());
// Target items may have their own dependencies.
if (entry.Target) {
@@ -514,7 +514,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
// The dependee must come after the depender.
if (depender_index >= 0) {
this->EntryConstraintGraph[depender_index].emplace_back(
- dependee_index, false, cmListFileBacktrace());
+ dependee_index, false, false, cmListFileBacktrace());
} else {
// This is a direct dependency of the target being linked.
this->OriginalEntries.push_back(dependee_index);
@@ -587,7 +587,7 @@ void cmComputeLinkDepends::InferDependencies()
cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index];
edges.reserve(edges.size() + common.size());
for (auto const& c : common) {
- edges.emplace_back(c, true, cmListFileBacktrace());
+ edges.emplace_back(c, true, false, cmListFileBacktrace());
}
}
}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 43bfd1db59..e806dff99e 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -7,12 +7,11 @@
#include <map>
#include <memory>
+#include <queue>
#include <set>
#include <string>
#include <vector>
-#include <queue>
-
#include "cmGraphAdjacencyList.h"
#include "cmLinkItem.h"
#include "cmListFileCache.h"
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index f3dd840cb0..11570d6448 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -8,8 +8,11 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -256,11 +259,10 @@ cmComputeLinkInformation::cmComputeLinkInformation(
"FIND_LIBRARY_USE_OPENBSD_VERSIONING");
// Allocate internals.
- this->OrderLinkerSearchPath = new cmOrderDirectories(
+ this->OrderLinkerSearchPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "linker search path");
- this->OrderRuntimeSearchPath = new cmOrderDirectories(
+ this->OrderRuntimeSearchPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "runtime search path");
- this->OrderDependentRPath = nullptr;
// Get the language used for linking this target.
this->LinkLanguage = this->Target->GetLinkerLanguage(config);
@@ -358,7 +360,7 @@ cmComputeLinkInformation::cmComputeLinkInformation(
this->SharedDependencyMode = SharedDepModeLibDir;
} else if (!this->RPathLinkFlag.empty()) {
this->SharedDependencyMode = SharedDepModeDir;
- this->OrderDependentRPath = new cmOrderDirectories(
+ this->OrderDependentRPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "dependent library path");
}
@@ -400,12 +402,7 @@ cmComputeLinkInformation::cmComputeLinkInformation(
"CMAKE_POLICY_WARNING_CMP0060");
}
-cmComputeLinkInformation::~cmComputeLinkInformation()
-{
- delete this->OrderLinkerSearchPath;
- delete this->OrderRuntimeSearchPath;
- delete this->OrderDependentRPath;
-}
+cmComputeLinkInformation::~cmComputeLinkInformation() = default;
void cmComputeLinkInformation::AppendValues(
std::string& result, std::vector<BT<std::string>>& values)
@@ -573,6 +570,15 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
cmGeneratorTarget::LinkClosure const* lc =
this->Target->GetLinkClosure(this->Config);
for (std::string const& li : lc->Languages) {
+
+ if (li == "CUDA") {
+ // These need to go before the other implicit link information
+ // as they could require symbols from those other library
+ // Currently restricted to CUDA as it is the only language
+ // we have documented runtime behavior controls for
+ this->AddRuntimeLinkLibrary(li);
+ }
+
// Skip those of the linker language. They are implicit.
if (li != this->LinkLanguage) {
this->AddImplicitLinkInfo(li);
@@ -580,6 +586,39 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
}
}
+void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
+{ // Add the lang runtime library flags. This is activated by the presence
+ // of a default selection whether or not it is overridden by a property.
+ std::string defaultVar =
+ cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT");
+ const char* langRuntimeLibraryDefault =
+ this->Makefile->GetDefinition(defaultVar);
+ if (langRuntimeLibraryDefault && *langRuntimeLibraryDefault) {
+ const char* runtimeLibraryValue =
+ this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
+ if (!runtimeLibraryValue) {
+ runtimeLibraryValue = langRuntimeLibraryDefault;
+ }
+
+ std::string runtimeLibrary =
+ cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+ runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
+ this->Target));
+ if (!runtimeLibrary.empty()) {
+ if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" +
+ runtimeLibrary)) {
+ std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
+ for (std::string const& i : libsVec) {
+ if (!cmContains(this->ImplicitLinkLibs, i)) {
+ this->AddItem(i, nullptr);
+ }
+ }
+ }
+ }
+ }
+}
+
void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
// Add libraries for this language that are not implied by the
@@ -749,10 +788,10 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
if (this->SharedDependencyMode == SharedDepModeLibDir &&
!this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */) {
// Add the item to the linker search path.
- order = this->OrderLinkerSearchPath;
+ order = this->OrderLinkerSearchPath.get();
} else if (this->SharedDependencyMode == SharedDepModeDir) {
// Add the item to the separate dependent library search path.
- order = this->OrderDependentRPath;
+ order = this->OrderDependentRPath.get();
}
if (order) {
if (tgt) {
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index ee74ccda97..e50d369beb 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -29,6 +30,9 @@ class cmComputeLinkInformation
public:
cmComputeLinkInformation(cmGeneratorTarget const* target,
const std::string& config);
+ cmComputeLinkInformation(const cmComputeLinkInformation&) = delete;
+ cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) =
+ delete;
~cmComputeLinkInformation();
bool Compute();
@@ -166,7 +170,7 @@ private:
cmsys::RegularExpression SplitFramework;
// Linker search path computation.
- cmOrderDirectories* OrderLinkerSearchPath;
+ std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
bool FinishLinkerSearchDirectories();
void PrintLinkPolicyDiagnosis(std::ostream&);
@@ -174,6 +178,7 @@ private:
void LoadImplicitLinkInfo();
void AddImplicitLinkInfo();
void AddImplicitLinkInfo(std::string const& lang);
+ void AddRuntimeLinkLibrary(std::string const& lang);
std::set<std::string> ImplicitLinkDirs;
std::set<std::string> ImplicitLinkLibs;
@@ -186,9 +191,9 @@ private:
std::vector<std::string> OldUserFlagItems;
std::set<std::string> CMP0060WarnItems;
// Dependent library path computation.
- cmOrderDirectories* OrderDependentRPath;
+ std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
// Runtime path computation.
- cmOrderDirectories* OrderRuntimeSearchPath;
+ std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;
bool OldLinkDirMode;
bool OpenBSD;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 162bab2987..a98a608e4e 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -4,6 +4,7 @@
#include <cassert>
#include <cstdio>
+#include <memory>
#include <sstream>
#include <utility>
@@ -150,6 +151,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
cmGeneratorTarget const* dep = this->Targets[ni];
auto di = deps.insert(dep).first;
di->SetType(ni.IsStrong());
+ di->SetCross(ni.IsCross());
di->SetBacktrace(ni.GetBacktrace());
}
}
@@ -157,15 +159,12 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
void cmComputeTargetDepends::CollectTargets()
{
// Collect all targets from all generators.
- std::vector<cmLocalGenerator*> const& lgens =
- this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgens) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
- for (cmGeneratorTarget const* ti : targets) {
+ auto const& lgens = this->GlobalGenerator->GetLocalGenerators();
+ for (const auto& lgen : lgens) {
+ for (const auto& ti : lgen->GetGeneratorTargets()) {
int index = static_cast<int>(this->Targets.size());
- this->TargetIndex[ti] = index;
- this->Targets.push_back(ti);
+ this->TargetIndex[ti.get()] = index;
+ this->Targets.push_back(ti.get());
}
}
}
@@ -219,7 +218,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
return;
}
const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(
- objLib);
+ objLib, false);
}
}
}
@@ -227,11 +226,12 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
// A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
for (cmLinkImplItem const& lib : impl->Libraries) {
// Don't emit the same library twice for this target.
if (emitted.insert(lib).second) {
- this->AddTargetDepend(depender_index, lib, true);
+ this->AddTargetDepend(depender_index, lib, true, false);
this->AddInterfaceDepends(depender_index, lib, it, emitted);
}
}
@@ -243,11 +243,12 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
std::set<cmLinkItem> emitted;
// A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
for (cmLinkItem const& litem : tutils) {
// Don't emit the same utility twice for this target.
if (emitted.insert(litem).second) {
- this->AddTargetDepend(depender_index, litem, false);
+ this->AddTargetDepend(depender_index, litem, false, litem.Cross);
}
}
}
@@ -269,7 +270,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
// code in the project that caused this dependency to be added.
cmLinkItem libBT = lib;
libBT.Backtrace = dependee_backtrace;
- this->AddTargetDepend(depender_index, libBT, true);
+ this->AddTargetDepend(depender_index, libBT, true, false);
this->AddInterfaceDepends(depender_index, libBT, config, emitted);
}
}
@@ -292,7 +293,8 @@ void cmComputeTargetDepends::AddInterfaceDepends(
if (dependee) {
// A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
this->AddInterfaceDepends(depender_index, dependee,
dependee_name.Backtrace, config, emitted);
}
@@ -300,7 +302,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
cmLinkItem const& dependee_name,
- bool linking)
+ bool linking, bool cross)
{
// Get the depender.
cmGeneratorTarget const* depender = this->Targets[depender_index];
@@ -345,13 +347,13 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
if (dependee) {
this->AddTargetDepend(depender_index, dependee, dependee_name.Backtrace,
- linking);
+ linking, cross);
}
}
void cmComputeTargetDepends::AddTargetDepend(
int depender_index, cmGeneratorTarget const* dependee,
- cmListFileBacktrace const& dependee_backtrace, bool linking)
+ cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
{
if (dependee->IsImported() ||
dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -361,7 +363,7 @@ void cmComputeTargetDepends::AddTargetDepend(
for (cmLinkItem const& i : utils) {
if (cmGeneratorTarget const* transitive_dependee = i.Target) {
this->AddTargetDepend(depender_index, transitive_dependee, i.Backtrace,
- false);
+ false, i.Cross);
}
}
} else {
@@ -373,7 +375,7 @@ void cmComputeTargetDepends::AddTargetDepend(
// Add this entry to the dependency graph.
this->InitialGraph[depender_index].emplace_back(dependee_index, !linking,
- dependee_backtrace);
+ cross, dependee_backtrace);
}
}
@@ -507,7 +509,8 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap,
for (cmGraphEdge const& edge : el) {
int j = edge;
if (cmap[j] == c && edge.IsStrong()) {
- this->FinalGraph[i].emplace_back(j, true, edge.GetBacktrace());
+ this->FinalGraph[i].emplace_back(j, true, edge.IsCross(),
+ edge.GetBacktrace());
if (!this->IntraComponent(cmap, c, j, head, emitted, visited)) {
return false;
}
@@ -516,7 +519,8 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap,
// Prepend to a linear linked-list of intra-component edges.
if (*head >= 0) {
- this->FinalGraph[i].emplace_back(*head, false, cmListFileBacktrace());
+ this->FinalGraph[i].emplace_back(*head, false, false,
+ cmListFileBacktrace());
} else {
this->ComponentTail[c] = i;
}
@@ -566,7 +570,8 @@ bool cmComputeTargetDepends::ComputeFinalDepends(
int dependee_component = ni;
int dependee_component_head = this->ComponentHead[dependee_component];
this->FinalGraph[depender_component_tail].emplace_back(
- dependee_component_head, ni.IsStrong(), ni.GetBacktrace());
+ dependee_component_head, ni.IsStrong(), ni.IsCross(),
+ ni.GetBacktrace());
}
}
return true;
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index d8060aede6..e0d625f9a1 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -46,10 +46,10 @@ private:
void CollectDepends();
void CollectTargetDepends(int depender_index);
void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name,
- bool linking);
+ bool linking, bool cross);
void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
cmListFileBacktrace const& dependee_backtrace,
- bool linking);
+ bool linking, bool cross);
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name,
const std::string& config,
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 003e60d572..fda687fd3b 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -9,6 +9,8 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
@@ -396,7 +398,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
// copy to the list structure
auto argP1 = arg;
argP1++;
- cmAppend(newArgs2, argP1, argClose);
+ cm::append(newArgs2, argP1, argClose);
newArgs2.pop_back();
// now recursively invoke IsTrue to handle the values inside the
// parenthetical expression
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 5711cae493..da04396b16 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -51,6 +51,8 @@ static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
"CMAKE_OSX_DEPLOYMENT_TARGET";
static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
+ "CMAKE_APPLE_ARCH_SYSROOTS";
static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
"CMAKE_POSITION_INDEPENDENT_CODE";
static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
@@ -723,6 +725,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_OSX_ARCHITECTURES);
vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET);
vars.insert(kCMAKE_OSX_SYSROOT);
+ vars.insert(kCMAKE_APPLE_ARCH_SYSROOTS);
vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
vars.insert(kCMAKE_SYSROOT);
vars.insert(kCMAKE_SYSROOT_COMPILE);
@@ -1042,7 +1045,9 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
if (deletedFiles.insert(fileName).second) {
std::string const fullPath =
std::string(binDir).append("/").append(fileName);
- if (cmSystemTools::FileIsDirectory(fullPath)) {
+ if (cmSystemTools::FileIsSymlink(fullPath)) {
+ cmSystemTools::RemoveFile(fullPath);
+ } else if (cmSystemTools::FileIsDirectory(fullPath)) {
this->CleanupFiles(fullPath);
cmSystemTools::RemoveADirectory(fullPath);
} else {
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 09d269b208..0dd8722cf9 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -4,27 +4,23 @@
#include <utility>
-#include "cmAlgorithms.h"
-#include "cmMakefile.h"
+#include <cmext/algorithm>
-cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
- std::vector<std::string> outputs,
+cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs,
std::vector<std::string> byproducts,
std::vector<std::string> depends,
cmCustomCommandLines commandLines,
- const char* comment,
+ cmListFileBacktrace lfbt, const char* comment,
const char* workingDirectory)
: Outputs(std::move(outputs))
, Byproducts(std::move(byproducts))
, Depends(std::move(depends))
, CommandLines(std::move(commandLines))
+ , Backtrace(std::move(lfbt))
, Comment(comment ? comment : "")
, WorkingDirectory(workingDirectory ? workingDirectory : "")
, HaveComment(comment != nullptr)
{
- if (mf) {
- this->Backtrace = mf->GetBacktrace();
- }
}
const std::vector<std::string>& cmCustomCommand::GetOutputs() const
@@ -55,12 +51,12 @@ const char* cmCustomCommand::GetComment() const
void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines)
{
- cmAppend(this->CommandLines, commandLines);
+ cm::append(this->CommandLines, commandLines);
}
void cmCustomCommand::AppendDepends(const std::vector<std::string>& depends)
{
- cmAppend(this->Depends, depends);
+ cm::append(this->Depends, depends);
}
bool cmCustomCommand::GetEscapeOldStyle() const
@@ -100,7 +96,7 @@ void cmCustomCommand::SetImplicitDepends(cmImplicitDependsList const& l)
void cmCustomCommand::AppendImplicitDepends(cmImplicitDependsList const& l)
{
- cmAppend(this->ImplicitDepends, l);
+ cm::append(this->ImplicitDepends, l);
}
bool cmCustomCommand::GetUsesTerminal() const
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 4689aceea0..d300fa569d 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -12,8 +12,6 @@
#include "cmCustomCommandLines.h"
#include "cmListFileCache.h"
-class cmMakefile;
-
class cmImplicitDependsList
: public std::vector<std::pair<std::string, std::string>>
{
@@ -28,11 +26,11 @@ class cmCustomCommand
{
public:
/** Main constructor specifies all information for the command. */
- cmCustomCommand(cmMakefile const* mf, std::vector<std::string> outputs,
+ cmCustomCommand(std::vector<std::string> outputs,
std::vector<std::string> byproducts,
std::vector<std::string> depends,
- cmCustomCommandLines commandLines, const char* comment,
- const char* workingDirectory);
+ cmCustomCommandLines commandLines, cmListFileBacktrace lfbt,
+ const char* comment, const char* workingDirectory);
/** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const;
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index c1f412df88..2432d2bb14 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -6,7 +6,8 @@
#include <memory>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorExpression.h"
@@ -29,10 +30,11 @@ void AppendPaths(const std::vector<std::string>& inputs,
for (std::string& it : result) {
cmSystemTools::ConvertToUnixSlashes(it);
if (cmSystemTools::FileIsFullPath(it)) {
- it = cmSystemTools::CollapseFullPath(it);
+ it = cmSystemTools::CollapseFullPath(
+ it, lg->GetMakefile()->GetHomeOutputDirectory());
}
}
- cmAppend(output, result);
+ cm::append(output, result);
}
}
}
@@ -56,7 +58,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg);
std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
if (this->CC.GetCommandExpandLists()) {
- cmAppend(argv, cmExpandedList(parsed_arg));
+ cm::append(argv, cmExpandedList(parsed_arg));
} else {
argv.push_back(std::move(parsed_arg));
}
@@ -137,7 +139,7 @@ const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
(target->IsImported() ||
target->GetProperty("CROSSCOMPILING_EMULATOR") ||
!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
- return target->GetLocation(this->Config);
+ return target->GetLocation(this->Config).c_str();
}
return nullptr;
}
@@ -201,7 +203,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->OldStyle) {
cmd += escapeForShellOldStyle(emulator[j]);
} else {
- cmd += this->LG->EscapeForShell(emulator[j], this->MakeVars);
+ cmd +=
+ this->LG->EscapeForShell(emulator[j], this->MakeVars, false, false,
+ this->MakeVars && this->LG->IsNinjaMulti());
}
}
@@ -222,7 +226,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->OldStyle) {
cmd += escapeForShellOldStyle(arg);
} else {
- cmd += this->LG->EscapeForShell(arg, this->MakeVars);
+ cmd +=
+ this->LG->EscapeForShell(arg, this->MakeVars, false, false,
+ this->MakeVars && this->LG->IsNinjaMulti());
}
}
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 3bb6e36a37..868c94ae94 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -7,12 +7,11 @@
#include <iosfwd>
#include <map>
+#include <queue>
#include <set>
#include <string>
#include <vector>
-#include <queue>
-
#include "cmsys/RegularExpression.hxx"
#include "cmDepends.h"
diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h
index 15cada6de3..641263de78 100644
--- a/Source/cmDocumentationSection.h
+++ b/Source/cmDocumentationSection.h
@@ -8,7 +8,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmDocumentationEntry.h"
// Low-level interface for custom documents:
@@ -47,7 +48,7 @@ public:
}
void Append(const std::vector<cmDocumentationEntry>& entries)
{
- cmAppend(this->Entries, entries);
+ cm::append(this->Entries, entries);
}
/** Append an entry to this section using NULL terminated chars */
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 5976b2f78b..202b205042 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -10,13 +10,12 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#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>
@@ -578,7 +577,7 @@ std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries(
}
char* pdyn = reinterpret_cast<char*>(&dyn);
- cmAppend(result, pdyn, pdyn + sizeof(ELF_Dyn));
+ cm::append(result, pdyn, pdyn + sizeof(ELF_Dyn));
}
return result;
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 80e4bcd636..5be5bcecfa 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -9,11 +9,12 @@
#include <memory>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/Process.h"
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -402,6 +403,6 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
--length;
}
#endif
- cmAppend(output, data, data + length);
+ cm::append(output, data, data + length);
}
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 7e9a98738d..d22bd48621 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -8,6 +8,7 @@
#include <sstream>
#include <utility>
+#include "cmAlgorithms.h"
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -300,11 +301,10 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
std::vector<std::string> exportFiles;
std::string ns;
- std::map<std::string, cmExportBuildFileGenerator*>& exportSets =
- gg->GetBuildExportSets();
+ auto& exportSets = gg->GetBuildExportSets();
for (auto const& exp : exportSets) {
- const cmExportBuildFileGenerator* exportSet = exp.second;
+ const auto& exportSet = exp.second;
std::vector<std::string> targets;
exportSet->GetTargets(targets);
if (cmContains(targets, name)) {
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 11fbd02d68..66e8cbb424 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -10,7 +10,8 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExportFileGenerator.h"
#include "cmStateTypes.h"
@@ -41,7 +42,7 @@ public:
void GetTargets(std::vector<std::string>& targets) const;
void AppendTargets(std::vector<std::string> const& targets)
{
- cmAppend(this->Targets, targets);
+ cm::append(this->Targets, targets);
}
void SetExportSet(cmExportSet*);
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 2a6bf5df7d..e49c17434a 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -6,6 +6,8 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#include "cmsys/RegularExpression.hxx"
#include "cm_static_string_view.hxx"
@@ -182,11 +184,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
// Setup export file generation.
- cmExportBuildFileGenerator* ebfg = nullptr;
+ std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
if (android) {
- ebfg = new cmExportBuildAndroidMKGenerator;
+ ebfg = cm::make_unique<cmExportBuildAndroidMKGenerator>();
} else {
- ebfg = new cmExportBuildFileGenerator;
+ ebfg = cm::make_unique<cmExportBuildFileGenerator>();
}
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(arguments.Namespace);
@@ -196,7 +198,6 @@ bool cmExportCommand(std::vector<std::string> const& args,
} else {
ebfg->SetTargets(targets);
}
- mf.AddExportBuildFileGenerator(ebfg);
ebfg->SetExportOld(arguments.ExportOld);
// Compute the set of configurations exported.
@@ -209,10 +210,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
ebfg->AddConfiguration(ct);
}
if (exportSet != nullptr) {
- gg->AddBuildExportExportSet(ebfg);
+ gg->AddBuildExportExportSet(ebfg.get());
} else {
- gg->AddBuildExportSet(ebfg);
+ gg->AddBuildExportSet(ebfg.get());
}
+ mf.AddExportBuildFileGenerator(std::move(ebfg));
return true;
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index aeef602bf6..6441e6f295 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -60,9 +61,9 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile)
cmSystemTools::GetFilenameLastExtension(this->MainImportFile);
}
-const char* cmExportFileGenerator::GetMainExportFileName() const
+const std::string& cmExportFileGenerator::GetMainExportFileName() const
{
- return this->MainImportFile.c_str();
+ return this->MainImportFile;
}
bool cmExportFileGenerator::GenerateImportFile()
@@ -640,6 +641,9 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string sep;
input.clear();
for (std::string& li : parts) {
+ if (cmHasLiteralPrefix(li, CMAKE_DIRECTORY_ID_SEP)) {
+ continue;
+ }
if (cmGeneratorExpression::Find(li) == std::string::npos) {
this->AddTargetNamespace(li, target, missingTargets);
} else {
@@ -1062,6 +1066,12 @@ void cmExportFileGenerator::GenerateImportTargetCode(
if (target->IsCFBundleOnApple()) {
os << "set_property(TARGET " << targetName << " PROPERTY BUNDLE 1)\n";
}
+
+ // generate DEPRECATION
+ if (target->IsDeprecated()) {
+ os << "set_property(TARGET " << targetName << " PROPERTY DEPRECATION "
+ << cmExportFileGeneratorEscape(target->GetDeprecation()) << ")\n";
+ }
os << "\n";
}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 0d69779f9a..e9d0da7397 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -46,7 +46,7 @@ public:
/** Set the full path to the export file to generate. */
void SetExportFile(const char* mainFile);
- const char* GetMainExportFileName() const;
+ const std::string& GetMainExportFileName() const;
/** Set the namespace in which to place exported target names. */
void SetNamespace(const std::string& ns) { this->Namespace = ns; }
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 2d732c1db9..9702e0e7c0 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -49,7 +49,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
if (te->ArchiveGenerator) {
dest = te->ArchiveGenerator->GetDestination("");
}
- te->Target->Target->SetProperty("__dest", dest.c_str());
+ te->Target->Target->SetProperty("__dest", dest);
}
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 6d29c9994f..987ec9ea7b 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -258,15 +258,7 @@ void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
{
- std::string::size_type pos = 0;
- std::string::size_type lastPos = pos;
-
- while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
- std::string::npos) {
- std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
- input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
- lastPos = endPos;
- }
+ cmGeneratorExpression::ReplaceInstallPrefix(input, "${_IMPORT_PREFIX}");
}
bool cmExportInstallFileGenerator::GenerateImportFileConfig(
@@ -525,13 +517,14 @@ void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
}
std::string cmExportInstallFileGenerator::InstallNameDir(
- cmGeneratorTarget* target, const std::string& /*config*/)
+ cmGeneratorTarget* target, const std::string& config)
{
std::string install_name_dir;
cmMakefile* mf = target->Target->GetMakefile();
if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
- install_name_dir = target->GetInstallNameDirForInstallTree();
+ install_name_dir =
+ target->GetInstallNameDirForInstallTree(config, "${_IMPORT_PREFIX}");
}
return install_name_dir;
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 89093e95fa..6011ba4b0f 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -12,6 +12,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -20,6 +21,8 @@
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"
+class cmListFileBacktrace;
+
static void FinalAction(cmMakefile& makefile, std::string const& filename,
bool append)
{
@@ -46,11 +49,11 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename,
// the project.
cmake* cm = makefile.GetCMakeInstance();
cmGlobalGenerator* global = cm->GetGlobalGenerator();
- const std::vector<cmMakefile*>& locals = global->GetMakefiles();
+ const auto& locals = global->GetMakefiles();
std::map<std::string, std::string> libDepsOld;
std::map<std::string, std::string> libDepsNew;
std::map<std::string, std::string> libTypes;
- for (cmMakefile* local : locals) {
+ for (const auto& local : locals) {
for (auto const& tgt : local->GetTargets()) {
// Get the current target.
cmTarget const& target = tgt.second;
@@ -150,9 +153,9 @@ bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
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);
+ status.GetMakefile().AddGeneratorAction(
+ [filename, append](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), filename, append);
});
return true;
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index fafa51b7b3..3df6a5c9a2 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -70,7 +70,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
- cmTarget::VisibilityNormal, tgt->Target->GetMakefile());
+ cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
+ true);
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index a472a06914..2b8d505a34 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -78,7 +79,7 @@ public:
std::vector<std::string> GetSupportedGlobalGenerators() const;
std::vector<std::string> Aliases;
- virtual cmExternalMakefileProjectGenerator*
+ virtual std::unique_ptr<cmExternalMakefileProjectGenerator>
CreateExternalMakefileProjectGenerator() const = 0;
void AddSupportedGlobalGenerator(const std::string& base);
@@ -100,10 +101,10 @@ public:
{
}
- cmExternalMakefileProjectGenerator* CreateExternalMakefileProjectGenerator()
- const override
+ std::unique_ptr<cmExternalMakefileProjectGenerator>
+ CreateExternalMakefileProjectGenerator() const override
{
- T* p = new T;
+ std::unique_ptr<cmExternalMakefileProjectGenerator> p(new T);
p->SetName(GetName());
return p;
}
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 5a5d959104..b710467c56 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -3,10 +3,13 @@
#include "cmExtraCodeBlocksGenerator.h"
#include <map>
+#include <memory>
#include <ostream>
#include <set>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -209,7 +212,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Collect all files
std::vector<std::string> listFiles;
for (cmLocalGenerator* lg : it.second) {
- cmAppend(listFiles, lg->GetMakefile()->GetListFiles());
+ cm::append(listFiles, lg->GetMakefile()->GetListFiles());
}
// Convert
@@ -283,8 +286,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
for (cmLocalGenerator* lg : lgs) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -315,7 +318,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
- cmGeneratorTarget* gt = target;
+ cmGeneratorTarget* gt = target.get();
this->AppendTarget(xml, targetName, gt, make, lg, compiler,
makeArgs);
std::string fastTarget = cmStrCat(targetName, "/fast");
@@ -341,8 +344,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
@@ -352,13 +355,12 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::UTILITY: // can have sources since 2.6.3
{
std::vector<cmSourceFile*> sources;
- cmGeneratorTarget* gt = target;
- gt->GetSourceFiles(sources,
- makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ target->GetSourceFiles(
+ sources, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* s : sources) {
// don't add source files from UTILITY target which have the
// GENERATED property set:
- if (gt->GetType() == cmStateEnums::UTILITY &&
+ if (target->GetType() == cmStateEnums::UTILITY &&
s->GetIsGenerated()) {
continue;
}
@@ -391,7 +393,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
}
CbpUnit& cbpUnit = allFiles[fullPath];
- cbpUnit.Targets.push_back(target);
+ cbpUnit.Targets.push_back(target.get());
}
}
default: // intended fallthrough
@@ -558,19 +560,19 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
{
std::vector<std::string> includes;
lg->GetIncludeDirectories(includes, target, "C", buildType);
- cmAppend(allIncludeDirs, includes);
+ cm::append(allIncludeDirs, includes);
}
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
auto end = cmRemoveDuplicates(allIncludeDirs);
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index c7b74570f7..de40c77d53 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -4,6 +4,7 @@
#include <cstring>
#include <map>
+#include <memory>
#include <set>
#include <sstream>
#include <utility>
@@ -116,10 +117,9 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
{
std::vector<std::string> retval;
// for each target in the workspace create a codelite project
- const std::vector<cmLocalGenerator*>& lgs =
- this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lg : lgs) {
- for (cmGeneratorTarget* lt : lg->GetGeneratorTargets()) {
+ const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
+ for (const auto& lg : lgs) {
+ for (const auto& lt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType type = lt->GetType();
std::string const& outputDir = lg->GetCurrentBinaryDirectory();
std::string targetName = lt->GetName();
@@ -142,7 +142,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
xml->Attribute("Active", "No");
xml->EndElement();
- CreateNewProjectFile(lt, filename);
+ CreateNewProjectFile(lt.get(), filename);
break;
default:
break;
@@ -269,9 +269,9 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- projectType = CollectSourceFiles(makefile, target, cFiles, otherFiles);
+ for (const auto& target : lg->GetGeneratorTargets()) {
+ projectType =
+ CollectSourceFiles(makefile, target.get(), cFiles, otherFiles);
}
}
@@ -634,7 +634,10 @@ std::string cmExtraCodeLiteGenerator::GetBuildCommand(
if (generator == "NMake Makefiles" || generator == "Ninja") {
ss << make;
} else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") {
- ss << make << " -f$(ProjectPath)/Makefile -j " << this->CpuCount;
+ ss << make << " -f$(ProjectPath)/Makefile";
+ if (this->CpuCount > 0) {
+ ss << " -j " << this->CpuCount;
+ }
}
if (!targetName.empty()) {
ss << " " << targetName;
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index b286acf0c8..78cabce178 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -6,6 +6,7 @@
#include <cassert>
#include <cstdio>
#include <map>
+#include <memory>
#include <sstream>
#include <utility>
@@ -98,7 +99,7 @@ void cmExtraEclipseCDT4Generator::EnableLanguage(
void cmExtraEclipseCDT4Generator::Generate()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
@@ -175,7 +176,7 @@ void cmExtraEclipseCDT4Generator::Generate()
void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
cmMakefile* mf = lg->GetMakefile();
const std::string filename =
@@ -198,7 +199,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
assert(this->HomeDirectory != this->HomeOutputDirectory);
// set up the project name: <project>-Source@<baseSourcePathName>
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
std::string name = cmExtraEclipseCDT4Generator::GenerateProjectName(
lg->GetProjectName(), "Source",
cmExtraEclipseCDT4Generator::GetPathBasename(this->HomeDirectory));
@@ -231,9 +232,9 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
const char* envVar,
- cmLocalGenerator* lg)
+ cmLocalGenerator& lg)
{
- cmMakefile* mf = lg->GetMakefile();
+ cmMakefile* mf = lg.GetMakefile();
// get the variables from the environment and from the cache and then
// figure out which one to use:
@@ -243,7 +244,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
const std::string* cacheValue =
- lg->GetState()->GetInitializedCacheValue(cacheEntryName);
+ lg.GetState()->GetInitializedCacheValue(cacheEntryName);
// now we have both, decide which one to use
std::string valueToUse;
@@ -256,7 +257,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
valueToUse = envVarValue;
mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
cacheEntryName.c_str(), cmStateEnums::STRING, true);
- mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+ mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
} else if (!envVarSet && cacheValue != nullptr) {
// It is already in the cache, but not in the env, so use it from the cache
valueToUse = *cacheValue;
@@ -272,7 +273,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
cacheEntryName.c_str(), cmStateEnums::STRING,
true);
- mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+ mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
}
}
@@ -283,7 +284,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
void cmExtraEclipseCDT4Generator::CreateProjectFile()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.project";
@@ -350,15 +351,15 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// set vsvars32.bat environment available at CMake time,
// but not necessarily when eclipse is open
if (compilerId == "MSVC") {
- AddEnvVar(environment, "PATH", lg);
- AddEnvVar(environment, "INCLUDE", lg);
- AddEnvVar(environment, "LIB", lg);
- AddEnvVar(environment, "LIBPATH", lg);
+ AddEnvVar(environment, "PATH", *lg);
+ AddEnvVar(environment, "INCLUDE", *lg);
+ AddEnvVar(environment, "LIB", *lg);
+ AddEnvVar(environment, "LIBPATH", *lg);
} else if (compilerId == "Intel") {
// if the env.var is set, use this one and put it in the cache
// if the env.var is not set, but the value is in the cache,
// use it from the cache:
- AddEnvVar(environment, "INTEL_LICENSE_FILE", lg);
+ AddEnvVar(environment, "INTEL_LICENSE_FILE", *lg);
}
AppendDictionary(xml, "org.eclipse.cdt.make.core.environment",
environment.str());
@@ -494,11 +495,11 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
cmExtraEclipseCDT4Generator::AppendLinkedResource(
xml, linkName, "virtual:/virtual", VirtualFolder);
- for (cmLocalGenerator* lg : this->GlobalGenerator->GetLocalGenerators()) {
+ for (const auto& lg : this->GlobalGenerator->GetLocalGenerators()) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
+ const auto& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string linkName2 = cmStrCat(linkName, '/');
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
@@ -519,10 +520,9 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
std::vector<cmSourceGroup> sourceGroups =
makefile->GetSourceGroups();
// get the files from the source lists then add them to the groups
- cmGeneratorTarget* gt = const_cast<cmGeneratorTarget*>(target);
std::vector<cmSourceFile*> files;
- gt->GetSourceFiles(files,
- makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ target->GetSourceFiles(
+ files, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* sf : files) {
// Add the file to the list of sources.
std::string const& source = sf->ResolveFullPath();
@@ -606,7 +606,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
std::set<std::string> emmited;
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.cproject";
@@ -752,7 +752,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// add pre-processor definitions to allow eclipse to gray out sections
emmited.clear();
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
if (const char* cdefs =
lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
@@ -859,16 +859,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// include dirs
emmited.clear();
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = lgen->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::vector<std::string> includeDirs;
std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
- lgen->GetIncludeDirectories(includeDirs, target, "C", config);
+ lgen->GetIncludeDirectories(includeDirs, target.get(), "C", config);
this->AppendIncludeDirectories(xml, includeDirs, emmited);
}
}
@@ -915,16 +914,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = lgen->GetGeneratorTargets();
std::string subdir = lgen->MaybeConvertToRelativePath(
this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());
if (subdir == ".") {
subdir.clear();
}
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -975,8 +973,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
std::string cleanArgs =
cmStrCat("-E chdir \"", lgen->GetCurrentBinaryDirectory(),
"\" \"", cmSystemTools::GetCMakeCommand(), "\" -P \"");
- cmGeneratorTarget* gt = target;
- cleanArgs += lgen->GetTargetDirectory(gt);
+ cleanArgs += lgen->GetTargetDirectory(target.get());
cleanArgs += "/cmake_clean.cmake\"";
cmExtraEclipseCDT4Generator::AppendTarget(
xml, "Clean", cmSystemTools::GetCMakeCommand(), cleanArgs,
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index ff4c59eeb0..a7aa549ddb 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -86,7 +86,7 @@ private:
std::set<std::string>& emittedDirs);
static void AddEnvVar(std::ostream& out, const char* envVar,
- cmLocalGenerator* lg);
+ cmLocalGenerator& lg);
void WriteGroups(std::vector<cmSourceGroup> const& sourceGroups,
std::string& linkName, cmXMLWriter& xml);
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index e8c9dd0020..3a22846cc6 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExtraKateGenerator.h"
#include <cstring>
+#include <memory>
#include <ostream>
#include <set>
#include <vector>
@@ -40,21 +41,21 @@ cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
void cmExtraKateGenerator::Generate()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
this->ProjectName = this->GenerateProjectName(
lg->GetProjectName(), mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
this->GetPathBasename(lg->GetBinaryDirectory()));
this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
- this->CreateKateProjectFile(lg);
- this->CreateDummyKateProjectFile(lg);
+ this->CreateKateProjectFile(*lg);
+ this->CreateDummyKateProjectFile(*lg);
}
void cmExtraKateGenerator::CreateKateProjectFile(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
- std::string filename = cmStrCat(lg->GetBinaryDirectory(), "/.kateproject");
+ std::string filename = cmStrCat(lg.GetBinaryDirectory(), "/.kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -64,21 +65,21 @@ void cmExtraKateGenerator::CreateKateProjectFile(
fout <<
"{\n"
"\t\"name\": \"" << this->ProjectName << "\",\n"
- "\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
+ "\t\"directory\": \"" << lg.GetSourceDirectory() << "\",\n"
"\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
/* clang-format on */
this->WriteTargets(lg, fout);
fout << "}\n";
}
-void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
+void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
cmGeneratedFileStream& fout) const
{
- cmMakefile const* mf = lg->GetMakefile();
+ cmMakefile const* mf = lg.GetMakefile();
const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
const std::string& makeArgs =
mf->GetSafeDefinition("CMAKE_KATE_MAKE_ARGUMENTS");
- std::string const& homeOutputDir = lg->GetBinaryDirectory();
+ std::string const& homeOutputDir = lg.GetBinaryDirectory();
/* clang-format off */
fout <<
@@ -109,14 +110,12 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
- for (cmLocalGenerator* localGen :
- this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- localGen->GetGeneratorTargets();
+ for (const auto& localGen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = localGen->GetGeneratorTargets();
std::string currentDir = localGen->GetCurrentBinaryDirectory();
bool topLevel = (currentDir == localGen->GetBinaryDirectory());
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string const& targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -205,10 +204,10 @@ void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
}
void cmExtraKateGenerator::CreateDummyKateProjectFile(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
std::string filename =
- cmStrCat(lg->GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
+ cmStrCat(lg.GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -219,26 +218,25 @@ void cmExtraKateGenerator::CreateDummyKateProjectFile(
}
std::string cmExtraKateGenerator::GenerateFilesString(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
- std::string s = cmStrCat(lg->GetSourceDirectory(), "/.git");
+ std::string s = cmStrCat(lg.GetSourceDirectory(), "/.git");
if (cmSystemTools::FileExists(s)) {
return "\"git\": 1 ";
}
- s = cmStrCat(lg->GetSourceDirectory(), "/.svn");
+ s = cmStrCat(lg.GetSourceDirectory(), "/.svn");
if (cmSystemTools::FileExists(s)) {
return "\"svn\": 1 ";
}
- s = cmStrCat(lg->GetSourceDirectory(), '/');
+ s = cmStrCat(lg.GetSourceDirectory(), '/');
std::set<std::string> files;
std::string tmp;
- const std::vector<cmLocalGenerator*>& lgs =
- this->GlobalGenerator->GetLocalGenerators();
+ const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgs) {
+ for (const auto& lgen : lgs) {
cmMakefile* makefile = lgen->GetMakefile();
const std::vector<std::string>& listFiles = makefile->GetListFiles();
for (std::string const& listFile : listFiles) {
@@ -248,8 +246,7 @@ std::string cmExtraKateGenerator::GenerateFilesString(
}
}
- const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
- for (cmSourceFile* sf : sources) {
+ for (const auto& sf : makefile->GetSourceFiles()) {
if (sf->GetIsGenerated()) {
continue;
}
diff --git a/Source/cmExtraKateGenerator.h b/Source/cmExtraKateGenerator.h
index be1376aa2f..1fb81b482d 100644
--- a/Source/cmExtraKateGenerator.h
+++ b/Source/cmExtraKateGenerator.h
@@ -25,16 +25,16 @@ public:
void Generate() override;
private:
- void CreateKateProjectFile(const cmLocalGenerator* lg) const;
- void CreateDummyKateProjectFile(const cmLocalGenerator* lg) const;
- void WriteTargets(const cmLocalGenerator* lg,
+ void CreateKateProjectFile(const cmLocalGenerator& lg) const;
+ void CreateDummyKateProjectFile(const cmLocalGenerator& lg) const;
+ void WriteTargets(const cmLocalGenerator& lg,
cmGeneratedFileStream& fout) const;
void AppendTarget(cmGeneratedFileStream& fout, const std::string& target,
const std::string& make, const std::string& makeArgs,
const std::string& path,
const std::string& homeOutputDir) const;
- std::string GenerateFilesString(const cmLocalGenerator* lg) const;
+ std::string GenerateFilesString(const cmLocalGenerator& lg) const;
std::string GetPathBasename(const std::string& path) const;
std::string GenerateProjectName(const std::string& name,
const std::string& type,
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 495324cbf3..413449c783 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExtraSublimeTextGenerator.h"
#include <cstring>
+#include <memory>
#include <set>
#include <sstream>
#include <utility>
@@ -182,8 +183,8 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
// and UTILITY targets
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -216,11 +217,11 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
- this->AppendTarget(fout, targetName, lg, target, make.c_str(),
+ this->AppendTarget(fout, targetName, lg, target.get(), make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
std::string fastTarget = cmStrCat(targetName, "/fast");
- this->AppendTarget(fout, fastTarget, lg, target, make.c_str(),
+ this->AppendTarget(fout, fastTarget, lg, target.get(), make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
} break;
@@ -296,8 +297,7 @@ void cmExtraSublimeTextGenerator::AppendTarget(
fout << "\t{\n\t\t\t\"name\": \"" << lg->GetProjectName() << " - "
<< targetName << "\",\n";
fout << "\t\t\t\"cmd\": ["
- << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
- << "],\n";
+ << this->BuildMakeCommand(make, makefileName, targetName) << "],\n";
fout << "\t\t\t\"working_dir\": \"${project_path}\",\n";
fout << "\t\t\t\"file_regex\": \""
"^(..[^:]*)(?::|\\\\()([0-9]+)(?::|\\\\))(?:([0-9]+):)?\\\\s*(.*)"
@@ -308,7 +308,8 @@ void cmExtraSublimeTextGenerator::AppendTarget(
// Create the command line for building the given target using the selected
// make
std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
- const std::string& make, const char* makefile, const std::string& target)
+ const std::string& make, const std::string& makefile,
+ const std::string& target)
{
std::string command = cmStrCat('"', make, '"');
std::string generator = this->GlobalGenerator->GetName();
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 7e8f2d4ec0..078cfe7c8d 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -44,7 +44,8 @@ private:
/** Returns the build command that needs to be executed to build the
* specified target.
*/
- std::string BuildMakeCommand(const std::string& make, const char* makefile,
+ std::string BuildMakeCommand(const std::string& make,
+ const std::string& makefile,
const std::string& target);
/** Appends the specified target to the generated project file as a Sublime
* Text build system.
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 11844e47d6..d88617a01b 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -6,15 +6,20 @@
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
class cmTarget;
-static void FinalAction(cmMakefile& makefile, std::string const& name)
+static void FinalAction(cmMakefile& makefile, std::string const& name,
+ const cmListFileBacktrace& lfbt)
{
// 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
@@ -26,7 +31,8 @@ static void FinalAction(cmMakefile& makefile, std::string const& name)
". The problem was found while processing the source directory: ",
makefile.GetCurrentSourceDirectory(),
". This FLTK_WRAP_UI call will be ignored.");
- cmSystemTools::Message(msg, "Warning");
+ makefile.GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_ERROR, msg,
+ lfbt);
}
}
@@ -116,7 +122,9 @@ bool cmFLTKWrapUICommand(std::vector<std::string> const& args,
std::string const varName = target + "_FLTK_UI_SRCS";
mf.AddDefinition(varName, sourceListValue);
- mf.AddFinalAction(
- [target](cmMakefile& makefile) { FinalAction(makefile, target); });
+ mf.AddGeneratorAction(
+ [target](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ FinalAction(*lg.GetMakefile(), target, lfbt);
+ });
return true;
}
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index f419997710..44ba96c253 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPICMakeFiles.h"
+#include <memory>
#include <string>
#include <vector>
@@ -67,7 +68,7 @@ Json::Value CMakeFiles::DumpInputs()
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
+ for (const auto& lg : gg->GetLocalGenerators()) {
cmMakefile const* mf = lg->GetMakefile();
for (std::string const& file : mf->GetListFiles()) {
inputs.append(this->DumpInput(file));
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index d7993c7d9f..955195f4fa 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -15,9 +15,10 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cm_jsoncpp_value.h"
-#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileAPI.h"
#include "cmGeneratorExpression.h"
@@ -426,7 +427,7 @@ Json::Value Codemodel::DumpConfigurations()
Json::Value configurations = Json::arrayValue;
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- auto makefiles = gg->GetMakefiles();
+ const auto& makefiles = gg->GetMakefiles();
if (!makefiles.empty()) {
std::vector<std::string> const& configs =
makefiles[0]->GetGeneratorConfigs();
@@ -469,17 +470,17 @@ void CodemodelConfig::ProcessDirectories()
{
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- std::vector<cmLocalGenerator*> const& localGens = gg->GetLocalGenerators();
+ auto const& localGens = gg->GetLocalGenerators();
// Add directories in forward order to process parents before children.
this->Directories.reserve(localGens.size());
- for (cmLocalGenerator* lg : localGens) {
+ for (const auto& lg : localGens) {
auto directoryIndex =
static_cast<Json::ArrayIndex>(this->Directories.size());
this->Directories.emplace_back();
Directory& d = this->Directories[directoryIndex];
d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
- d.LocalGenerator = lg;
+ d.LocalGenerator = lg.get();
this->DirectoryMap[d.Snapshot] = directoryIndex;
d.ProjectIndex = this->AddProject(d.Snapshot);
@@ -492,8 +493,9 @@ void CodemodelConfig::ProcessDirectories()
Directory& d = *di;
// Accumulate the presence of install rules on the way up.
- for (auto gen : d.LocalGenerator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(gen)) {
+ for (const auto& gen :
+ d.LocalGenerator->GetMakefile()->GetInstallGenerators()) {
+ if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(gen.get())) {
d.HasInstallRule = true;
break;
}
@@ -554,8 +556,8 @@ Json::Value CodemodelConfig::DumpTargets()
std::vector<cmGeneratorTarget*> targetList;
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
- cmAppend(targetList, lg->GetGeneratorTargets());
+ for (const auto& lg : gg->GetLocalGenerators()) {
+ cm::append(targetList, lg->GetGeneratorTargets());
}
std::sort(targetList.begin(), targetList.end(),
[](cmGeneratorTarget* l, cmGeneratorTarget* r) {
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d45414f725..79110ab401 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
@@ -783,7 +784,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
}
std::vector<std::string>& foundFiles = g.GetFiles();
- cmAppend(files, foundFiles);
+ cm::append(files, foundFiles);
if (configureDepends) {
std::sort(foundFiles.begin(), foundFiles.end());
@@ -1394,8 +1395,8 @@ size_t cmWriteToMemoryCallback(void* ptr, size_t size, size_t nmemb,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr,
- chPtr + realsize);
+ cm::append(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr,
+ chPtr + realsize);
return realsize;
}
@@ -1408,7 +1409,7 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
case CURLINFO_TEXT:
case CURLINFO_HEADER_IN:
case CURLINFO_HEADER_OUT:
- cmAppend(vec, chPtr, chPtr + size);
+ cm::append(vec, chPtr, chPtr + size);
break;
case CURLINFO_DATA_IN:
case CURLINFO_DATA_OUT:
@@ -1418,7 +1419,7 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
int n = sprintf(buf, "[%" KWIML_INT_PRIu64 " bytes data]\n",
static_cast<KWIML_INT_uint64_t>(size));
if (n > 0) {
- cmAppend(vec, buf, buf + n);
+ cm::append(vec, buf, buf + n);
}
} break;
default:
@@ -1707,7 +1708,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// as we receive downloaded bits from curl...
//
std::string dir = cmSystemTools::GetFilenamePath(file);
- if (!cmSystemTools::FileExists(dir) && !cmSystemTools::MakeDirectory(dir)) {
+ if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
+ !cmSystemTools::MakeDirectory(dir)) {
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.";
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index e90f57140e..6010233cad 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -3,11 +3,23 @@
#include "cmFileLock.h"
#include <cassert>
+#include <utility>
#include "cmFileLockResult.h"
// Common implementation
+cmFileLock::cmFileLock(cmFileLock&& other) noexcept
+{
+ this->File = other.File;
+#if defined(_WIN32)
+ other.File = INVALID_HANDLE_VALUE;
+#else
+ other.File = -1;
+#endif
+ this->Filename = std::move(other.Filename);
+}
+
cmFileLock::~cmFileLock()
{
if (!this->Filename.empty()) {
@@ -17,6 +29,19 @@ cmFileLock::~cmFileLock()
}
}
+cmFileLock& cmFileLock::operator=(cmFileLock&& other) noexcept
+{
+ this->File = other.File;
+#if defined(_WIN32)
+ other.File = INVALID_HANDLE_VALUE;
+#else
+ other.File = -1;
+#endif
+ this->Filename = std::move(other.Filename);
+
+ return *this;
+}
+
cmFileLockResult cmFileLock::Lock(const std::string& filename,
unsigned long timeout)
{
diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h
index 2130d65dbe..5fe068e8f1 100644
--- a/Source/cmFileLock.h
+++ b/Source/cmFileLock.h
@@ -26,7 +26,9 @@ public:
~cmFileLock();
cmFileLock(cmFileLock const&) = delete;
+ cmFileLock(cmFileLock&&) noexcept;
cmFileLock& operator=(cmFileLock const&) = delete;
+ cmFileLock& operator=(cmFileLock&&) noexcept;
/**
* @brief Lock the file.
diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx
index 8db2db2103..e1f6e948a9 100644
--- a/Source/cmFileLockPool.cxx
+++ b/Source/cmFileLockPool.cxx
@@ -3,40 +3,34 @@
#include "cmFileLockPool.h"
#include <cassert>
+#include <utility>
-#include "cmAlgorithms.h"
#include "cmFileLock.h"
#include "cmFileLockResult.h"
cmFileLockPool::cmFileLockPool() = default;
-cmFileLockPool::~cmFileLockPool()
-{
- cmDeleteAll(this->FunctionScopes);
- cmDeleteAll(this->FileScopes);
-}
+cmFileLockPool::~cmFileLockPool() = default;
void cmFileLockPool::PushFunctionScope()
{
- this->FunctionScopes.push_back(new ScopePool());
+ this->FunctionScopes.push_back(ScopePool());
}
void cmFileLockPool::PopFunctionScope()
{
assert(!this->FunctionScopes.empty());
- delete this->FunctionScopes.back();
this->FunctionScopes.pop_back();
}
void cmFileLockPool::PushFileScope()
{
- this->FileScopes.push_back(new ScopePool());
+ this->FileScopes.push_back(ScopePool());
}
void cmFileLockPool::PopFileScope()
{
assert(!this->FileScopes.empty());
- delete this->FileScopes.back();
this->FileScopes.pop_back();
}
@@ -49,7 +43,7 @@ cmFileLockResult cmFileLockPool::LockFunctionScope(const std::string& filename,
if (this->FunctionScopes.empty()) {
return cmFileLockResult::MakeNoFunction();
}
- return this->FunctionScopes.back()->Lock(filename, timeoutSec);
+ return this->FunctionScopes.back().Lock(filename, timeoutSec);
}
cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
@@ -59,7 +53,7 @@ cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
return cmFileLockResult::MakeAlreadyLocked();
}
assert(!this->FileScopes.empty());
- return this->FileScopes.back()->Lock(filename, timeoutSec);
+ return this->FileScopes.back().Lock(filename, timeoutSec);
}
cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
@@ -74,14 +68,14 @@ cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
cmFileLockResult cmFileLockPool::Release(const std::string& filename)
{
for (auto& funcScope : this->FunctionScopes) {
- const cmFileLockResult result = funcScope->Release(filename);
+ const cmFileLockResult result = funcScope.Release(filename);
if (!result.IsOk()) {
return result;
}
}
for (auto& fileScope : this->FileScopes) {
- const cmFileLockResult result = fileScope->Release(filename);
+ const cmFileLockResult result = fileScope.Release(filename);
if (!result.IsOk()) {
return result;
}
@@ -93,14 +87,14 @@ cmFileLockResult cmFileLockPool::Release(const std::string& filename)
bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
{
for (auto const& funcScope : this->FunctionScopes) {
- const bool result = funcScope->IsAlreadyLocked(filename);
+ const bool result = funcScope.IsAlreadyLocked(filename);
if (result) {
return true;
}
}
for (auto const& fileScope : this->FileScopes) {
- const bool result = fileScope->IsAlreadyLocked(filename);
+ const bool result = fileScope.IsAlreadyLocked(filename);
if (result) {
return true;
}
@@ -111,21 +105,29 @@ bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
cmFileLockPool::ScopePool::ScopePool() = default;
-cmFileLockPool::ScopePool::~ScopePool()
+cmFileLockPool::ScopePool::~ScopePool() = default;
+
+cmFileLockPool::ScopePool::ScopePool(ScopePool&&) noexcept = default;
+
+cmFileLockPool::ScopePool& cmFileLockPool::ScopePool::operator=(
+ ScopePool&& other) noexcept
{
- cmDeleteAll(this->Locks);
+ if (this != &other) {
+ this->Locks = std::move(other.Locks);
+ }
+
+ return *this;
}
cmFileLockResult cmFileLockPool::ScopePool::Lock(const std::string& filename,
unsigned long timeoutSec)
{
- cmFileLock* lock = new cmFileLock();
- const cmFileLockResult result = lock->Lock(filename, timeoutSec);
+ cmFileLock lock;
+ const cmFileLockResult result = lock.Lock(filename, timeoutSec);
if (result.IsOk()) {
- this->Locks.push_back(lock);
+ this->Locks.push_back(std::move(lock));
return cmFileLockResult::MakeOk();
}
- delete lock;
return result;
}
@@ -133,8 +135,8 @@ cmFileLockResult cmFileLockPool::ScopePool::Release(
const std::string& filename)
{
for (auto& lock : this->Locks) {
- if (lock->IsLocked(filename)) {
- return lock->Release();
+ if (lock.IsLocked(filename)) {
+ return lock.Release();
}
}
return cmFileLockResult::MakeOk();
@@ -144,7 +146,7 @@ bool cmFileLockPool::ScopePool::IsAlreadyLocked(
const std::string& filename) const
{
for (auto const& lock : this->Locks) {
- if (lock->IsLocked(filename)) {
+ if (lock.IsLocked(filename)) {
return true;
}
}
diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h
index dae68dd011..d45c82cc41 100644
--- a/Source/cmFileLockPool.h
+++ b/Source/cmFileLockPool.h
@@ -8,7 +8,8 @@
#include <string>
#include <vector>
-class cmFileLock;
+#include "cmFileLock.h"
+
class cmFileLockResult;
class cmFileLockPool
@@ -64,7 +65,9 @@ private:
~ScopePool();
ScopePool(ScopePool const&) = delete;
+ ScopePool(ScopePool&&) noexcept;
ScopePool& operator=(ScopePool const&) = delete;
+ ScopePool& operator=(ScopePool&&) noexcept;
cmFileLockResult Lock(const std::string& filename,
unsigned long timeoutSec);
@@ -72,17 +75,12 @@ private:
bool IsAlreadyLocked(const std::string& filename) const;
private:
- using List = std::vector<cmFileLock*>;
- using It = List::iterator;
- using CIt = List::const_iterator;
+ using List = std::vector<cmFileLock>;
List Locks;
};
- using List = std::vector<ScopePool*>;
-
- using It = List::iterator;
- using CIt = List::const_iterator;
+ using List = std::vector<ScopePool>;
List FunctionScopes;
List FileScopes;
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
index ac8a37eee0..8cfdb2ddd8 100644
--- a/Source/cmFileMonitor.cxx
+++ b/Source/cmFileMonitor.cxx
@@ -7,9 +7,9 @@
#include <unordered_map>
#include <utility>
-#include "cmsys/SystemTools.hxx"
+#include <cm/memory>
-#include "cmAlgorithms.h"
+#include "cmsys/SystemTools.hxx"
namespace {
void on_directory_change(uv_fs_event_t* handle, const char* filename,
@@ -37,12 +37,12 @@ public:
class cmVirtualDirectoryWatcher : public cmIBaseWatcher
{
public:
- ~cmVirtualDirectoryWatcher() override { cmDeleteAll(this->Children); }
+ ~cmVirtualDirectoryWatcher() override = default;
cmIBaseWatcher* Find(const std::string& ps)
{
const auto i = this->Children.find(ps);
- return (i == this->Children.end()) ? nullptr : i->second;
+ return (i == this->Children.end()) ? nullptr : i->second.get();
}
void Trigger(const std::string& pathSegment, int events,
@@ -96,11 +96,7 @@ public:
return result;
}
- void Reset()
- {
- cmDeleteAll(this->Children);
- this->Children.clear();
- }
+ void Reset() { this->Children.clear(); }
void AddChildWatcher(const std::string& ps, cmIBaseWatcher* watcher)
{
@@ -108,11 +104,12 @@ public:
assert(this->Children.find(ps) == this->Children.end());
assert(watcher);
- this->Children.emplace(std::make_pair(ps, watcher));
+ this->Children.emplace(ps, std::unique_ptr<cmIBaseWatcher>(watcher));
}
private:
- std::unordered_map<std::string, cmIBaseWatcher*> Children; // owned!
+ std::unordered_map<std::string, std::unique_ptr<cmIBaseWatcher>>
+ Children; // owned!
};
// Root of all the different (on windows!) root directories:
@@ -295,14 +292,11 @@ void on_fs_close(uv_handle_t* handle)
} // namespace
cmFileMonitor::cmFileMonitor(uv_loop_t* l)
- : Root(new cmRootWatcher(l))
+ : Root(cm::make_unique<cmRootWatcher>(l))
{
}
-cmFileMonitor::~cmFileMonitor()
-{
- delete this->Root;
-}
+cmFileMonitor::~cmFileMonitor() = default;
void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
Callback const& cb)
@@ -316,7 +310,7 @@ void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
if (segmentCount < 2) { // Expect at least rootdir and filename
continue;
}
- cmVirtualDirectoryWatcher* currentWatcher = this->Root;
+ cmVirtualDirectoryWatcher* currentWatcher = this->Root.get();
for (size_t i = 0; i < segmentCount; ++i) {
assert(currentWatcher);
@@ -334,11 +328,12 @@ void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment);
if (!nextWatcher) {
if (rootSegment) { // Root part
- assert(currentWatcher == this->Root);
- nextWatcher = new cmRootDirectoryWatcher(this->Root, currentSegment);
+ assert(currentWatcher == this->Root.get());
+ nextWatcher =
+ new cmRootDirectoryWatcher(this->Root.get(), currentSegment);
assert(currentWatcher->Find(currentSegment) == nextWatcher);
} else if (fileSegment) { // File part
- assert(currentWatcher != this->Root);
+ assert(currentWatcher != this->Root.get());
nextWatcher = new cmFileWatcher(
dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
currentSegment, cb);
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
index 7ffc9294ef..b510a2cd24 100644
--- a/Source/cmFileMonitor.h
+++ b/Source/cmFileMonitor.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
+#include <memory>
#include <string>
#include <vector>
@@ -30,5 +31,5 @@ public:
std::vector<std::string> WatchedDirectories() const;
private:
- cmRootWatcher* Root;
+ std::unique_ptr<cmRootWatcher> Root;
};
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 7d741182d2..bec99bb7ee 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -4,10 +4,11 @@
#include <cstddef>
#include <deque>
-#include <iostream>
#include <map>
+#include <utility>
+
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSearchPath.h"
@@ -116,17 +117,19 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
this->NoDefaultPath = true;
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
+ } else {
// Some common arguments were accidentally supported by CMake
// 2.4 and 2.6.0 in the short-hand form of the command, so we
// must support it even though it is not documented.
- } else if (doing == DoingNames) {
- this->Names.push_back(args[j]);
- } else if (doing == DoingPaths) {
- this->UserGuessArgs.push_back(args[j]);
- } else if (doing == DoingHints) {
- this->UserHintsArgs.push_back(args[j]);
- } else if (doing == DoingPathSuffixes) {
- this->AddPathSuffix(args[j]);
+ if (doing == DoingNames) {
+ this->Names.push_back(args[j]);
+ } else if (doing == DoingPaths) {
+ this->UserGuessArgs.push_back(args[j]);
+ } else if (doing == DoingHints) {
+ this->UserHintsArgs.push_back(args[j]);
+ } else if (doing == DoingPathSuffixes) {
+ this->AddPathSuffix(args[j]);
+ }
}
}
@@ -153,7 +156,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
std::vector<std::string> shortArgs = this->Names;
this->Names.clear(); // clear out any values in Names
this->Names.push_back(shortArgs[0]);
- cmAppend(this->UserGuessArgs, shortArgs.begin() + 1, shortArgs.end());
+ cm::append(this->UserGuessArgs, shortArgs.begin() + 1, shortArgs.end());
}
this->ExpandPaths();
@@ -288,33 +291,6 @@ void cmFindBase::FillUserGuessPath()
paths.AddSuffixes(this->SearchPathSuffixes);
}
-void cmFindBase::PrintFindStuff()
-{
- std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n";
- std::cerr << "SearchFrameworkOnly: " << this->SearchFrameworkOnly << "\n";
- std::cerr << "SearchFrameworkFirst: " << this->SearchFrameworkFirst << "\n";
- std::cerr << "SearchAppBundleLast: " << this->SearchAppBundleLast << "\n";
- std::cerr << "SearchAppBundleOnly: " << this->SearchAppBundleOnly << "\n";
- std::cerr << "SearchAppBundleFirst: " << this->SearchAppBundleFirst << "\n";
- std::cerr << "VariableName " << this->VariableName << "\n";
- std::cerr << "VariableDocumentation " << this->VariableDocumentation << "\n";
- std::cerr << "NoDefaultPath " << this->NoDefaultPath << "\n";
- std::cerr << "NoCMakeEnvironmentPath " << this->NoCMakeEnvironmentPath
- << "\n";
- std::cerr << "NoCMakePath " << this->NoCMakePath << "\n";
- std::cerr << "NoSystemEnvironmentPath " << this->NoSystemEnvironmentPath
- << "\n";
- std::cerr << "NoCMakeSystemPath " << this->NoCMakeSystemPath << "\n";
- std::cerr << "EnvironmentPath " << this->EnvironmentPath << "\n";
- std::cerr << "CMakePathName " << this->CMakePathName << "\n";
- std::cerr << "Names " << cmJoin(this->Names, " ") << "\n";
- std::cerr << "\n";
- std::cerr << "SearchPathSuffixes ";
- std::cerr << cmJoin(this->SearchPathSuffixes, "\n") << "\n";
- std::cerr << "SearchPaths\n";
- std::cerr << cmWrap("[", this->SearchPaths, "]", "\n") << "\n";
-}
-
bool cmFindBase::CheckForVariableInCache()
{
if (const char* cacheValue =
@@ -343,3 +319,87 @@ bool cmFindBase::CheckForVariableInCache()
}
return false;
}
+
+cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
+ cmFindBase const* findBase)
+ : FindCommand(findBase)
+ , CommandName(std::move(commandName))
+{
+}
+
+cmFindBaseDebugState::~cmFindBaseDebugState()
+{
+ if (this->FindCommand->DebugMode) {
+ std::string buffer =
+ cmStrCat(this->CommandName, " called with the following settings:\n");
+ buffer += cmStrCat(" VAR: ", this->FindCommand->VariableName, "\n");
+ buffer += cmStrCat(
+ " NAMES: ", cmWrap("\"", this->FindCommand->Names, "\"", "\n "),
+ "\n");
+ buffer += cmStrCat(
+ " Documentation: ", this->FindCommand->VariableDocumentation, "\n");
+ buffer += " Framework\n";
+ buffer += cmStrCat(" Only Search Frameworks: ",
+ this->FindCommand->SearchFrameworkOnly, "\n");
+
+ buffer += cmStrCat(" Search Frameworks Last: ",
+ this->FindCommand->SearchFrameworkLast, "\n");
+ buffer += cmStrCat(" Search Frameworks First: ",
+ this->FindCommand->SearchFrameworkFirst, "\n");
+ buffer += " AppBundle\n";
+ buffer += cmStrCat(" Only Search AppBundle: ",
+ this->FindCommand->SearchAppBundleOnly, "\n");
+ buffer += cmStrCat(" Search AppBundle Last: ",
+ this->FindCommand->SearchAppBundleLast, "\n");
+ buffer += cmStrCat(" Search AppBundle First: ",
+ this->FindCommand->SearchAppBundleFirst, "\n");
+
+ if (this->FindCommand->NoDefaultPath) {
+ buffer += " NO_DEFAULT_PATH Enabled\n";
+ } else {
+ buffer += cmStrCat(
+ " CMAKE_FIND_USE_CMAKE_PATH: ", !this->FindCommand->NoCMakePath, "\n",
+ " CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: ",
+ !this->FindCommand->NoCMakeEnvironmentPath, "\n",
+ " CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ",
+ !this->FindCommand->NoSystemEnvironmentPath, "\n",
+ " CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ",
+ !this->FindCommand->NoCMakeSystemPath, "\n");
+ }
+
+ buffer +=
+ cmStrCat(this->CommandName, " considered the following locations:\n");
+ for (auto const& state : this->FailedSearchLocations) {
+ std::string path = cmStrCat(" ", state.path);
+ if (!state.regexName.empty()) {
+ path = cmStrCat(path, "/", state.regexName);
+ }
+ buffer += cmStrCat(path, "\n");
+ }
+
+ if (!this->FoundSearchLocation.path.empty()) {
+ buffer += cmStrCat("The item was found at\n ",
+ this->FoundSearchLocation.path, "\n");
+ } else {
+ buffer += "The item was not found.\n";
+ }
+
+ this->FindCommand->DebugMessage(buffer);
+ }
+}
+
+void cmFindBaseDebugState::FoundAt(std::string const& path,
+ std::string regexName)
+{
+ if (this->FindCommand->DebugMode) {
+ this->FoundSearchLocation = DebugLibState{ std::move(regexName), path };
+ }
+}
+
+void cmFindBaseDebugState::FailedAt(std::string const& path,
+ std::string regexName)
+{
+ if (this->FindCommand->DebugMode) {
+ this->FailedSearchLocations.emplace_back(std::move(regexName), path);
+ }
+}
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index f75db5ff3f..fce0b11896 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
+#include <utility>
#include <vector>
#include "cmFindCommon.h"
@@ -31,7 +32,7 @@ public:
virtual bool ParseArguments(std::vector<std::string> const& args);
protected:
- void PrintFindStuff();
+ friend class cmFindBaseDebugState;
void ExpandPaths();
// see if the VariableName is already set in the cache,
@@ -63,4 +64,33 @@ private:
void FillUserGuessPath();
};
+class cmFindBaseDebugState
+{
+public:
+ explicit cmFindBaseDebugState(std::string name, cmFindBase const* findBase);
+ ~cmFindBaseDebugState();
+
+ void FoundAt(std::string const& path, std::string regexName = std::string());
+ void FailedAt(std::string const& path,
+ std::string regexName = std::string());
+
+private:
+ struct DebugLibState
+ {
+ DebugLibState() = default;
+ DebugLibState(std::string&& n, std::string p)
+ : regexName(n)
+ , path(std::move(p))
+ {
+ }
+ std::string regexName;
+ std::string path;
+ };
+
+ cmFindBase const* FindCommand;
+ std::string CommandName;
+ std::vector<DebugLibState> FailedSearchLocations;
+ DebugLibState FoundSearchLocation;
+};
+
#endif
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index badec55a8a..82acfedad3 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -7,11 +7,14 @@
#include <cstring>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL");
cmFindCommon::PathLabel cmFindCommon::PathLabel::PackageRoot(
@@ -52,6 +55,8 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status)
this->SearchAppBundleLast = false;
this->InitializeSearchPathGroups();
+
+ this->DebugMode = false;
}
void cmFindCommon::SetError(std::string const& e)
@@ -59,6 +64,19 @@ void cmFindCommon::SetError(std::string const& e)
this->Status.SetError(e);
}
+void cmFindCommon::DebugMessage(std::string const& msg) const
+{
+ if (this->Makefile) {
+ this->Makefile->IssueMessage(MessageType::LOG, msg);
+ }
+}
+
+bool cmFindCommon::ComputeIfDebugModeWanted()
+{
+ return this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE") ||
+ this->Makefile->GetCMakeInstance()->GetDebugFindOutput();
+}
+
void cmFindCommon::InitializeSearchPathGroups()
{
std::vector<PathLabel>* labels;
@@ -249,7 +267,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
// If searching both rooted and unrooted paths add the original
// paths again.
if (this->FindRootPathMode == RootPathModeBoth) {
- cmAppend(paths, unrootedPaths);
+ cm::append(paths, unrootedPaths);
}
}
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 8177eacd6e..916f3bc9ba 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -30,8 +30,11 @@ public:
void SetError(std::string const& e);
+ bool DebugModeEnabled() const { return this->DebugMode; }
+
protected:
friend class cmSearchPath;
+ friend class cmFindBaseDebugState;
/** Used to define groups of path labels */
class PathGroup : public cmPathLabel
@@ -96,6 +99,10 @@ protected:
/** Compute the current default search modes based on global variables. */
void SelectDefaultSearchModes();
+ /** The `InitialPass` functions of the child classes should set
+ this->DebugMode to the result of this. */
+ bool ComputeIfDebugModeWanted();
+
// Path arguments prior to path manipulation routines
std::vector<std::string> UserHintsArgs;
std::vector<std::string> UserGuessArgs;
@@ -106,6 +113,8 @@ protected:
bool CheckCommonArgument(std::string const& arg);
void AddPathSuffix(std::string const& arg);
+ void DebugMessage(std::string const& msg) const;
+ bool DebugMode;
bool NoDefaultPath;
bool NoPackageRootPath;
bool NoCMakePath;
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 20221b12e0..d5a4bde97e 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -29,6 +29,7 @@ cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
// cmFindLibraryCommand
bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a library.";
this->CMakePathName = "LIBRARY";
if (!this->ParseArguments(argsIn)) {
@@ -92,6 +93,13 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
original.swap(this->SearchPaths);
for (std::string const& o : original) {
this->AddArchitecturePath(o, 0, suffix);
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") removed original suffix ", o,
+ " from PATH_SUFFIXES while adding architecture paths for suffix '",
+ suffix, "'");
+ this->DebugMessage(msg);
+ }
}
}
@@ -153,11 +161,23 @@ void cmFindLibraryCommand::AddArchitecturePath(
if (use_dirX) {
dirX += "/";
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") added replacement path ",
+ dirX, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+ this->DebugMessage(msg);
+ }
this->SearchPaths.push_back(std::move(dirX));
}
if (use_dir) {
this->SearchPaths.push_back(dir);
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") added replacement path ",
+ dir, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+ this->DebugMessage(msg);
+ }
}
}
}
@@ -179,7 +199,7 @@ std::string cmFindLibraryCommand::FindLibrary()
struct cmFindLibraryHelper
{
- cmFindLibraryHelper(cmMakefile* mf);
+ cmFindLibraryHelper(cmMakefile* mf, cmFindBase const* findBase);
// Context information.
cmMakefile* Makefile;
@@ -198,6 +218,8 @@ struct cmFindLibraryHelper
// Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
bool OpenBSD;
+ bool DebugMode;
+
// Current names under consideration.
struct Name
{
@@ -227,10 +249,33 @@ struct cmFindLibraryHelper
void SetName(std::string const& name);
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
+
+ cmFindBaseDebugState DebugSearches;
+
+ void DebugLibraryFailed(std::string const& name, std::string const& path)
+ {
+ if (this->DebugMode) {
+ auto regexName =
+ cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
+ this->DebugSearches.FailedAt(path, regexName);
+ }
+ };
+
+ void DebugLibraryFound(std::string const& name, std::string const& path)
+ {
+ if (this->DebugMode) {
+ auto regexName =
+ cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
+ this->DebugSearches.FoundAt(path, regexName);
+ }
+ };
};
-cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf)
+cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf,
+ cmFindBase const* base)
: Makefile(mf)
+ , DebugMode(base->DebugModeEnabled())
+ , DebugSearches("find_library", base)
{
this->GG = this->Makefile->GetGlobalGenerator();
@@ -350,7 +395,12 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
// library or an import library).
if (name.TryRaw) {
this->TestPath = cmStrCat(path, name.Raw);
- if (cmSystemTools::FileExists(this->TestPath, true)) {
+
+ const bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ if (!exists) {
+ this->DebugLibraryFailed(name.Raw, path);
+ } else {
+ this->DebugLibraryFound(name.Raw, path);
this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
cmSystemTools::ConvertToUnixSlashes(this->BestPath);
return true;
@@ -376,6 +426,8 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
if (name.Regex.find(testName)) {
this->TestPath = cmStrCat(path, origName);
if (!cmSystemTools::FileIsDirectory(this->TestPath)) {
+ this->DebugLibraryFound(name.Raw, dir);
+
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
// followed by earlier suffixes. For OpenBSD, shared library
@@ -402,6 +454,12 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
}
}
+ if (this->BestPath.empty()) {
+ this->DebugLibraryFailed(name.Raw, dir);
+ } else {
+ this->DebugLibraryFound(name.Raw, this->BestPath);
+ }
+
// Use the best candidate found in this directory, if any.
return !this->BestPath.empty();
}
@@ -417,7 +475,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
{
// Search for all names in each directory.
- cmFindLibraryHelper helper(this->Makefile);
+ cmFindLibraryHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -434,7 +492,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
{
// Search the entire path for each name.
- cmFindLibraryHelper helper(this->Makefile);
+ cmFindLibraryHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 2b11b62a21..297c72b0f5 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -160,8 +160,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]);
}
- // Check for debug mode.
- this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
+ this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugBuffer.clear();
// Lookup target architecture, if any.
if (const char* arch =
@@ -576,6 +576,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
this->AppendSuccessInformation();
+
return loadedPackage;
}
@@ -695,8 +696,23 @@ void cmFindPackageCommand::RestoreFindDefinitions()
bool cmFindPackageCommand::FindModule(bool& found)
{
std::string module = cmStrCat("Find", this->Name, ".cmake");
+
bool system = false;
- std::string mfile = this->Makefile->GetModulesFile(module, system);
+ std::string debugBuffer =
+ cmStrCat("find_package considered the following paths for ", this->Name,
+ ".cmake\n");
+ std::string mfile = this->Makefile->GetModulesFile(
+ module, system, this->DebugMode, debugBuffer);
+ if (this->DebugMode) {
+ if (mfile.empty()) {
+ debugBuffer = cmStrCat(debugBuffer, "The file was not found.");
+ } else {
+ debugBuffer =
+ cmStrCat(debugBuffer, "The file was found at\n ", mfile, "\n");
+ }
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
+
if (!mfile.empty()) {
if (system) {
auto it = this->DeprecatedFindModules.find(this->Name);
@@ -827,6 +843,11 @@ bool cmFindPackageCommand::HandlePackageMode(
result = false;
}
+ if (this->DebugMode) {
+ this->DebugMessage(this->DebugBuffer);
+ this->DebugBuffer.clear();
+ }
+
// package not found
if (result && !found) {
// warn if package required or neither quiet nor in config mode
@@ -987,6 +1008,11 @@ bool cmFindPackageCommand::FindConfig()
// Look for the project's configuration file.
bool found = false;
+ if (this->DebugMode) {
+ this->DebugBuffer = cmStrCat(this->DebugBuffer,
+ "find_package considered the following "
+ "locations for the Config module:\n");
+ }
// Search for frameworks.
if (!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly)) {
@@ -1013,6 +1039,16 @@ bool cmFindPackageCommand::FindConfig()
found = this->FindAppBundleConfig();
}
+ if (this->DebugMode) {
+ if (found) {
+ this->DebugBuffer = cmStrCat(
+ this->DebugBuffer, "The file was found at\n ", this->FileFound, "\n");
+ } else {
+ this->DebugBuffer =
+ cmStrCat(this->DebugBuffer, "The file was not found.\n");
+ }
+ }
+
// Store the entry in the cache so it can be set by the user.
std::string init;
if (found) {
@@ -1026,6 +1062,7 @@ bool cmFindPackageCommand::FindConfig()
// 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);
+
return found;
}
@@ -1164,6 +1201,21 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->Makefile->FindPackageRootPathStack.pop_back();
}
+inline std::size_t collectPathsForDebug(std::string& buffer,
+ cmSearchPath const& searchPath,
+ std::size_t startIndex = 0)
+{
+ const auto& paths = searchPath.GetPaths();
+ if (paths.empty()) {
+ buffer += " none";
+ return 0;
+ }
+ for (std::size_t i = startIndex; i < paths.size(); i++) {
+ buffer += " " + paths[i] + "\n";
+ }
+ return paths.size();
+}
+
void cmFindPackageCommand::ComputePrefixes()
{
if (!this->NoDefaultPath) {
@@ -1177,7 +1229,9 @@ void cmFindPackageCommand::ComputePrefixes()
this->FillPrefixesCMakeEnvironment();
}
}
+
this->FillPrefixesUserHints();
+
if (!this->NoDefaultPath) {
if (!this->NoSystemEnvironmentPath) {
this->FillPrefixesSystemEnvironment();
@@ -1209,29 +1263,72 @@ void cmFindPackageCommand::FillPrefixesPackageRoot()
paths.AddPath(path);
}
}
+ if (this->DebugMode) {
+ std::string debugBuffer = "<PackageName>_ROOT CMake variable "
+ "[CMAKE_FIND_USE_PACKAGE_ROOT_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesCMakeEnvironment()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
+ std::string debugBuffer;
+ std::size_t debugOffset = 0;
// Check the environment variable with the same name as the cache
// entry.
paths.AddEnvPath(this->Variable);
+ if (this->DebugMode) {
+ debugBuffer = cmStrCat("Env variable ", this->Variable,
+ " [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ debugOffset = collectPathsForDebug(debugBuffer, paths);
+ }
// And now the general CMake environment variables
paths.AddEnvPath("CMAKE_PREFIX_PATH");
+ if (this->DebugMode) {
+ debugBuffer = cmStrCat(debugBuffer,
+ "\nCMAKE_PREFIX_PATH env variable "
+ "[CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ debugOffset = collectPathsForDebug(debugBuffer, paths, debugOffset);
+ }
+
paths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
paths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
+ if (this->DebugMode) {
+ debugBuffer =
+ cmStrCat(debugBuffer,
+ "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH env "
+ "variables [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ collectPathsForDebug(debugBuffer, paths, debugOffset);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesCMakeVariable()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMake];
+ std::string debugBuffer;
+ std::size_t debugOffset = 0;
paths.AddCMakePath("CMAKE_PREFIX_PATH");
+ if (this->DebugMode) {
+ debugBuffer = "CMAKE_PREFIX_PATH variable [CMAKE_FIND_USE_CMAKE_PATH].\n";
+ debugOffset = collectPathsForDebug(debugBuffer, paths);
+ }
+
paths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
paths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
+ if (this->DebugMode) {
+ debugBuffer =
+ cmStrCat(debugBuffer,
+ "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH variables "
+ "[CMAKE_FIND_USE_CMAKE_PATH].\n");
+ collectPathsForDebug(debugBuffer, paths, debugOffset);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesSystemEnvironment()
@@ -1251,6 +1348,12 @@ void cmFindPackageCommand::FillPrefixesSystemEnvironment()
paths.AddPath(i);
}
}
+ if (this->DebugMode) {
+ std::string debugBuffer = "Standard system environment variables "
+ "[CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserRegistry()
@@ -1274,6 +1377,13 @@ void cmFindPackageCommand::FillPrefixesUserRegistry()
this->LabeledPaths[PathLabel::UserRegistry]);
}
#endif
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "CMake User Package Registry [CMAKE_FIND_USE_PACKAGE_REGISTRY].\n";
+ collectPathsForDebug(debugBuffer,
+ this->LabeledPaths[PathLabel::UserRegistry]);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesSystemRegistry()
@@ -1285,6 +1395,15 @@ void cmFindPackageCommand::FillPrefixesSystemRegistry()
#if defined(_WIN32) && !defined(__CYGWIN__)
this->LoadPackageRegistryWinSystem();
#endif
+
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "CMake System Package Registry "
+ "[CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY].\n";
+ collectPathsForDebug(debugBuffer,
+ this->LabeledPaths[PathLabel::SystemRegistry]);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1457,6 +1576,13 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+
+ if (this->DebugMode) {
+ std::string debugBuffer = "CMake variables defined in the Platform file "
+ "[CMAKE_FIND_USE_CMAKE_SYSTEM_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserGuess()
@@ -1466,6 +1592,12 @@ void cmFindPackageCommand::FillPrefixesUserGuess()
for (std::string const& p : this->UserGuessArgs) {
paths.AddUserPath(p);
}
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "Paths specified by the find_package PATHS option.\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserHints()
@@ -1475,6 +1607,12 @@ void cmFindPackageCommand::FillPrefixesUserHints()
for (std::string const& p : this->UserHintsArgs) {
paths.AddUserPath(p);
}
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "Paths specified by the find_package HINTS option.\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
@@ -1519,7 +1657,7 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
for (std::string const& c : this->Configs) {
file = cmStrCat(dir, '/', c);
if (this->DebugMode) {
- fprintf(stderr, "Checking file [%s]\n", file.c_str());
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, "\n");
}
if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
// Allow resolving symlinks when the config file is found through a link
@@ -2032,9 +2170,6 @@ private:
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str());
- }
// Skip this if the prefix does not exist.
if (!cmSystemTools::FileIsDirectory(prefix_in)) {
@@ -2188,9 +2323,6 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str());
- }
// Strip the trailing slash because the path generator is about to
// add one.
@@ -2249,9 +2381,6 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str());
- }
// Strip the trailing slash because the path generator is about to
// add one.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 85fe7b6e51..ae9ade73e9 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -174,7 +174,6 @@ private:
bool UseFindModules;
bool NoUserRegistry;
bool NoSystemRegistry;
- bool DebugMode;
bool UseLib32Paths;
bool UseLib64Paths;
bool UseLibx32Paths;
@@ -184,6 +183,7 @@ private:
std::vector<std::string> Names;
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
+ std::string DebugBuffer;
/*! the selected sortOrder (None by default)*/
SortOrderType SortOrder;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index f5e2631081..908f0c13c6 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -21,6 +21,7 @@ cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
// cmFindPathCommand
bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a file.";
this->CMakePathName = "INCLUDE";
if (!this->ParseArguments(argsIn)) {
@@ -55,16 +56,19 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string cmFindPathCommand::FindHeader()
{
+ std::string debug_name = this->IncludeFileInPath ? "find_file" : "find_path";
+ cmFindBaseDebugState debug(debug_name, this);
std::string header;
if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
- header = this->FindFrameworkHeader();
+ header = this->FindFrameworkHeader(debug);
}
if (header.empty() && !this->SearchFrameworkOnly) {
- header = this->FindNormalHeader();
+ header = this->FindNormalHeader(debug);
}
if (header.empty() && this->SearchFrameworkLast) {
- header = this->FindFrameworkHeader();
+ header = this->FindFrameworkHeader(debug);
}
+
return header;
}
@@ -116,28 +120,31 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file,
return "";
}
-std::string cmFindPathCommand::FindNormalHeader()
+std::string cmFindPathCommand::FindNormalHeader(cmFindBaseDebugState& debug)
{
std::string tryPath;
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
tryPath = cmStrCat(sp, n);
if (cmSystemTools::FileExists(tryPath)) {
+ debug.FoundAt(tryPath);
if (this->IncludeFileInPath) {
return tryPath;
}
return sp;
}
+ debug.FailedAt(tryPath);
}
}
return "";
}
-std::string cmFindPathCommand::FindFrameworkHeader()
+std::string cmFindPathCommand::FindFrameworkHeader(cmFindBaseDebugState& debug)
{
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
std::string fwPath = this->FindHeaderInFramework(n, sp);
+ fwPath.empty() ? debug.FailedAt(fwPath) : debug.FoundAt(fwPath);
if (!fwPath.empty()) {
return fwPath;
}
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index 8d1ea8b60e..18bfb7dd86 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -32,8 +32,8 @@ private:
std::string FindHeaderInFramework(std::string const& file,
std::string const& dir);
std::string FindHeader();
- std::string FindNormalHeader();
- std::string FindFrameworkHeader();
+ std::string FindNormalHeader(cmFindBaseDebugState& debug);
+ std::string FindFrameworkHeader(cmFindBaseDebugState& debug);
};
bool cmFindPath(std::vector<std::string> const& args,
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index e0a3fbfcf5..3e4917262c 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -15,7 +15,9 @@ class cmExecutionStatus;
struct cmFindProgramHelper
{
- cmFindProgramHelper()
+ cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
+ : DebugSearches("find_program", base)
+ , Makefile(makefile)
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
// Consider platform-specific extensions.
@@ -41,6 +43,10 @@ struct cmFindProgramHelper
// Current full path under consideration.
std::string TestPath;
+ // Debug state
+ cmFindBaseDebugState DebugSearches;
+ cmMakefile* Makefile;
+
void AddName(std::string const& name) { this->Names.push_back(name); }
void SetName(std::string const& name)
{
@@ -78,8 +84,10 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
-
- if (cmSystemTools::FileExists(this->TestPath, true)) {
+ bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ exists ? this->DebugSearches.FoundAt(this->TestPath)
+ : this->DebugSearches.FailedAt(this->TestPath);
+ if (exists) {
this->BestPath = this->TestPath;
return true;
}
@@ -97,6 +105,7 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a program.";
this->CMakePathName = "PROGRAM";
// call cmFindBase::ParseArguments
@@ -158,7 +167,7 @@ std::string cmFindProgramCommand::FindNormalProgram()
std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
// Search for all names in each directory.
- cmFindProgramHelper helper;
+ cmFindProgramHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -181,7 +190,7 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
// Search the entire path for each name.
- cmFindProgramHelper helper;
+ cmFindProgramHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 44392baa75..054618659a 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -2,8 +2,18 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmForEachCommand.h"
-#include <cstdio>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+// NOTE The declaration of `std::abs` has moved to `cmath` since C++17
+// See https://en.cppreference.com/w/cpp/numeric/math/abs
+// ALERT But IWYU used to lint `#include`s do not "understand"
+// conditional compilation (i.e. `#if __cplusplus >= 201703L`)
#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <stdexcept>
#include <utility>
#include <cm/memory>
@@ -21,12 +31,10 @@
#include "cmSystemTools.h"
namespace {
-bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile);
-
class cmForEachFunctionBlocker : public cmFunctionBlocker
{
public:
- cmForEachFunctionBlocker(cmMakefile* mf);
+ explicit cmForEachFunctionBlocker(cmMakefile* mf);
~cmForEachFunctionBlocker() override;
cm::string_view StartCommandName() const override { return "foreach"_s; }
@@ -38,10 +46,33 @@ public:
bool Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& inStatus) override;
+ void SetIterationVarsCount(const std::size_t varsCount)
+ {
+ this->IterationVarsCount = varsCount;
+ }
+ void SetZipLists() { this->ZipLists = true; }
+
std::vector<std::string> Args;
private:
+ struct InvokeResult
+ {
+ bool Restore;
+ bool Break;
+ };
+
+ bool ReplayItems(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus);
+
+ bool ReplayZipLists(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus);
+
+ InvokeResult invoke(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus, cmMakefile& mf);
+
cmMakefile* Makefile;
+ std::size_t IterationVarsCount = 0u;
+ bool ZipLists = false;
};
cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf)
@@ -60,53 +91,288 @@ bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
{
std::vector<std::string> expandedArguments;
mf.ExpandArguments(lff.Arguments, expandedArguments);
- return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+ return expandedArguments.empty() ||
+ expandedArguments.front() == this->Args.front();
}
bool cmForEachFunctionBlocker::Replay(
std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
{
- cmMakefile& mf = inStatus.GetMakefile();
- // at end of for each execute recorded commands
+ return this->ZipLists ? this->ReplayZipLists(functions, inStatus)
+ : this->ReplayItems(functions, inStatus);
+}
+
+bool cmForEachFunctionBlocker::ReplayItems(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus)
+{
+ assert("Unexpected number of iteration variables" &&
+ this->IterationVarsCount == 1);
+
+ auto& 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]);
+ if (mf.GetDefinition(this->Args.front())) {
+ oldDef = mf.GetDefinition(this->Args.front());
}
+ auto restore = false;
for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
- // set the variable to the loop value
- mf.AddDefinition(this->Args[0], arg);
+ // Set the variable to the loop value
+ mf.AddDefinition(this->Args.front(), arg);
+ // Invoke all the functions that were collected in the block.
+ auto r = this->invoke(functions, inStatus, mf);
+ restore = r.Restore;
+ if (r.Break) {
+ break;
+ }
+ }
+
+ if (restore) {
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args.front(), oldDef);
+ }
+ return true;
+}
+
+bool cmForEachFunctionBlocker::ReplayZipLists(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus)
+{
+ assert("Unexpected number of iteration variables" &&
+ this->IterationVarsCount >= 1);
+
+ auto& mf = inStatus.GetMakefile();
+
+ // Expand the list of list-variables into a list of lists of strings
+ std::vector<std::vector<std::string>> values;
+ values.reserve(this->Args.size() - this->IterationVarsCount);
+ // Also track the longest list size
+ std::size_t maxItems = 0u;
+ for (auto const& var :
+ cmMakeRange(this->Args).advance(this->IterationVarsCount)) {
+ std::vector<std::string> items;
+ auto const& value = mf.GetSafeDefinition(var);
+ if (!value.empty()) {
+ cmExpandList(value, items, true);
+ }
+ maxItems = std::max(maxItems, items.size());
+ values.emplace_back(std::move(items));
+ }
+
+ // Form the list of iteration variables
+ std::vector<std::string> iterationVars;
+ if (this->IterationVarsCount > 1) {
+ // If multiple iteration variables has given,
+ // just copy them to the `iterationVars` list.
+ iterationVars.reserve(values.size());
+ std::copy(this->Args.begin(),
+ this->Args.begin() + this->IterationVarsCount,
+ std::back_inserter(iterationVars));
+ } else {
+ // In case of the only iteration variable,
+ // generate names as `var_name_N`,
+ // where `N` is the count of lists to zip
+ iterationVars.resize(values.size());
+ const auto iter_var_prefix = this->Args.front() + "_";
+ auto i = 0u;
+ std::generate(
+ iterationVars.begin(), iterationVars.end(),
+ [&]() -> std::string { return iter_var_prefix + std::to_string(i++); });
+ }
+ assert("Sanity check" && iterationVars.size() == values.size());
+
+ // Store old values for iteration variables
+ std::map<std::string, std::string> oldDefs;
+ for (auto i = 0u; i < values.size(); ++i) {
+ if (mf.GetDefinition(iterationVars[i])) {
+ oldDefs.emplace(iterationVars[i], mf.GetDefinition(iterationVars[i]));
+ }
+ }
+
+ // Form a vector of current positions in all lists (Ok, vectors) of values
+ std::vector<decltype(values)::value_type::iterator> positions;
+ positions.reserve(values.size());
+ std::transform(
+ values.begin(), values.end(), std::back_inserter(positions),
+ // Set the initial position to the beginning of every list
+ [](decltype(values)::value_type& list) { return list.begin(); });
+ assert("Sanity check" && positions.size() == values.size());
+
+ auto restore = false;
+ // Iterate over all the lists simulateneously
+ for (auto i = 0u; i < maxItems; ++i) {
+ // Declare iteration variables
+ for (auto j = 0u; j < values.size(); ++j) {
+ // Define (or not) the iteration variable if the current position
+ // still not at the end...
+ if (positions[j] != values[j].end()) {
+ mf.AddDefinition(iterationVars[j], *positions[j]);
+ ++positions[j];
+ } else {
+ mf.RemoveDefinition(iterationVars[j]);
+ }
+ }
// 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);
+ auto r = this->invoke(functions, inStatus, mf);
+ restore = r.Restore;
+ if (r.Break) {
+ break;
+ }
+ }
+
+ // Restore the variables to its prior value
+ if (restore) {
+ for (auto const& p : oldDefs) {
+ mf.AddDefinition(p.first, p.second);
+ }
+ }
+ return true;
+}
+
+auto cmForEachFunctionBlocker::invoke(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus, cmMakefile& mf) -> InvokeResult
+{
+ InvokeResult result = { true, false };
+ // 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();
+ result.Break = true;
+ break;
+ }
+ if (status.GetBreakInvoked()) {
+ result.Break = true;
+ break;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ result.Restore = false;
+ result.Break = true;
+ break;
+ }
+ }
+ return result;
+}
+
+bool HandleInMode(std::vector<std::string> const& args,
+ std::vector<std::string>::const_iterator kwInIter,
+ cmMakefile& makefile)
+{
+ assert("A valid iterator expected" && kwInIter != args.end());
+
+ auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
+
+ // Copy iteration variable names first
+ std::copy(args.begin(), kwInIter, std::back_inserter(fb->Args));
+ // Remember the count of given iteration variable names
+ const auto varsCount = fb->Args.size();
+ fb->SetIterationVarsCount(varsCount);
+
+ enum Doing
+ {
+ DoingNone,
+ DoingLists,
+ DoingItems,
+ DoingZipLists
+ };
+ Doing doing = DoingNone;
+ // Iterate over arguments past the "IN" keyword
+ for (std::string const& arg : cmMakeRange(++kwInIter, args.end())) {
+ if (arg == "LISTS") {
+ if (doing == DoingZipLists) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
+ return true;
+ }
+ if (varsCount != 1u) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "ITEMS or LISTS require exactly one iteration variable");
return true;
}
- if (status.GetBreakInvoked()) {
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ doing = DoingLists;
+
+ } else if (arg == "ITEMS") {
+ if (doing == DoingZipLists) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
return true;
}
- if (status.GetContinueInvoked()) {
- break;
+ if (varsCount != 1u) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "ITEMS or LISTS require exactly one iteration variable");
+ return true;
}
- if (cmSystemTools::GetFatalErrorOccured()) {
+ doing = DoingItems;
+
+ } else if (arg == "ZIP_LISTS") {
+ if (doing != DoingNone) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
return true;
}
+ doing = DoingZipLists;
+ fb->SetZipLists();
+
+ } else if (doing == DoingLists) {
+ auto const& value = makefile.GetSafeDefinition(arg);
+ if (!value.empty()) {
+ cmExpandList(value, fb->Args, true);
+ }
+
+ } else if (doing == DoingItems || doing == DoingZipLists) {
+ fb->Args.push_back(arg);
+
+ } else {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Unknown argument:\n", " ", arg, "\n"));
+ return true;
}
}
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ // If `ZIP_LISTS` given and variables count more than 1,
+ // make sure the given lists count matches variables...
+ if (doing == DoingZipLists && varsCount > 1u &&
+ (2u * varsCount) != fb->Args.size()) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Expected ", std::to_string(varsCount),
+ " list variables, but given ",
+ std::to_string(fb->Args.size() - varsCount)));
+ return true;
+ }
+
+ makefile.AddFunctionBlocker(std::move(fb));
+
return true;
}
+
+bool TryParseInteger(cmExecutionStatus& status, const std::string& str, int& i)
+{
+ try {
+ i = std::stoi(str);
+ } catch (std::invalid_argument&) {
+ std::ostringstream e;
+ e << "Invalid integer: '" << str << "'";
+ status.SetError(e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ return true;
}
+} // anonymous namespace
+
bool cmForEachCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -114,8 +380,9 @@ bool cmForEachCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments");
return false;
}
- if (args.size() > 1 && args[1] == "IN") {
- return HandleInMode(args, status.GetMakefile());
+ auto kwInIter = std::find(args.begin(), args.end(), "IN");
+ if (kwInIter != args.end()) {
+ return HandleInMode(args, kwInIter, status.GetMakefile());
}
// create a function blocker
@@ -126,16 +393,28 @@ bool cmForEachCommand(std::vector<std::string> const& args,
int stop = 0;
int step = 0;
if (args.size() == 3) {
- stop = atoi(args[2].c_str());
+ if (!TryParseInteger(status, args[2], stop)) {
+ return false;
+ }
}
if (args.size() == 4) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
}
if (args.size() == 5) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
- step = atoi(args[4].c_str());
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[4], step)) {
+ return false;
+ }
}
if (step == 0) {
if (start > stop) {
@@ -149,69 +428,36 @@ bool cmForEachCommand(std::vector<std::string> const& args,
status.SetError(
cmStrCat("called with incorrect range specification: start ", start,
", stop ", stop, ", step ", step));
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
- std::vector<std::string> range;
- char buffer[100];
- range.push_back(args[0]);
- int cc;
- for (cc = start;; cc += step) {
- if ((step > 0 && cc > stop) || (step < 0 && cc < stop)) {
- break;
- }
- sprintf(buffer, "%d", cc);
- range.emplace_back(buffer);
- if (cc == stop) {
- break;
- }
- }
- fb->Args = range;
+
+ // Calculate expected iterations count and reserve enough space
+ // in the `fb->Args` vector. The first item is the iteration variable
+ // name...
+ const std::size_t iter_cnt = 2u +
+ int(start < stop) * (stop - start) / std::abs(step) +
+ int(start > stop) * (start - stop) / std::abs(step);
+ fb->Args.resize(iter_cnt);
+ fb->Args.front() = args.front();
+ auto cc = start;
+ auto generator = [&cc, step]() -> std::string {
+ auto result = std::to_string(cc);
+ cc += step;
+ return result;
+ };
+ // Fill the `range` vector w/ generated string values
+ // (starting from 2nd position)
+ std::generate(++fb->Args.begin(), fb->Args.end(), generator);
} else {
fb->Args = args;
}
} else {
fb->Args = args;
}
- status.GetMakefile().AddFunctionBlocker(std::move(fb));
-
- return true;
-}
-
-namespace {
-bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile)
-{
- auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
- fb->Args.push_back(args[0]);
-
- enum Doing
- {
- DoingNone,
- DoingLists,
- DoingItems
- };
- Doing doing = DoingNone;
- for (unsigned int i = 2; i < args.size(); ++i) {
- if (doing == DoingItems) {
- 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 = makefile.GetDefinition(args[i]);
- if (value && *value) {
- cmExpandList(value, fb->Args, true);
- }
- } else {
- makefile.IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Unknown argument:\n", " ", args[i], "\n"));
- return true;
- }
- }
- makefile.AddFunctionBlocker(std::move(fb));
+ fb->SetIterationVarsCount(1u);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
return true;
}
-}
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index b3ddfe01f3..a4c907232c 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -2,15 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFunctionCommand.h"
-#include <sstream>
#include <utility>
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
@@ -19,8 +18,20 @@
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
namespace {
+std::string const ARGC = "ARGC";
+std::string const ARGN = "ARGN";
+std::string const ARGV = "ARGV";
+std::string const CMAKE_CURRENT_FUNCTION = "CMAKE_CURRENT_FUNCTION";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_FILE =
+ "CMAKE_CURRENT_FUNCTION_LIST_FILE";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_DIR =
+ "CMAKE_CURRENT_FUNCTION_LIST_DIR";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_LINE =
+ "CMAKE_CURRENT_FUNCTION_LIST_LINE";
+
// define the class for function commands
class cmFunctionHelperCommand
{
@@ -36,8 +47,8 @@ public:
std::vector<cmListFileFunction> Functions;
cmPolicies::PolicyMap Policies;
std::string FilePath;
+ long Line;
};
-}
bool cmFunctionHelperCommand::operator()(
std::vector<cmListFileArgument> const& args,
@@ -52,9 +63,9 @@ bool cmFunctionHelperCommand::operator()(
// 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 = cmStrCat(
+ auto const errorMsg = cmStrCat(
"Function invoked with incorrect arguments for function named: ",
- this->Args[0]);
+ this->Args.front());
inStatus.SetError(errorMsg);
return false;
}
@@ -63,30 +74,40 @@ bool cmFunctionHelperCommand::operator()(
this->Policies);
// set the value of argc
- makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size()));
- 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;
- makefile.AddDefinition(tmpStream.str(), expandedArgs[t]);
- makefile.MarkVariableAsUsed(tmpStream.str());
+ for (auto t = 0u; t < expandedArgs.size(); ++t) {
+ auto const value = cmStrCat(ARGV, std::to_string(t));
+ makefile.AddDefinition(value, expandedArgs[t]);
+ makefile.MarkVariableAsUsed(value);
}
// define the formal arguments
- for (unsigned int j = 1; j < this->Args.size(); ++j) {
+ for (auto j = 1u; j < this->Args.size(); ++j) {
makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]);
}
// define ARGV and ARGN
- std::string argvDef = cmJoin(expandedArgs, ";");
- auto eit = expandedArgs.begin() + (this->Args.size() - 1);
- std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
- makefile.AddDefinition("ARGV", argvDef);
- makefile.MarkVariableAsUsed("ARGV");
- makefile.AddDefinition("ARGN", argnDef);
- makefile.MarkVariableAsUsed("ARGN");
+ auto const argvDef = cmJoin(expandedArgs, ";");
+ auto const eit = expandedArgs.begin() + (this->Args.size() - 1);
+ auto const argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
+ makefile.AddDefinition(ARGV, argvDef);
+ makefile.MarkVariableAsUsed(ARGV);
+ makefile.AddDefinition(ARGN, argnDef);
+ makefile.MarkVariableAsUsed(ARGN);
+
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION, this->Args.front());
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_FILE, this->FilePath);
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_FILE);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_DIR,
+ cmSystemTools::GetFilenamePath(this->FilePath));
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_DIR);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_LINE,
+ std::to_string(this->Line));
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_LINE);
// Invoke all the functions that were collected in the block.
// for each function
@@ -100,7 +121,7 @@ bool cmFunctionHelperCommand::operator()(
return false;
}
if (status.GetReturnInvoked()) {
- return true;
+ break;
}
}
@@ -129,7 +150,8 @@ bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
std::vector<std::string> expandedArguments;
mf.ExpandArguments(lff.Arguments, expandedArguments,
this->GetStartingContext().FilePath.c_str());
- return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+ return expandedArguments.empty() ||
+ expandedArguments.front() == this->Args.front();
}
bool cmFunctionFunctionBlocker::Replay(
@@ -141,11 +163,14 @@ bool cmFunctionFunctionBlocker::Replay(
f.Args = this->Args;
f.Functions = std::move(functions);
f.FilePath = this->GetStartingContext().FilePath;
+ f.Line = this->GetStartingContext().Line;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f));
return true;
}
+} // anonymous namespace
+
bool cmFunctionCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -155,10 +180,9 @@ bool cmFunctionCommand(std::vector<std::string> const& args,
}
// create a function blocker
- {
- auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
- cmAppend(fb->Args, args);
- status.GetMakefile().AddFunctionBlocker(std::move(fb));
- }
+ auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
+ cm::append(fb->Args, args);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
+
return true;
}
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
new file mode 100644
index 0000000000..957896f521
--- /dev/null
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -0,0 +1,126 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmGccDepfileLexerHelper.h"
+
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmGccDepfileReaderTypes.h"
+
+#include "LexerParser/cmGccDepfileLexer.h"
+
+#ifdef _WIN32
+# include "cmsys/Encoding.h"
+#endif
+
+bool cmGccDepfileLexerHelper::readFile(const char* filePath)
+{
+#ifdef _WIN32
+ wchar_t* wpath = cmsysEncoding_DupToWide(filePath);
+ FILE* file = _wfopen(wpath, L"rb");
+ free(wpath);
+#else
+ FILE* file = fopen(filePath, "r");
+#endif
+ if (!file) {
+ return false;
+ }
+ newEntry();
+ yyscan_t scanner;
+ cmGccDepfile_yylex_init(&scanner);
+ cmGccDepfile_yyset_extra(this, scanner);
+ cmGccDepfile_yyrestart(file, scanner);
+ cmGccDepfile_yylex(scanner);
+ cmGccDepfile_yylex_destroy(scanner);
+ sanitizeContent();
+ fclose(file);
+ return true;
+}
+
+void cmGccDepfileLexerHelper::newEntry()
+{
+ this->HelperState = State::Rule;
+ this->Content.emplace_back();
+ newRule();
+}
+
+void cmGccDepfileLexerHelper::newRule()
+{
+ auto& entry = this->Content.back();
+ if (entry.rules.empty() || !entry.rules.back().empty()) {
+ entry.rules.emplace_back();
+ }
+}
+
+void cmGccDepfileLexerHelper::newDependency()
+{
+ // printf("NEW DEP\n");
+ this->HelperState = State::Dependency;
+ if (this->Content.back().paths.empty() ||
+ !this->Content.back().paths.back().empty()) {
+ this->Content.back().paths.emplace_back();
+ }
+}
+
+void cmGccDepfileLexerHelper::newRuleOrDependency()
+{
+ if (this->HelperState == State::Rule) {
+ newRule();
+ } else {
+ newDependency();
+ }
+}
+
+void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
+{
+ if (this->Content.empty()) {
+ return;
+ }
+ cmGccStyleDependency* dep = &this->Content.back();
+ std::string* dst = nullptr;
+ switch (this->HelperState) {
+ case State::Rule: {
+ if (dep->rules.empty()) {
+ return;
+ }
+ dst = &dep->rules.back();
+ } break;
+ case State::Dependency: {
+ if (dep->paths.empty()) {
+ return;
+ }
+ dst = &dep->paths.back();
+ } break;
+ }
+ dst->append(s);
+}
+
+void cmGccDepfileLexerHelper::sanitizeContent()
+{
+ for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // Remove empty rules
+ for (auto rit = it->rules.begin(); rit != it->rules.end();) {
+ if (rit->empty()) {
+ rit = it->rules.erase(rit);
+ } else {
+ ++rit;
+ }
+ }
+ // Remove the entry if rules are empty
+ if (it->rules.empty()) {
+ it = this->Content.erase(it);
+ } else {
+ // Remove empty paths
+ for (auto pit = it->paths.begin(); pit != it->paths.end();) {
+ if (pit->empty()) {
+ pit = it->paths.erase(pit);
+ } else {
+ ++pit;
+ }
+ }
+ ++it;
+ }
+ }
+}
diff --git a/Source/cmGccDepfileLexerHelper.h b/Source/cmGccDepfileLexerHelper.h
new file mode 100644
index 0000000000..e6b2fcf5b2
--- /dev/null
+++ b/Source/cmGccDepfileLexerHelper.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 cmGccDepfileLexerHelper_h
+#define cmGccDepfileLexerHelper_h
+
+#include <utility>
+
+#include <cmGccDepfileReaderTypes.h>
+
+class cmGccDepfileLexerHelper
+{
+public:
+ cmGccDepfileLexerHelper() = default;
+
+ bool readFile(const char* filePath);
+ cmGccDepfileContent extractContent() && { return std::move(this->Content); }
+
+ // Functions called by the lexer
+ void newEntry();
+ void newRule();
+ void newDependency();
+ void newRuleOrDependency();
+ void addToCurrentPath(const char* s);
+
+private:
+ void sanitizeContent();
+
+ cmGccDepfileContent Content;
+
+ enum class State
+ {
+ Rule,
+ Dependency
+ };
+ State HelperState = State::Rule;
+};
+
+#define YY_EXTRA_TYPE cmGccDepfileLexerHelper*
+
+#endif
diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx
new file mode 100644
index 0000000000..9d70edec54
--- /dev/null
+++ b/Source/cmGccDepfileReader.cxx
@@ -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. */
+#include "cmGccDepfileReader.h"
+
+#include <type_traits>
+#include <utility>
+
+#include "cmGccDepfileLexerHelper.h"
+
+cmGccDepfileContent cmReadGccDepfile(const char* filePath)
+{
+ cmGccDepfileContent result;
+ cmGccDepfileLexerHelper helper;
+ if (helper.readFile(filePath)) {
+ result = std::move(helper).extractContent();
+ }
+ return result;
+}
diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h
new file mode 100644
index 0000000000..9313010c43
--- /dev/null
+++ b/Source/cmGccDepfileReader.h
@@ -0,0 +1,10 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGccDepfileReader_h
+#define cmGccDepfileReader_h
+
+#include "cmGccDepfileReaderTypes.h"
+
+cmGccDepfileContent cmReadGccDepfile(const char* filePath);
+
+#endif
diff --git a/Source/cmGccDepfileReaderTypes.h b/Source/cmGccDepfileReaderTypes.h
new file mode 100644
index 0000000000..8b15c73757
--- /dev/null
+++ b/Source/cmGccDepfileReaderTypes.h
@@ -0,0 +1,17 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGccDepfileReaderTypes_h
+#define cmGccDepfileReaderTypes_h
+
+#include <string>
+#include <vector>
+
+struct cmGccStyleDependency
+{
+ std::vector<std::string> rules;
+ std::vector<std::string> paths;
+};
+
+using cmGccDepfileContent = std::vector<cmGccStyleDependency>;
+
+#endif
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index b7f7d1d9b6..81d1e46927 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -8,7 +8,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
@@ -22,6 +21,8 @@ cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
{
}
+cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() = default;
+
cmGeneratorExpression::~cmGeneratorExpression() = default;
std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
@@ -86,7 +87,7 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
this->Output.clear();
- for (const cmGeneratorExpressionEvaluator* it : this->Evaluators) {
+ for (const auto& it : this->Evaluators) {
this->Output += it->Evaluate(&context, dagChecker);
this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
@@ -129,11 +130,6 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
}
}
-cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
-{
- cmDeleteAll(this->Evaluators);
-}
-
std::string cmGeneratorExpression::StripEmptyListElements(
const std::string& input)
{
@@ -385,6 +381,20 @@ bool cmGeneratorExpression::IsValidTargetName(const std::string& input)
return targetNameValidator.find(input);
}
+void cmGeneratorExpression::ReplaceInstallPrefix(
+ std::string& input, const std::string& replacement)
+{
+ std::string::size_type pos = 0;
+ std::string::size_type lastPos = pos;
+
+ while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
+ std::string::npos) {
+ std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+ input.replace(pos, endPos - pos, replacement);
+ lastPos = endPos;
+ }
+}
+
void cmCompiledGeneratorExpression::GetMaxLanguageStandard(
const cmGeneratorTarget* tgt, std::map<std::string, std::string>& mapping)
{
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 4bd1c9f88a..c4be3a13bf 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -87,6 +87,9 @@ public:
return input != nullptr && input[0] == '$' && input[1] == '<';
}
+ static void ReplaceInstallPrefix(std::string& input,
+ const std::string& replacement);
+
private:
cmListFileBacktrace Backtrace;
};
@@ -160,7 +163,7 @@ private:
friend class cmGeneratorExpression;
cmListFileBacktrace Backtrace;
- std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators;
const std::string Input;
bool NeedsEvaluation;
bool EvaluateForBuildsystem;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index e0ae170c08..4129a0c4fd 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -2,10 +2,8 @@
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"
@@ -16,6 +14,8 @@ GeneratorExpressionContent::GeneratorExpressionContent(
{
}
+GeneratorExpressionContent::~GeneratorExpressionContent() = default;
+
std::string GeneratorExpressionContent::GetOriginalExpression() const
{
return std::string(this->StartContent, this->ContentLength);
@@ -25,14 +25,13 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit) const
+ std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
{
std::string result;
const auto pend = this->ParamChildren.end();
for (; pit != pend; ++pit) {
- for (cmGeneratorExpressionEvaluator* pExprEval : *pit) {
+ for (auto& pExprEval : *pit) {
if (node->RequiresLiteralInput()) {
if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
reportError(context, this->GetOriginalExpression(),
@@ -64,8 +63,7 @@ std::string GeneratorExpressionContent::Evaluate(
{
std::string identifier;
{
- for (cmGeneratorExpressionEvaluator* pExprEval :
- this->IdentifierChildren) {
+ for (auto& pExprEval : this->IdentifierChildren) {
identifier += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
@@ -126,7 +124,7 @@ std::string GeneratorExpressionContent::EvaluateParameters(
return std::string();
}
std::string parameter;
- for (cmGeneratorExpressionEvaluator* pExprEval : *pit) {
+ for (auto& pExprEval : *pit) {
parameter += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
@@ -174,10 +172,3 @@ std::string GeneratorExpressionContent::EvaluateParameters(
}
return std::string();
}
-
-GeneratorExpressionContent::~GeneratorExpressionContent()
-{
- cmDeleteAll(this->IdentifierChildren);
- std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
- cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>);
-}
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index b10bb5bda7..10496fd682 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -36,6 +37,9 @@ struct cmGeneratorExpressionEvaluator
cmGeneratorExpressionDAGChecker*) const = 0;
};
+using cmGeneratorExpressionEvaluatorVector =
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
+
struct TextContent : public cmGeneratorExpressionEvaluator
{
TextContent(const char* start, size_t length)
@@ -68,13 +72,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
{
GeneratorExpressionContent(const char* startContent, size_t length);
- void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier)
+ void SetIdentifier(cmGeneratorExpressionEvaluatorVector&& identifier)
{
this->IdentifierChildren = std::move(identifier);
}
void SetParameters(
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters)
+ std::vector<cmGeneratorExpressionEvaluatorVector>&& parameters)
{
this->ParamChildren = std::move(parameters);
}
@@ -102,12 +106,12 @@ private:
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit) const;
+ std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
+ const;
private:
- std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> ParamChildren;
+ cmGeneratorExpressionEvaluatorVector IdentifierChildren;
+ std::vector<cmGeneratorExpressionEvaluatorVector> ParamChildren;
const char* StartContent;
size_t ContentLength;
};
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 66f1c71f42..14478c22c7 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -14,6 +14,7 @@
#include <utility>
#include <cm/iterator>
+#include <cm/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
@@ -37,7 +38,6 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmString.hxx"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index d6cc6ab1c6..c2c9ef7230 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -6,7 +6,10 @@
#include <cstddef>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
+
#include "cmGeneratorExpressionEvaluator.h"
cmGeneratorExpressionParser::cmGeneratorExpressionParser(
@@ -17,7 +20,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser(
}
void cmGeneratorExpressionParser::Parse(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
it = this->Tokens.begin();
@@ -27,40 +30,38 @@ void cmGeneratorExpressionParser::Parse(
}
static void extendText(
- std::vector<cmGeneratorExpressionEvaluator*>& result,
+ cmGeneratorExpressionEvaluatorVector& result,
std::vector<cmGeneratorExpressionToken>::const_iterator it)
{
if (!result.empty() &&
(*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text) {
- TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(it->Length);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(it->Length);
} else {
- TextContent* textContent = new TextContent(it->Content, it->Length);
- result.push_back(textContent);
+ auto textContent = cm::make_unique<TextContent>(it->Content, it->Length);
+ result.push_back(std::move(textContent));
}
}
static void extendResult(
- std::vector<cmGeneratorExpressionEvaluator*>& result,
- const std::vector<cmGeneratorExpressionEvaluator*>& contents)
+ cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector& result,
+ cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector&& contents)
{
if (!result.empty() &&
(*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text &&
contents.front()->GetType() == cmGeneratorExpressionEvaluator::Text) {
- TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(
- static_cast<TextContent*>(contents.front())->GetLength());
- delete contents.front();
- cmAppend(result, contents.begin() + 1, contents.end());
- } else {
- cmAppend(result, contents);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(
+ cm::static_reference_cast<TextContent>(contents.front()).GetLength());
+ contents.erase(contents.begin());
}
+ cm::append(result, std::move(contents));
}
void cmGeneratorExpressionParser::ParseGeneratorExpression(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
assert(this->it != this->Tokens.end());
unsigned int nestedLevel = this->NestingLevel;
@@ -68,7 +69,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
auto startToken = this->it - 1;
- std::vector<cmGeneratorExpressionEvaluator*> identifier;
+ cmGeneratorExpressionEvaluatorVector identifier;
while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression &&
this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) {
if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) {
@@ -87,18 +88,18 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
if (this->it != this->Tokens.end() &&
this->it->TokenType == cmGeneratorExpressionToken::EndExpression) {
- GeneratorExpressionContent* content = new GeneratorExpressionContent(
+ auto content = cm::make_unique<GeneratorExpressionContent>(
startToken->Content,
this->it->Content - startToken->Content + this->it->Length);
assert(this->it != this->Tokens.end());
++this->it;
--this->NestingLevel;
content->SetIdentifier(std::move(identifier));
- result.push_back(content);
+ result.push_back(std::move(content));
return;
}
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters;
+ std::vector<cmGeneratorExpressionEvaluatorVector> parameters;
std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
commaTokens;
std::vector<cmGeneratorExpressionToken>::const_iterator colonToken;
@@ -169,7 +170,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
// treat the '$<' as having been plain text, along with the
// corresponding : and , tokens that might have been found.
extendText(result, startToken);
- extendResult(result, identifier);
+ extendResult(result, std::move(identifier));
if (!parameters.empty()) {
extendText(result, colonToken);
@@ -179,7 +180,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
assert(parameters.size() > commaTokens.size());
for (; pit != pend; ++pit, ++commaIt) {
if (!pit->empty() && !emptyParamTermination) {
- extendResult(result, *pit);
+ extendResult(result, std::move(*pit));
}
if (commaIt != commaTokens.end()) {
extendText(result, *commaIt);
@@ -193,15 +194,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
size_t contentLength =
((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length;
- GeneratorExpressionContent* content =
- new GeneratorExpressionContent(startToken->Content, contentLength);
+ auto content = cm::make_unique<GeneratorExpressionContent>(
+ startToken->Content, contentLength);
content->SetIdentifier(std::move(identifier));
content->SetParameters(std::move(parameters));
- result.push_back(content);
+ result.push_back(std::move(content));
}
void cmGeneratorExpressionParser::ParseContent(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
assert(this->it != this->Tokens.end());
switch (this->it->TokenType) {
@@ -213,17 +214,16 @@ void cmGeneratorExpressionParser::ParseContent(
// A comma in 'plain text' could have split text that should
// otherwise be continuous. Extend the last text content instead of
// creating a new one.
- TextContent* textContent =
- static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(this->it->Length);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(this->it->Length);
assert(this->it != this->Tokens.end());
++this->it;
return;
}
}
- cmGeneratorExpressionEvaluator* n =
- new TextContent(this->it->Content, this->it->Length);
- result.push_back(n);
+ auto n =
+ cm::make_unique<TextContent>(this->it->Content, this->it->Length);
+ result.push_back(std::move(n));
assert(this->it != this->Tokens.end());
++this->it;
return;
diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h
index e663496dae..1ba1654187 100644
--- a/Source/cmGeneratorExpressionParser.h
+++ b/Source/cmGeneratorExpressionParser.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <vector>
#include "cmGeneratorExpressionLexer.h"
@@ -15,11 +16,14 @@ struct cmGeneratorExpressionParser
{
cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens);
- void Parse(std::vector<cmGeneratorExpressionEvaluator*>& result);
+ using cmGeneratorExpressionEvaluatorVector =
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
+
+ void Parse(cmGeneratorExpressionEvaluatorVector& result);
private:
- void ParseContent(std::vector<cmGeneratorExpressionEvaluator*>&);
- void ParseGeneratorExpression(std::vector<cmGeneratorExpressionEvaluator*>&);
+ void ParseContent(cmGeneratorExpressionEvaluatorVector&);
+ void ParseGeneratorExpression(cmGeneratorExpressionEvaluatorVector&);
private:
std::vector<cmGeneratorExpressionToken>::const_iterator it;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 171c3ed395..ba2e31435b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -10,15 +10,14 @@
#include <cstdlib>
#include <cstring>
#include <iterator>
-#include <memory>
+#include <queue>
#include <sstream>
#include <unordered_set>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
-#include <queue>
-
#include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
@@ -26,6 +25,7 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
+#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
@@ -55,11 +55,11 @@ const char* cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
cmListFileBacktrace const& /* context */)
{
- return tgt->GetSourcesProperty();
+ return tgt->GetSourcesProperty().c_str();
}
template <>
-const char*
+const std::string&
cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>(
cmGeneratorTarget const* tgt)
{
@@ -67,7 +67,8 @@ cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>(
}
template <>
-const char* cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>(
+const std::string&
+cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, const std::string& config)
{
return tgt->GetLocation(config);
@@ -162,7 +163,8 @@ private:
cmListFileBacktrace Backtrace;
};
-cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry(
+std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>
+CreateTargetPropertyEntry(
const std::string& propertyValue,
cmListFileBacktrace backtrace = cmListFileBacktrace(),
bool evaluateForBuildsystem = false)
@@ -172,15 +174,18 @@ cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry(
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(propertyValue);
cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
- return new TargetPropertyEntryGenex(std::move(cge));
+ return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>(
+ cm::make_unique<TargetPropertyEntryGenex>(std::move(cge)));
}
- return new TargetPropertyEntryString(propertyValue, std::move(backtrace));
+ return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>(
+ cm::make_unique<TargetPropertyEntryString>(propertyValue,
+ std::move(backtrace)));
}
void CreatePropertyGeneratorExpressions(
cmStringRange entries, cmBacktraceRange backtraces,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+ std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items,
bool evaluateForBuildsystem = false)
{
auto btIt = backtraces.begin();
@@ -219,13 +224,13 @@ struct EvaluatedTargetPropertyEntry
EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
cmGeneratorTarget const* thisTarget, std::string const& config,
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
- cmGeneratorTarget::TargetPropertyEntry* entry)
+ cmGeneratorTarget::TargetPropertyEntry& entry)
{
- EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace());
- cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config,
- thisTarget, dagChecker, lang),
+ EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
+ cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config,
+ thisTarget, dagChecker, lang),
ee.Values);
- if (entry->GetHadContextSensitiveCondition()) {
+ if (entry.GetHadContextSensitiveCondition()) {
ee.ContextDependent = true;
}
return ee;
@@ -234,13 +239,14 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
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<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
+ in)
{
std::vector<EvaluatedTargetPropertyEntry> out;
out.reserve(in.size());
- for (cmGeneratorTarget::TargetPropertyEntry* entry : in) {
+ for (auto& entry : in) {
out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
- dagChecker, entry));
+ dagChecker, *entry));
}
return out;
}
@@ -304,29 +310,18 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->PolicyMap = t->GetPolicyMap();
}
-cmGeneratorTarget::~cmGeneratorTarget()
-{
- cmDeleteAll(this->IncludeDirectoriesEntries);
- cmDeleteAll(this->CompileOptionsEntries);
- cmDeleteAll(this->CompileFeaturesEntries);
- cmDeleteAll(this->CompileDefinitionsEntries);
- cmDeleteAll(this->LinkOptionsEntries);
- cmDeleteAll(this->LinkDirectoriesEntries);
- cmDeleteAll(this->PrecompileHeadersEntries);
- cmDeleteAll(this->SourceEntries);
- cmDeleteAll(this->LinkInformation);
-}
+cmGeneratorTarget::~cmGeneratorTarget() = default;
-const char* cmGeneratorTarget::GetSourcesProperty() const
+const std::string& cmGeneratorTarget::GetSourcesProperty() const
{
std::vector<std::string> values;
- for (TargetPropertyEntry* se : this->SourceEntries) {
+ for (auto& se : this->SourceEntries) {
values.push_back(se->GetInput());
}
static std::string value;
value.clear();
value = cmJoin(values, ";");
- return value.c_str();
+ return value;
}
cmGlobalGenerator* cmGeneratorTarget::GetGlobalGenerator() const
@@ -655,6 +650,7 @@ void cmGeneratorTarget::ClearSourcesCache()
this->KindedSourcesMap.clear();
this->LinkImplementationLanguageIsContextDependent = true;
this->Objects.clear();
+ this->VisitedConfigsForObjects.clear();
}
void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
@@ -744,7 +740,7 @@ void cmGeneratorTarget::GetObjectSources(
{
IMPLEMENT_VISIT(SourceKindObjectSource);
- if (!this->Objects.empty()) {
+ if (this->VisitedConfigsForObjects.count(config)) {
return;
}
@@ -753,16 +749,17 @@ void cmGeneratorTarget::GetObjectSources(
}
this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
+ this->VisitedConfigsForObjects.insert(config);
}
void cmGeneratorTarget::ComputeObjectMapping()
{
- if (!this->Objects.empty()) {
+ auto const& configs = this->Makefile->GetGeneratorConfigs();
+ std::set<std::string> configSet(configs.begin(), configs.end());
+ if (configSet == this->VisitedConfigsForObjects) {
return;
}
- std::vector<std::string> const& configs =
- this->Makefile->GetGeneratorConfigs();
for (std::string const& c : configs) {
std::vector<cmSourceFile const*> sourceFiles;
this->GetObjectSources(sourceFiles, c);
@@ -982,13 +979,15 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
{
if (!this->UtilityItemsDone) {
this->UtilityItemsDone = true;
- std::set<BT<std::string>> const& utilities = this->GetUtilities();
- for (BT<std::string> const& i : utilities) {
+ std::set<BT<std::pair<std::string, bool>>> const& utilities =
+ this->GetUtilities();
+ for (BT<std::pair<std::string, bool>> const& i : utilities) {
if (cmGeneratorTarget* gt =
- this->LocalGenerator->FindGeneratorTargetToUse(i.Value)) {
- this->UtilityItems.insert(cmLinkItem(gt, i.Backtrace));
+ this->LocalGenerator->FindGeneratorTargetToUse(i.Value.first)) {
+ this->UtilityItems.insert(cmLinkItem(gt, i.Value.second, i.Backtrace));
} else {
- this->UtilityItems.insert(cmLinkItem(i.Value, i.Backtrace));
+ this->UtilityItems.insert(
+ cmLinkItem(i.Value.first, i.Value.second, i.Backtrace));
}
}
}
@@ -1001,7 +1000,8 @@ void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data,
IMPLEMENT_VISIT(SourceKindXaml);
}
-const char* cmGeneratorTarget::GetLocation(const std::string& config) const
+const std::string& cmGeneratorTarget::GetLocation(
+ const std::string& config) const
{
static std::string location;
if (this->IsImported()) {
@@ -1010,7 +1010,7 @@ const char* cmGeneratorTarget::GetLocation(const std::string& config) const
} else {
location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
}
- return location.c_str();
+ return location;
}
std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands()
@@ -1041,13 +1041,13 @@ bool cmGeneratorTarget::IsImportedGloballyVisible() const
return this->Target->IsImportedGloballyVisible();
}
-const char* cmGeneratorTarget::GetLocationForBuild() const
+const std::string& cmGeneratorTarget::GetLocationForBuild() const
{
static std::string location;
if (this->IsImported()) {
location = this->Target->ImportedGetFullPath(
"", cmStateEnums::RuntimeBinaryArtifact);
- return location.c_str();
+ return location;
}
// Now handle the deprecated build-time configuration location.
@@ -1067,7 +1067,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
}
location += "/";
location += this->GetFullName("", cmStateEnums::RuntimeBinaryArtifact);
- return location.c_str();
+ return location;
}
bool cmGeneratorTarget::IsSystemIncludeDirectory(
@@ -1122,7 +1122,8 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
}
bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
- std::string const& prop, cmGeneratorExpressionContext* context) const
+ std::string const& prop, cmGeneratorExpressionContext* context,
+ bool usage_requirements_only) const
{
std::string const key = prop + '@' + context->Config;
auto i = this->MaybeInterfacePropertyExists.find(key);
@@ -1141,7 +1142,7 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
context->HeadTarget ? context->HeadTarget : this;
if (cmLinkInterfaceLibraries const* iface =
this->GetLinkInterfaceLibraries(context->Config, headTarget,
- true)) {
+ usage_requirements_only)) {
if (iface->HadHeadSensitiveCondition) {
// With a different head target we may get to a library with
// this interface property.
@@ -1151,7 +1152,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
// head target, so we can follow them.
for (cmLinkItem const& lib : iface->Libraries) {
if (lib.Target &&
- lib.Target->MaybeHaveInterfaceProperty(prop, context)) {
+ lib.Target->MaybeHaveInterfaceProperty(
+ prop, context, usage_requirements_only)) {
maybeInterfaceProp = true;
break;
}
@@ -1165,12 +1167,14 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
std::string cmGeneratorTarget::EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+ cmGeneratorExpressionDAGChecker* dagCheckerParent,
+ bool usage_requirements_only) const
{
std::string result;
// If the property does not appear transitively at all, we are done.
- if (!this->MaybeHaveInterfaceProperty(prop, context)) {
+ if (!this->MaybeHaveInterfaceProperty(prop, context,
+ usage_requirements_only)) {
return result;
}
@@ -1202,8 +1206,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
p, context->LG, context, headTarget, &dagChecker, this);
}
- if (cmLinkInterfaceLibraries const* iface =
- this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) {
+ if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
+ context->Config, headTarget, usage_requirements_only)) {
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
@@ -1217,8 +1221,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
context->EvaluateForBuildsystem, context->Backtrace,
context->Language);
std::string libResult = cmGeneratorExpression::StripEmptyListElements(
- lib.Target->EvaluateInterfaceProperty(prop, &libContext,
- &dagChecker));
+ lib.Target->EvaluateInterfaceProperty(prop, &libContext, &dagChecker,
+ usage_requirements_only));
if (!libResult.empty()) {
if (result.empty()) {
result = std::move(libResult);
@@ -1246,7 +1250,8 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<EvaluatedTargetPropertyEntry>& entries)
+ std::vector<EvaluatedTargetPropertyEntry>& entries,
+ bool usage_requirements_only = true)
{
if (cmLinkImplementationLibraries const* impl =
headTarget->GetLinkImplementationLibraries(config)) {
@@ -1259,9 +1264,9 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
cmGeneratorExpressionContext context(
headTarget->GetLocalGenerator(), config, false, headTarget,
headTarget, true, lib.Backtrace, lang);
- cmExpandList(
- lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker),
- ee.Values);
+ cmExpandList(lib.Target->EvaluateInterfaceProperty(
+ prop, &context, dagChecker, usage_requirements_only),
+ ee.Values);
ee.ContextDependent = context.HadContextSensitiveCondition;
entries.emplace_back(std::move(ee));
}
@@ -1672,6 +1677,19 @@ void cmGeneratorTarget::ComputeAllConfigSources() const
}
}
+std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const
+{
+ std::set<std::string> languages;
+ std::vector<AllConfigSource> const& sources = this->GetAllConfigSources();
+ for (AllConfigSource const& si : sources) {
+ std::string const& lang = si.Source->GetOrDetermineLanguage();
+ if (!lang.empty()) {
+ languages.emplace(lang);
+ }
+ }
+ return languages;
+}
+
std::string cmGeneratorTarget::GetCompilePDBName(
const std::string& config) const
{
@@ -2114,7 +2132,9 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree(
// If building directly for installation then the build tree install_name
// is the same as the install tree.
if (this->MacOSXUseInstallNameDir()) {
- return this->GetInstallNameDirForInstallTree();
+ std::string installPrefix =
+ this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ return this->GetInstallNameDirForInstallTree(config, installPrefix);
}
// Use the build tree directory for the target.
@@ -2132,7 +2152,8 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree(
return "";
}
-std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
+std::string cmGeneratorTarget::GetInstallNameDirForInstallTree(
+ const std::string& config, const std::string& installPrefix) const
{
if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
std::string dir;
@@ -2140,7 +2161,13 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
if (install_name_dir && *install_name_dir) {
- dir = cmStrCat(install_name_dir, '/');
+ dir = install_name_dir;
+ cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
+ dir =
+ cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config);
+ if (!dir.empty()) {
+ dir = cmStrCat(dir, '/');
+ }
}
}
if (!install_name_dir) {
@@ -2158,7 +2185,8 @@ cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const
return this->Target->GetBacktrace();
}
-const std::set<BT<std::string>>& cmGeneratorTarget::GetUtilities() const
+const std::set<BT<std::pair<std::string, bool>>>&
+cmGeneratorTarget::GetUtilities() const
{
return this->Target->GetUtilities();
}
@@ -2492,11 +2520,11 @@ 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_BOOTSTRAP)
+#if !defined(CMAKE_BOOTSTRAP)
info.DefFileGenerated =
info.WindowsExportAllSymbols || info.Sources.size() > 1;
#else
- // Our __create_def helper is only available on Windows.
+ // Our __create_def helper is not available during CMake bootstrap.
info.DefFileGenerated = false;
#endif
if (info.DefFileGenerated) {
@@ -2691,12 +2719,23 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
if (i == this->NameMap.end() || i->first != name) {
// Check if we know how to generate this file.
cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+ // If we failed to find a target or source and we have a relative path, it
+ // might be a valid source if made relative to the current binary
+ // directory.
+ if (!sources.Target && !sources.Source &&
+ !cmSystemTools::FileIsFullPath(name)) {
+ auto fullname =
+ cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
+ fullname = cmSystemTools::CollapseFullPath(
+ fullname, this->Makefile->GetHomeOutputDirectory());
+ sources = this->Makefile->GetSourcesWithOutput(fullname);
+ }
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());
+ this->GeneratorTarget->Target->AddUtility(t->GetName(), false);
}
if (cmSourceFile* sf = i->second.Source) {
// For now only follow the dependency if the source file is not a
@@ -2751,14 +2790,14 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
depLocation = cmSystemTools::CollapseFullPath(depLocation);
tLocation = cmSystemTools::CollapseFullPath(tLocation);
if (depLocation == tLocation) {
- this->GeneratorTarget->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util, false);
return true;
}
}
} else {
// The original name of the dependency was not a full path. It
// must name a target, so add the target-level dependency.
- this->GeneratorTarget->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util, false);
return true;
}
}
@@ -2786,7 +2825,7 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
// this project. Add the target-level dependency to make
// sure the executable is up to date before this custom
// command possibly runs.
- this->GeneratorTarget->Target->AddUtility(command);
+ this->GeneratorTarget->Target->AddUtility(command, true);
}
}
@@ -2801,7 +2840,7 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
}
for (cmGeneratorTarget* target : targets) {
- this->GeneratorTarget->Target->AddUtility(target->GetName());
+ this->GeneratorTarget->Target->AddUtility(target->GetName(), true);
}
// Queue the custom command dependencies.
@@ -3064,7 +3103,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
cmLinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config);
for (cmLinkImplItem const& lib : impl->Libraries) {
- std::string libDir = cmSystemTools::CollapseFullPath(lib.AsStr());
+ std::string libDir = cmSystemTools::CollapseFullPath(
+ lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
static cmsys::RegularExpression frameworkCheck(
"(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
@@ -3277,10 +3317,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
CM_FALLTHROUGH;
}
case cmPolicies::OLD: {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(configProp));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(configProp);
entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ this, config, language, &dagChecker, *entry));
} break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
@@ -3373,14 +3413,22 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
{ "OBJCXX", ".objcxx.hxx" }
};
- filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(),
- ".dir/cmake_pch", languageToExtension.at(language));
+ filename =
+ cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(), ".dir");
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ filename = cmStrCat(filename, "/", config);
+ }
+
+ filename =
+ cmStrCat(filename, "/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");
+ std::string firstHeaderOnDisk;
{
cmGeneratedFileStream file(
filename_tmp, false,
@@ -3404,6 +3452,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
} else {
file << "#include \"" << header_bt.Value << "\"\n";
}
+
+ if (cmSystemTools::FileExists(header_bt.Value) &&
+ firstHeaderOnDisk.empty()) {
+ firstHeaderOnDisk = header_bt.Value;
+ }
}
if (language == "CXX") {
file << "#endif // __cplusplus\n";
@@ -3415,6 +3468,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
file << pchEpilogue << "\n";
}
}
+
+ if (!firstHeaderOnDisk.empty()) {
+ cmFileTimes::Copy(firstHeaderOnDisk, filename_tmp);
+ }
+
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
}
@@ -3473,6 +3531,7 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
cmGeneratedFileStream file(filename_tmp);
file << "/* generated by CMake */\n";
}
+ cmFileTimes::Copy(pchHeader, filename_tmp);
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
}
@@ -3647,7 +3706,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
this->LinkOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, debugOptions,
"link options", OptionsParse::Shell);
@@ -3779,10 +3839,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
std::vector<std::string> options = cmExpandedList(linkOptions);
for (const auto& option : options) {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(option));
- entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(option);
+ entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
+ &dagChecker, *entry));
}
}
processOptions(this, entries, result, uniqueOptions, false,
@@ -3902,7 +3962,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
this->LinkDirectoriesEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processLinkDirectories(this, entries, result, uniqueDirectories,
debugDirectories);
@@ -3933,14 +3994,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
std::vector<std::string> depends = cmExpandedList(linkDepends);
for (const auto& depend : depends) {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(depend));
- entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(depend);
+ entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
+ &dagChecker, *entry));
}
}
AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, false, "link depends",
OptionsParse::None);
@@ -4720,9 +4782,9 @@ std::string intersect(const std::set<std::string>& s1,
}
void cmGeneratorTarget::CheckPropertyCompatibility(
- cmComputeLinkInformation* info, const std::string& config) const
+ cmComputeLinkInformation& info, const std::string& config) const
{
- const cmComputeLinkInformation::ItemVector& deps = info->GetItems();
+ const cmComputeLinkInformation::ItemVector& deps = info.GetItems();
std::set<std::string> emittedBools;
static const std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
@@ -5067,10 +5129,11 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
}
std::string interfaceProperty = "INTERFACE_" + p;
- std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter(
- p == "POSITION_INDEPENDENT_CODE" ? new cmGeneratorExpressionInterpreter(
- tgt->GetLocalGenerator(), config, tgt)
- : nullptr);
+ std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter;
+ if (p == "POSITION_INDEPENDENT_CODE") {
+ genexInterpreter = cm::make_unique<cmGeneratorExpressionInterpreter>(
+ tgt->GetLocalGenerator(), config, tgt);
+ }
for (cmGeneratorTarget const* theTarget : deps) {
// An error should be reported if one dependency
@@ -5217,32 +5280,41 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation(
auto i = this->LinkInformation.find(key);
if (i == this->LinkInformation.end()) {
// Compute information for this configuration.
- cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config);
- if (!info || !info->Compute()) {
- delete info;
- info = nullptr;
+ auto info = cm::make_unique<cmComputeLinkInformation>(this, config);
+ if (info && !info->Compute()) {
+ info.reset();
}
// Store the information for this configuration.
- cmTargetLinkInformationMap::value_type entry(key, info);
- i = this->LinkInformation.insert(entry).first;
+ i = this->LinkInformation.emplace(key, std::move(info)).first;
- if (info) {
- this->CheckPropertyCompatibility(info, config);
+ if (i->second) {
+ this->CheckPropertyCompatibility(*i->second, config);
}
}
- return i->second;
+ return i->second.get();
}
void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const
{
int patch;
- this->GetTargetVersion(false, major, minor, patch);
+ this->GetTargetVersion("VERSION", major, minor, patch);
}
-void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
- int& minor, int& patch) const
+void cmGeneratorTarget::GetTargetVersionFallback(
+ const std::string& property, const std::string& fallback_property,
+ int& major, int& minor, int& patch) const
+{
+ if (this->GetProperty(property)) {
+ this->GetTargetVersion(property, major, minor, patch);
+ } else {
+ this->GetTargetVersion(fallback_property, major, minor, patch);
+ }
+}
+
+void cmGeneratorTarget::GetTargetVersion(const std::string& property,
+ int& major, int& minor,
+ int& patch) const
{
// Set the default values.
major = 0;
@@ -5251,9 +5323,7 @@ void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
- // Look for a VERSION or SOVERSION property.
- const char* prop = soversion ? "SOVERSION" : "VERSION";
- if (const char* version = this->GetProperty(prop)) {
+ if (const char* version = this->GetProperty(property)) {
// Try to parse the version number and store the results that were
// successfully parsed.
int parsed_major;
@@ -5383,16 +5453,39 @@ void cmGeneratorTarget::ReportPropertyOrigin(
areport);
}
+bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
+ cmLocalGenerator const*& lg) const
+{
+ if (cmHasLiteralPrefix(n, CMAKE_DIRECTORY_ID_SEP)) {
+ cmDirectoryId const dirId = n.substr(sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
+ if (dirId.String.empty()) {
+ lg = this->LocalGenerator;
+ return true;
+ }
+ if (cmLocalGenerator const* otherLG =
+ this->GlobalGenerator->FindLocalGenerator(dirId)) {
+ lg = otherLG;
+ return true;
+ }
+ }
+ return false;
+}
+
void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
cmListFileBacktrace const& bt,
std::vector<cmLinkItem>& items) const
{
+ cmLocalGenerator const* lg = this->LocalGenerator;
for (std::string const& n : names) {
+ if (this->IsLinkLookupScope(n, lg)) {
+ continue;
+ }
+
std::string name = this->CheckCMP0004(n);
if (name == this->GetName() || name.empty()) {
continue;
}
- items.push_back(this->ResolveLinkItem(name, bt));
+ items.push_back(this->ResolveLinkItem(name, bt, lg));
}
}
@@ -5401,6 +5494,7 @@ void cmGeneratorTarget::ExpandLinkItems(
cmGeneratorTarget const* headTarget, bool usage_requirements_only,
std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
{
+ // Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
// The $<LINK_ONLY> expression may be in a link interface to specify private
@@ -6330,6 +6424,21 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
return lib;
}
+bool cmGeneratorTarget::IsDeprecated() const
+{
+ const char* deprecation = this->GetProperty("DEPRECATION");
+ return deprecation && *deprecation;
+}
+
+std::string cmGeneratorTarget::GetDeprecation() const
+{
+ // find DEPRECATION property
+ if (const char* deprecation = this->GetProperty("DEPRECATION")) {
+ return deprecation;
+ }
+ return std::string();
+}
+
void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
const std::string& config) const
{
@@ -6379,8 +6488,7 @@ bool cmGeneratorTarget::IsCSharpOnly() const
this->GetType() != cmStateEnums::EXECUTABLE) {
return false;
}
- std::set<std::string> languages;
- this->GetLanguages(languages, "");
+ std::set<std::string> languages = this->GetAllConfigCompileLanguages();
// Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
@@ -6462,6 +6570,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
const std::string& config, cmOptionalLinkImplementation& impl,
cmGeneratorTarget const* head) const
{
+ cmLocalGenerator const* lg = this->LocalGenerator;
cmStringRange entryRange = this->Target->GetLinkImplementationEntries();
cmBacktraceRange btRange = this->Target->GetLinkImplementationBacktraces();
cmBacktraceRange::const_iterator btIt = btRange.begin();
@@ -6470,6 +6579,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
end = entryRange.end();
le != end; ++le, ++btIt) {
std::vector<std::string> llibs;
+ // Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
cmGeneratorExpression ge(*btIt);
@@ -6482,6 +6592,10 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
}
for (std::string const& lib : llibs) {
+ if (this->IsLinkLookupScope(lib, lg)) {
+ continue;
+ }
+
// Skip entries that resolve to the target itself or are empty.
std::string name = this->CheckCMP0004(lib);
if (name == this->GetName() || name.empty()) {
@@ -6516,7 +6630,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
}
// The entry is meant for this configuration.
- impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt),
+ impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt, lg),
evaluated != *le);
}
@@ -6553,38 +6667,16 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
std::string const& name) const
{
- cmLocalGenerator const* lg = this->LocalGenerator;
- std::string const* lookupName = &name;
-
- // When target_link_libraries() is called with a LHS target that is
- // not created in the calling directory it adds a directory id suffix
- // that we can use to look up the calling directory. It is that scope
- // in which the item name is meaningful. This case is relatively rare
- // so we allocate a separate string only when the directory id is present.
- std::string::size_type pos = name.find(CMAKE_DIRECTORY_ID_SEP);
- std::string plainName;
- if (pos != std::string::npos) {
- // We will look up the plain name without the directory id suffix.
- plainName = name.substr(0, pos);
-
- // We will look up in the scope of the directory id.
- // If we do not recognize the id then leave the original
- // syntax in place to produce an indicative error later.
- cmDirectoryId const dirId =
- name.substr(pos + sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
- if (cmLocalGenerator const* otherLG =
- this->GlobalGenerator->FindLocalGenerator(dirId)) {
- lg = otherLG;
- lookupName = &plainName;
- }
- }
+ return this->ResolveTargetReference(name, this->LocalGenerator);
+}
+cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
+ std::string const& name, cmLocalGenerator const* lg) const
+{
TargetOrString resolved;
- if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(*lookupName)) {
+ if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(name)) {
resolved.Target = tgt;
- } else if (lookupName == &plainName) {
- resolved.String = std::move(plainName);
} else {
resolved.String = name;
}
@@ -6595,10 +6687,30 @@ cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
cmLinkItem cmGeneratorTarget::ResolveLinkItem(
std::string const& name, cmListFileBacktrace const& bt) const
{
- TargetOrString resolved = this->ResolveTargetReference(name);
+ return this->ResolveLinkItem(name, bt, this->LocalGenerator);
+}
+
+cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name,
+ cmListFileBacktrace const& bt,
+ cmLocalGenerator const* lg) const
+{
+ TargetOrString resolved = this->ResolveTargetReference(name, lg);
if (!resolved.Target) {
- return cmLinkItem(resolved.String, bt);
+ return cmLinkItem(resolved.String, false, bt);
+ }
+
+ // Check deprecation, issue message with `bt` backtrace.
+ if (resolved.Target->IsDeprecated()) {
+ std::ostringstream w;
+ /* clang-format off */
+ w <<
+ "The library that is being linked to, " << resolved.Target->GetName() <<
+ ", is marked as being deprecated by the owner. The message provided by "
+ "the developer is: \n" << resolved.Target->GetDeprecation() << "\n";
+ /* clang-format on */
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING, w.str(), bt);
}
// Skip targets that will not really be linked. This is probably a
@@ -6606,10 +6718,10 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(
// within the project.
if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE &&
!resolved.Target->IsExecutableWithExports()) {
- return cmLinkItem(resolved.Target->GetName(), bt);
+ return cmLinkItem(resolved.Target->GetName(), false, bt);
}
- return cmLinkItem(resolved.Target, bt);
+ return cmLinkItem(resolved.Target, false, bt);
}
std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 493eafcf01..d81bb3d851 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
@@ -45,7 +46,7 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
- const char* GetLocation(const std::string& config) const;
+ const std::string& GetLocation(const std::string& config) const;
std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
@@ -64,7 +65,7 @@ public:
/** Get the location of the target in the build tree with a placeholder
referencing the configuration in the native build system. This
location is suitable for use as the LOCATION target property. */
- const char* GetLocationForBuild() const;
+ const std::string& GetLocationForBuild() const;
cmComputeLinkInformation* GetLinkInformation(
const std::string& config) const;
@@ -125,7 +126,7 @@ public:
struct AllConfigSource
{
- cmSourceFile const* Source;
+ cmSourceFile* Source;
cmGeneratorTarget::SourceKind Kind;
std::vector<size_t> Configs;
};
@@ -134,6 +135,10 @@ public:
per-source configurations assigned. */
std::vector<AllConfigSource> const& GetAllConfigSources() const;
+ /** Get all languages used to compile sources in any configuration.
+ This excludes the languages of objects from object libraries. */
+ std::set<std::string> GetAllConfigCompileLanguages() const;
+
void GetObjectSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
const std::string& GetObjectName(cmSourceFile const* file);
@@ -245,6 +250,13 @@ public:
std::string GetAppBundleDirectory(const std::string& config,
BundleDirectoryLevel level) const;
+ /** Return whether this target is marked as deprecated by the
+ maintainer */
+ bool IsDeprecated() const;
+
+ /** Returns the deprecation message provided by the maintainer */
+ std::string GetDeprecation() const;
+
/** Return whether this target is an executable Bundle, a framework
or CFBundle on Apple. */
bool IsBundleOnApple() const;
@@ -274,11 +286,12 @@ public:
/** Return the install name directory for the target in the
* install tree. For example: "\@rpath/" or "\@loader_path/". */
- std::string GetInstallNameDirForInstallTree() const;
+ std::string GetInstallNameDirForInstallTree(
+ const std::string& config, const std::string& installPrefix) const;
cmListFileBacktrace GetBacktrace() const;
- std::set<BT<std::string>> const& GetUtilities() const;
+ std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
bool LinkLanguagePropagatesToDependents() const
{
@@ -365,9 +378,14 @@ public:
cmGeneratorTarget* Target = nullptr;
};
TargetOrString ResolveTargetReference(std::string const& name) const;
+ TargetOrString ResolveTargetReference(std::string const& name,
+ cmLocalGenerator const* lg) const;
cmLinkItem ResolveLinkItem(std::string const& name,
cmListFileBacktrace const& bt) const;
+ cmLinkItem ResolveLinkItem(std::string const& name,
+ cmListFileBacktrace const& bt,
+ cmLocalGenerator const* lg) const;
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
@@ -701,7 +719,8 @@ public:
std::string EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagCheckerParent) const;
+ cmGeneratorExpressionDAGChecker* dagCheckerParent,
+ bool usage_requirements_only = true) const;
bool HaveInstallTreeRPATH(const std::string& config) const;
@@ -736,14 +755,22 @@ public:
void GetTargetVersion(int& major, int& minor) const;
/** Get the target major, minor, and patch version numbers
- interpreted from the VERSION or SOVERSION property. Version 0
+ interpreted from the given property. Version 0
is returned if the property is not set or cannot be parsed. */
- void GetTargetVersion(bool soversion, int& major, int& minor,
+ void GetTargetVersion(std::string const& property, int& major, int& minor,
int& patch) const;
+ /** Get the target major, minor, and patch version numbers
+ interpreted from the given property and if empty use the
+ fallback property. Version 0 is returned if the property is
+ not set or cannot be parsed. */
+ void GetTargetVersionFallback(const std::string& property,
+ const std::string& fallback_property,
+ int& major, int& minor, int& patch) const;
+
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
- const char* GetSourcesProperty() const;
+ const std::string& GetSourcesProperty() const;
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -760,6 +787,7 @@ private:
};
using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
SourceEntriesType SourceDepends;
+ mutable std::set<std::string> VisitedConfigsForObjects;
mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName;
mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
@@ -816,10 +844,10 @@ private:
mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
using cmTargetLinkInformationMap =
- std::map<std::string, cmComputeLinkInformation*>;
+ std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>;
mutable cmTargetLinkInformationMap LinkInformation;
- void CheckPropertyCompatibility(cmComputeLinkInformation* info,
+ void CheckPropertyCompatibility(cmComputeLinkInformation& info,
const std::string& config) const;
struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
@@ -880,16 +908,20 @@ private:
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;
+ cmGeneratorExpressionContext* context,
+ bool usage_requirements_only) const;
+
+ using TargetPropertyEntryVector =
+ std::vector<std::unique_ptr<TargetPropertyEntry>>;
+
+ TargetPropertyEntryVector IncludeDirectoriesEntries;
+ TargetPropertyEntryVector CompileOptionsEntries;
+ TargetPropertyEntryVector CompileFeaturesEntries;
+ TargetPropertyEntryVector CompileDefinitionsEntries;
+ TargetPropertyEntryVector LinkOptionsEntries;
+ TargetPropertyEntryVector LinkDirectoriesEntries;
+ TargetPropertyEntryVector PrecompileHeadersEntries;
+ TargetPropertyEntryVector SourceEntries;
mutable std::set<std::string> LinkImplicitNullProperties;
mutable std::map<std::string, std::string> PchHeaders;
mutable std::map<std::string, std::string> PchSources;
@@ -900,6 +932,9 @@ private:
std::unordered_set<std::string> UnityBatchedSourceFiles;
+ bool IsLinkLookupScope(std::string const& n,
+ cmLocalGenerator const*& lg) const;
+
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config,
const cmGeneratorTarget* headTarget,
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 8e4352e29f..5e2248ed10 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -113,7 +113,7 @@ void cmGhsMultiTargetGenerator::Generate()
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
- this->Name.c_str());
+ this->Name);
this->GeneratorTarget->Target->SetProperty(
"GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
@@ -279,10 +279,10 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
std::string frameworkPath;
std::string linkPath;
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->GetGlobalGenerator()->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
this->LocalGenerator->GetTargetFlags(
linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx
index 481777345a..9ac5cd5cd0 100644
--- a/Source/cmGlobVerificationManager.cxx
+++ b/Source/cmGlobVerificationManager.cxx
@@ -38,6 +38,8 @@ bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
<< cmVersion::GetMajorVersion() << "."
<< cmVersion::GetMinorVersion() << "\n";
+ verifyScriptFile << "cmake_policy(SET CMP0009 NEW)\n";
+
for (auto const& i : this->Cache) {
CacheEntryKey k = std::get<0>(i);
CacheEntryValue v = std::get<1>(i);
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 51d681dee2..06943e7fff 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalBorlandMakefileGenerator.h"
+#include <utility>
+
+#include <cm/memory>
+
#include "cmDocumentationEntry.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -35,15 +39,14 @@ void cmGlobalBorlandMakefileGenerator::EnableLanguage(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalUnixMakefileGenerator3* lg =
- new cmLocalUnixMakefileGenerator3(this, mf);
+ auto lg = cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf);
lg->SetMakefileVariableSize(32);
lg->SetMakeCommandEscapeTargetTwice(true);
lg->SetBorlandMakeCurlyHack(true);
- return lg;
+ return std::unique_ptr<cmLocalGenerator>(std::move(lg));
}
void cmGlobalBorlandMakefileGenerator::GetDocumentation(
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index da04743ac0..9af0eac412 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalBorlandMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalNMakeMakefileGenerator.h"
@@ -16,10 +17,10 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalBorlandMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalBorlandMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalBorlandMakefileGenerator>());
}
//! Get the name for the generator.
@@ -33,7 +34,8 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9fa4467b2a..e04eef1b44 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalCommonGenerator.h"
+#include <memory>
#include <utility>
#include "cmGeneratorTarget.h"
@@ -24,15 +25,15 @@ std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
cmGlobalCommonGenerator::ComputeDirectoryTargets() const
{
std::map<std::string, DirectoryTarget> dirTargets;
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
std::string const& currentBinaryDir(
lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
- dirTarget.LG = lg;
+ dirTarget.LG = lg.get();
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
- for (auto gt : lg->GetGeneratorTargets()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType const type = gt->GetType();
if (type != cmStateEnums::EXECUTABLE &&
type != cmStateEnums::STATIC_LIBRARY &&
@@ -43,7 +44,7 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const
continue;
}
DirectoryTarget::Target t;
- t.GT = gt;
+ t.GT = gt.get();
if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
if (cmIsOn(exclude)) {
// This target has been explicitly excluded.
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 09fb87dd70..6a2d4c77cc 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -7,9 +7,13 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <functional>
#include <initializer_list>
#include <iterator>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -31,6 +35,7 @@
#include "cmGeneratorTarget.h"
#include "cmInstallGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
@@ -121,6 +126,7 @@ Json::Value cmGlobalGenerator::GetJson() const
{
Json::Value generator = Json::objectValue;
generator["name"] = this->GetName();
+ generator["multiConfig"] = this->IsMultiConfig();
return generator;
}
#endif
@@ -165,7 +171,7 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
return false;
}
-bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
+bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, bool,
cmMakefile* mf)
{
if (ts.empty()) {
@@ -264,8 +270,8 @@ void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
void cmGlobalGenerator::AddBuildExportExportSet(
cmExportBuildFileGenerator* gen)
{
- this->BuildExportSets[gen->GetMainExportFileName()] = gen;
this->BuildExportExportSets[gen->GetMainExportFileName()] = gen;
+ this->AddBuildExportSet(gen);
}
bool cmGlobalGenerator::GenerateImportFile(const std::string& file)
@@ -275,13 +281,11 @@ bool cmGlobalGenerator::GenerateImportFile(const std::string& file)
bool result = it->second->GenerateImportFile();
if (!this->ConfigureDoneCMP0026AndCMP0024) {
- for (cmMakefile* m : this->Makefiles) {
+ for (const auto& m : this->Makefiles) {
m->RemoveExportBuildFileGeneratorCMP0024(it->second);
}
}
- delete it->second;
- it->second = nullptr;
this->BuildExportSets.erase(it);
return result;
}
@@ -295,8 +299,8 @@ void cmGlobalGenerator::ForceLinkerLanguages()
bool cmGlobalGenerator::CheckTargetsForMissingSources() const
{
bool failed = false;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ for (const auto& localGen : this->LocalGenerators) {
+ for (const auto& target : localGen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::TargetType::UTILITY ||
@@ -335,8 +339,8 @@ bool cmGlobalGenerator::CheckTargetsForType() const
return false;
}
bool failed = false;
- for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ for (const auto& generator : this->LocalGenerators) {
+ for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::EXECUTABLE &&
target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
std::vector<std::string> const& configs =
@@ -363,8 +367,8 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
return false;
}
bool failed = false;
- for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ for (const auto& generator : this->LocalGenerators) {
+ for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::TargetType::UTILITY ||
@@ -650,7 +654,7 @@ void cmGlobalGenerator::EnableLanguage(
// Tell the generator about the toolset, if any.
std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
- if (!this->SetGeneratorToolset(toolset, mf)) {
+ if (!this->SetGeneratorToolset(toolset, false, mf)) {
cmSystemTools::SetFatalErrorOccured();
return;
}
@@ -1199,13 +1203,12 @@ void cmGlobalGenerator::ClearEnabledLanguages()
void cmGlobalGenerator::CreateLocalGenerators()
{
this->LocalGeneratorSearchIndex.clear();
- cmDeleteAll(this->LocalGenerators);
this->LocalGenerators.clear();
this->LocalGenerators.reserve(this->Makefiles.size());
- for (cmMakefile* m : this->Makefiles) {
- cmLocalGenerator* lg = this->CreateLocalGenerator(m);
- this->LocalGenerators.push_back(lg);
- this->IndexLocalGenerator(lg);
+ for (const auto& m : this->Makefiles) {
+ auto lg = this->CreateLocalGenerator(m.get());
+ this->IndexLocalGenerator(lg.get());
+ this->LocalGenerators.push_back(std::move(lg));
}
}
@@ -1221,9 +1224,10 @@ void cmGlobalGenerator::Configure()
snapshot.GetDirectory().SetCurrentBinary(
this->CMakeInstance->GetHomeOutputDirectory());
- cmMakefile* dirMf = new cmMakefile(this, snapshot);
+ auto dirMfu = cm::make_unique<cmMakefile>(this, snapshot);
+ auto dirMf = dirMfu.get();
+ this->Makefiles.push_back(std::move(dirMfu));
dirMf->SetRecursionDepth(this->RecursionDepth);
- this->Makefiles.push_back(dirMf);
this->IndexMakefile(dirMf);
this->BinaryDirectories.insert(
@@ -1241,11 +1245,11 @@ void cmGlobalGenerator::Configure()
std::vector<GlobalTargetInfo> globalTargets;
this->CreateDefaultGlobalTargets(globalTargets);
- for (cmMakefile* mf : this->Makefiles) {
+ for (const auto& mf : this->Makefiles) {
auto& targets = mf->GetTargets();
for (GlobalTargetInfo const& globalTarget : globalTargets) {
targets.emplace(globalTarget.Name,
- this->CreateGlobalTarget(globalTarget, mf));
+ this->CreateGlobalTarget(globalTarget, mf.get()));
}
}
}
@@ -1258,10 +1262,6 @@ void cmGlobalGenerator::Configure()
"number of local generators",
cmStateEnums::INTERNAL);
- // check for link libraries and include directories containing "NOTFOUND"
- // and for infinite loops
- this->CheckTargetProperties();
-
if (this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE) {
std::ostringstream msg;
if (cmSystemTools::GetErrorOccuredFlag()) {
@@ -1284,6 +1284,10 @@ void cmGlobalGenerator::Configure()
void cmGlobalGenerator::CreateGenerationObjects(TargetTypes targetTypes)
{
this->CreateLocalGenerators();
+ // Commit side effects only if we are actually generating
+ if (this->GetConfigureDoneCMP0026()) {
+ this->CheckTargetProperties();
+ }
this->CreateGeneratorTargets(targetTypes);
this->ComputeBuildFileGenerators();
}
@@ -1294,8 +1298,11 @@ void cmGlobalGenerator::CreateImportedGenerationObjects(
{
this->CreateGenerationObjects(ImportedOnly);
auto const mfit =
- std::find(this->Makefiles.begin(), this->Makefiles.end(), mf);
- cmLocalGenerator* lg =
+ std::find_if(this->Makefiles.begin(), this->Makefiles.end(),
+ [mf](const std::unique_ptr<cmMakefile>& item) {
+ return item.get() == mf;
+ });
+ auto& lg =
this->LocalGenerators[std::distance(this->Makefiles.begin(), mfit)];
for (std::string const& t : targets) {
cmGeneratorTarget* gt = lg->FindGeneratorTargetToUse(t);
@@ -1345,16 +1352,51 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
void cmGlobalGenerator::ComputeBuildFileGenerators()
{
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- std::vector<cmExportBuildFileGenerator*> gens =
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const& gens =
this->Makefiles[i]->GetExportBuildFileGenerators();
- for (cmExportBuildFileGenerator* g : gens) {
- g->Compute(this->LocalGenerators[i]);
+ for (std::unique_ptr<cmExportBuildFileGenerator> const& g : gens) {
+ g->Compute(this->LocalGenerators[i].get());
}
}
}
+bool cmGlobalGenerator::UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const
+{
+ if (!supported && this->Makefiles.front()->GetDefinition(name)) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support variable\n"
+ " " << name << "\n"
+ "but it has been specified."
+ ;
+ /* clang-format on */
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return true;
+ }
+
+ return false;
+}
+
bool cmGlobalGenerator::Compute()
{
+ // Make sure unsupported variables are not used.
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_BUILD_TYPE",
+ this->SupportsDefaultBuildType())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_CROSS_CONFIGS",
+ this->SupportsCrossConfigs())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_CONFIGS",
+ this->SupportsDefaultConfigs())) {
+ return false;
+ }
+
// Some generators track files replaced during the Generate.
// Start with an empty vector:
this->FilesReplacedDuringGenerate.clear();
@@ -1387,7 +1429,7 @@ bool cmGlobalGenerator::Compute()
}
// Add generator specific helper commands
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->AddHelperCommands();
}
@@ -1397,16 +1439,16 @@ bool cmGlobalGenerator::Compute()
// on the original cmTarget instance. It accumulates features
// across all configurations. Some refactoring is needed to
// compute a per-config resulta purely during generation.
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
if (!localGen->ComputeTargetCompileFeatures()) {
return false;
}
}
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
cmMakefile* mf = localGen->GetMakefile();
- for (cmInstallGenerator* g : mf->GetInstallGenerators()) {
- if (!g->Compute(localGen)) {
+ for (const auto& g : mf->GetInstallGenerators()) {
+ if (!g->Compute(localGen.get())) {
return false;
}
}
@@ -1416,7 +1458,7 @@ bool cmGlobalGenerator::Compute()
// Trace the dependencies, after that no custom commands should be added
// because their dependencies might not be handled correctly
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->TraceDependencies();
}
@@ -1428,7 +1470,7 @@ bool cmGlobalGenerator::Compute()
this->ForceLinkerLanguages();
// Compute the manifest of main targets generated.
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->ComputeTargetManifest();
}
@@ -1445,7 +1487,7 @@ bool cmGlobalGenerator::Compute()
return false;
}
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->ComputeHomeRelativeOutputPath();
}
@@ -1460,6 +1502,8 @@ void cmGlobalGenerator::Generate()
this->ProcessEvaluationFiles();
+ this->CMakeInstance->UpdateProgress("Generating", 0.1f);
+
// Generate project files
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile());
@@ -1471,8 +1515,9 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->GenerateTestFiles();
this->CMakeInstance->UpdateProgress(
"Generating",
- (static_cast<float>(i) + 1.0f) /
- static_cast<float>(this->LocalGenerators.size()));
+ 0.1f +
+ 0.9f * (static_cast<float>(i) + 1.0f) /
+ static_cast<float>(this->LocalGenerators.size()));
}
this->SetCurrentMakefile(nullptr);
@@ -1555,40 +1600,42 @@ bool cmGlobalGenerator::QtAutoGen()
bool cmGlobalGenerator::AddAutomaticSources()
{
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
lg->CreateEvaluationFileOutputs();
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
gt->GetType() == cmStateEnums::UTILITY ||
gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
continue;
}
- lg->AddUnityBuild(gt);
- lg->AddPchDependencies(gt);
+ lg->AddUnityBuild(gt.get());
+ lg->AddPchDependencies(gt.get());
}
}
// The above transformations may have changed the classification of sources.
// Clear the source list and classification cache (KindedSources) of all
// targets so that it will be recomputed correctly by the generators later
// now that the above transformations are done for all targets.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
gt->ClearSourcesCache();
}
}
return true;
}
-cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer> cmGlobalGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) const
{
- return new cmLinkLineComputer(outputConverter, stateDir);
+ return cm::make_unique<cmLinkLineComputer>(outputConverter, stateDir);
}
-cmLinkLineComputer* cmGlobalGenerator::CreateMSVC60LinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmGlobalGenerator::CreateMSVC60LinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) const
{
- return new cmMSVC60LinkLineComputer(outputConverter, stateDir);
+ return std::unique_ptr<cmLinkLineComputer>(
+ cm::make_unique<cmMSVC60LinkLineComputer>(outputConverter, stateDir));
}
void cmGlobalGenerator::FinalizeTargetCompileInfo()
@@ -1597,7 +1644,7 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
this->CMakeInstance->GetState()->GetEnabledLanguages();
// Construct per-target generator information.
- for (cmMakefile* mf : this->Makefiles) {
+ for (const auto& mf : this->Makefiles) {
const cmStringRange noconfig_compile_definitions =
mf->GetCompileDefinitionsEntries();
const cmBacktraceRange noconfig_compile_definitions_bts =
@@ -1632,7 +1679,9 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
for (std::string const& c : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
- t->AppendProperty(defPropName, mf->GetProperty(defPropName));
+ if (const char* val = mf->GetProperty(defPropName)) {
+ t->AppendProperty(defPropName, val);
+ }
}
}
}
@@ -1661,8 +1710,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(
if (targetTypes == AllTargets) {
for (auto& target : mf->GetTargets()) {
cmTarget* t = &target.second;
- cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
- lg->AddGeneratorTarget(gt);
+ lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(t, lg));
}
}
@@ -1675,31 +1723,28 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
{
std::map<cmTarget*, cmGeneratorTarget*> importedMap;
for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
- cmMakefile* mf = this->Makefiles[i];
- for (cmTarget* ownedImpTgt : mf->GetOwnedImportedTargets()) {
- cmLocalGenerator* lg = this->LocalGenerators[i];
- cmGeneratorTarget* gt = new cmGeneratorTarget(ownedImpTgt, lg);
- lg->AddOwnedImportedGeneratorTarget(gt);
- importedMap[ownedImpTgt] = gt;
+ auto& mf = this->Makefiles[i];
+ for (const auto& ownedImpTgt : mf->GetOwnedImportedTargets()) {
+ cmLocalGenerator* lg = this->LocalGenerators[i].get();
+ auto gt = cm::make_unique<cmGeneratorTarget>(ownedImpTgt.get(), lg);
+ importedMap[ownedImpTgt.get()] = gt.get();
+ lg->AddOwnedImportedGeneratorTarget(std::move(gt));
}
}
// Construct per-target generator information.
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- this->CreateGeneratorTargets(targetTypes, this->Makefiles[i],
- this->LocalGenerators[i], importedMap);
+ this->CreateGeneratorTargets(targetTypes, this->Makefiles[i].get(),
+ this->LocalGenerators[i].get(), importedMap);
}
}
void cmGlobalGenerator::ClearGeneratorMembers()
{
- cmDeleteAll(this->BuildExportSets);
this->BuildExportSets.clear();
- cmDeleteAll(this->Makefiles);
this->Makefiles.clear();
- cmDeleteAll(this->LocalGenerators);
this->LocalGenerators.clear();
this->AliasTargets.clear();
@@ -1722,12 +1767,12 @@ void cmGlobalGenerator::ComputeTargetObjectDirectory(
void cmGlobalGenerator::CheckTargetProperties()
{
+ // check for link libraries and include directories containing "NOTFOUND"
+ // and for infinite loops
std::map<std::string, std::string> notFoundMap;
- // std::set<std::string> notFoundMap;
- // after it is all done do a ConfigureFinalPass
cmState* state = this->GetCMakeInstance()->GetState();
for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
- this->Makefiles[i]->ConfigureFinalPass();
+ this->Makefiles[i]->Generate(*this->LocalGenerators[i]);
for (auto const& target : this->Makefiles[i]->GetTargets()) {
if (target.second.GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
@@ -1771,11 +1816,6 @@ void cmGlobalGenerator::CheckTargetProperties()
}
}
}
- this->CMakeInstance->UpdateProgress(
- "Configuring",
- 0.9f +
- 0.1f * (static_cast<float>(i) + 1.0f) /
- static_cast<float>(this->Makefiles.size()));
}
if (!notFoundMap.empty()) {
@@ -1872,6 +1912,10 @@ int cmGlobalGenerator::Build(
output += "\n";
return 1;
}
+ std::string realConfig = config;
+ if (realConfig.empty()) {
+ realConfig = this->GetDefaultBuildConfig();
+ }
int retVal = 0;
cmSystemTools::SetRunCommandHideConsole(true);
@@ -1880,7 +1924,7 @@ int cmGlobalGenerator::Build(
std::vector<GeneratedMakeCommand> makeCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets,
- config, fast, jobs, verbose, nativeOptions);
+ realConfig, fast, jobs, verbose, nativeOptions);
// Workaround to convince some commands to produce output.
if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
@@ -1892,7 +1936,7 @@ int cmGlobalGenerator::Build(
if (clean) {
std::vector<GeneratedMakeCommand> cleanCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
- { "clean" }, config, fast, jobs, verbose);
+ { "clean" }, realConfig, fast, jobs, verbose);
output += "\nRun Clean Command:";
output += cleanCommand.front().Printable();
output += "\n";
@@ -1999,10 +2043,10 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
return makeCommand;
}
-void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
+void cmGlobalGenerator::AddMakefile(std::unique_ptr<cmMakefile> mf)
{
- this->Makefiles.push_back(mf);
- this->IndexMakefile(mf);
+ this->IndexMakefile(mf.get());
+ this->Makefiles.push_back(std::move(mf));
// update progress
// estimate how many lg there will be
@@ -2025,10 +2069,10 @@ void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
}
int numGen = atoi(numGenC->c_str());
- float prog = 0.9f * static_cast<float>(this->Makefiles.size()) /
- static_cast<float>(numGen);
- if (prog > 0.9f) {
- prog = 0.9f;
+ float prog =
+ static_cast<float>(this->Makefiles.size()) / static_cast<float>(numGen);
+ if (prog > 1.0f) {
+ prog = 1.0f;
}
this->CMakeInstance->UpdateProgress("Configuring", prog);
}
@@ -2045,9 +2089,10 @@ void cmGlobalGenerator::EnableInstallTarget()
this->InstallTargetEnabled = true;
}
-cmLocalGenerator* cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalGenerator(this, mf);
+ return cm::make_unique<cmLocalGenerator>(this, mf);
}
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator* gen,
@@ -2142,7 +2187,7 @@ int cmGlobalGenerator::GetLinkerPreference(const std::string& lang) const
void cmGlobalGenerator::FillProjectMap()
{
this->ProjectMap.clear(); // make sure we start with a clean map
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
// for each local generator add all projects
cmStateSnapshot snp = localGen->GetStateSnapshot();
std::string name;
@@ -2150,7 +2195,7 @@ void cmGlobalGenerator::FillProjectMap()
std::string snpProjName = snp.GetProjectName();
if (name != snpProjName) {
name = snpProjName;
- this->ProjectMap[name].push_back(localGen);
+ this->ProjectMap[name].push_back(localGen.get());
}
snp = snp.GetBuildsystemDirectoryParent();
} while (snp.IsValid());
@@ -2353,7 +2398,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(
void cmGlobalGenerator::AddGlobalTarget_Package(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
std::string configFile =
cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
@@ -2402,7 +2447,7 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource(
return;
}
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
std::string configFile =
cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackSourceConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
@@ -2434,7 +2479,7 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource(
void cmGlobalGenerator::AddGlobalTarget_Test(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
if (!mf->IsOn("CMAKE_TESTING_ENABLED")) {
return;
}
@@ -2454,6 +2499,13 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
+ if (auto testArgs = mf->GetDefinition("CMAKE_CTEST_ARGUMENTS")) {
+ std::vector<std::string> args;
+ cmExpandList(testArgs, args);
+ for (auto const& arg : args) {
+ singleLine.push_back(arg);
+ }
+ }
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
singleLine.push_back("-C");
singleLine.push_back(cmakeCfgIntDir);
@@ -2475,6 +2527,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
}
GlobalTargetInfo gti;
gti.Name = editCacheTargetName;
+ gti.PerConfig = false;
cmCustomCommandLine singleLine;
// Use generator preference for the edit_cache rule if it is defined.
@@ -2509,8 +2562,10 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
gti.Name = rebuildCacheTargetName;
gti.Message = "Running CMake to regenerate build system...";
gti.UsesTerminal = true;
+ gti.PerConfig = false;
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCMakeCommand());
+ singleLine.push_back("--regenerate-during-build");
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.CommandLines.push_back(std::move(singleLine));
@@ -2520,7 +2575,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
void cmGlobalGenerator::AddGlobalTarget_Install(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
bool skipInstallRules = mf->IsOn("CMAKE_SKIP_INSTALL_RULES");
if (this->InstallTargetEnabled && skipInstallRules) {
@@ -2570,7 +2625,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
singleLine.push_back(cmd);
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
std::string cfgArg = "-DBUILD_TYPE=";
- bool useEPN = this->UseEffectivePlatformName(mf);
+ bool useEPN = this->UseEffectivePlatformName(mf.get());
if (useEPN) {
cfgArg += "$(CONFIGURATION)";
singleLine.push_back(cfgArg);
@@ -2653,22 +2708,22 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
{
// Package
cmTarget target(gti.Name, cmStateEnums::GLOBAL_TARGET,
- cmTarget::VisibilityNormal, mf);
+ cmTarget::VisibilityNormal, mf, gti.PerConfig);
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
std::vector<std::string> no_outputs;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
// Store the custom command in the target.
- cmCustomCommand cc(nullptr, no_outputs, no_byproducts, no_depends,
- gti.CommandLines, nullptr, gti.WorkingDir.c_str());
+ cmCustomCommand cc(no_outputs, no_byproducts, no_depends, gti.CommandLines,
+ cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str());
cc.SetUsesTerminal(gti.UsesTerminal);
target.AddPostBuildCommand(std::move(cc));
if (!gti.Message.empty()) {
- target.SetProperty("EchoString", gti.Message.c_str());
+ target.SetProperty("EchoString", gti.Message);
}
for (std::string const& d : gti.Depends) {
- target.AddUtility(d);
+ target.AddUtility(d, false);
}
// Organize in the "predefined targets" folder:
@@ -2737,9 +2792,9 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
- cmExternalMakefileProjectGenerator* extraGenerator)
+ std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator)
{
- this->ExtraGenerator.reset(extraGenerator);
+ this->ExtraGenerator = std::move(extraGenerator);
if (this->ExtraGenerator) {
this->ExtraGenerator->SetGlobalGenerator(this);
}
@@ -2765,27 +2820,26 @@ void cmGlobalGenerator::GetFilesReplacedDuringGenerate(
std::back_inserter(filenames));
}
-void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
- TargetDependSet& originalTargets,
- cmLocalGenerator* root,
- GeneratorVector const& generators)
+void cmGlobalGenerator::GetTargetSets(
+ TargetDependSet& projectTargets, TargetDependSet& originalTargets,
+ cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{
// loop over all local generators
- for (cmLocalGenerator* generator : generators) {
+ for (auto generator : generators) {
// check to make sure generator is not excluded
if (this->IsExcluded(root, generator)) {
continue;
}
// loop over all the generator targets in the makefile
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
- if (this->IsRootOnlyTarget(target) &&
+ for (const auto& target : generator->GetGeneratorTargets()) {
+ if (this->IsRootOnlyTarget(target.get()) &&
target->GetLocalGenerator() != root) {
continue;
}
// put the target in the set of original targets
- originalTargets.insert(target);
+ originalTargets.insert(target.get());
// Get the set of targets that depend on target
- this->AddTargetDepends(target, projectTargets);
+ this->AddTargetDepends(target.get(), projectTargets);
}
}
}
@@ -2961,12 +3015,12 @@ void cmGlobalGenerator::WriteSummary()
"/CMakeFiles/TargetDirectories.txt");
cmGeneratedFileStream fout(fname);
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& tgt : lg->GetGeneratorTargets()) {
if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->WriteSummary(tgt);
+ this->WriteSummary(tgt.get());
fout << tgt->GetSupportDirectory() << "\n";
}
}
@@ -3108,10 +3162,20 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const
return this->FilenameTargetDepends[sf];
}
+const std::string& cmGlobalGenerator::GetRealPath(const std::string& dir)
+{
+ auto i = this->RealPaths.lower_bound(dir);
+ if (i == this->RealPaths.end() ||
+ this->RealPaths.key_comp()(dir, i->first)) {
+ i = this->RealPaths.emplace_hint(i, dir, cmSystemTools::GetRealPath(dir));
+ }
+ return i->second;
+}
+
void cmGlobalGenerator::ProcessEvaluationFiles()
{
std::vector<std::string> generatedFiles;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (auto& localGen : this->LocalGenerators) {
localGen->ProcessEvaluationFiles(generatedFiles);
}
}
@@ -3127,7 +3191,7 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
cmake::InstalledFilesMap const& installedFiles =
this->CMakeInstance->GetInstalledFiles();
- cmLocalGenerator* lg = this->LocalGenerators[0];
+ const auto& lg = this->LocalGenerators[0];
cmMakefile* mf = lg->GetMakefile();
std::vector<std::string> configs;
@@ -3146,8 +3210,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
for (auto const& i : installedFiles) {
cmInstalledFile const& installedFile = i.second;
- cmCPackPropertiesGenerator cpackPropertiesGenerator(lg, installedFile,
- configs);
+ cmCPackPropertiesGenerator cpackPropertiesGenerator(
+ lg.get(), installedFile, configs);
cpackPropertiesGenerator.Generate(file, config, configs);
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index f25ff7b77e..7dc4822382 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -14,9 +14,10 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cm_codecvt.hxx"
-#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
@@ -43,6 +44,7 @@ class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
class cmSourceFile;
+class cmState;
class cmStateDirectory;
class cmake;
@@ -71,7 +73,7 @@ struct GeneratedMakeCommand
void Add(std::vector<std::string>::const_iterator start,
std::vector<std::string>::const_iterator end)
{
- cmAppend(PrimaryCommand, start, end);
+ cm::append(PrimaryCommand, start, end);
}
std::string Printable() const { return cmJoin(PrimaryCommand, " "); }
@@ -90,11 +92,14 @@ struct GeneratedMakeCommand
class cmGlobalGenerator
{
public:
+ using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
+
//! Free any memory allocated with the GlobalGenerator
cmGlobalGenerator(cmake* cm);
virtual ~cmGlobalGenerator();
- virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
+ virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf);
//! Get the name for this generator
virtual std::string GetName() const { return "Generic"; }
@@ -128,7 +133,14 @@ public:
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
- virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ virtual bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf);
+
+ /** Read any other cache entries needed for cmake --build. */
+ virtual bool ReadCacheEntriesForBuild(const cmState& /*state*/)
+ {
+ return true;
+ }
/**
* Create LocalGenerators and process the CMakeLists files. This does not
@@ -157,11 +169,11 @@ public:
*/
virtual void Generate();
- virtual cmLinkLineComputer* CreateLinkLineComputer(
+ virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const;
- cmLinkLineComputer* CreateMSVC60LinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const;
@@ -244,11 +256,11 @@ public:
cmake* GetCMakeInstance() const { return this->CMakeInstance; }
void SetConfiguredFilesPath(cmGlobalGenerator* gen);
- const std::vector<cmMakefile*>& GetMakefiles() const
+ const std::vector<std::unique_ptr<cmMakefile>>& GetMakefiles() const
{
return this->Makefiles;
}
- const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+ const LocalGeneratorVector& GetLocalGenerators() const
{
return this->LocalGenerators;
}
@@ -263,11 +275,11 @@ public:
this->CurrentConfigureMakefile = mf;
}
- void AddMakefile(cmMakefile* mf);
+ void AddMakefile(std::unique_ptr<cmMakefile> mf);
//! Set an generator for an "external makefile based project"
void SetExternalMakefileProjectGenerator(
- cmExternalMakefileProjectGenerator* extraGenerator);
+ std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator);
std::string GetExtraGeneratorName() const;
@@ -377,6 +389,9 @@ public:
// Lookup edit_cache target command preferred by this generator.
virtual std::string GetEditCacheCommand() const { return ""; }
+ // Default config to use for cmake --build
+ virtual std::string GetDefaultBuildConfig() const { return "Debug"; }
+
// Class to track a set of dependencies.
using TargetDependSet = cmTargetDependSet;
@@ -410,6 +425,8 @@ public:
virtual bool IsXcode() const { return false; }
+ virtual bool IsVisualStudio() const { return false; }
+
/** Return true if we know the exact location of object files.
If false, store the reason in the given string.
This is meaningful only after EnableLanguage has been called. */
@@ -431,11 +448,17 @@ public:
MacFolder. */
virtual bool ShouldStripResourcePath(cmMakefile*) const;
+ virtual bool SupportsCustomCommandDepfile() const { return false; }
+
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
+ virtual bool SupportsDefaultBuildType() const { return false; }
+ virtual bool SupportsCrossConfigs() const { return false; }
+ virtual bool SupportsDefaultConfigs() const { return false; }
+
static std::string EscapeJSON(const std::string& s);
void ProcessEvaluationFiles();
@@ -444,8 +467,8 @@ public:
{
return this->BuildExportSets;
}
- void AddBuildExportSet(cmExportBuildFileGenerator*);
- void AddBuildExportExportSet(cmExportBuildFileGenerator*);
+ void AddBuildExportSet(cmExportBuildFileGenerator* gen);
+ void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
bool IsExportedTargetsFile(const std::string& filename) const;
bool GenerateImportFile(const std::string& file);
cmExportBuildFileGenerator* GetExportedTargetsFile(
@@ -475,13 +498,19 @@ public:
int RecursionDepth;
+ virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
+ {
+ configs.emplace_back("$<CONFIG>");
+ }
+
+ std::string const& GetRealPath(std::string const& dir);
+
protected:
- 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,
TargetDependSet& originalTargets, cmLocalGenerator* root,
- GeneratorVector const&);
+ std::vector<cmLocalGenerator*>& generators);
bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
void AddTargetDepends(const cmGeneratorTarget* target,
TargetDependSet& projectTargets);
@@ -524,6 +553,7 @@ protected:
std::vector<std::string> Depends;
std::string WorkingDir;
bool UsesTerminal = false;
+ bool PerConfig = true;
};
void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
@@ -539,8 +569,8 @@ protected:
std::string FindMakeProgramFile;
std::string ConfiguredFilesPath;
cmake* CMakeInstance;
- std::vector<cmMakefile*> Makefiles;
- std::vector<cmLocalGenerator*> LocalGenerators;
+ std::vector<std::unique_ptr<cmMakefile>> Makefiles;
+ LocalGeneratorVector LocalGenerators;
cmMakefile* CurrentConfigureMakefile;
// map from project name to vector of local generators in that project
std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
@@ -646,6 +676,9 @@ private:
virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
+ bool UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const;
+
// Cache directory content and target files to be built.
struct DirectoryContent
{
@@ -666,6 +699,8 @@ private:
mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
FilenameTargetDepends;
+ std::map<std::string, std::string> RealPaths;
+
#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
cmFileLockPool FileLockPool;
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index bb5f74cca3..3709365970 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -8,6 +8,8 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
class cmGlobalGenerator;
class cmake;
struct cmDocumentationEntry;
@@ -23,8 +25,8 @@ public:
virtual ~cmGlobalGeneratorFactory() = default;
/** Create a GlobalGenerator */
- virtual cmGlobalGenerator* CreateGlobalGenerator(const std::string& n,
- cmake* cm) const = 0;
+ virtual std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& n, cmake* cm) const = 0;
/** Get the documentation entry for this factory */
virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
@@ -51,13 +53,13 @@ class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory
{
public:
/** Create a GlobalGenerator */
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
if (name != T::GetActualName()) {
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- return new T(cm);
+ return std::unique_ptr<cmGlobalGenerator>(cm::make_unique<T>(cm));
}
/** Get the documentation entry for this factory */
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 5a708abbcb..bb9dd37343 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -8,6 +8,8 @@
#include <ostream>
#include <utility>
+#include <cm/memory>
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
@@ -40,10 +42,11 @@ cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() = default;
-cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalGhsMultiGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalGhsMultiGenerator>(this, mf));
}
void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
@@ -64,8 +67,11 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
}
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
- cmMakefile* mf)
+ bool build, cmMakefile* mf)
{
+ if (build) {
+ return true;
+ }
std::string tsp; /* toolset path */
this->GetToolset(mf, tsp, ts);
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index ccfe073820..b82e9f57b9 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -4,6 +4,7 @@
#define cmGhsMultiGenerator_h
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -28,13 +29,15 @@ public:
cmGlobalGhsMultiGenerator(cmake* cm);
~cmGlobalGhsMultiGenerator() override;
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>());
}
//! create the correct local generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/// @return the name of this generator.
static std::string GetActualName() { return "Green Hills MULTI"; }
@@ -58,7 +61,8 @@ public:
static bool SupportsPlatform() { return true; }
// Toolset / Platform Support
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
/**
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index ff54288680..fc3123a44d 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -66,7 +66,7 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
// Since we have full control over the invocation of JOM, let us
// make it quiet.
jomMakeOptions.push_back(this->MakeSilentFlag);
- cmAppend(jomMakeOptions, makeOptions);
+ cm::append(jomMakeOptions, makeOptions);
// JOM does parallel builds by default, the -j is only needed if a specific
// number is given
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index fc39ddf427..9f1ec8bd44 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalJOMMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -16,9 +17,10 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalJOMMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h
index d6e4847feb..b2de4ff50c 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.h
+++ b/Source/cmGlobalMSYSMakefileGenerator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalMSYSMakefileGenerator_h
#define cmGlobalMSYSMakefileGenerator_h
+#include <memory>
+
#include "cmGlobalUnixMakefileGenerator3.h"
/** \class cmGlobalMSYSMakefileGenerator
@@ -14,9 +16,10 @@ class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalMSYSMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalMSYSMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalMSYSMakefileGenerator>());
}
//! Get the name for the generator.
diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h
index 15297e3c7a..a9f92a1081 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.h
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalMinGWMakefileGenerator_h
#define cmGlobalMinGWMakefileGenerator_h
+#include <memory>
+
#include "cmGlobalUnixMakefileGenerator3.h"
/** \class cmGlobalMinGWMakefileGenerator
@@ -14,10 +16,10 @@ class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalMinGWMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalMinGWMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalMinGWMakefileGenerator>());
}
//! Get the name for the generator.
virtual std::string GetName() const
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 2273c00ac6..c4bec2387e 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -66,7 +66,7 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
// Since we have full control over the invocation of nmake, let us
// make it quiet.
nmakeMakeOptions.push_back(this->MakeSilentFlag);
- cmAppend(nmakeMakeOptions, makeOptions);
+ cm::append(nmakeMakeOptions, makeOptions);
return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
makeProgram, projectName, projectDir, targetNames, config, fast,
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 4586b77b15..fdf6006c2c 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalNMakeMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -16,10 +17,10 @@ class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalNMakeMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalNMakeMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNMakeMakefileGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index da21d6c2a2..f4d102ee44 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -9,6 +9,8 @@
#include <sstream>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
#include "cmsys/FStream.hxx"
@@ -23,6 +25,7 @@
#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -42,8 +45,6 @@
#include "cmVersion.h"
#include "cmake.h"
-class cmLinkLineComputer;
-
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
const char* cmGlobalNinjaGenerator::INDENT = " ";
@@ -83,13 +84,15 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
os << "# " << comment.substr(lpos) << "\n\n";
}
-cmLinkLineComputer* cmGlobalNinjaGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmGlobalNinjaGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& /* stateDir */) const
{
- return new cmNinjaLinkLineComputer(
- outputConverter,
- this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this);
+ return std::unique_ptr<cmLinkLineComputer>(
+ cm::make_unique<cmNinjaLinkLineComputer>(
+ outputConverter,
+ this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this));
}
std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
@@ -114,6 +117,11 @@ std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
std::string result = lit;
cmSystemTools::ReplaceString(result, "$", "$$");
cmSystemTools::ReplaceString(result, "\n", "$\n");
+ if (this->IsMultiConfig()) {
+ cmSystemTools::ReplaceString(result,
+ cmStrCat('$', this->GetCMakeCFGIntDir()),
+ this->GetCMakeCFGIntDir());
+ }
return result;
}
@@ -248,8 +256,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& job_pool, bool uses_terminal, bool restat,
- const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps,
- const cmNinjaDeps& orderOnlyDeps)
+ const cmNinjaDeps& outputs, const std::string& config,
+ const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps)
{
this->AddCustomCommandRule();
@@ -282,7 +290,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
if (!depfile.empty()) {
vars["depfile"] = depfile;
}
- this->WriteBuild(*this->BuildFileStream, build);
+ if (config.empty()) {
+ this->WriteBuild(*this->GetCommonFileStream(), build);
+ } else {
+ this->WriteBuild(*this->GetImplFileStream(config), build);
+ }
}
if (this->ComputingUnknownDependencies) {
@@ -304,14 +316,15 @@ void cmGlobalNinjaGenerator::AddMacOSXContentRule()
}
void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(std::string input,
- std::string output)
+ std::string output,
+ const std::string& config)
{
this->AddMacOSXContentRule();
{
cmNinjaBuild build("COPY_OSX_CONTENT");
build.Outputs.push_back(std::move(output));
build.ExplicitDeps.push_back(std::move(input));
- this->WriteBuild(*this->BuildFileStream, build);
+ this->WriteBuild(*this->GetImplFileStream(config), build);
}
}
@@ -429,9 +442,11 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
// Virtual public methods.
-cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalNinjaGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalNinjaGenerator>(this, mf));
}
codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
@@ -470,14 +485,19 @@ void cmGlobalNinjaGenerator::Generate()
msg.str());
return;
}
- if (!this->OpenBuildFileStream()) {
+ if (!this->InspectConfigTypeVariables()) {
+ return;
+ }
+ if (!this->OpenBuildFileStreams()) {
return;
}
if (!this->OpenRulesFileStream()) {
return;
}
- this->TargetDependsClosures.clear();
+ for (auto& it : this->Configs) {
+ it.second.TargetDependsClosures.clear();
+ }
this->InitOutputPathPrefix();
this->TargetAll = this->NinjaOutputPath("all");
@@ -493,19 +513,101 @@ void cmGlobalNinjaGenerator::Generate()
this->cmGlobalGenerator::Generate();
this->WriteAssumedSourceDependencies();
- this->WriteTargetAliases(*this->BuildFileStream);
- this->WriteFolderTargets(*this->BuildFileStream);
- this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
- this->WriteBuiltinTargets(*this->BuildFileStream);
+ this->WriteTargetAliases(*this->GetCommonFileStream());
+ this->WriteFolderTargets(*this->GetCommonFileStream());
+ this->WriteUnknownExplicitDependencies(*this->GetCommonFileStream());
+ this->WriteBuiltinTargets(*this->GetCommonFileStream());
if (cmSystemTools::GetErrorOccuredFlag()) {
this->RulesFileStream->setstate(std::ios::failbit);
- this->BuildFileStream->setstate(std::ios::failbit);
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ this->GetImplFileStream(config)->setstate(std::ios::failbit);
+ this->GetConfigFileStream(config)->setstate(std::ios::failbit);
+ }
+ this->GetCommonFileStream()->setstate(std::ios::failbit);
}
this->CloseCompileCommandsStream();
this->CloseRulesFileStream();
- this->CloseBuildFileStream();
+ this->CloseBuildFileStreams();
+
+#ifdef _WIN32
+ // The ninja tools will not be able to update metadata on Windows
+ // when we are re-generating inside an existing 'ninja' invocation
+ // because the outer tool has the files open for write.
+ if (!this->GetCMakeInstance()->GetRegenerateDuringBuild())
+#endif
+ {
+ this->CleanMetaData();
+ }
+}
+
+void cmGlobalNinjaGenerator::CleanMetaData()
+{
+ auto run_ninja_tool = [this](std::vector<char const*> const& args) {
+ std::vector<std::string> command;
+ command.push_back(this->NinjaCommand);
+ command.emplace_back("-C");
+ command.emplace_back(this->GetCMakeInstance()->GetHomeOutputDirectory());
+ command.emplace_back("-t");
+ for (auto const& arg : args) {
+ command.emplace_back(arg);
+ }
+ std::string error;
+ if (!cmSystemTools::RunSingleCommand(command, nullptr, &error, nullptr,
+ nullptr,
+ cmSystemTools::OUTPUT_NONE)) {
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ "Running\n '" +
+ cmJoin(command, "' '") +
+ "'\n"
+ "failed with:\n " +
+ error);
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ };
+
+ // Can the tools below expect 'build.ninja' to be loadable?
+ bool const expectBuildManifest =
+ !this->IsMultiConfig() && this->OutputPathPrefix.empty();
+
+ // Skip some ninja tools if they need 'build.ninja' but it is missing.
+ bool const missingBuildManifest = expectBuildManifest &&
+ (this->NinjaSupportsCleanDeadTool ||
+ this->NinjaSupportsUnconditionalRecompactTool) &&
+ !cmSystemTools::FileExists("build.ninja");
+
+ // The `cleandead` tool needs to know about all outputs in the build we just
+ // wrote out. Ninja-Multi doesn't have a single `build.ninja` we can use that
+ // is the union of all generated configurations, so we can't run it reliably
+ // in that case.
+ if (this->NinjaSupportsCleanDeadTool && expectBuildManifest &&
+ !missingBuildManifest) {
+ run_ninja_tool({ "cleandead" });
+ }
+ // The `recompact` tool loads the manifest. As above, we don't have a single
+ // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the
+ // future pending further investigation into how Ninja works upstream
+ // (ninja#1721).
+ if (this->NinjaSupportsUnconditionalRecompactTool && expectBuildManifest &&
+ !missingBuildManifest) {
+ run_ninja_tool({ "recompact" });
+ }
+ if (this->NinjaSupportsRestatTool && this->OutputPathPrefix.empty()) {
+ // XXX(ninja): We only list `build.ninja` entry files here because CMake
+ // *always* rewrites these files on a reconfigure. If CMake ever gets
+ // smarter about this, all CMake-time created/edited files listed as
+ // outputs for the reconfigure build statement will need to be listed here.
+ cmNinjaDeps outputs;
+ this->AddRebuildManifestOutputs(outputs);
+ std::vector<const char*> args;
+ args.reserve(outputs.size() + 1);
+ args.push_back("restat");
+ for (auto const& output : outputs) {
+ args.push_back(output.c_str());
+ }
+ run_ninja_tool(args);
+ }
}
bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
@@ -569,6 +671,16 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
}
}
}
+ this->NinjaSupportsCleanDeadTool = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForCleanDeadTool().c_str());
+ this->NinjaSupportsUnconditionalRecompactTool =
+ !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForUnconditionalRecompactTool().c_str());
+ this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForRestatTool().c_str());
}
bool cmGlobalNinjaGenerator::CheckLanguages(
@@ -577,6 +689,17 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
if (cmContains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
+ if (cmContains(languages, "Swift")) {
+ const std::string architectures =
+ mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
+ if (architectures.find_first_of(';') != std::string::npos) {
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ "multiple values for CMAKE_OSX_ARCHITECTURES not "
+ "supported with Swift");
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
return true;
}
@@ -609,6 +732,17 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
void cmGlobalNinjaGenerator::EnableLanguage(
std::vector<std::string> const& langs, cmMakefile* mf, bool optional)
{
+ if (this->IsMultiConfig()) {
+ if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
+ mf->AddCacheDefinition(
+ "CMAKE_CONFIGURATION_TYPES", "Debug;Release;RelWithDebInfo",
+ "Semicolon separated list of supported configuration types, only "
+ "supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything "
+ "else will be ignored",
+ cmStateEnums::STRING);
+ }
+ }
+
this->cmGlobalGenerator::EnableLanguage(langs, mf, optional);
for (std::string const& l : langs) {
if (l == "NONE") {
@@ -650,7 +784,7 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalNinjaGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
const std::string& /*projectDir*/,
- std::vector<std::string> const& targetNames, const std::string& /*config*/,
+ std::vector<std::string> const& targetNames, const std::string& config,
bool /*fast*/, int jobs, bool verbose,
std::vector<std::string> const& makeOptions)
{
@@ -666,6 +800,8 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
makeCommand.Add("-j", std::to_string(jobs));
}
+ this->AppendNinjaFileArgument(makeCommand, config);
+
makeCommand.Add(makeOptions.begin(), makeOptions.end());
for (const auto& tname : targetNames) {
if (!tname.empty()) {
@@ -707,44 +843,76 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
- std::string dir =
- cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
- gt->LocalGenerator->GetTargetDirectory(gt), '/');
+ std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
+ '/', gt->LocalGenerator->GetTargetDirectory(gt),
+ '/', this->GetCMakeCFGIntDir(), '/');
gt->ObjectDirectory = dir;
}
// Private methods
-bool cmGlobalNinjaGenerator::OpenBuildFileStream()
+bool cmGlobalNinjaGenerator::OpenBuildFileStreams()
{
- // Compute Ninja's build file path.
- std::string buildFilePath =
- cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
- cmGlobalNinjaGenerator::NINJA_BUILD_FILE);
+ if (!this->OpenFileStream(this->BuildFileStream,
+ cmGlobalNinjaGenerator::NINJA_BUILD_FILE)) {
+ return false;
+ }
+ // Write a comment about this file.
+ *this->BuildFileStream
+ << "# This file contains all the build statements describing the\n"
+ << "# compilation DAG.\n\n";
+
+ return true;
+}
+
+bool cmGlobalNinjaGenerator::OpenFileStream(
+ std::unique_ptr<cmGeneratedFileStream>& stream, const std::string& name)
+{
// Get a stream where to generate things.
- if (!this->BuildFileStream) {
- this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
- buildFilePath, false, this->GetMakefileEncoding());
- if (!(*this->BuildFileStream)) {
+ if (!stream) {
+ // Compute Ninja's build file path.
+ std::string path =
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/', name);
+ stream = cm::make_unique<cmGeneratedFileStream>(
+ path, false, this->GetMakefileEncoding());
+ if (!(*stream)) {
// An error message is generated by the constructor if it cannot
// open the file.
return false;
}
+
+ // Write the do not edit header.
+ this->WriteDisclaimer(*stream);
}
- // Write the do not edit header.
- this->WriteDisclaimer(*this->BuildFileStream);
+ return true;
+}
- // Write a comment about this file.
- *this->BuildFileStream
- << "# This file contains all the build statements describing the\n"
- << "# compilation DAG.\n\n";
+cm::optional<std::set<std::string>> cmGlobalNinjaGenerator::ListSubsetWithAll(
+ const std::set<std::string>& all, const std::set<std::string>& defaults,
+ const std::vector<std::string>& items)
+{
+ std::set<std::string> result;
- return true;
+ for (auto const& item : items) {
+ if (item == "all") {
+ if (items.size() == 1) {
+ result = defaults;
+ } else {
+ return cm::nullopt;
+ }
+ } else if (all.count(item)) {
+ result.insert(item);
+ } else {
+ return cm::nullopt;
+ }
+ }
+
+ return cm::make_optional(result);
}
-void cmGlobalNinjaGenerator::CloseBuildFileStream()
+void cmGlobalNinjaGenerator::CloseBuildFileStreams()
{
if (this->BuildFileStream) {
this->BuildFileStream.reset();
@@ -755,25 +923,11 @@ void cmGlobalNinjaGenerator::CloseBuildFileStream()
bool cmGlobalNinjaGenerator::OpenRulesFileStream()
{
- // Compute Ninja's build file path.
- std::string rulesFilePath =
- cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
- cmGlobalNinjaGenerator::NINJA_RULES_FILE);
-
- // Get a stream where to generate things.
- if (!this->RulesFileStream) {
- this->RulesFileStream = cm::make_unique<cmGeneratedFileStream>(
- rulesFilePath, false, this->GetMakefileEncoding());
- if (!(*this->RulesFileStream)) {
- // An error message is generated by the constructor if it cannot
- // open the file.
- return false;
- }
+ if (!this->OpenFileStream(this->RulesFileStream,
+ cmGlobalNinjaGenerator::NINJA_RULES_FILE)) {
+ return false;
}
- // Write the do not edit header.
- this->WriteDisclaimer(*this->RulesFileStream);
-
// Write comment about this file.
/* clang-format off */
*this->RulesFileStream
@@ -819,10 +973,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
return f->second;
}
- cmLocalNinjaGenerator* ng =
- static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
- std::string const& bin_dir = ng->GetState()->GetBinaryDirectory();
- std::string convPath = ng->MaybeConvertToRelativePath(bin_dir, path);
+ const auto& ng =
+ cm::static_reference_cast<cmLocalNinjaGenerator>(this->LocalGenerators[0]);
+ std::string const& bin_dir = ng.GetState()->GetBinaryDirectory();
+ std::string convPath = ng.MaybeConvertToRelativePath(bin_dir, path);
convPath = this->NinjaOutputPath(convPath);
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -831,9 +985,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
.first->second;
}
-void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName)
+void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
+ const std::string& config)
{
- this->AdditionalCleanFiles.emplace(std::move(fileName));
+ this->Configs[config].AdditionalCleanFiles.emplace(std::move(fileName));
}
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
@@ -901,23 +1056,22 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
"Assume dependencies for generated source file.",
/*depfile*/ "", /*job_pool*/ "",
/*uses_terminal*/ false,
- /*restat*/ true, cmNinjaDeps(1, asd.first),
+ /*restat*/ true, cmNinjaDeps(1, asd.first), "",
cmNinjaDeps(), orderOnlyDeps);
}
}
-std::string OrderDependsTargetForTarget(cmGeneratorTarget const* target)
+std::string cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& config)
{
- return "cmake_object_order_depends_target_" + target->GetName();
+ return "cmake_object_order_depends_target_" + target->GetName() + "_" +
+ config;
}
void cmGlobalNinjaGenerator::AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
- cmNinjaTargetDepends depends)
+ const std::string& config, cmNinjaTargetDepends depends)
{
- std::string configName =
- target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
-
// for frameworks, we want the real name, not smple name
// frameworks always appear versioned, and the build.ninja
// will always attempt to manage symbolic links instead
@@ -929,19 +1083,19 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target));
+ outputs.push_back(OrderDependsTargetForTarget(target, config));
break;
}
}
// FALLTHROUGH
case cmStateEnums::EXECUTABLE: {
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
- configName, cmStateEnums::RuntimeBinaryArtifact, realname)));
+ config, cmStateEnums::RuntimeBinaryArtifact, realname)));
break;
}
case cmStateEnums::OBJECT_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target));
+ outputs.push_back(OrderDependsTargetForTarget(target, config));
break;
}
}
@@ -951,7 +1105,11 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
std::string path =
target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
std::string("/") + target->GetName();
- outputs.push_back(this->ConvertToNinjaPath(path));
+ std::string output = this->ConvertToNinjaPath(path);
+ if (target->Target->IsPerConfig()) {
+ output = this->BuildAlias(output, config);
+ }
+ outputs.push_back(output);
break;
}
@@ -962,15 +1120,17 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
void cmGlobalNinjaGenerator::AppendTargetDepends(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config, const std::string& fileConfig,
cmNinjaTargetDepends depends)
{
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// These depend only on other CMake-provided targets, e.g. "all".
- for (BT<std::string> const& util : target->GetUtilities()) {
+ for (BT<std::pair<std::string, bool>> const& util :
+ target->GetUtilities()) {
std::string d =
target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
- util.Value;
- outputs.push_back(this->ConvertToNinjaPath(d));
+ util.Value.first;
+ outputs.push_back(this->BuildAlias(this->ConvertToNinjaPath(d), config));
}
} else {
cmNinjaDeps outs;
@@ -979,29 +1139,36 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->AppendTargetOutputs(targetDep, outs, depends);
+ if (targetDep.IsCross()) {
+ this->AppendTargetOutputs(targetDep, outs, fileConfig, depends);
+ } else {
+ this->AppendTargetOutputs(targetDep, outs, config, depends);
+ }
}
std::sort(outs.begin(), outs.end());
- cmAppend(outputs, outs);
+ cm::append(outputs, outs);
}
}
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
- cmGeneratorTarget const* target, cmNinjaDeps& outputs)
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config)
{
cmNinjaOuts outs;
- this->AppendTargetDependsClosure(target, outs, true);
- cmAppend(outputs, outs);
+ this->AppendTargetDependsClosure(target, outs, config, true);
+ cm::append(outputs, outs);
}
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
- cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self)
+ cmGeneratorTarget const* target, cmNinjaOuts& outputs,
+ const std::string& config, bool omit_self)
{
// try to locate the target in the cache
- auto find = this->TargetDependsClosures.lower_bound(target);
+ auto find = this->Configs[config].TargetDependsClosures.lower_bound(target);
- if (find == this->TargetDependsClosures.end() || find->first != target) {
+ if (find == this->Configs[config].TargetDependsClosures.end() ||
+ find->first != target) {
// We now calculate the closure outputs by inspecting the dependent
// targets recursively.
// For that we have to distinguish between a local result set that is only
@@ -1011,15 +1178,16 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmNinjaOuts this_outs; // this will be the new cache entry
for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
- if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+ (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
continue;
}
// Collect the dependent targets for _this_ target
- this->AppendTargetDependsClosure(dep_target, this_outs, false);
+ this->AppendTargetDependsClosure(dep_target, this_outs, config, false);
}
- find = this->TargetDependsClosures.emplace_hint(find, target,
- std::move(this_outs));
+ find = this->Configs[config].TargetDependsClosures.emplace_hint(
+ find, target, std::move(this_outs));
}
// now fill the outputs of the final result from the newly generated cache
@@ -1029,29 +1197,56 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
// finally generate the outputs of the target itself, if applicable
cmNinjaDeps outs;
if (!omit_self) {
- this->AppendTargetOutputs(target, outs);
+ this->AppendTargetOutputs(target, outs, config);
}
outputs.insert(outs.begin(), outs.end());
}
void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
- cmGeneratorTarget* target)
+ cmGeneratorTarget* target,
+ const std::string& config)
{
- std::string buildAlias = this->NinjaOutputPath(alias);
+ std::string outputPath = this->NinjaOutputPath(alias);
+ std::string buildAlias = this->BuildAlias(outputPath, config);
cmNinjaDeps outputs;
- this->AppendTargetOutputs(target, outputs);
- // Mark the target's outputs as ambiguous to ensure that no other target uses
- // the output as an alias.
+ this->AppendTargetOutputs(target, outputs, config);
+ // Mark the target's outputs as ambiguous to ensure that no other target
+ // uses the output as an alias.
for (std::string const& output : outputs) {
- TargetAliases[output] = nullptr;
+ this->TargetAliases[output].GeneratorTarget = nullptr;
+ this->DefaultTargetAliases[output].GeneratorTarget = nullptr;
+ for (const std::string& config2 :
+ this->Makefiles.front()->GetGeneratorConfigs()) {
+ this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
+ }
}
// Insert the alias into the map. If the alias was already present in the
// map and referred to another target, mark it as ambiguous.
- std::pair<TargetAliasMap::iterator, bool> newAlias =
- TargetAliases.insert(std::make_pair(buildAlias, target));
- if (newAlias.second && newAlias.first->second != target) {
- newAlias.first->second = nullptr;
+ TargetAlias ta;
+ ta.GeneratorTarget = target;
+ ta.Config = config;
+
+ auto newAliasGlobal =
+ this->TargetAliases.insert(std::make_pair(buildAlias, ta));
+ if (newAliasGlobal.second &&
+ newAliasGlobal.first->second.GeneratorTarget != target) {
+ newAliasGlobal.first->second.GeneratorTarget = nullptr;
+ }
+
+ auto newAliasConfig =
+ this->Configs[config].TargetAliases.insert(std::make_pair(outputPath, ta));
+ if (newAliasConfig.second &&
+ newAliasConfig.first->second.GeneratorTarget != target) {
+ newAliasConfig.first->second.GeneratorTarget = nullptr;
+ }
+ if (this->DefaultConfigs.count(config)) {
+ auto newAliasDefaultGlobal =
+ this->DefaultTargetAliases.insert(std::make_pair(outputPath, ta));
+ if (newAliasDefaultGlobal.second &&
+ newAliasDefaultGlobal.first->second.GeneratorTarget != target) {
+ newAliasDefaultGlobal.first->second.GeneratorTarget = nullptr;
+ }
}
}
@@ -1061,10 +1256,10 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
os << "# Target aliases.\n\n";
cmNinjaBuild build("phony");
- build.Outputs.emplace_back("");
- for (auto const& ta : TargetAliases) {
+ build.Outputs.emplace_back();
+ for (auto const& ta : this->TargetAliases) {
// Don't write ambiguous aliases.
- if (!ta.second) {
+ if (!ta.second.GeneratorTarget) {
continue;
}
@@ -1074,13 +1269,69 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
continue;
}
- // Outputs
- build.Outputs[0] = ta.first;
- // Explicit depdendencies
+ build.Outputs.front() = ta.first;
build.ExplicitDeps.clear();
- this->AppendTargetOutputs(ta.second, build.ExplicitDeps);
- // Write
- this->WriteBuild(os, build);
+ if (ta.second.Config == "all") {
+ for (auto const& config : this->CrossConfigs) {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ }
+ } else {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps,
+ ta.second.Config);
+ }
+ this->WriteBuild(this->EnableCrossConfigBuild() &&
+ (ta.second.Config == "all" ||
+ this->CrossConfigs.count(ta.second.Config))
+ ? os
+ : *this->GetImplFileStream(ta.second.Config),
+ build);
+ }
+
+ if (this->IsMultiConfig()) {
+ for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+ for (auto const& ta : this->Configs[config].TargetAliases) {
+ // Don't write ambiguous aliases.
+ if (!ta.second.GeneratorTarget) {
+ continue;
+ }
+
+ // Don't write alias if there is a already a custom command with
+ // matching output
+ if (this->HasCustomCommandOutput(ta.first)) {
+ continue;
+ }
+
+ build.Outputs.front() = ta.first;
+ build.ExplicitDeps.clear();
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
+ }
+ }
+
+ if (!this->DefaultConfigs.empty()) {
+ for (auto const& ta : this->DefaultTargetAliases) {
+ // Don't write ambiguous aliases.
+ if (!ta.second.GeneratorTarget) {
+ continue;
+ }
+
+ // Don't write alias if there is a already a custom command with
+ // matching output
+ if (this->HasCustomCommandOutput(ta.first)) {
+ continue;
+ }
+
+ build.Outputs.front() = ta.first;
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ }
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
+ }
+ }
}
}
@@ -1097,24 +1348,73 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
std::string const& currentBinaryDir = it.first;
DirectoryTarget const& dt = it.second;
+ std::vector<std::string> configs;
+ dt.LG->GetMakefile()->GetConfigurations(configs, true);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
// Setup target
+ cmNinjaDeps configDeps;
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);
+ build.Outputs.emplace_back();
+ for (auto const& config : configs) {
+ build.ExplicitDeps.clear();
+ build.Outputs.front() = this->BuildAlias(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"), config);
+ configDeps.emplace_back(build.Outputs.front());
+ for (DirectoryTarget::Target const& t : dt.Targets) {
+ if (!t.ExcludeFromAll) {
+ this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
+ }
+ }
+ for (DirectoryTarget::Dir const& d : dt.Children) {
+ if (!d.ExcludeFromAll) {
+ build.ExplicitDeps.emplace_back(this->BuildAlias(
+ this->ConvertToNinjaPath(d.Path + "/all"), config));
+ }
}
+ // Write target
+ this->WriteBuild(this->EnableCrossConfigBuild() &&
+ this->CrossConfigs.count(config)
+ ? os
+ : *this->GetImplFileStream(config),
+ build);
}
- for (DirectoryTarget::Dir const& d : dt.Children) {
- if (!d.ExcludeFromAll) {
- build.ExplicitDeps.emplace_back(
- this->ConvertToNinjaPath(d.Path + "/all"));
+
+ // Add shortcut target
+ if (this->IsMultiConfig()) {
+ for (auto const& config : configs) {
+ build.ExplicitDeps = { this->BuildAlias(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
+ build.Outputs.front() =
+ this->ConvertToNinjaPath(currentBinaryDir + "/all");
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+ }
+ build.Outputs.front() =
+ this->ConvertToNinjaPath(currentBinaryDir + "/all");
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
}
}
- // Write target
- this->WriteBuild(os, build);
+
+ // Add target for all configs
+ if (this->EnableCrossConfigBuild()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->CrossConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+ }
+ build.Outputs.front() = this->BuildAlias(
+ this->ConvertToNinjaPath(currentBinaryDir + "/all"), "all");
+ this->WriteBuild(os, build);
+ }
}
}
@@ -1148,7 +1448,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
// get the list of files that cmake itself has generated as a
// product of configuration.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
// get the vector of files created by this makefile and convert them
// to ninja paths, which are all relative in respect to the build directory
for (std::string const& file : lg->GetMakefile()->GetOutputFiles()) {
@@ -1161,8 +1461,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
knownDependencies.insert(this->ConvertToNinjaPath(j));
}
}
- for (cmGeneratorExpressionEvaluationFile* li :
- lg->GetMakefile()->GetEvaluationFiles()) {
+ for (const auto& li : lg->GetMakefile()->GetEvaluationFiles()) {
// get all the files created by generator expressions and convert them
// to ninja paths
for (std::string const& evaluationFile : li->GetFiles()) {
@@ -1247,10 +1546,17 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Built-in targets\n\n";
- this->WriteTargetDefault(os);
this->WriteTargetRebuildManifest(os);
this->WriteTargetClean(os);
this->WriteTargetHelp(os);
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ this->WriteTargetDefault(*this->GetConfigFileStream(config));
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ this->WriteTargetDefault(*this->GetDefaultFileStream());
+ }
}
void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os)
@@ -1268,12 +1574,12 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
return;
}
- cmLocalGenerator* lg = this->LocalGenerators[0];
+ const auto& lg = this->LocalGenerators[0];
{
cmNinjaRule rule("RERUN_CMAKE");
rule.Command =
- cmStrCat(CMakeCmd(), " -S",
+ cmStrCat(CMakeCmd(), " --regenerate-during-build -S",
lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL),
" -B",
@@ -1287,9 +1593,9 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmNinjaBuild reBuild("RERUN_CMAKE");
reBuild.Comment = "Re-run CMake if any of its inputs changed.";
- reBuild.Outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
+ this->AddRebuildManifestOutputs(reBuild.Outputs);
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) {
reBuild.ImplicitDeps.push_back(this->ConvertToNinjaPath(fi));
}
@@ -1376,14 +1682,14 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
std::string cmGlobalNinjaGenerator::CMakeCmd() const
{
- cmLocalGenerator* lgen = this->LocalGenerators.at(0);
+ const auto& lgen = this->LocalGenerators.at(0);
return lgen->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
cmOutputConverter::SHELL);
}
std::string cmGlobalNinjaGenerator::NinjaCmd() const
{
- cmLocalGenerator* lgen = this->LocalGenerators[0];
+ const auto& lgen = this->LocalGenerators[0];
if (lgen != nullptr) {
return lgen->ConvertToOutputFormat(this->NinjaCommand,
cmOutputConverter::SHELL);
@@ -1413,13 +1719,27 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const
bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
- cmLocalGenerator* lgr = this->LocalGenerators.at(0);
+ const auto& lgr = this->LocalGenerators.at(0);
std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
std::string cleanScriptAbs =
cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
+ std::vector<std::string> configs;
+ this->Makefiles[0]->GetConfigurations(configs, true);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
// Check if there are additional files to clean
- if (this->AdditionalCleanFiles.empty()) {
+ bool empty = true;
+ for (auto const& config : configs) {
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end() &&
+ !it->second.AdditionalCleanFiles.empty()) {
+ empty = false;
+ break;
+ }
+ }
+ if (empty) {
// Remove cmake clean script file if it exists
cmSystemTools::RemoveFile(cleanScriptAbs);
return false;
@@ -1431,14 +1751,23 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
if (!fout) {
return false;
}
- fout << "# Additional clean files\n\n";
- fout << "file(REMOVE_RECURSE\n";
- for (std::string const& acf : this->AdditionalCleanFiles) {
- fout << " "
- << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
- << '\n';
+ fout << "# Additional clean files\ncmake_minimum_required(VERSION 3.16)\n";
+ for (auto const& config : configs) {
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end() &&
+ !it->second.AdditionalCleanFiles.empty()) {
+ fout << "\nif(\"${CONFIG}\" STREQUAL \"\" OR \"${CONFIG}\" STREQUAL \""
+ << config << "\")\n";
+ fout << " file(REMOVE_RECURSE\n";
+ for (std::string const& acf : it->second.AdditionalCleanFiles) {
+ fout << " "
+ << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
+ << '\n';
+ }
+ fout << " )\n";
+ fout << "endif()\n";
+ }
}
- fout << ")\n";
}
// Register clean script file
lgr->GetMakefile()->AddCMakeOutputFile(cleanScriptAbs);
@@ -1447,7 +1776,7 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmNinjaRule rule("CLEAN_ADDITIONAL");
rule.Command = cmStrCat(
- CMakeCmd(), " -P ",
+ CMakeCmd(), " -DCONFIG=$CONFIG -P ",
lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel),
cmOutputConverter::SHELL));
rule.Description = "Cleaning additional files...";
@@ -1459,9 +1788,19 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmNinjaBuild build("CLEAN_ADDITIONAL");
build.Comment = "Clean additional files.";
- build.Outputs.push_back(
- this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
- WriteBuild(os, build);
+ build.Outputs.emplace_back();
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()), config);
+ build.Variables["CONFIG"] = config;
+ WriteBuild(os, build);
+ }
+ if (this->IsMultiConfig()) {
+ build.Outputs.front() =
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName());
+ build.Variables["CONFIG"] = "";
+ WriteBuild(os, build);
+ }
}
// Return success
return true;
@@ -1476,22 +1815,113 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
// Write rule
{
cmNinjaRule rule("CLEAN");
- rule.Command = NinjaCmd() + " -t clean";
+ rule.Command = NinjaCmd() + " $FILE_ARG -t clean $TARGETS";
rule.Description = "Cleaning all built files...";
rule.Comment = "Rule for cleaning all built files.";
WriteRule(*this->RulesFileStream, rule);
}
+ auto const configs = this->Makefiles.front()->GetGeneratorConfigs();
+
// Write build
{
cmNinjaBuild build("CLEAN");
build.Comment = "Clean all the built files.";
- build.Outputs.push_back(this->NinjaOutputPath(this->GetCleanTargetName()));
- if (additionalFiles) {
- build.ExplicitDeps.push_back(
- this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
+ build.Outputs.emplace_back();
+
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config);
+ if (this->IsMultiConfig()) {
+ build.Variables["TARGETS"] =
+ cmStrCat(this->BuildAlias(GetByproductsForCleanTargetName(), config),
+ " ", GetByproductsForCleanTargetName());
+ }
+ build.ExplicitDeps.clear();
+ if (additionalFiles) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
+ config));
+ }
+ for (auto const& fileConfig : configs) {
+ if (fileConfig != config && !this->EnableCrossConfigBuild()) {
+ continue;
+ }
+ if (this->IsMultiConfig()) {
+ build.Variables["FILE_ARG"] = cmStrCat(
+ "-f ",
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ }
+ this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
+ }
+ }
+
+ if (this->EnableCrossConfigBuild()) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), "all");
+ build.ExplicitDeps.clear();
+
+ if (additionalFiles) {
+ for (auto const& config : this->CrossConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
+ config));
+ }
+ }
+
+ std::vector<std::string> byproducts;
+ for (auto const& config : this->CrossConfigs) {
+ byproducts.push_back(
+ this->BuildAlias(GetByproductsForCleanTargetName(), config));
+ }
+ build.Variables["TARGETS"] = cmJoin(byproducts, " ");
+
+ for (auto const& fileConfig : configs) {
+ build.Variables["FILE_ARG"] = cmStrCat(
+ "-f ",
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
+ }
+ }
+ }
+
+ if (this->IsMultiConfig()) {
+ cmNinjaBuild build("phony");
+ build.Outputs.emplace_back(
+ this->NinjaOutputPath(this->GetCleanTargetName()));
+ build.ExplicitDeps.emplace_back();
+
+ for (auto const& config : configs) {
+ build.ExplicitDeps.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config);
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
+ }
+
+ if (!this->DefaultConfigs.empty()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config));
+ }
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
}
+ }
+
+ // Write byproducts
+ if (this->IsMultiConfig()) {
+ cmNinjaBuild build("phony");
+ build.Comment = "Clean byproducts.";
+ build.Outputs.emplace_back(
+ this->ConvertToNinjaPath(GetByproductsForCleanTargetName()));
+ build.ExplicitDeps = this->ByproductsForCleanTarget;
WriteBuild(os, build);
+
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config);
+ build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget;
+ WriteBuild(os, build);
+ }
}
}
@@ -1809,11 +2239,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str());
snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str());
auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
- std::unique_ptr<cmLocalNinjaGenerator> lgd(
- static_cast<cmLocalNinjaGenerator*>(
- this->CreateLocalGenerator(mfd.get())));
- this->Makefiles.push_back(mfd.release());
- this->LocalGenerators.push_back(lgd.release());
+ auto lgd = this->CreateLocalGenerator(mfd.get());
+ this->Makefiles.push_back(std::move(mfd));
+ this->LocalGenerators.push_back(std::move(lgd));
}
std::vector<cmDyndepObjectInfo> objects;
@@ -1920,6 +2348,11 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
return true;
}
+bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
+{
+ return !this->CrossConfigs.empty();
+}
+
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd)
{
@@ -1990,13 +2423,266 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
cm.SetHomeOutputDirectory(dir_top_bld);
- std::unique_ptr<cmGlobalNinjaGenerator> ggd(
- static_cast<cmGlobalNinjaGenerator*>(cm.CreateGlobalGenerator("Ninja")));
+ auto ggd = cm.CreateGlobalGenerator("Ninja");
if (!ggd ||
- !ggd->WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld,
- arg_dd, arg_ddis, module_dir, linked_target_dirs,
- arg_lang)) {
+ !cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile(
+ dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis,
+ module_dir, linked_target_dirs, arg_lang)) {
return 1;
}
return 0;
}
+
+void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
+ const std::string& prefix, const std::string& config,
+ const std::string& suffix, std::string& dir)
+{
+ if (!config.empty() && this->IsMultiConfig()) {
+ dir += prefix;
+ dir += config;
+ dir += suffix;
+ }
+}
+
+std::set<std::string> cmGlobalNinjaGenerator::GetCrossConfigs(
+ const std::string& fileConfig) const
+{
+ auto result = this->CrossConfigs;
+ result.insert(fileConfig);
+ return result;
+}
+
+const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE =
+ "CMakeFiles/common.ninja";
+const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja";
+
+cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
+ : cmGlobalNinjaGenerator(cm)
+{
+ cm->GetState()->SetIsGeneratorMultiConfig(true);
+ cm->GetState()->SetNinjaMulti(true);
+}
+
+void cmGlobalNinjaMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
+{
+ entry.Name = cmGlobalNinjaMultiGenerator::GetActualName();
+ entry.Brief = "Generates build-<Config>.ninja files.";
+}
+
+std::string cmGlobalNinjaMultiGenerator::ExpandCFGIntDir(
+ const std::string& str, const std::string& config) const
+{
+ std::string result = str;
+ cmSystemTools::ReplaceString(result, this->GetCMakeCFGIntDir(), config);
+ return result;
+}
+
+bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
+{
+ if (!this->OpenFileStream(this->CommonFileStream,
+ cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE)) {
+ return false;
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ if (!this->OpenFileStream(this->DefaultFileStream, NINJA_BUILD_FILE)) {
+ return false;
+ }
+ *this->DefaultFileStream
+ << "# Build using rules for '" << this->DefaultFileConfig << "'.\n\n"
+ << "include " << GetNinjaImplFilename(this->DefaultFileConfig) << "\n\n";
+ }
+
+ // Write a comment about this file.
+ *this->CommonFileStream
+ << "# This file contains build statements common to all "
+ "configurations.\n\n";
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ // Open impl file.
+ if (!this->OpenFileStream(this->ImplFileStreams[config],
+ GetNinjaImplFilename(config))) {
+ return false;
+ }
+
+ // Write a comment about this file.
+ *this->ImplFileStreams[config]
+ << "# This file contains build statements specific to the \"" << config
+ << "\"\n# configuration.\n\n";
+
+ // Open config file.
+ if (!this->OpenFileStream(this->ConfigFileStreams[config],
+ GetNinjaConfigFilename(config))) {
+ return false;
+ }
+
+ // Write a comment about this file.
+ *this->ConfigFileStreams[config]
+ << "# This file contains aliases specific to the \"" << config
+ << "\"\n# configuration.\n\n"
+ << "include " << GetNinjaImplFilename(config) << "\n\n";
+ }
+
+ return true;
+}
+
+void cmGlobalNinjaMultiGenerator::CloseBuildFileStreams()
+{
+ if (this->CommonFileStream) {
+ this->CommonFileStream.reset();
+ } else {
+ cmSystemTools::Error("Common file stream was not open.");
+ }
+
+ if (this->DefaultFileStream) {
+ this->DefaultFileStream.reset();
+ } // No error if it wasn't open
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ if (this->ImplFileStreams[config]) {
+ this->ImplFileStreams[config].reset();
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("Impl file stream for \"", config, "\" was not open."));
+ }
+ if (this->ConfigFileStreams[config]) {
+ this->ConfigFileStreams[config].reset();
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("Config file stream for \"", config, "\" was not open."));
+ }
+ }
+}
+
+void cmGlobalNinjaMultiGenerator::AppendNinjaFileArgument(
+ GeneratedMakeCommand& command, const std::string& config) const
+{
+ if (!config.empty()) {
+ command.Add("-f");
+ command.Add(GetNinjaConfigFilename(config));
+ }
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(
+ const std::string& config)
+{
+ return cmStrCat("CMakeFiles/impl-", config,
+ cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetNinjaConfigFilename(
+ const std::string& config)
+{
+ return cmStrCat("build-", config,
+ cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
+}
+
+void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
+ cmNinjaDeps& outputs) const
+{
+ for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+ outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
+ outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
+ }
+ if (!this->DefaultFileConfig.empty()) {
+ outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
+ }
+}
+
+void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
+ std::vector<std::string>& configs) const
+{
+ auto const oldSize = configs.size();
+ this->Makefiles.front()->GetConfigurations(configs);
+ if (configs.size() == oldSize) {
+ configs.emplace_back();
+ }
+}
+
+bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
+{
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_BUILD_TYPE");
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_CROSS_CONFIGS");
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_CONFIGS");
+ return this->ReadCacheEntriesForBuild(*this->Makefiles.front()->GetState());
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
+{
+ return "";
+}
+
+bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
+ const cmState& state)
+{
+ std::vector<std::string> configsVec;
+ cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CONFIGURATION_TYPES"),
+ configsVec);
+ if (configsVec.empty()) {
+ configsVec.emplace_back();
+ }
+ std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
+
+ this->DefaultFileConfig =
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE");
+ if (this->DefaultFileConfig.empty()) {
+ this->DefaultFileConfig = configsVec.front();
+ }
+ if (!configs.count(this->DefaultFileConfig)) {
+ std::ostringstream msg;
+ msg << "The configuration specified by "
+ << "CMAKE_DEFAULT_BUILD_TYPE (" << this->DefaultFileConfig
+ << ") is not present in CMAKE_CONFIGURATION_TYPES";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+
+ std::vector<std::string> crossConfigsVec;
+ cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"),
+ crossConfigsVec);
+ auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
+ if (!crossConfigs) {
+ std::ostringstream msg;
+ msg << "CMAKE_CROSS_CONFIGS is not a subset of "
+ << "CMAKE_CONFIGURATION_TYPES";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+ this->CrossConfigs = *crossConfigs;
+
+ auto defaultConfigsString =
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS");
+ if (defaultConfigsString.empty()) {
+ defaultConfigsString = this->DefaultFileConfig;
+ }
+ if (!defaultConfigsString.empty() &&
+ defaultConfigsString != this->DefaultFileConfig &&
+ (this->DefaultFileConfig.empty() || this->CrossConfigs.empty())) {
+ std::ostringstream msg;
+ msg << "CMAKE_DEFAULT_CONFIGS cannot be used without "
+ << "CMAKE_DEFAULT_BUILD_TYPE or CMAKE_CROSS_CONFIGS";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+
+ std::vector<std::string> defaultConfigsVec;
+ cmExpandList(defaultConfigsString, defaultConfigsVec);
+ if (!this->DefaultFileConfig.empty()) {
+ auto defaultConfigs =
+ ListSubsetWithAll(this->GetCrossConfigs(this->DefaultFileConfig),
+ this->CrossConfigs, defaultConfigsVec);
+ if (!defaultConfigs) {
+ std::ostringstream msg;
+ msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+ this->DefaultConfigs = *defaultConfigs;
+ }
+
+ return true;
+}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 244e9fd384..5668dd1280 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -15,6 +15,8 @@
#include <utility>
#include <vector>
+#include <cm/optional>
+
#include "cm_codecvt.hxx"
#include "cmGeneratedFileStream.h"
@@ -22,6 +24,7 @@
#include "cmGlobalGeneratorFactory.h"
#include "cmNinjaTypes.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
class cmCustomCommand;
class cmGeneratorTarget;
@@ -29,6 +32,7 @@ class cmLinkLineComputer;
class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
+class cmState;
class cmStateDirectory;
class cmake;
struct cmDocumentationEntry;
@@ -73,10 +77,10 @@ public:
static void WriteDivider(std::ostream& os);
static std::string EncodeRuleName(std::string const& name);
- static std::string EncodeLiteral(const std::string& lit);
+ std::string EncodeLiteral(const std::string& lit);
std::string EncodePath(const std::string& path);
- cmLinkLineComputer* CreateLinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const override;
@@ -111,11 +115,12 @@ public:
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& pool, bool uses_terminal, bool restat,
- const cmNinjaDeps& outputs,
+ const cmNinjaDeps& outputs, const std::string& config,
const cmNinjaDeps& explicitDeps = cmNinjaDeps(),
const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
- void WriteMacOSXContentBuild(std::string input, std::string output);
+ void WriteMacOSXContentBuild(std::string input, std::string output,
+ const std::string& config);
/**
* Write a rule statement to @a os.
@@ -151,12 +156,14 @@ public:
public:
cmGlobalNinjaGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>());
}
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
std::string GetName() const override
{
@@ -204,7 +211,26 @@ public:
}
const char* GetCleanTargetName() const override { return "clean"; }
- cmGeneratedFileStream* GetBuildFileStream() const
+ bool SupportsCustomCommandDepfile() const override { return true; }
+
+ virtual cmGeneratedFileStream* GetImplFileStream(
+ const std::string& /*config*/) const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetConfigFileStream(
+ const std::string& /*config*/) const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetDefaultFileStream() const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetCommonFileStream() const
{
return this->BuildFileStream.get();
}
@@ -231,12 +257,17 @@ public:
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
// -- Additional clean files
- void AddAdditionalCleanFile(std::string fileName);
+ void AddAdditionalCleanFile(std::string fileName, const std::string& config);
const char* GetAdditionalCleanTargetName() const
{
return "CMakeFiles/clean.additional";
}
+ static const char* GetByproductsForCleanTargetName()
+ {
+ return "CMakeFiles/cmake_byproducts_for_clean_target";
+ }
+
void AddCXXCompileCommand(const std::string& commandLine,
const std::string& sourceFile);
@@ -260,9 +291,9 @@ public:
/// Called when we have seen the given custom command. Returns true
/// if we has seen it before.
- bool SeenCustomCommand(cmCustomCommand const* cc)
+ bool SeenCustomCommand(cmCustomCommand const* cc, const std::string& config)
{
- return !this->CustomCommands.insert(cc).second;
+ return !this->Configs[config].CustomCommands.insert(cc).second;
}
/// Called when we have seen the given custom command output.
@@ -284,25 +315,43 @@ public:
ASD.insert(deps.begin(), deps.end());
}
+ static std::string OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& config);
+
void AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AppendTargetDepends(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config, const std::string& fileConfig,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
- cmNinjaDeps& outputs);
+ cmNinjaDeps& outputs,
+ const std::string& config);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
- cmNinjaOuts& outputs, bool omit_self);
+ cmNinjaOuts& outputs,
+ const std::string& config, bool omit_self);
+
+ void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
+ std::string& dir) override;
- const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+ virtual void AppendNinjaFileArgument(GeneratedMakeCommand& /*command*/,
+ const std::string& /*config*/) const
{
- return LocalGenerators;
+ }
+
+ virtual void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const
+ {
+ outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
- void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
+ void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
+ const std::string& config);
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
@@ -316,6 +365,12 @@ public:
return "1.9";
}
static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; }
+ static std::string RequiredNinjaVersionForRestatTool() { return "1.10"; }
+ static std::string RequiredNinjaVersionForUnconditionalRecompactTool()
+ {
+ return "1.10";
+ }
+ static std::string RequiredNinjaVersionForCleanDeadTool() { return "1.10"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -335,11 +390,52 @@ public:
std::vector<std::string> const& linked_target_dirs,
std::string const& arg_lang);
+ virtual std::string BuildAlias(const std::string& alias,
+ const std::string& /*config*/) const
+ {
+ return alias;
+ }
+
+ virtual std::string ConfigDirectory(const std::string& /*config*/) const
+ {
+ return "";
+ }
+
+ cmNinjaDeps& GetByproductsForCleanTarget()
+ {
+ return this->ByproductsForCleanTarget;
+ }
+
+ cmNinjaDeps& GetByproductsForCleanTarget(const std::string& config)
+ {
+ return this->Configs[config].ByproductsForCleanTarget;
+ }
+
+ bool EnableCrossConfigBuild() const;
+
+ std::set<std::string> GetCrossConfigs(const std::string& config) const;
+
protected:
void Generate() override;
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
+ virtual bool OpenBuildFileStreams();
+ virtual void CloseBuildFileStreams();
+
+ bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
+ const std::string& name);
+
+ static cm::optional<std::set<std::string>> ListSubsetWithAll(
+ const std::set<std::string>& all, const std::set<std::string>& defaults,
+ const std::vector<std::string>& items);
+
+ virtual bool InspectConfigTypeVariables() { return true; }
+
+ std::set<std::string> CrossConfigs;
+ std::set<std::string> DefaultConfigs;
+ std::string DefaultFileConfig;
+
private:
std::string GetEditCacheCommand() const override;
bool FindMakeProgram(cmMakefile* mf) override;
@@ -348,13 +444,11 @@ private:
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
- bool OpenBuildFileStream();
- void CloseBuildFileStream();
-
void CloseCompileCommandsStream();
bool OpenRulesFileStream();
void CloseRulesFileStream();
+ void CleanMetaData();
/// Write the common disclaimer text at the top of each build file.
void WriteDisclaimer(std::ostream& os);
@@ -395,9 +489,6 @@ private:
bool UsingGCCOnWindows = false;
- /// The set of custom commands we have seen.
- std::set<cmCustomCommand const*> CustomCommands;
-
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
@@ -416,10 +507,14 @@ private:
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
- using TargetAliasMap = std::map<std::string, cmGeneratorTarget*>;
+ struct TargetAlias
+ {
+ cmGeneratorTarget* GeneratorTarget;
+ std::string Config;
+ };
+ using TargetAliasMap = std::map<std::string, TargetAlias>;
TargetAliasMap TargetAliases;
-
- std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+ TargetAliasMap DefaultTargetAliases;
/// the local cache for calls to ConvertToNinjaPath
mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
@@ -431,6 +526,9 @@ private:
bool NinjaSupportsManifestRestat = false;
bool NinjaSupportsMultilineDepfile = false;
bool NinjaSupportsDyndeps = false;
+ bool NinjaSupportsRestatTool = false;
+ bool NinjaSupportsUnconditionalRecompactTool = false;
+ bool NinjaSupportsCleanDeadTool = false;
private:
void InitOutputPathPrefix();
@@ -438,7 +536,125 @@ private:
std::string OutputPathPrefix;
std::string TargetAll;
std::string CMakeCacheFile;
- std::set<std::string> AdditionalCleanFiles;
+
+ struct ByConfig
+ {
+ std::set<std::string> AdditionalCleanFiles;
+
+ /// The set of custom commands we have seen.
+ std::set<cmCustomCommand const*> CustomCommands;
+
+ std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+
+ TargetAliasMap TargetAliases;
+
+ cmNinjaDeps ByproductsForCleanTarget;
+ };
+ std::map<std::string, ByConfig> Configs;
+
+ cmNinjaDeps ByproductsForCleanTarget;
+};
+
+class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator
+{
+public:
+ /// The default name of Ninja's common file. Typically: common.ninja.
+ static const char* NINJA_COMMON_FILE;
+ /// The default file extension to use for per-config Ninja files.
+ static const char* NINJA_FILE_EXTENSION;
+
+ cmGlobalNinjaMultiGenerator(cmake* cm);
+ bool IsMultiConfig() const override { return true; }
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
+ {
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaMultiGenerator>());
+ }
+
+ static void GetDocumentation(cmDocumentationEntry& entry);
+
+ std::string GetName() const override
+ {
+ return cmGlobalNinjaMultiGenerator::GetActualName();
+ }
+
+ static std::string GetActualName() { return "Ninja Multi-Config"; }
+
+ std::string BuildAlias(const std::string& alias,
+ const std::string& config) const override
+ {
+ if (config.empty()) {
+ return alias;
+ }
+ return cmStrCat(alias, ":", config);
+ }
+
+ std::string ConfigDirectory(const std::string& config) const override
+ {
+ if (!config.empty()) {
+ return cmStrCat('/', config);
+ }
+ return "";
+ }
+
+ const char* GetCMakeCFGIntDir() const override { return "${CONFIGURATION}"; }
+
+ std::string ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const override;
+
+ cmGeneratedFileStream* GetImplFileStream(
+ const std::string& config) const override
+ {
+ return this->ImplFileStreams.at(config).get();
+ }
+
+ cmGeneratedFileStream* GetConfigFileStream(
+ const std::string& config) const override
+ {
+ return this->ConfigFileStreams.at(config).get();
+ }
+
+ cmGeneratedFileStream* GetDefaultFileStream() const override
+ {
+ return this->DefaultFileStream.get();
+ }
+
+ cmGeneratedFileStream* GetCommonFileStream() const override
+ {
+ return this->CommonFileStream.get();
+ }
+
+ void AppendNinjaFileArgument(GeneratedMakeCommand& command,
+ const std::string& config) const override;
+
+ static std::string GetNinjaImplFilename(const std::string& config);
+ static std::string GetNinjaConfigFilename(const std::string& config);
+
+ void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const override;
+
+ void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
+
+ bool InspectConfigTypeVariables() override;
+
+ std::string GetDefaultBuildConfig() const override;
+
+ bool ReadCacheEntriesForBuild(const cmState& state) override;
+
+ bool SupportsDefaultBuildType() const override { return true; }
+ bool SupportsCrossConfigs() const override { return true; }
+ bool SupportsDefaultConfigs() const override { return true; }
+
+protected:
+ bool OpenBuildFileStreams() override;
+ void CloseBuildFileStreams() override;
+
+private:
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
+ ImplFileStreams;
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
+ ConfigFileStreams;
+ std::unique_ptr<cmGeneratedFileStream> CommonFileStream;
+ std::unique_ptr<cmGeneratedFileStream> DefaultFileStream;
};
#endif // ! cmGlobalNinjaGenerator_h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4c2d69f091..90c9ef0d24 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -8,8 +8,9 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -61,10 +62,11 @@ void cmGlobalUnixMakefileGenerator3::EnableLanguage(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalUnixMakefileGenerator3(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf));
}
void cmGlobalUnixMakefileGenerator3::GetDocumentation(
@@ -144,11 +146,11 @@ void cmGlobalUnixMakefileGenerator3::Generate()
for (auto& pmi : this->ProgressMap) {
pmi.second.WriteProgressVariables(total, current);
}
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
std::string markFileName =
cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks");
cmGeneratedFileStream markFile(markFileName);
- markFile << this->CountProgressMarksInAll(lg) << "\n";
+ markFile << this->CountProgressMarksInAll(*lg) << "\n";
}
// write the main makefile
@@ -203,11 +205,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// get a local generator for some useful methods
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+ auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
// Write the do not edit header.
- lg->WriteDisclaimer(makefileStream);
+ lg.WriteDisclaimer(makefileStream);
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
@@ -217,10 +219,10 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
depends.emplace_back("all");
// Write the rule.
- lg->WriteMakeRule(makefileStream,
- "Default target executed when no arguments are "
- "given to make.",
- "default_target", depends, no_commands, true);
+ lg.WriteMakeRule(makefileStream,
+ "Default target executed when no arguments are "
+ "given to make.",
+ "default_target", depends, no_commands, true);
depends.clear();
@@ -231,7 +233,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// Write out the "special" stuff
- lg->WriteSpecialTargetsTop(makefileStream);
+ lg.WriteSpecialTargetsTop(makefileStream);
// Write the directory level rules.
for (auto const& it : this->ComputeDirectoryTargets()) {
@@ -239,13 +241,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// Write the target convenience rules
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
this->WriteConvenienceRules2(
- makefileStream, static_cast<cmLocalUnixMakefileGenerator3*>(localGen));
+ makefileStream,
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen));
}
// Write special bottom targets
- lg->WriteSpecialTargetsBottom(makefileStream);
+ lg.WriteSpecialTargetsBottom(makefileStream);
}
void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
@@ -268,12 +271,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
std::string makefileName =
cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), "/Makefile");
- // get a local generator for some useful methods
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+ {
+ // get a local generator for some useful methods
+ auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
- // Write the do not edit header.
- lg->WriteDisclaimer(cmakefileStream);
+ // Write the do not edit header.
+ lg.WriteDisclaimer(cmakefileStream);
+ }
// Save the generator name
cmakefileStream << "# The generator used is:\n"
@@ -282,9 +287,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// for each cmMakefile get its list of dependencies
std::vector<std::string> lfiles;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
// Get the list of files contributing to this generation step.
- cmAppend(lfiles, localGen->GetMakefile()->GetListFiles());
+ cm::append(lfiles, localGen->GetMakefile()->GetListFiles());
}
cmake* cm = this->GetCMakeInstance();
@@ -300,59 +305,61 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
lfiles.erase(new_end, lfiles.end());
#endif
- // reset lg to the first makefile
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
-
- std::string currentBinDir = lg->GetCurrentBinaryDirectory();
- // Save the list to the cmake file.
- cmakefileStream
- << "# The top level Makefile was generated from the following files:\n"
- << "set(CMAKE_MAKEFILE_DEPENDS\n"
- << " \"CMakeCache.txt\"\n";
- for (std::string const& f : lfiles) {
- cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir, f)
- << "\"\n";
- }
- cmakefileStream << " )\n\n";
-
- // Build the path to the cache check file.
- 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"
- << "set(CMAKE_MAKEFILE_OUTPUTS\n"
- << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir,
- makefileName)
- << "\"\n"
- << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir, check)
- << "\"\n";
- cmakefileStream << " )\n\n";
-
- const std::string binDir = lg->GetBinaryDirectory();
-
- // CMake must rerun if a byproduct is missing.
{
- cmakefileStream << "# Byproducts of CMake generate step:\n"
- << "set(CMAKE_MAKEFILE_PRODUCTS\n";
- for (std::string const& outfile : lg->GetMakefile()->GetOutputFiles()) {
+ // reset lg to the first makefile
+ const auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
+
+ const std::string& currentBinDir = lg.GetCurrentBinaryDirectory();
+ // Save the list to the cmake file.
+ cmakefileStream
+ << "# The top level Makefile was generated from the following files:\n"
+ << "set(CMAKE_MAKEFILE_DEPENDS\n"
+ << " \"CMakeCache.txt\"\n";
+ for (std::string const& f : lfiles) {
cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(binDir, outfile)
+ << lg.MaybeConvertToRelativePath(currentBinDir, f)
<< "\"\n";
}
+ cmakefileStream << " )\n\n";
+
+ // Build the path to the cache check file.
+ 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"
+ << "set(CMAKE_MAKEFILE_OUTPUTS\n"
+ << " \""
+ << lg.MaybeConvertToRelativePath(currentBinDir,
+ makefileName)
+ << "\"\n"
+ << " \""
+ << lg.MaybeConvertToRelativePath(currentBinDir, check)
+ << "\"\n";
+ cmakefileStream << " )\n\n";
+
+ const std::string& binDir = lg.GetBinaryDirectory();
+
+ // CMake must rerun if a byproduct is missing.
+ {
+ cmakefileStream << "# Byproducts of CMake generate step:\n"
+ << "set(CMAKE_MAKEFILE_PRODUCTS\n";
+ for (std::string const& outfile : lg.GetMakefile()->GetOutputFiles()) {
+ cmakefileStream << " \""
+ << lg.MaybeConvertToRelativePath(binDir, outfile)
+ << "\"\n";
+ }
+ }
// add in all the directory information files
std::string tmpStr;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
- tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(),
+ for (const auto& localGen : this->LocalGenerators) {
+ tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
"/CMakeFiles/CMakeDirectoryInformation.cmake");
cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(binDir, tmpStr)
+ << localGen->MaybeConvertToRelativePath(binDir, tmpStr)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -364,26 +371,24 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
cmGeneratedFileStream& cmakefileStream,
- std::vector<cmLocalGenerator*>& lGenerators)
+ std::vector<std::unique_ptr<cmLocalGenerator>>& lGenerators)
{
- cmLocalUnixMakefileGenerator3* lg;
-
// now list all the target info files
cmakefileStream << "# Dependency information for all targets:\n";
cmakefileStream << "set(CMAKE_DEPEND_INFO_FILES\n";
- for (cmLocalGenerator* lGenerator : lGenerators) {
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(lGenerator);
+ for (const auto& lGenerator : lGenerators) {
+ const auto& lg =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
// for all of out targets
- for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
+ for (const auto& tgt : lg.GetGeneratorTargets()) {
if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
(tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
(tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
(tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
(tgt->GetType() == cmStateEnums::UTILITY)) {
- cmGeneratorTarget* gt = tgt;
- std::string tname =
- cmStrCat(lg->GetRelativeTargetDirectory(gt), "/DependInfo.cmake");
+ std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
+ "/DependInfo.cmake");
cmSystemTools::ConvertToUnixSlashes(tname);
cmakefileStream << " \"" << tname << "\"\n";
}
@@ -487,7 +492,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
std::unique_ptr<cmMakefile> mfu;
cmMakefile* mf;
if (!this->Makefiles.empty()) {
- mf = this->Makefiles[0];
+ mf = this->Makefiles[0].get();
} else {
cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentSource(
@@ -545,11 +550,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
}
// write the target convenience rules
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+ for (const auto& localGen : this->LocalGenerators) {
+ auto& lg =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
+ for (const auto& gtarget : lg.GetGeneratorTargets()) {
// Don't emit the same rule twice (e.g. two targets with the same
// simple name)
int type = gtarget->GetType();
@@ -564,23 +569,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
(type == cmStateEnums::OBJECT_LIBRARY) ||
(type == cmStateEnums::UTILITY))) {
// Add a rule to build the target by name.
- lg->WriteDivider(ruleFileStream);
+ lg.WriteDivider(ruleFileStream);
ruleFileStream << "# Target rules for targets named " << name
<< "\n\n";
// Write the rule.
commands.clear();
std::string tmp = "CMakeFiles/Makefile2";
- commands.push_back(lg->GetRecursiveMakeCall(tmp, name));
+ commands.push_back(lg.GetRecursiveMakeCall(tmp, name));
depends.clear();
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- lg->WriteMakeRule(ruleFileStream, "Build rule for target.", name,
- depends, commands, true);
+ lg.WriteMakeRule(ruleFileStream, "Build rule for target.", name,
+ depends, commands, true);
// Add a fast rule to build the target
- std::string localName = lg->GetRelativeTargetDirectory(gtarget);
+ std::string localName = lg.GetRelativeTargetDirectory(gtarget.get());
std::string makefileName;
makefileName = cmStrCat(localName, "/build.make");
depends.clear();
@@ -588,23 +593,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
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.",
- localName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream, "fast build rule for target.",
+ localName, depends, commands, true);
// Add a local name for the rule to relink the target before
// installation.
- if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- makeTargetName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
+ makeTargetName = cmStrCat(
+ lg.GetRelativeTargetDirectory(gtarget.get()), "/preinstall");
localName = cmStrCat(name, "/preinstall");
depends.clear();
commands.clear();
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- lg->WriteMakeRule(ruleFileStream,
- "Manual pre-install relink rule for target.",
- localName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream,
+ "Manual pre-install relink rule for target.",
+ localName, depends, commands, true);
}
}
}
@@ -612,7 +617,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
}
void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
- std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg)
+ std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& lg)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
@@ -625,7 +630,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
+ for (const auto& gtarget : lg.GetGeneratorTargets()) {
int type = gtarget->GetType();
std::string name = gtarget->GetName();
if (!name.empty() &&
@@ -637,31 +642,31 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
(type == cmStateEnums::UTILITY))) {
std::string makefileName;
// Add a rule to build the target by name.
- localName = lg->GetRelativeTargetDirectory(gtarget);
+ localName = lg.GetRelativeTargetDirectory(gtarget.get());
makefileName = cmStrCat(localName, "/build.make");
- lg->WriteDivider(ruleFileStream);
+ lg.WriteDivider(ruleFileStream);
ruleFileStream << "# Target rules for target " << localName << "\n\n";
commands.clear();
makeTargetName = cmStrCat(localName, "/depend");
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
makeTargetName = cmStrCat(localName, "/build");
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
// Write the rule.
localName += "/all";
depends.clear();
cmLocalUnixMakefileGenerator3::EchoProgress progress;
- progress.Dir = cmStrCat(lg->GetBinaryDirectory(), "/CMakeFiles");
+ progress.Dir = cmStrCat(lg.GetBinaryDirectory(), "/CMakeFiles");
{
std::ostringstream progressArg;
const char* sep = "";
- for (unsigned long progFile : this->ProgressMap[gtarget].Marks) {
+ for (unsigned long progFile : this->ProgressMap[gtarget.get()].Marks) {
progressArg << sep << progFile;
sep = ",";
}
@@ -676,13 +681,13 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
if (targetMessages) {
- lg->AppendEcho(commands, "Built target " + name,
- cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+ lg.AppendEcho(commands, "Built target " + name,
+ cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
}
- this->AppendGlobalTargetDepends(depends, gtarget);
- lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
- localName, depends, commands, true);
+ this->AppendGlobalTargetDepends(depends, gtarget.get());
+ lg.WriteMakeRule(ruleFileStream, "All Build rule for target.", localName,
+ depends, commands, true);
// Write the rule.
commands.clear();
@@ -692,20 +697,21 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
- progCmd << lg->ConvertToOutputFormat(
+ progCmd << lg.ConvertToOutputFormat(
cmSystemTools::CollapseFullPath(progress.Dir),
cmOutputConverter::SHELL);
//
std::set<cmGeneratorTarget const*> emitted;
- progCmd << " " << this->CountProgressMarksInTarget(gtarget, emitted);
+ progCmd << " "
+ << this->CountProgressMarksInTarget(gtarget.get(), emitted);
commands.push_back(progCmd.str());
}
std::string tmp = "CMakeFiles/Makefile2";
- commands.push_back(lg->GetRecursiveMakeCall(tmp, localName));
+ commands.push_back(lg.GetRecursiveMakeCall(tmp, localName));
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << lg->ConvertToOutputFormat(
+ progCmd << lg.ConvertToOutputFormat(
cmSystemTools::CollapseFullPath(progress.Dir),
cmOutputConverter::SHELL);
progCmd << " 0";
@@ -715,39 +721,39 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/rule");
- lg->WriteMakeRule(ruleFileStream,
- "Build rule for subdir invocation for target.",
- localName, depends, commands, true);
+ localName =
+ cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()), "/rule");
+ lg.WriteMakeRule(ruleFileStream,
+ "Build rule for subdir invocation for target.",
+ localName, depends, commands, true);
// Add a target with the canonical name (no prefix, suffix or path).
commands.clear();
depends.clear();
depends.push_back(localName);
- lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
- depends, commands, true);
+ lg.WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
+ depends, commands, true);
// Add rules to prepare the target for installation.
- if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- localName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
+ localName = cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()),
+ "/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);
+ commands.push_back(lg.GetRecursiveMakeCall(makefileName, localName));
+ lg.WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.",
+ localName, depends, commands, true);
}
// add the clean rule
- localName = lg->GetRelativeTargetDirectory(gtarget);
+ localName = lg.GetRelativeTargetDirectory(gtarget.get());
makeTargetName = cmStrCat(localName, "/clean");
depends.clear();
commands.clear();
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
- makeTargetName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream, "clean rule for target.",
+ makeTargetName, depends, commands, true);
commands.clear();
}
}
@@ -759,8 +765,8 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
{
this->DirectoryTargetsMap.clear();
// Loop over all targets in all local generators.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
cmLocalGenerator* tlg = gt->GetLocalGenerator();
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -778,12 +784,13 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
// This local generator includes the target.
std::set<cmGeneratorTarget const*>& targetSet =
this->DirectoryTargetsMap[csnp];
- targetSet.insert(gt);
+ targetSet.insert(gt.get());
// Add dependencies of the included target. An excluded
// target may still be included if it is a dependency of a
// non-excluded target.
- for (cmTargetDepend const& tgtdep : this->GetTargetDirectDepends(gt)) {
+ for (cmTargetDepend const& tgtdep :
+ this->GetTargetDirectDepends(gt.get())) {
targetSet.insert(tgtdep);
}
}
@@ -808,12 +815,12 @@ size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInTarget(
}
size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInAll(
- cmLocalGenerator* lg)
+ const cmLocalGenerator& lg)
{
size_t count = 0;
std::set<cmGeneratorTarget const*> emitted;
for (cmGeneratorTarget const* target :
- this->DirectoryTargetsMap[lg->GetStateSnapshot()]) {
+ this->DirectoryTargetsMap[lg.GetStateSnapshot()]) {
count += this->CountProgressMarksInTarget(target, emitted);
}
return count;
@@ -885,33 +892,48 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
// Keep track of targets already listed.
std::set<std::string> emittedTargets;
+ std::set<std::string> utility_targets;
+ std::set<std::string> globals_targets;
+ std::set<std::string> project_targets;
// for each local generator
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- cmLocalUnixMakefileGenerator3* lg2 =
- static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+ for (const auto& localGen : this->LocalGenerators) {
+ const auto& lg2 =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
// for the passed in makefile or if this is the top Makefile wripte out
// the targets
- if (lg2 == lg || lg->IsRootMakefile()) {
+ if (&lg2 == lg || lg->IsRootMakefile()) {
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* target : lg2->GetGeneratorTargets()) {
+ for (const auto& target : lg2.GetGeneratorTargets()) {
cmStateEnums::TargetType type = target->GetType();
if ((type == cmStateEnums::EXECUTABLE) ||
(type == cmStateEnums::STATIC_LIBRARY) ||
(type == cmStateEnums::SHARED_LIBRARY) ||
(type == cmStateEnums::MODULE_LIBRARY) ||
- (type == cmStateEnums::OBJECT_LIBRARY) ||
- (type == cmStateEnums::GLOBAL_TARGET) ||
- (type == cmStateEnums::UTILITY)) {
- std::string const& name = target->GetName();
- if (emittedTargets.insert(name).second) {
- path = cmStrCat("... ", name);
- lg->AppendEcho(commands, path);
- }
+ (type == cmStateEnums::OBJECT_LIBRARY)) {
+ project_targets.insert(target->GetName());
+ } else if (type == cmStateEnums::GLOBAL_TARGET) {
+ globals_targets.insert(target->GetName());
+ } else if (type == cmStateEnums::UTILITY) {
+ utility_targets.insert(target->GetName());
}
}
}
}
+
+ for (std::string const& name : globals_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+ for (std::string const& name : utility_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+ for (std::string const& name : project_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+
for (std::string const& o : lg->GetLocalHelp()) {
path = cmStrCat("... ", o);
lg->AppendEcho(commands, path);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 79db30ebd6..340a7efa5b 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -8,6 +8,7 @@
#include <cstddef>
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -61,10 +62,10 @@ class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
{
public:
cmGlobalUnixMakefileGenerator3(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalUnixMakefileGenerator3>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
}
//! Get the name for the generator.
@@ -89,7 +90,8 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -107,8 +109,9 @@ public:
*/
void Generate() override;
- void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
- std::vector<cmLocalGenerator*>&);
+ void WriteMainCMakefileLanguageRules(
+ cmGeneratedFileStream& cmakefileStream,
+ std::vector<std::unique_ptr<cmLocalGenerator>>&);
// write out the help rule listing the valid targets
void WriteHelpRule(std::ostream& ruleFileStream,
@@ -161,7 +164,7 @@ protected:
void WriteMainCMakefile();
void WriteConvenienceRules2(std::ostream& ruleFileStream,
- cmLocalUnixMakefileGenerator3*);
+ cmLocalUnixMakefileGenerator3&);
void WriteDirectoryRule2(std::ostream& ruleFileStream,
DirectoryTarget const& dt, const char* pass,
@@ -227,7 +230,7 @@ protected:
size_t CountProgressMarksInTarget(
cmGeneratorTarget const* target,
std::set<cmGeneratorTarget const*>& emitted);
- size_t CountProgressMarksInAll(cmLocalGenerator* lg);
+ size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
cmGeneratedFileStream* CommandDatabase;
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index f6472ab069..ccb6c50f14 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -4,6 +4,8 @@
#include <algorithm>
+#include <cm/memory>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -26,6 +28,16 @@
static const char vs10generatorName[] = "Visual Studio 10 2010";
static std::map<std::string, std::vector<cmIDEFlagTable>> loadedFlagJsonFiles;
+static void ConvertToWindowsSlashes(std::string& s)
+{
+ // first convert all of the slashes
+ for (auto& ch : s) {
+ if (ch == '/') {
+ ch = '\\';
+ }
+ }
+}
+
// Map generator name without year to name with year.
static const char* cmVS10GenName(const std::string& name, std::string& genName)
{
@@ -45,27 +57,30 @@ class cmGlobalVisualStudio10Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS10GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, "x64"));
}
if (strcmp(p, "IA64") == 0) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "Itanium");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, "Itanium"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -105,9 +120,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio10Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
@@ -193,7 +209,7 @@ static void cmCudaToolVersion(std::string& s)
}
bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
- std::string const& ts, cmMakefile* mf)
+ std::string const& ts, bool build, cmMakefile* mf)
{
if (this->SystemIsWindowsCE && ts.empty() &&
this->DefaultPlatformToolset.empty()) {
@@ -208,7 +224,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return false;
}
- if (!this->FindVCTargetsPath(mf)) {
+ if (build) {
+ return true;
+ }
+
+ if (this->CustomVCTargetsPath.empty() && !this->FindVCTargetsPath(mf)) {
return false;
}
@@ -355,6 +375,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir);
}
+ if (const char* vcTargetsDir = this->GetCustomVCTargetsPath()) {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR",
+ vcTargetsDir);
+ }
+
return true;
}
@@ -448,6 +473,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
this->GeneratorToolsetVersion = value;
return true;
}
+ if (key == "VCTargetsPath") {
+ this->CustomVCTargetsPath = value;
+ ConvertToWindowsSlashes(this->CustomVCTargetsPath);
+ return true;
+ }
return false;
}
@@ -556,10 +586,11 @@ std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalVisualStudio10Generator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalVisualStudio10Generator>(this, mf));
}
void cmGlobalVisualStudio10Generator::Generate()
@@ -590,7 +621,7 @@ void cmGlobalVisualStudio10Generator::Generate()
"To avoid this problem CMake must use a full path for this file "
"which then triggers the VS 10 property dialog bug.";
/* clang-format on */
- lg->IssueMessage(MessageType::WARNING, e.str().c_str());
+ lg->IssueMessage(MessageType::WARNING, e.str());
}
}
@@ -609,6 +640,14 @@ void cmGlobalVisualStudio10Generator::EnableLanguage(
cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
}
+const char* cmGlobalVisualStudio10Generator::GetCustomVCTargetsPath() const
+{
+ if (this->CustomVCTargetsPath.empty()) {
+ return nullptr;
+ }
+ return this->CustomVCTargetsPath.c_str();
+}
+
const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const
{
std::string const& toolset = this->GetPlatformToolsetString();
@@ -803,7 +842,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
// Prepare the work directory.
if (!cmSystemTools::MakeDirectory(wd)) {
std::string e = "Failed to make directory:\n " + wd;
- mf->IssueMessage(MessageType::FATAL_ERROR, e.c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -924,7 +963,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
if (ret != 0) {
e << "Exit code: " << ret << "\n";
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -1098,8 +1137,7 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile(
// Hide them away under the CMakeFiles directory.
std::string ruleDir = cmStrCat(
this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/",
- cmSystemTools::ComputeStringMD5(
- cmSystemTools::GetFilenamePath(output).c_str()));
+ cmSystemTools::ComputeStringMD5(cmSystemTools::GetFilenamePath(output)));
std::string ruleFile =
cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule");
return ruleFile;
@@ -1293,7 +1331,7 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::LoadFlagTable(
e << "JSON flag table \"" << filename <<
"\" could not be loaded.\n";
/* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
return ret;
}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 56f119363b..f659ff3e37 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio10Generator_h
#define cmGlobalVisualStudio10Generator_h
+#include <memory>
+
#include "cmGlobalVisualStudio8Generator.h"
#include "cmVisualStudio10ToolsetOptions.h"
@@ -14,13 +16,14 @@
class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
bool SetSystemName(std::string const& s, cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
@@ -30,7 +33,8 @@ public:
std::vector<std::string>()) override;
//! create the correct local generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -45,6 +49,9 @@ public:
bool IsNsightTegra() const;
std::string GetNsightTegraVersion() const;
+ /** The vctargets path for the target platform. */
+ const char* GetCustomVCTargetsPath() const;
+
/** The toolset name for the target platform. */
const char* GetPlatformToolset() const;
std::string const& GetPlatformToolsetString() const;
@@ -157,6 +164,7 @@ protected:
std::string GeneratorToolset;
std::string GeneratorToolsetVersion;
std::string GeneratorToolsetHostArchitecture;
+ std::string GeneratorToolsetCustomVCTargetsDir;
std::string GeneratorToolsetCuda;
std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
@@ -209,6 +217,7 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ std::string CustomVCTargetsPath;
std::string VCTargetsPath;
bool FindVCTargetsPath(cmMakefile* mf);
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 4b74ef1b2d..a385375d64 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio11Generator.h"
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -28,38 +30,41 @@ class cmGlobalVisualStudio11Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS11GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, "ARM"));
}
std::set<std::string> installedSDKs =
cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
if (installedSDKs.find(p) == installedSDKs.end()) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- cmGlobalVisualStudio11Generator* ret =
- new cmGlobalVisualStudio11Generator(cm, name, p);
+ auto ret = std::unique_ptr<cmGlobalVisualStudio11Generator>(
+ new cmGlobalVisualStudio11Generator(cm, name, p));
ret->WindowsCEVersion = "8.00";
- return ret;
+ return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -113,9 +118,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio11Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index f8cce18980..5f1ff737e0 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
@@ -20,7 +21,7 @@ class cmake;
class cmGlobalVisualStudio11Generator : public cmGlobalVisualStudio10Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index d9702c9eed..5a27994872 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -28,27 +28,30 @@ class cmGlobalVisualStudio12Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS12GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -88,9 +91,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio12Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 53b709157a..bdd40ff6eb 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio11Generator.h"
@@ -18,7 +19,7 @@ class cmake;
class cmGlobalVisualStudio12Generator : public cmGlobalVisualStudio11Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index cd48474272..f549b6aae6 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio14Generator.h"
-#include "cmAlgorithms.h"
+#include <cm/vector>
+
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -28,27 +29,30 @@ class cmGlobalVisualStudio14Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS14GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -88,9 +92,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio14Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
@@ -299,7 +304,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that do not contain <um/windows.h> because that indicates that
// only the UCRT MSIs were installed for them.
- cmEraseIf(sdks, NoWindowsH());
+ cm::erase_if(sdks, NoWindowsH());
// Only use the filename, which will be the SDK version.
for (std::string& i : sdks) {
@@ -309,7 +314,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that cannot be used with our toolset.
std::string maxVersion = this->GetWindows10SDKMaxVersion();
if (!maxVersion.empty()) {
- cmEraseIf(sdks, WindowsSDKTooRecent(maxVersion));
+ cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion));
}
// Sort the results to make sure we select the most recent one.
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index 6e12d3e2c2..ccc29177ef 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio12Generator.h"
@@ -18,7 +19,7 @@ class cmake;
class cmGlobalVisualStudio14Generator : public cmGlobalVisualStudio12Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index e8e9eced93..d0aec6193d 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -87,7 +87,7 @@ void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
// the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
const std::string& dspname,
- const char* dir,
+ const std::string& dir,
cmGeneratorTarget const* t)
{
// check to see if this is a fortran build
@@ -109,7 +109,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
std::string guid = this->GetGUID(dspname);
fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir)
- << (dir[0] ? "\\" : "") << dspname << ext << "\", \"{" << guid
+ << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid
<< "}\"\n";
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
this->WriteProjectDepends(fout, dspname, dir, t);
@@ -138,7 +138,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteProjectDepends(
- std::ostream& fout, const std::string&, const char*,
+ std::ostream& fout, const std::string&, const std::string&,
cmGeneratorTarget const* target)
{
VSDependSet const& depends = this->VSTargetDepends[target];
@@ -156,8 +156,9 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends(
// Write a dsp file into the SLN file, Note, that dependencies from
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteExternalProject(
- std::ostream& fout, const std::string& name, const char* location,
- const char* typeGuid, const std::set<BT<std::string>>& depends)
+ std::ostream& fout, const std::string& name, const std::string& location,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& depends)
{
fout << "Project(\"{"
<< (typeGuid ? typeGuid : this->ExternalProjectType(location))
@@ -169,8 +170,8 @@ void cmGlobalVisualStudio71Generator::WriteExternalProject(
// project instead of in the global section
if (!depends.empty()) {
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
- for (BT<std::string> const& it : depends) {
- std::string const& dep = it.Value;
+ for (BT<std::pair<std::string, bool>> const& it : depends) {
+ std::string const& dep = it.Value.first;
if (!dep.empty()) {
fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep)
<< "}\n";
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index 85755af60d..7eadaf3bf4 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -22,18 +22,20 @@ protected:
virtual void WriteSolutionConfigurations(
std::ostream& fout, std::vector<std::string> const& configs);
void WriteProject(std::ostream& fout, const std::string& name,
- const char* path, const cmGeneratorTarget* t) override;
+ const std::string& path,
+ const cmGeneratorTarget* t) override;
void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
cmGeneratorTarget const* t) override;
void WriteProjectConfigurations(
std::ostream& fout, const std::string& name,
cmGeneratorTarget const& target, std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
const std::string& platformMapping = "") override;
- void WriteExternalProject(std::ostream& fout, const std::string& name,
- const char* path, const char* typeGuid,
- const std::set<BT<std::string>>& depends) override;
+ void WriteExternalProject(
+ std::ostream& fout, const std::string& name, const std::string& path,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& depends) override;
// Folders are not supported by VS 7.1.
bool UseFolderProperty() const override { return false; }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 40b214c032..97991240b5 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -2,8 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio7Generator.h"
+#include <utility>
#include <vector>
+#include <cm/memory>
#include <cm/string_view>
#include <windows.h>
@@ -184,7 +186,7 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
}
const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
- const char* location)
+ const std::string& location)
{
std::string extension = cmSystemTools::GetFilenameLastExtension(location);
if (extension == ".vbproj") {
@@ -263,12 +265,11 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio7Generator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalVisualStudio7Generator* lg =
- new cmLocalVisualStudio7Generator(this, mf);
- return lg;
+ auto lg = cm::make_unique<cmLocalVisualStudio7Generator>(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(std::move(lg));
}
#if !defined(CMAKE_BOOTSTRAP)
@@ -300,7 +301,7 @@ void cmGlobalVisualStudio7Generator::Generate()
if (!cmSystemTools::GetErrorOccuredFlag() &&
!this->LocalGenerators.empty()) {
this->CallVisualStudioMacro(MacroReload,
- GetSLNFile(this->LocalGenerators[0]));
+ GetSLNFile(this->LocalGenerators[0].get()));
}
}
@@ -345,8 +346,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
if (expath) {
std::set<std::string> allConfigurations(configs.begin(), configs.end());
const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
- this->WriteProjectConfigurations(fout, target->GetName().c_str(),
- *target, configs, allConfigurations,
+ this->WriteProjectConfigurations(fout, target->GetName(), *target,
+ configs, allConfigurations,
mapping ? mapping : "");
} else {
const std::set<std::string>& configsPartOfDefaultBuild =
@@ -379,7 +380,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::string project = target->GetName();
std::string location = expath;
- this->WriteExternalProject(fout, project.c_str(), location.c_str(),
+ this->WriteExternalProject(fout, project, location,
target->GetProperty("VS_PROJECT_TYPE"),
target->GetUtilities());
written = true;
@@ -388,11 +389,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
if (vcprojName) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
- dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str());
+ dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir);
if (dir == ".") {
dir.clear(); // msbuild cannot handle ".\" prefix
}
- this->WriteProject(fout, vcprojName, dir.c_str(), target);
+ this->WriteProject(fout, vcprojName, dir, target);
written = true;
}
}
@@ -482,7 +483,7 @@ void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
}
std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath(
- const char* path)
+ const std::string& path)
{
// Convert to backslashes. Do not use ConvertToOutputPath because
// we will add quoting ourselves, and we know these projects always
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 7a9fcefa24..6cc1cf86d8 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio7Generator_h
#define cmGlobalVisualStudio7Generator_h
+#include <memory>
+
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -20,7 +22,8 @@ public:
~cmGlobalVisualStudio7Generator();
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
#if !defined(CMAKE_BOOTSTRAP)
Json::Value GetJson() const override;
@@ -107,16 +110,17 @@ protected:
std::string const& GetDevEnvCommand();
virtual std::string FindDevEnvCommand();
- static const char* ExternalProjectType(const char* location);
+ static const char* ExternalProjectType(const std::string& location);
virtual void OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators) = 0;
virtual void WriteProject(std::ostream& fout, const std::string& name,
- const char* path, const cmGeneratorTarget* t) = 0;
+ const std::string& path,
+ const cmGeneratorTarget* t) = 0;
virtual void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
cmGeneratorTarget const* t) = 0;
virtual void WriteProjectConfigurations(
std::ostream& fout, const std::string& name,
@@ -138,10 +142,11 @@ protected:
OrderedTargetDependSet const& projectTargets);
virtual void WriteExternalProject(
- std::ostream& fout, const std::string& name, const char* path,
- const char* typeGuid, const std::set<BT<std::string>>& dependencies) = 0;
+ std::ostream& fout, const std::string& name, const std::string& path,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
- std::string ConvertToSolutionPath(const char* path);
+ std::string ConvertToSolutionPath(const std::string& path);
std::set<std::string> IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 8e6125b8a2..1c62fbd918 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio8Generator.h"
+#include <cm/memory>
+#include <cmext/memory>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
@@ -96,21 +99,22 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
return false;
}
- std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
- cmLocalVisualStudio7Generator* lg =
- static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
- cmMakefile* mf = lg->GetMakefile();
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& generators =
+ this->LocalGenerators;
+ auto& lg =
+ cm::static_reference_cast<cmLocalVisualStudio7Generator>(generators[0]);
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, cmCommandOrigin::Generator, false,
- no_working_directory, no_byproducts, no_depends, no_commands);
+ cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
+ no_working_directory, no_byproducts,
+ no_depends, no_commands);
- cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
- lg->AddGeneratorTarget(gt);
+ auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
+ auto gt = ptr.get();
+ lg.AddGeneratorTarget(std::move(ptr));
// Organize in the "predefined targets" folder:
//
@@ -128,7 +132,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
stampList);
std::string stampFile;
cmGeneratedFileStream fout(stampListFile.c_str());
- for (cmLocalGenerator const* gi : generators) {
+ for (const auto& gi : generators) {
stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
"/CMakeFiles/generate.stamp");
fout << stampFile << "\n";
@@ -141,8 +145,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Collect the input files used to generate all targets in this
// project.
std::vector<std::string> listFiles;
- for (cmLocalGenerator* gen : generators) {
- cmAppend(listFiles, gen->GetMakefile()->GetListFiles());
+ for (const auto& gen : generators) {
+ cm::append(listFiles, gen->GetMakefile()->GetListFiles());
}
// Add a custom prebuild target to run the VerifyGlobs script.
@@ -153,7 +157,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
std::vector<std::string> byproducts;
byproducts.push_back(cm->GetGlobVerifyStamp());
- mf->AddCustomCommandToTarget(
+ lg.AddCustomCommandToTarget(
CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
verifyCommandLines, cmCustomCommandType::PRE_BUILD,
"Checking File Globs", no_working_directory, false);
@@ -171,10 +175,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.erase(new_end, listFiles.end());
// Create a rule to re-run CMake.
- std::string argS = cmStrCat("-S", lg->GetSourceDirectory());
- std::string argB = cmStrCat("-B", lg->GetBinaryDirectory());
+ std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
+ std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
std::string const sln =
- lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln";
+ lg.GetBinaryDirectory() + "/" + lg.GetProjectName() + ".sln";
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
stampList, "--vs-solution-file", sln });
@@ -185,7 +189,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// (this could be avoided with per-target source files)
std::string no_main_dependency;
cmImplicitDependsList no_implicit_depends;
- if (cmSourceFile* file = mf->AddCustomCommandToOutput(
+ if (cmSourceFile* file = lg.AddCustomCommandToOutput(
stamps, no_byproducts, listFiles, no_main_dependency,
no_implicit_depends, commandLines, "Checking Build System",
no_working_directory, true, false)) {
@@ -203,12 +207,11 @@ void cmGlobalVisualStudio8Generator::AddExtraIDETargets()
cmGlobalVisualStudio7Generator::AddExtraIDETargets();
if (this->AddCheckTarget()) {
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- const std::vector<cmGeneratorTarget*>& tgts =
- this->LocalGenerators[i]->GetGeneratorTargets();
+ const auto& tgts = this->LocalGenerators[i]->GetGeneratorTargets();
// All targets depend on the build-system check target.
- for (cmGeneratorTarget const* ti : tgts) {
+ for (const auto& ti : tgts) {
if (ti->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- ti->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ ti->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false);
}
}
}
@@ -304,7 +307,7 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
}
void cmGlobalVisualStudio8Generator::WriteProjectDepends(
- std::ostream& fout, const std::string&, const char*,
+ std::ostream& fout, const std::string&, const std::string&,
cmGeneratorTarget const* gt)
{
TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
@@ -322,9 +325,10 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
cmGeneratorTarget* target)
{
// Look for utility dependencies that magically link.
- for (BT<std::string> const& ui : target->GetUtilities()) {
+ for (BT<std::pair<std::string, bool>> const& ui : target->GetUtilities()) {
if (cmGeneratorTarget* depTarget =
- target->GetLocalGenerator()->FindGeneratorTargetToUse(ui.Value)) {
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(
+ ui.Value.first)) {
if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
// This utility dependency names an external .vcproj target.
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 352bc3c2bc..8f8e33b8ed 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -74,7 +74,7 @@ protected:
const std::string& platformMapping = "") override;
bool ComputeTargetDepends() override;
void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
const cmGeneratorTarget* t) override;
bool UseFolderProperty() const override;
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 6e61d2681c..9f73c15f0f 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio9Generator.h"
+#include <utility>
+
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -13,43 +15,46 @@ static const char vs9generatorName[] = "Visual Studio 9 2008";
class cmGlobalVisualStudio9Generator::Factory : public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
if (strncmp(name.c_str(), vs9generatorName,
sizeof(vs9generatorName) - 1) != 0) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
const char* p = name.c_str() + sizeof(vs9generatorName) - 1;
if (p[0] == '\0') {
- return new cmGlobalVisualStudio9Generator(cm, name, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, ""));
}
if (p[0] != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
++p;
if (!strcmp(p, "IA64")) {
- return new cmGlobalVisualStudio9Generator(cm, name, "Itanium");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, "Itanium"));
}
if (!strcmp(p, "Win64")) {
- return new cmGlobalVisualStudio9Generator(cm, name, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, "x64"));
}
cmVisualStudioWCEPlatformParser parser(p);
parser.ParseVersion("9.0");
if (!parser.Found()) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- cmGlobalVisualStudio9Generator* ret =
- new cmGlobalVisualStudio9Generator(cm, name, p);
+ auto ret = std::unique_ptr<cmGlobalVisualStudio9Generator>(
+ new cmGlobalVisualStudio9Generator(cm, name, p));
ret->WindowsCEVersion = parser.GetOSVersion();
- return ret;
+ return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -103,9 +108,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio9Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
index 7bebfd65f2..53318a62b1 100644
--- a/Source/cmGlobalVisualStudio9Generator.h
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio9Generator_h
#define cmGlobalVisualStudio9Generator_h
+#include <memory>
+
#include "cmGlobalVisualStudio8Generator.h"
/** \class cmGlobalVisualStudio9Generator
@@ -13,7 +15,7 @@
class cmGlobalVisualStudio9Generator : public cmGlobalVisualStudio8Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
/**
* Where does this version of Visual Studio look for macros for the
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index ed0cba7ddf..1ec1559106 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -7,6 +7,7 @@
#include <iostream>
#include <cm/iterator>
+#include <cm/memory>
#include <windows.h>
@@ -196,12 +197,12 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
if (!gen.empty()) {
// 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", cmCommandOrigin::Generator, true, no_working_dir,
- no_byproducts, no_depends, no_commands, false, "Build all projects");
+ cmTarget* allBuild = gen[0]->AddUtilityCommand(
+ "ALL_BUILD", 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);
+ gen[0]->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(allBuild, gen[0]));
//
// Organize in the "predefined targets" folder:
@@ -212,13 +213,13 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
// Now make all targets depend on the ALL_BUILD target
for (cmLocalGenerator const* i : gen) {
- for (cmGeneratorTarget* tgt : i->GetGeneratorTargets()) {
+ for (const auto& tgt : i->GetGeneratorTargets()) {
if (tgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
tgt->IsImported()) {
continue;
}
- if (!this->IsExcluded(gen[0], tgt)) {
- allBuild->AddUtility(tgt->GetName());
+ if (!this->IsExcluded(gen[0], tgt.get())) {
+ allBuild->AddUtility(tgt->GetName(), false);
}
}
}
@@ -307,7 +308,7 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
if (!dir.empty()) {
std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
std::string nextSubkeyName;
- if (cmSystemTools::FileExists(macrosFile.c_str()) &&
+ if (cmSystemTools::FileExists(macrosFile) &&
IsVisualStudioMacrosFileRegistered(
macrosFile, this->GetUserMacrosRegKeyBase(), nextSubkeyName)) {
if (m == MacroReload) {
@@ -389,8 +390,8 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
}
for (auto const& it : this->ProjectMap) {
for (const cmLocalGenerator* i : it.second) {
- for (cmGeneratorTarget* ti : i->GetGeneratorTargets()) {
- this->ComputeVSTargetDepends(ti);
+ for (const auto& ti : i->GetGeneratorTargets()) {
+ this->ComputeVSTargetDepends(ti.get());
}
}
}
@@ -592,7 +593,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
std::string filepath;
std::string filepathname;
std::string filepathpath;
- if (cmSystemTools::FileExists(fullname.c_str())) {
+ if (cmSystemTools::FileExists(fullname)) {
filename = cmSystemTools::GetFilenameName(fullname);
filepath = cmSystemTools::GetFilenamePath(fullname);
filepathname = cmSystemTools::GetFilenameName(filepath);
@@ -799,19 +800,9 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
cmGeneratorTarget const* gt)
{
- // check to see if this is a fortran build
- {
- // Issue diagnostic if the source files depend on the config.
- std::vector<cmSourceFile*> sources;
- if (!gt->GetConfigCommonSourceFiles(sources)) {
- return false;
- }
- }
-
// If there's only one source language, Fortran has to be used
// in order for the sources to compile.
- std::set<std::string> languages;
- gt->GetLanguages(languages, "");
+ std::set<std::string> languages = gt->GetAllConfigCompileLanguages();
// Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
// This allows the project to control the language choice in
@@ -926,7 +917,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
std::string objFile = it;
// replace $(ConfigurationName) in the object names
cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
- configName.c_str());
+ configName);
if (cmHasLiteralSuffix(objFile, ".obj")) {
fout << objFile << "\n";
}
@@ -939,9 +930,10 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
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);
+ cmCustomCommand command(outputs, empty, empty, commandLines,
+ gt->Target->GetMakefile()->GetBacktrace(),
+ "Auto build dll exports", ".");
+ commands.push_back(std::move(command));
}
static bool OpenSolution(std::string sln)
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 4f2007f758..29a5c2cdc1 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -150,6 +150,8 @@ public:
bool Open(const std::string& bindir, const std::string& projectName,
bool dryRun) override;
+ bool IsVisualStudio() const override { return true; }
+
protected:
cmGlobalVisualStudioGenerator(cmake* cm,
std::string const& platformInGeneratorName);
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index a371633ed0..13ae32a554 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -121,30 +121,33 @@ class cmGlobalVisualStudioVersionedGenerator::Factory15
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS15GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -185,10 +188,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory*
+std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory15()
{
- return new Factory15;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory15);
}
static const char vs16generatorName[] = "Visual Studio 16 2019";
@@ -212,19 +215,20 @@ class cmGlobalVisualStudioVersionedGenerator::Factory16
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS16GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS16, cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS16, cm, genName, ""));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -265,10 +269,10 @@ public:
}
};
-cmGlobalGeneratorFactory*
+std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory16()
{
- return new Factory16;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory16);
}
cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index 466816ba8b..abb609536e 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio14Generator.h"
@@ -19,8 +20,8 @@ class cmGlobalVisualStudioVersionedGenerator
: public cmGlobalVisualStudio14Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory15();
- static cmGlobalGeneratorFactory* NewFactory16();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory15();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory16();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 64ace13597..c0daf8a7fe 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -25,9 +26,10 @@ class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalWatcomWMakeGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalWatcomWMakeGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalWatcomWMakeGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index aee475b092..e0005a4ed1 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalXCodeGenerator.h"
+#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
@@ -9,6 +10,7 @@
#include <sstream>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -129,8 +131,8 @@ public:
class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override;
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override;
void GetDocumentation(cmDocumentationEntry& entry) const override
{
@@ -179,16 +181,17 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(
cm->GetState()->SetIsGeneratorMultiConfig(true);
}
-cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory> cmGlobalXCodeGenerator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
-cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
- const std::string& name, cmake* cm) const
+std::unique_ptr<cmGlobalGenerator>
+cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name,
+ cmake* cm) const
{
if (name != GetActualName()) {
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
#if !defined(CMAKE_BOOTSTRAP)
cmXcodeVersionParser parser;
@@ -224,16 +227,17 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
if (version_number < 50) {
cm->IssueMessage(MessageType::FATAL_ERROR,
"Xcode " + version_string + " not supported.");
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- auto gg = cm::make_unique<cmGlobalXCodeGenerator>(cm, version_string,
- version_number);
- return gg.release();
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalXCodeGenerator>(cm, version_string,
+ version_number));
#else
std::cerr << "CMake should be built with cmake to use Xcode, "
"default to Xcode 1.5\n";
- return new cmGlobalXCodeGenerator(cm);
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalXCodeGenerator>(cm));
#endif
}
@@ -267,7 +271,7 @@ std::string cmGlobalXCodeGenerator::FindXcodeBuildCommand()
}
bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
- cmMakefile* mf)
+ bool build, cmMakefile* mf)
{
if (ts.find_first_of(",=") != std::string::npos) {
std::ostringstream e;
@@ -283,6 +287,9 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
return false;
}
this->GeneratorToolset = ts;
+ if (build) {
+ return true;
+ }
if (!this->GeneratorToolset.empty()) {
mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset);
}
@@ -388,9 +395,11 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalXCodeGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalXCodeGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalXCodeGenerator>(this, mf));
}
void cmGlobalXCodeGenerator::AddExtraIDETargets()
@@ -409,10 +418,10 @@ void cmGlobalXCodeGenerator::ComputeTargetOrder()
{
size_t index = 0;
auto const& lgens = this->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgens) {
- auto const& targets = lgen->GetGeneratorTargets();
- for (cmGeneratorTarget const* gt : targets) {
- this->ComputeTargetOrder(gt, index);
+ for (auto const& lgen : lgens) {
+ const auto& targets = lgen->GetGeneratorTargets();
+ for (const auto& gt : targets) {
+ this->ComputeTargetOrder(gt.get(), index);
}
}
assert(index == this->TargetOrderIndex.size());
@@ -496,20 +505,16 @@ std::string cmGlobalXCodeGenerator::PostBuildMakeTarget(
void cmGlobalXCodeGenerator::AddExtraTargets(
cmLocalGenerator* root, std::vector<cmLocalGenerator*>& gens)
{
- cmMakefile* mf = root->GetMakefile();
-
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", cmCommandOrigin::Generator, true, no_working_directory,
- no_byproducts, no_depends,
+ cmTarget* allbuild = root->AddUtilityCommand(
+ "ALL_BUILD", true, no_working_directory, no_byproducts, no_depends,
cmMakeSingleCommandLine({ "echo", "Build all projects" }));
- cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
- root->AddGeneratorTarget(allBuildGt);
+ root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(allbuild, root));
// Add XCODE depend helper
std::string dir = root->GetCurrentBinaryDirectory();
@@ -520,52 +525,53 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
// Add ZERO_CHECK
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
bool generateTopLevelProjectOnly =
- mf->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY");
+ root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY");
bool isTopLevel =
!root->GetStateSnapshot().GetBuildsystemDirectoryParent().IsValid();
- if (regenerate && (isTopLevel || !generateTopLevelProjectOnly)) {
+ bool isGenerateProject = isTopLevel || !generateTopLevelProjectOnly;
+ if (regenerate && isGenerateProject) {
this->CreateReRunCMakeFile(root, gens);
std::string file =
this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile);
cmSystemTools::ReplaceString(file, "\\ ", " ");
- cmTarget* check = mf->AddUtilityCommand(
- CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, true,
- no_working_directory, no_byproducts, no_depends,
- cmMakeSingleCommandLine({ "make", "-f", file }));
+ cmTarget* check =
+ root->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true,
+ no_working_directory, no_byproducts, no_depends,
+ cmMakeSingleCommandLine({ "make", "-f", file }));
- cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
- root->AddGeneratorTarget(checkGt);
+ root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(check, root));
}
// now make the allbuild depend on all the non-utility targets
// in the project
for (auto& gen : gens) {
- for (auto target : gen->GetGeneratorTargets()) {
+ for (const auto& target : gen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
continue;
}
if (regenerate &&
(target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) {
- target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false);
}
// make all exe, shared libs and modules
// run the depend check makefile as a post build rule
// this will make sure that when the next target is built
// things are up-to-date
- if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ if (isGenerateProject &&
+ target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
commandLines.front().back() = // fill placeholder
this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)");
- gen->GetMakefile()->AddCustomCommandToTarget(
+ gen->AddCustomCommandToTarget(
target->GetName(), no_byproducts, no_depends, commandLines,
cmCustomCommandType::POST_BUILD, "Depend check for xcode",
dir.c_str(), true, false, "", "", false,
cmObjectLibraryCommands::Accept);
}
- if (!this->IsExcluded(gens[0], target)) {
- allbuild->AddUtility(target->GetName());
+ if (!this->IsExcluded(gens[0], target.get())) {
+ allbuild->AddUtility(target->GetName(), false);
}
}
}
@@ -576,7 +582,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
{
std::vector<std::string> lfiles;
for (auto gen : gens) {
- cmAppend(lfiles, gen->GetMakefile()->GetListFiles());
+ cm::append(lfiles, gen->GetMakefile()->GetListFiles());
}
// sort the array
@@ -1093,8 +1099,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets)
{
this->SetCurrentLocalGenerator(gen);
- std::vector<cmGeneratorTarget*> gts =
- this->CurrentLocalGenerator->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> gts;
+ cm::append(gts, this->CurrentLocalGenerator->GetGeneratorTargets());
std::sort(gts.begin(), gts.end(),
[this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) {
return this->TargetOrderIndex[l] < this->TargetOrderIndex[r];
@@ -1364,11 +1370,11 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
void cmGlobalXCodeGenerator::ForceLinkerLanguages()
{
- for (auto localGenerator : this->LocalGenerators) {
+ for (const auto& localGenerator : this->LocalGenerators) {
// All targets depend on the build-system check target.
- for (auto tgt : localGenerator->GetGeneratorTargets()) {
+ for (const auto& tgt : localGenerator->GetGeneratorTargets()) {
// This makes sure all targets link using the proper language.
- this->ForceLinkerLanguage(tgt);
+ this->ForceLinkerLanguage(tgt.get());
}
}
}
@@ -1460,12 +1466,12 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
{ 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>(),
- std::vector<std::string>(), cmd,
- "Creating symlinks", "");
+ cmCustomCommand command(
+ std::vector<std::string>(), std::vector<std::string>(),
+ std::vector<std::string>(), cmd, this->CurrentMakefile->GetBacktrace(),
+ "Creating symlinks", "");
- postbuild.push_back(command);
+ postbuild.push_back(std::move(command));
}
std::vector<cmSourceFile*> classes;
@@ -2353,9 +2359,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("SECTORDER_FLAGS", this->CreateString(""));
buildSettings->AddAttribute("USE_HEADERMAP", this->CreateString("NO"));
cmXCodeObject* group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
- group->AddObject(this->CreateString("-Wmost"));
- group->AddObject(this->CreateString("-Wno-four-char-constants"));
- group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
group->AddObject(this->CreateString("$(inherited)"));
buildSettings->AddAttribute("WARNING_CFLAGS", group);
@@ -2365,8 +2368,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
int minor;
int patch;
- // VERSION -> current_version
- gtgt->GetTargetVersion(false, major, minor, patch);
+ // MACHO_CURRENT_VERSION or VERSION -> current_version
+ gtgt->GetTargetVersionFallback("MACHO_CURRENT_VERSION", "VERSION", major,
+ minor, patch);
std::ostringstream v;
// Xcode always wants at least 1.0.0 or nothing
@@ -2376,8 +2380,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString(v.str()));
- // SOVERSION -> compatibility_version
- gtgt->GetTargetVersion(true, major, minor, patch);
+ // MACHO_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version
+ gtgt->GetTargetVersionFallback("MACHO_COMPATIBILITY_VERSION", "SOVERSION",
+ major, minor, patch);
std::ostringstream vso;
// Xcode always wants at least 1.0.0 or nothing
@@ -2834,7 +2839,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(
for (auto& generator : generators) {
cmMakefile* mf = generator->GetMakefile();
std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
- for (auto gtgt : generator->GetGeneratorTargets()) {
+ for (const auto& gtgt : generator->GetGeneratorTargets()) {
// Same skipping logic here as in CreateXCodeTargets so that we do not
// end up with (empty anyhow) ZERO_CHECK, install, or test source
// groups:
@@ -2849,11 +2854,12 @@ bool cmGlobalXCodeGenerator::CreateGroups(
continue;
}
- auto addSourceToGroup = [this, mf, gtgt,
+ auto addSourceToGroup = [this, mf, &gtgt,
&sourceGroups](std::string const& source) {
cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
- cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
- std::string key = GetGroupMapKeyFromPath(gtgt, source);
+ cmXCodeObject* pbxgroup =
+ this->CreateOrGetPBXGroup(gtgt.get(), sourceGroup);
+ std::string key = GetGroupMapKeyFromPath(gtgt.get(), source);
this->GroupMap[key] = pbxgroup;
};
@@ -2879,7 +2885,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(
// Add the Info.plist we are about to generate for an App Bundle.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
- std::string plist = this->ComputeInfoPListLocation(gtgt);
+ std::string plist = this->ComputeInfoPListLocation(gtgt.get());
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
plist, true, cmSourceFileLocationKind::Known);
addSourceToGroup(sf->ResolveFullPath());
@@ -3415,7 +3421,7 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
(root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
obj->GetTarget()->GetPropertyAsBool("XCODE_GENERATE_SCHEME"))) {
const std::string& targetName = obj->GetTarget()->GetName();
- cmXCodeScheme schm(obj, testables[targetName],
+ cmXCodeScheme schm(root, obj, testables[targetName],
this->CurrentConfigurationTypes,
this->XcodeVersion);
schm.WriteXCodeSharedScheme(xcProjDir,
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index af905d00c4..df68f803e4 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -7,6 +7,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -34,7 +35,7 @@ class cmGlobalXCodeGenerator : public cmGlobalGenerator
public:
cmGlobalXCodeGenerator(cmake* cm, std::string const& version_string,
unsigned int version_number);
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
//! Get the name for the generator.
std::string GetName() const override
@@ -47,7 +48,8 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -103,7 +105,8 @@ public:
bool ShouldStripResourcePath(cmMakefile*) const override;
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
void AppendFlag(std::string& flags, std::string const& flag) const;
protected:
diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h
index 5ed6af4613..4e1f1284ff 100644
--- a/Source/cmGraphAdjacencyList.h
+++ b/Source/cmGraphAdjacencyList.h
@@ -18,9 +18,10 @@
class cmGraphEdge
{
public:
- cmGraphEdge(int n, bool s, cmListFileBacktrace bt)
+ cmGraphEdge(int n, bool s, bool c, cmListFileBacktrace bt)
: Dest(n)
, Strong(s)
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
@@ -28,11 +29,14 @@ public:
bool IsStrong() const { return this->Strong; }
+ bool IsCross() const { return this->Cross; }
+
cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; }
private:
int Dest;
bool Strong;
+ bool Cross;
cmListFileBacktrace Backtrace;
};
struct cmGraphEdgeList : public std::vector<cmGraphEdge>
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index e0d545d86d..1b776786a2 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -2,174 +2,190 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGraphVizWriter.h"
-#include <cstddef>
+#include <cctype>
#include <iostream>
#include <memory>
-#include <sstream>
+#include <set>
#include <utility>
+#include <cm/memory>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
#include "cmake.h"
namespace {
-enum LinkLibraryScopeType
-{
- LLT_SCOPE_PUBLIC,
- LLT_SCOPE_PRIVATE,
- LLT_SCOPE_INTERFACE
-};
-const char* const GRAPHVIZ_PRIVATE_EDEGE_STYLE = "dashed";
-const char* const GRAPHVIZ_INTERFACE_EDEGE_STYLE = "dotted";
+char const* const GRAPHVIZ_EDGE_STYLE_PUBLIC = "solid";
+char const* const GRAPHVIZ_EDGE_STYLE_INTERFACE = "dashed";
+char const* const GRAPHVIZ_EDGE_STYLE_PRIVATE = "dotted";
-std::string getLinkLibraryStyle(const LinkLibraryScopeType& type)
-{
- std::string style;
- switch (type) {
- case LLT_SCOPE_PRIVATE:
- style = "[style = " + std::string(GRAPHVIZ_PRIVATE_EDEGE_STYLE) + "]";
- break;
- case LLT_SCOPE_INTERFACE:
- style = "[style = " + std::string(GRAPHVIZ_INTERFACE_EDEGE_STYLE) + "]";
- break;
- default:
- break;
- }
- return style;
-}
+char const* const GRAPHVIZ_NODE_SHAPE_EXECUTABLE = "egg"; // egg-xecutable
+
+// Normal libraries.
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC = "octagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED = "doubleoctagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE = "tripleoctagon";
-const char* getShapeForTarget(const cmGeneratorTarget* target)
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE = "pentagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT = "hexagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN = "septagon";
+
+char const* const GRAPHVIZ_NODE_SHAPE_UTILITY = "box";
+
+const char* getShapeForTarget(const cmLinkItem& item)
{
- if (!target) {
- return "ellipse";
+ if (item.Target == nullptr) {
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
- switch (target->GetType()) {
+ switch (item.Target->GetType()) {
case cmStateEnums::EXECUTABLE:
- return "house";
+ return GRAPHVIZ_NODE_SHAPE_EXECUTABLE;
case cmStateEnums::STATIC_LIBRARY:
- return "diamond";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC;
case cmStateEnums::SHARED_LIBRARY:
- return "polygon";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED;
case cmStateEnums::MODULE_LIBRARY:
- return "octagon";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE;
+ case cmStateEnums::OBJECT_LIBRARY:
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT;
+ case cmStateEnums::UTILITY:
+ return GRAPHVIZ_NODE_SHAPE_UTILITY;
+ case cmStateEnums::INTERFACE_LIBRARY:
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE;
+ case cmStateEnums::UNKNOWN_LIBRARY:
default:
- break;
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
+}
+}
- return "box";
+cmGraphVizWriter::cmGraphVizWriter(std::string const& fileName,
+ const cmGlobalGenerator* globalGenerator)
+ : FileName(fileName)
+ , GlobalFileStream(fileName)
+ , GraphName(globalGenerator->GetSafeGlobalSetting("CMAKE_PROJECT_NAME"))
+ , GraphHeader("node [\n fontsize = \"12\"\n];")
+ , GraphNodePrefix("node")
+ , GlobalGenerator(globalGenerator)
+ , NextNodeId(0)
+ , GenerateForExecutables(true)
+ , GenerateForStaticLibs(true)
+ , GenerateForSharedLibs(true)
+ , GenerateForModuleLibs(true)
+ , GenerateForInterfaceLibs(true)
+ , GenerateForObjectLibs(true)
+ , GenerateForUnknownLibs(true)
+ , GenerateForCustomTargets(false)
+ , GenerateForExternals(true)
+ , GeneratePerTarget(true)
+ , GenerateDependers(true)
+{
}
-std::map<std::string, LinkLibraryScopeType> getScopedLinkLibrariesFromTarget(
- cmTarget* Target, const cmGlobalGenerator* globalGenerator)
+cmGraphVizWriter::~cmGraphVizWriter()
{
- char sep = ';';
- std::map<std::string, LinkLibraryScopeType> tokens;
- size_t start = 0;
- size_t end = 0;
+ this->WriteFooter(this->GlobalFileStream);
- const char* pInterfaceLinkLibraries =
- Target->GetProperty("INTERFACE_LINK_LIBRARIES");
- const char* pLinkLibraries = Target->GetProperty("LINK_LIBRARIES");
+ for (auto& fileStream : this->PerTargetFileStreams) {
+ this->WriteFooter(*fileStream.second);
+ }
- if (!pInterfaceLinkLibraries && !pLinkLibraries) {
- return tokens; // target is not linked against any other libraries
+ for (auto& fileStream : this->TargetDependersFileStreams) {
+ this->WriteFooter(*fileStream.second);
}
+}
- // make sure we don't touch a null-ptr
- auto interfaceLinkLibraries =
- std::string(pInterfaceLinkLibraries ? pInterfaceLinkLibraries : "");
- auto linkLibraries = std::string(pLinkLibraries ? pLinkLibraries : "");
+void cmGraphVizWriter::VisitGraph(std::string const&)
+{
+ this->WriteHeader(GlobalFileStream, this->GraphName);
+ this->WriteLegend(GlobalFileStream);
+}
- // first extract interfaceLinkLibraries
- while (start < interfaceLinkLibraries.length()) {
+void cmGraphVizWriter::OnItem(cmLinkItem const& item)
+{
+ if (this->ItemExcluded(item)) {
+ return;
+ }
- if ((end = interfaceLinkLibraries.find(sep, start)) == std::string::npos) {
- end = interfaceLinkLibraries.length();
- }
+ NodeNames[item.AsStr()] = cmStrCat(GraphNodePrefix, NextNodeId);
+ ++NextNodeId;
- std::string element = interfaceLinkLibraries.substr(start, end - start);
- if (globalGenerator->IsAlias(element)) {
- const auto tgt = globalGenerator->FindTarget(element);
- if (tgt) {
- element = tgt->GetName();
- }
- }
+ this->WriteNode(this->GlobalFileStream, item);
- if (std::string::npos == element.find("$<LINK_ONLY:", 0)) {
- // we assume first, that this library is an interface library.
- // if we find it again in the linklibraries property, we promote it to an
- // public library.
- tokens[element] = LLT_SCOPE_INTERFACE;
- } else {
- // this is an private linked static library.
- // we take care of this case in the second iterator.
- }
- start = end + 1;
+ if (this->GeneratePerTarget) {
+ this->CreateTargetFile(this->PerTargetFileStreams, item);
}
- // second extract linkLibraries
- start = 0;
- while (start < linkLibraries.length()) {
-
- if ((end = linkLibraries.find(sep, start)) == std::string::npos) {
- end = linkLibraries.length();
- }
+ if (this->GenerateDependers) {
+ this->CreateTargetFile(this->TargetDependersFileStreams, item,
+ ".dependers");
+ }
+}
- std::string element = linkLibraries.substr(start, end - start);
- if (globalGenerator->IsAlias(element)) {
- const auto tgt = globalGenerator->FindTarget(element);
- if (tgt) {
- element = tgt->GetName();
- }
- }
+void cmGraphVizWriter::CreateTargetFile(FileStreamMap& fileStreamMap,
+ cmLinkItem const& item,
+ std::string const& fileNameSuffix)
+{
+ auto const pathSafeItemName = PathSafeString(item.AsStr());
+ auto const perTargetFileName =
+ cmStrCat(this->FileName, '.', pathSafeItemName, fileNameSuffix);
+ auto perTargetFileStream =
+ cm::make_unique<cmGeneratedFileStream>(perTargetFileName);
- if (tokens.find(element) == tokens.end()) {
- // this library is not found in interfaceLinkLibraries but in
- // linkLibraries.
- // this results in a private linked library.
- tokens[element] = LLT_SCOPE_PRIVATE;
- } else if (LLT_SCOPE_INTERFACE == tokens[element]) {
- // this library is found in interfaceLinkLibraries and linkLibraries.
- // this results in a public linked library.
- tokens[element] = LLT_SCOPE_PUBLIC;
- } else {
- // private and public linked libraries should not be changed anymore.
- }
+ this->WriteHeader(*perTargetFileStream, item.AsStr());
+ this->WriteNode(*perTargetFileStream, item);
- start = end + 1;
- }
+ fileStreamMap.emplace(item.AsStr(), std::move(perTargetFileStream));
+}
- return tokens;
+void cmGraphVizWriter::OnDirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee,
+ DependencyType dt)
+{
+ this->VisitLink(depender, dependee, true, GetEdgeStyle(dt));
}
+
+void cmGraphVizWriter::OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee)
+{
+ this->VisitLink(depender, dependee, false);
}
-cmGraphVizWriter::cmGraphVizWriter(const cmGlobalGenerator* globalGenerator)
- : GraphType("digraph")
- , GraphName("GG")
- , GraphHeader("node [\n fontsize = \"12\"\n];")
- , GraphNodePrefix("node")
- , GlobalGenerator(globalGenerator)
- , LocalGenerators(globalGenerator->GetLocalGenerators())
- , GenerateForExecutables(true)
- , GenerateForStaticLibs(true)
- , GenerateForSharedLibs(true)
- , GenerateForModuleLibs(true)
- , GenerateForInterface(true)
- , GenerateForExternals(true)
- , GeneratePerTarget(true)
- , GenerateDependers(true)
- , HaveTargetsAndLibs(false)
+void cmGraphVizWriter::VisitLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee, bool isDirectLink,
+ std::string const& scopeType)
{
+ if (this->ItemExcluded(depender) || this->ItemExcluded(dependee)) {
+ return;
+ }
+
+ if (!isDirectLink) {
+ return;
+ }
+
+ this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
+
+ if (this->GeneratePerTarget) {
+ auto fileStream = PerTargetFileStreams[depender.AsStr()].get();
+ this->WriteNode(*fileStream, dependee);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
+ }
+
+ if (this->GenerateDependers) {
+ auto fileStream = TargetDependersFileStreams[dependee.AsStr()].get();
+ this->WriteNode(*fileStream, depender);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
+ }
}
void cmGraphVizWriter::ReadSettings(
@@ -208,7 +224,6 @@ void cmGraphVizWriter::ReadSettings(
} \
} while (false)
- __set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
__set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
__set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
__set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");
@@ -225,7 +240,10 @@ void cmGraphVizWriter::ReadSettings(
__set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS");
__set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS");
__set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS");
- __set_bool_if_set(this->GenerateForInterface, "GRAPHVIZ_INTERFACE");
+ __set_bool_if_set(this->GenerateForInterfaceLibs, "GRAPHVIZ_INTERFACE_LIBS");
+ __set_bool_if_set(this->GenerateForObjectLibs, "GRAPHVIZ_OBJECT_LIBS");
+ __set_bool_if_set(this->GenerateForUnknownLibs, "GRAPHVIZ_UNKNOWN_LIBS");
+ __set_bool_if_set(this->GenerateForCustomTargets, "GRAPHVIZ_CUSTOM_TARGETS");
__set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS");
__set_bool_if_set(this->GeneratePerTarget, "GRAPHVIZ_GENERATE_PER_TARGET");
__set_bool_if_set(this->GenerateDependers, "GRAPHVIZ_GENERATE_DEPENDERS");
@@ -248,329 +266,170 @@ void cmGraphVizWriter::ReadSettings(
}
}
-// Iterate over all targets and write for each one a graph which shows
-// which other targets depend on it.
-void cmGraphVizWriter::WriteTargetDependersFiles(const std::string& fileName)
+void cmGraphVizWriter::Write()
{
- if (!this->GenerateDependers) {
- return;
- }
-
- this->CollectTargetsAndLibs();
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- std::string currentFilename =
- cmStrCat(fileName, '.', ptr.first, ".dependers");
-
- cmGeneratedFileStream str(currentFilename);
- if (!str) {
- return;
+ auto gg = this->GlobalGenerator;
+
+ this->VisitGraph(gg->GetName());
+
+ // We want to traverse in a determined order, such that the output is always
+ // the same for a given project (this makes tests reproducible, etc.)
+ std::set<cmGeneratorTarget const*, cmGeneratorTarget::StrictTargetComparison>
+ sortedGeneratorTargets;
+
+ for (const auto& lg : gg->GetLocalGenerators()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
+ // Reserved targets have inconsistent names across platforms (e.g. 'all'
+ // vs. 'ALL_BUILD'), which can disrupt the traversal ordering.
+ // We don't need or want them anyway.
+ if (!cmGlobalGenerator::IsReservedTarget(gt->GetName())) {
+ sortedGeneratorTargets.insert(gt.get());
+ }
}
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- std::cout << "Writing " << currentFilename << "..." << std::endl;
- this->WriteHeader(str);
-
- this->WriteDependerConnections(ptr.first, insertedNodes,
- insertedConnections, str);
-
- this->WriteFooter(str);
- }
-}
-
-// Iterate over all targets and write for each one a graph which shows
-// on which targets it depends.
-void cmGraphVizWriter::WritePerTargetFiles(const std::string& fileName)
-{
- if (!this->GeneratePerTarget) {
- return;
}
- this->CollectTargetsAndLibs();
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- std::string currentFilename = cmStrCat(fileName, '.', ptr.first);
- cmGeneratedFileStream str(currentFilename);
- if (!str) {
- return;
- }
-
- std::cout << "Writing " << currentFilename << "..." << std::endl;
- this->WriteHeader(str);
-
- this->WriteConnections(ptr.first, insertedNodes, insertedConnections, str);
- this->WriteFooter(str);
+ for (auto const gt : sortedGeneratorTargets) {
+ auto item = cmLinkItem(gt, false, gt->GetBacktrace());
+ this->VisitItem(item);
}
}
-void cmGraphVizWriter::WriteGlobalFile(const std::string& fileName)
+void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& fs,
+ const std::string& name)
{
- this->CollectTargetsAndLibs();
-
- cmGeneratedFileStream str(fileName);
- if (!str) {
- return;
- }
- this->WriteHeader(str);
-
- std::cout << "Writing " << fileName << "..." << std::endl;
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- this->WriteConnections(ptr.first, insertedNodes, insertedConnections, str);
- }
- this->WriteFooter(str);
+ auto const escapedGraphName = EscapeForDotFile(name);
+ fs << "digraph \"" << escapedGraphName << "\" {" << std::endl;
+ fs << this->GraphHeader << std::endl;
}
-void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& fs)
{
- str << this->GraphType << " \"" << this->GraphName << "\" {" << std::endl;
- str << this->GraphHeader << std::endl;
+ fs << "}" << std::endl;
}
-void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
{
- str << "}" << std::endl;
+ // Note that the subgraph name must start with "cluster", as done here, to
+ // make Graphviz layout engines do the right thing and keep the nodes
+ // together.
+ fs << "subgraph clusterLegend {" << std::endl;
+ fs << " label = \"Legend\";" << std::endl;
+ // Set the color of the box surrounding the legend.
+ fs << " color = black;" << std::endl;
+ // We use invisible edges just to enforce the layout.
+ fs << " edge [ style = invis ];" << std::endl;
+
+ // Nodes.
+ fs << " legendNode0 [ label = \"Executable\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];" << std::endl;
+
+ fs << " legendNode1 [ label = \"Static Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];" << std::endl;
+ fs << " legendNode2 [ label = \"Shared Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];" << std::endl;
+ fs << " legendNode3 [ label = \"Module Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];" << std::endl;
+
+ fs << " legendNode4 [ label = \"Interface Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];" << std::endl;
+ fs << " legendNode5 [ label = \"Object Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];" << std::endl;
+ fs << " legendNode6 [ label = \"Unknown Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];" << std::endl;
+
+ fs << " legendNode7 [ label = \"Custom Target\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];" << std::endl;
+
+ // Edges.
+ // Some of those are dummy (invisible) edges to enforce a layout.
+ fs << " legendNode0 -> legendNode1 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
+ << " ];" << std::endl;
+ fs << " legendNode0 -> legendNode2 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
+ << " ];" << std::endl;
+ fs << " legendNode0 -> legendNode3;" << std::endl;
+
+ fs << " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
+ << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];" << std::endl;
+ fs << " legendNode2 -> legendNode5 [ label = \"Private\", style = "
+ << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];" << std::endl;
+ fs << " legendNode3 -> legendNode6 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
+ << " ];" << std::endl;
+
+ fs << " legendNode0 -> legendNode7;" << std::endl;
+
+ fs << "}" << std::endl;
}
-void cmGraphVizWriter::WriteConnections(
- const std::string& targetName, std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
+ cmLinkItem const& item)
{
- auto targetPtrIt = this->TargetPtrs.find(targetName);
+ auto const& itemName = item.AsStr();
+ auto const& nodeName = this->NodeNames[itemName];
- if (targetPtrIt == this->TargetPtrs.end()) // not found at all
- {
- return;
- }
-
- this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
-
- if (targetPtrIt->second == nullptr) // it's an external library
- {
- return;
- }
+ auto const itemNameWithAliases = ItemNameWithAliases(itemName);
+ auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
- std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
- std::map<std::string, LinkLibraryScopeType> ll =
- getScopedLinkLibrariesFromTarget(targetPtrIt->second->Target,
- GlobalGenerator);
-
- for (auto const& llit : ll) {
- const std::string& libName = llit.first;
- auto libNameIt = this->TargetNamesNodes.find(libName);
-
- // can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
- if (libNameIt == this->TargetNamesNodes.end()) {
- continue;
- }
+ fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel
+ << "\", shape = " << getShapeForTarget(item) << " ];" << std::endl;
+}
- std::string connectionName = cmStrCat(myNodeName, '-', libNameIt->second);
- if (insertedConnections.find(connectionName) ==
- insertedConnections.end()) {
- insertedConnections.insert(connectionName);
- this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
- insertedNodes, str);
+void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
+ cmLinkItem const& depender,
+ cmLinkItem const& dependee,
+ std::string const& edgeStyle)
+{
+ auto const& dependerName = depender.AsStr();
+ auto const& dependeeName = dependee.AsStr();
- str << " \"" << myNodeName << "\" -> \"" << libNameIt->second << "\"";
+ fs << " \"" << this->NodeNames[dependerName] << "\" -> \""
+ << this->NodeNames[dependeeName] << "\" ";
- str << getLinkLibraryStyle(llit.second);
+ fs << edgeStyle;
- str << " // " << targetName << " -> " << libName << std::endl;
- this->WriteConnections(libName, insertedNodes, insertedConnections, str);
- }
- }
+ fs << " // " << dependerName << " -> " << dependeeName << std::endl;
}
-void cmGraphVizWriter::WriteDependerConnections(
- const std::string& targetName, std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
+bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
{
- auto targetPtrIt = this->TargetPtrs.find(targetName);
+ auto const itemName = item.AsStr();
- if (targetPtrIt == this->TargetPtrs.end()) // not found at all
- {
- return;
+ if (this->ItemNameFilteredOut(itemName)) {
+ return true;
}
- this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
-
- if (targetPtrIt->second == nullptr) // it's an external library
- {
- return;
+ if (item.Target == nullptr) {
+ return !this->GenerateForExternals;
}
- std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
-
- // now search who links against me
- for (auto const& tptr : this->TargetPtrs) {
- if (tptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(tptr.second->GetType())) {
- continue;
- }
-
- // Now we have a target, check whether it links against targetName.
- // If so, draw a connection, and then continue with dependers on that one.
- std::map<std::string, LinkLibraryScopeType> ll =
- getScopedLinkLibrariesFromTarget(tptr.second->Target, GlobalGenerator);
-
- for (auto const& llit : ll) {
- if (llit.first == targetName) {
- // So this target links against targetName.
- auto dependerNodeNameIt = this->TargetNamesNodes.find(tptr.first);
-
- if (dependerNodeNameIt != this->TargetNamesNodes.end()) {
- std::string connectionName =
- cmStrCat(dependerNodeNameIt->second, '-', myNodeName);
-
- if (insertedConnections.find(connectionName) ==
- insertedConnections.end()) {
- insertedConnections.insert(connectionName);
- this->WriteNode(tptr.first, tptr.second, insertedNodes, str);
-
- str << " \"" << dependerNodeNameIt->second << "\" -> \""
- << myNodeName << "\"";
- str << " // " << targetName << " -> " << tptr.first << std::endl;
- str << getLinkLibraryStyle(llit.second);
- this->WriteDependerConnections(tptr.first, insertedNodes,
- insertedConnections, str);
- }
- }
- break;
- }
+ if (item.Target->GetType() == cmStateEnums::UTILITY) {
+ if ((itemName.find("Nightly") == 0) ||
+ (itemName.find("Continuous") == 0) ||
+ (itemName.find("Experimental") == 0)) {
+ return true;
}
}
-}
-void cmGraphVizWriter::WriteNode(const std::string& targetName,
- const cmGeneratorTarget* target,
- std::set<std::string>& insertedNodes,
- cmGeneratedFileStream& str) const
-{
- if (insertedNodes.find(targetName) == insertedNodes.end()) {
- insertedNodes.insert(targetName);
- auto nameIt = this->TargetNamesNodes.find(targetName);
-
- str << " \"" << nameIt->second << "\" [ label=\"" << targetName
- << "\" shape=\"" << getShapeForTarget(target) << "\"];" << std::endl;
+ if (item.Target->IsImported() && !this->GenerateForExternals) {
+ return true;
}
-}
-void cmGraphVizWriter::CollectTargetsAndLibs()
-{
- if (!this->HaveTargetsAndLibs) {
- this->HaveTargetsAndLibs = true;
- int cnt = this->CollectAllTargets();
- if (this->GenerateForExternals) {
- this->CollectAllExternalLibs(cnt);
- }
- }
+ return !this->TargetTypeEnabled(item.Target->GetType());
}
-int cmGraphVizWriter::CollectAllTargets()
+bool cmGraphVizWriter::ItemNameFilteredOut(std::string const& itemName)
{
- int cnt = 0;
- // First pass get the list of all cmake targets
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- const std::string& realTargetName = target->GetName();
- if (this->IgnoreThisTarget(realTargetName)) {
- // Skip ignored targets
- continue;
- }
- // std::cout << "Found target: " << tit->first << std::endl;
- std::ostringstream ostr;
- ostr << this->GraphNodePrefix << cnt++;
- this->TargetNamesNodes[realTargetName] = ostr.str();
- this->TargetPtrs[realTargetName] = target;
- }
+ if (itemName == ">") {
+ // FIXME: why do we even receive such a target here?
+ return true;
}
- return cnt;
-}
-
-int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
-{
- // Ok, now find all the stuff we link to that is not in cmake
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- const std::string& realTargetName = target->GetName();
- if (this->IgnoreThisTarget(realTargetName)) {
- // Skip ignored targets
- continue;
- }
- const cmTarget::LinkLibraryVectorType* ll =
- &(target->Target->GetOriginalLinkLibraries());
- for (auto const& llit : *ll) {
- std::string libName = llit.first;
- if (this->IgnoreThisTarget(libName)) {
- // Skip ignored targets
- continue;
- }
-
- if (GlobalGenerator->IsAlias(libName)) {
- const auto tgt = GlobalGenerator->FindTarget(libName);
- if (tgt) {
- libName = tgt->GetName();
- }
- }
-
- auto tarIt = this->TargetPtrs.find(libName);
- if (tarIt == this->TargetPtrs.end()) {
- std::ostringstream ostr;
- ostr << this->GraphNodePrefix << cnt++;
- this->TargetNamesNodes[libName] = ostr.str();
- this->TargetPtrs[libName] = nullptr;
- // str << " \"" << ostr << "\" [ label=\"" << libName
- // << "\" shape=\"ellipse\"];" << std::endl;
- }
- }
- }
+ if (cmGlobalGenerator::IsReservedTarget(itemName)) {
+ return true;
}
- return cnt;
-}
-bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
-{
for (cmsys::RegularExpression& regEx : this->TargetsToIgnoreRegex) {
if (regEx.is_valid()) {
- if (regEx.find(name)) {
+ if (regEx.find(itemName)) {
return true;
}
}
@@ -579,7 +438,7 @@ bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
return false;
}
-bool cmGraphVizWriter::GenerateForTargetType(
+bool cmGraphVizWriter::TargetTypeEnabled(
cmStateEnums::TargetType targetType) const
{
switch (targetType) {
@@ -592,9 +451,73 @@ bool cmGraphVizWriter::GenerateForTargetType(
case cmStateEnums::MODULE_LIBRARY:
return this->GenerateForModuleLibs;
case cmStateEnums::INTERFACE_LIBRARY:
- return this->GenerateForInterface;
+ return this->GenerateForInterfaceLibs;
+ case cmStateEnums::OBJECT_LIBRARY:
+ return this->GenerateForObjectLibs;
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ return this->GenerateForUnknownLibs;
+ case cmStateEnums::UTILITY:
+ return this->GenerateForCustomTargets;
+ case cmStateEnums::GLOBAL_TARGET:
+ // Built-in targets like edit_cache, etc.
+ // We don't need/want those in the dot file.
+ return false;
default:
break;
}
return false;
}
+
+std::string cmGraphVizWriter::ItemNameWithAliases(
+ std::string const& itemName) const
+{
+ auto nameWithAliases = itemName;
+
+ for (auto const& lg : this->GlobalGenerator->GetLocalGenerators()) {
+ for (auto const& aliasTargets : lg->GetMakefile()->GetAliasTargets()) {
+ if (aliasTargets.second == itemName) {
+ nameWithAliases += "\\n(" + aliasTargets.first + ")";
+ }
+ }
+ }
+
+ return nameWithAliases;
+}
+
+std::string cmGraphVizWriter::GetEdgeStyle(DependencyType dt)
+{
+ std::string style;
+ switch (dt) {
+ case DependencyType::LinkPrivate:
+ style = "[ style = " + std::string(GRAPHVIZ_EDGE_STYLE_PRIVATE) + " ]";
+ break;
+ case DependencyType::LinkInterface:
+ style = "[ style = " + std::string(GRAPHVIZ_EDGE_STYLE_INTERFACE) + " ]";
+ break;
+ default:
+ break;
+ }
+ return style;
+}
+
+std::string cmGraphVizWriter::EscapeForDotFile(std::string const& str)
+{
+ return cmSystemTools::EscapeChars(str.data(), "\"");
+}
+
+std::string cmGraphVizWriter::PathSafeString(std::string const& str)
+{
+ std::string pathSafeStr;
+
+ // We'll only keep alphanumerical characters, plus the following ones that
+ // are common, and safe on all platforms:
+ auto const extra_chars = std::set<char>{ '.', '-', '_' };
+
+ for (char c : str) {
+ if (std::isalnum(c) || extra_chars.find(c) != extra_chars.cend()) {
+ pathSafeStr += c;
+ }
+ }
+
+ return pathSafeStr;
+}
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 9c3051f2c1..578660dbbb 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -6,87 +6,106 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <set>
+#include <memory>
#include <string>
#include <vector>
#include "cmsys/RegularExpression.hxx"
+#include "cmGeneratedFileStream.h"
+#include "cmLinkItemGraphVisitor.h"
#include "cmStateTypes.h"
-class cmGeneratedFileStream;
-class cmGeneratorTarget;
-class cmLocalGenerator;
+class cmLinkItem;
class cmGlobalGenerator;
/** This class implements writing files for graphviz (dot) for graphs
* representing the dependencies between the targets in the project. */
-class cmGraphVizWriter
+class cmGraphVizWriter : public cmLinkItemGraphVisitor
{
public:
- cmGraphVizWriter(const cmGlobalGenerator* globalGenerator);
+ cmGraphVizWriter(std::string const& fileName,
+ const cmGlobalGenerator* globalGenerator);
+ ~cmGraphVizWriter() override;
+
+ void VisitGraph(std::string const& name) override;
+
+ void OnItem(cmLinkItem const& item) override;
+
+ void OnDirectLink(cmLinkItem const& depender, cmLinkItem const& dependee,
+ DependencyType dt) override;
+
+ void OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee) override;
void ReadSettings(const std::string& settingsFileName,
const std::string& fallbackSettingsFileName);
- void WritePerTargetFiles(const std::string& fileName);
- void WriteTargetDependersFiles(const std::string& fileName);
+ void Write();
+
+private:
+ using FileStreamMap =
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
+
+ void VisitLink(cmLinkItem const& depender, cmLinkItem const& dependee,
+ bool isDirectLink, std::string const& scopeType = "");
+
+ void WriteHeader(cmGeneratedFileStream& fs, std::string const& name);
- void WriteGlobalFile(const std::string& fileName);
+ void WriteFooter(cmGeneratedFileStream& fs);
-protected:
- void CollectTargetsAndLibs();
+ void WriteLegend(cmGeneratedFileStream& fs);
- int CollectAllTargets();
+ void WriteNode(cmGeneratedFileStream& fs, cmLinkItem const& item);
- int CollectAllExternalLibs(int cnt);
+ void CreateTargetFile(FileStreamMap& fileStreamMap, cmLinkItem const& target,
+ std::string const& fileNameSuffix = "");
- void WriteHeader(cmGeneratedFileStream& str) const;
+ void WriteConnection(cmGeneratedFileStream& fs,
+ cmLinkItem const& dependerTargetName,
+ cmLinkItem const& dependeeTargetName,
+ std::string const& edgeStyle);
- void WriteConnections(const std::string& targetName,
- std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections,
- cmGeneratedFileStream& str) const;
+ bool ItemExcluded(cmLinkItem const& item);
+ bool ItemNameFilteredOut(std::string const& itemName);
+ bool TargetTypeEnabled(cmStateEnums::TargetType targetType) const;
- void WriteDependerConnections(const std::string& targetName,
- std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections,
- cmGeneratedFileStream& str) const;
+ std::string ItemNameWithAliases(std::string const& itemName) const;
- void WriteNode(const std::string& targetName,
- const cmGeneratorTarget* target,
- std::set<std::string>& insertedNodes,
- cmGeneratedFileStream& str) const;
+ static std::string GetEdgeStyle(DependencyType dt);
- void WriteFooter(cmGeneratedFileStream& str) const;
+ static std::string EscapeForDotFile(std::string const& str);
- bool IgnoreThisTarget(const std::string& name);
+ static std::string PathSafeString(std::string const& str);
- bool GenerateForTargetType(cmStateEnums::TargetType targetType) const;
+ std::string FileName;
+ cmGeneratedFileStream GlobalFileStream;
+ FileStreamMap PerTargetFileStreams;
+ FileStreamMap TargetDependersFileStreams;
- std::string GraphType;
std::string GraphName;
std::string GraphHeader;
std::string GraphNodePrefix;
std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
- const cmGlobalGenerator* GlobalGenerator;
- const std::vector<cmLocalGenerator*>& LocalGenerators;
+ cmGlobalGenerator const* GlobalGenerator;
- std::map<std::string, const cmGeneratorTarget*> TargetPtrs;
- // maps from the actual target names to node names in dot:
- std::map<std::string, std::string> TargetNamesNodes;
+ int NextNodeId;
+ // maps from the actual item names to node names in dot:
+ std::map<std::string, std::string> NodeNames;
bool GenerateForExecutables;
bool GenerateForStaticLibs;
bool GenerateForSharedLibs;
bool GenerateForModuleLibs;
- bool GenerateForInterface;
+ bool GenerateForInterfaceLibs;
+ bool GenerateForObjectLibs;
+ bool GenerateForUnknownLibs;
+ bool GenerateForCustomTargets;
bool GenerateForExternals;
bool GeneratePerTarget;
bool GenerateDependers;
- bool HaveTargetsAndLibs;
};
#endif
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 71326d23ad..b53319f510 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -4,6 +4,8 @@
#include <iterator>
+#include <cmext/algorithm>
+
#include <string.h>
#include "cmsys/String.h"
@@ -173,7 +175,7 @@ void cmIDEOptions::AddDefines(std::string const& defines)
}
void cmIDEOptions::AddDefines(const std::vector<std::string>& defines)
{
- cmAppend(this->Defines, defines);
+ cm::append(this->Defines, defines);
}
std::vector<std::string> const& cmIDEOptions::GetDefines() const
@@ -195,7 +197,7 @@ void cmIDEOptions::AddIncludes(std::string const& includes)
}
void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes)
{
- cmAppend(this->Includes, includes);
+ cm::append(this->Includes, includes);
}
std::vector<std::string> const& cmIDEOptions::GetIncludes() const
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 170aea1258..b408f7210f 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -6,7 +6,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
@@ -58,9 +59,9 @@ bool cmIncludeDirectoryCommand(std::vector<std::string> const& args,
GetIncludes(mf, *i, includes);
if (before) {
- cmAppend(beforeIncludes, includes);
+ cm::append(beforeIncludes, includes);
} else {
- cmAppend(afterIncludes, includes);
+ cm::append(afterIncludes, includes);
}
if (system) {
systemIncludes.insert(includes.begin(), includes.end());
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
index fa1e8bcf96..5b532ce0fa 100644
--- a/Source/cmIncludeExternalMSProjectCommand.cxx
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -77,28 +77,27 @@ bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args,
if (!customGuid.empty()) {
std::string guidVariable = utility_name + "_GUID_CMAKE";
- mf.GetCMakeInstance()->AddCacheEntry(guidVariable.c_str(),
- customGuid.c_str(), "Stored GUID",
+ mf.GetCMakeInstance()->AddCacheEntry(guidVariable, customGuid.c_str(),
+ "Stored GUID",
cmStateEnums::INTERNAL);
}
// Create a target instance for this utility.
- cmTarget* target =
- mf.AddNewTarget(cmStateEnums::UTILITY, utility_name.c_str());
+ cmTarget* target = mf.AddNewTarget(cmStateEnums::UTILITY, utility_name);
if (mf.GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
- target->SetProperty("GENERATOR_FILE_NAME", utility_name.c_str());
- target->SetProperty("EXTERNAL_MSPROJECT", path.c_str());
+ target->SetProperty("GENERATOR_FILE_NAME", utility_name);
+ target->SetProperty("EXTERNAL_MSPROJECT", path);
if (!customType.empty())
- target->SetProperty("VS_PROJECT_TYPE", customType.c_str());
+ target->SetProperty("VS_PROJECT_TYPE", customType);
if (!platformMapping.empty())
- target->SetProperty("VS_PLATFORM_MAPPING", platformMapping.c_str());
+ target->SetProperty("VS_PLATFORM_MAPPING", platformMapping);
for (std::string const& d : depends) {
- target->AddUtility(d.c_str());
+ target->AddUtility(d, false);
}
}
#endif
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index e511196e86..d669ed7e9b 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -85,7 +85,7 @@ public:
std::string DefaultComponentName;
};
-cmInstallTargetGenerator* CreateInstallTargetGenerator(
+std::unique_ptr<cmInstallTargetGenerator> CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, const std::string& destination,
bool forceOpt = false, bool namelink = false)
@@ -93,18 +93,17 @@ cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
target.SetHaveInstallRule(true);
- const char* component = namelink ? args.GetNamelinkComponent().c_str()
- : args.GetComponent().c_str();
- auto g = new cmInstallTargetGenerator(
- target.GetName(), destination.c_str(), impLib,
- args.GetPermissions().c_str(), args.GetConfigurations(), component,
- message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
- backtrace);
- target.AddInstallGenerator(g);
+ const std::string& component =
+ namelink ? args.GetNamelinkComponent() : args.GetComponent();
+ auto g = cm::make_unique<cmInstallTargetGenerator>(
+ target.GetName(), destination, impLib, args.GetPermissions(),
+ args.GetConfigurations(), component, message, args.GetExcludeFromAll(),
+ args.GetOptional() || forceOpt, backtrace);
+ target.AddInstallGenerator(g.get());
return g;
}
-cmInstallTargetGenerator* CreateInstallTargetGenerator(
+std::unique_ptr<cmInstallTargetGenerator> CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, bool forceOpt = false,
bool namelink = false)
@@ -114,20 +113,20 @@ cmInstallTargetGenerator* CreateInstallTargetGenerator(
namelink);
}
-cmInstallFilesGenerator* CreateInstallFilesGenerator(
+std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs,
const std::string& destination)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(mf);
- return new cmInstallFilesGenerator(
- absFiles, destination.c_str(), programs, args.GetPermissions().c_str(),
- args.GetConfigurations(), args.GetComponent().c_str(), message,
- args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional());
+ return cm::make_unique<cmInstallFilesGenerator>(
+ absFiles, destination, programs, args.GetPermissions(),
+ args.GetConfigurations(), args.GetComponent(), message,
+ args.GetExcludeFromAll(), args.GetRename(), args.GetOptional());
}
-cmInstallFilesGenerator* CreateInstallFilesGenerator(
+std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs)
{
@@ -196,13 +195,15 @@ bool HandleScriptMode(std::vector<std::string> const& args,
status.SetError("given a directory as value of SCRIPT argument.");
return false;
}
- helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
- script.c_str(), false, component.c_str(), exclude_from_all));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallScriptGenerator>(script, false, component,
+ exclude_from_all));
} else if (doing_code) {
doing_code = false;
std::string const& code = arg;
- helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
- code.c_str(), true, component.c_str(), exclude_from_all));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallScriptGenerator>(code, true, component,
+ exclude_from_all));
}
}
@@ -449,16 +450,16 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (cmTarget* ti : targets) {
// Handle each target type.
cmTarget& target = *ti;
- cmInstallTargetGenerator* archiveGenerator = nullptr;
- cmInstallTargetGenerator* libraryGenerator = nullptr;
- cmInstallTargetGenerator* namelinkGenerator = nullptr;
- cmInstallTargetGenerator* runtimeGenerator = nullptr;
- cmInstallTargetGenerator* objectGenerator = nullptr;
- cmInstallTargetGenerator* frameworkGenerator = nullptr;
- cmInstallTargetGenerator* bundleGenerator = nullptr;
- cmInstallFilesGenerator* privateHeaderGenerator = nullptr;
- cmInstallFilesGenerator* publicHeaderGenerator = nullptr;
- cmInstallFilesGenerator* resourceGenerator = nullptr;
+ std::unique_ptr<cmInstallTargetGenerator> archiveGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> libraryGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> namelinkGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> runtimeGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> objectGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> frameworkGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> bundleGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> privateHeaderGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> publicHeaderGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> resourceGenerator;
// Avoid selecting default destinations for PUBLIC_HEADER and
// PRIVATE_HEADER if any artifacts are specified.
@@ -491,7 +492,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
target, runtimeArgs, false, helper.Makefile->GetBacktrace());
artifactsSpecified = true;
}
- if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) {
+ if (!archiveGenerator && !runtimeGenerator) {
archiveGenerator = CreateInstallTargetGenerator(
target, archiveArgs, true, helper.Makefile->GetBacktrace(),
helper.GetArchiveDestination(nullptr));
@@ -744,43 +745,18 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
}
- // Keep track of whether we're installing anything in each category
- installsArchive = installsArchive || archiveGenerator != nullptr;
- installsLibrary = installsLibrary || libraryGenerator != nullptr;
- installsNamelink = installsNamelink || namelinkGenerator != nullptr;
- installsRuntime = installsRuntime || runtimeGenerator != nullptr;
- installsObject = installsObject || objectGenerator != nullptr;
- installsFramework = installsFramework || frameworkGenerator != nullptr;
- installsBundle = installsBundle || bundleGenerator != nullptr;
- installsPrivateHeader =
- installsPrivateHeader || privateHeaderGenerator != nullptr;
- installsPublicHeader =
- installsPublicHeader || publicHeaderGenerator != nullptr;
- installsResource = installsResource || 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) {
auto te = cm::make_unique<cmTargetExport>();
te->TargetName = target.GetName();
- te->ArchiveGenerator = archiveGenerator;
- te->BundleGenerator = bundleGenerator;
- te->FrameworkGenerator = frameworkGenerator;
- te->HeaderGenerator = publicHeaderGenerator;
- te->LibraryGenerator = libraryGenerator;
- te->RuntimeGenerator = runtimeGenerator;
- te->ObjectsGenerator = objectGenerator;
+ te->ArchiveGenerator = archiveGenerator.get();
+ te->BundleGenerator = bundleGenerator.get();
+ te->FrameworkGenerator = frameworkGenerator.get();
+ te->HeaderGenerator = publicHeaderGenerator.get();
+ te->LibraryGenerator = libraryGenerator.get();
+ te->RuntimeGenerator = runtimeGenerator.get();
+ te->ObjectsGenerator = objectGenerator.get();
te->InterfaceIncludeDirectories =
cmJoin(includesArgs.GetIncludeDirs(), ";");
@@ -788,6 +764,29 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
->GetExportSets()[exports]
.AddTargetExport(std::move(te));
}
+
+ // Keep track of whether we're installing anything in each category
+ installsArchive = installsArchive || archiveGenerator;
+ installsLibrary = installsLibrary || libraryGenerator;
+ installsNamelink = installsNamelink || namelinkGenerator;
+ installsRuntime = installsRuntime || runtimeGenerator;
+ installsObject = installsObject || objectGenerator;
+ installsFramework = installsFramework || frameworkGenerator;
+ installsBundle = installsBundle || bundleGenerator;
+ installsPrivateHeader = installsPrivateHeader || privateHeaderGenerator;
+ installsPublicHeader = installsPublicHeader || publicHeaderGenerator;
+ installsResource = installsResource || resourceGenerator;
+
+ helper.Makefile->AddInstallGenerator(std::move(archiveGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(namelinkGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(objectGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(bundleGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(privateHeaderGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(publicHeaderGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(resourceGenerator));
}
// Tell the global generator about any installation component names
@@ -975,7 +974,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
bool exclude_from_all = false;
bool message_never = false;
std::vector<std::string> dirs;
- const char* destination = nullptr;
+ const std::string* destination = nullptr;
std::string permissions_file;
std::string permissions_dir;
std::vector<std::string> configurations;
@@ -1134,7 +1133,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
} else if (doing == DoingConfigurations) {
configurations.push_back(args[i]);
} else if (doing == DoingDestination) {
- destination = args[i].c_str();
+ destination = &args[i];
doing = DoingNone;
} else if (doing == DoingType) {
if (allowedTypes.count(args[i]) == 0) {
@@ -1220,7 +1219,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
return false;
}
destinationStr = helper.GetDestinationForType(nullptr, type);
- destination = destinationStr.c_str();
+ destination = &destinationStr;
} else if (!type.empty()) {
status.SetError(cmStrCat(args[0],
" given both TYPE and DESTINATION "
@@ -1232,10 +1231,10 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never);
// Create the directory install generator.
- 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));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallDirectoryGenerator>(
+ dirs, *destination, permissions_file, permissions_dir, configurations,
+ component, message, exclude_from_all, literal_args, optional));
// Tell the global generator about any installation component names
// specified.
@@ -1323,12 +1322,11 @@ bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
- cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- &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);
- helper.Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallExportGenerator>(
+ &exportSet, ica.GetDestination(), ica.GetPermissions(),
+ ica.GetConfigurations(), ica.GetComponent(), message,
+ ica.GetExcludeFromAll(), fname, name_space, exportOld, true));
return true;
#else
@@ -1437,12 +1435,11 @@ bool HandleExportMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
- cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- &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);
- helper.Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallExportGenerator>(
+ &exportSet, ica.GetDestination(), ica.GetPermissions(),
+ ica.GetConfigurations(), ica.GetComponent(), message,
+ ica.GetExcludeFromAll(), fname, name_space, exportOld, false));
return true;
}
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 259c7f76dd..175e7cf0be 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallDirectoryGenerator.h"
+#include <utility>
+
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
@@ -10,18 +12,18 @@
#include "cmSystemTools.h"
cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
- std::vector<std::string> const& dirs, const char* dest,
- const char* file_permissions, const char* dir_permissions,
- std::vector<std::string> const& configurations, const char* component,
- MessageLevel message, bool exclude_from_all, const char* literal_args,
+ std::vector<std::string> const& dirs, std::string const& dest,
+ std::string file_permissions, std::string dir_permissions,
+ std::vector<std::string> const& configurations, std::string const& component,
+ MessageLevel message, bool exclude_from_all, std::string literal_args,
bool optional)
: cmInstallGenerator(dest, configurations, component, message,
exclude_from_all)
, LocalGenerator(nullptr)
, Directories(dirs)
- , FilePermissions(file_permissions)
- , DirPermissions(dir_permissions)
- , LiteralArguments(literal_args)
+ , FilePermissions(std::move(file_permissions))
+ , DirPermissions(std::move(dir_permissions))
+ , LiteralArguments(std::move(literal_args))
, Optional(optional)
{
// We need per-config actions if destination have generator expressions.
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 84c06948e8..bec89df733 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -21,12 +21,13 @@ class cmInstallDirectoryGenerator : public cmInstallGenerator
{
public:
cmInstallDirectoryGenerator(std::vector<std::string> const& dirs,
- const char* dest, const char* file_permissions,
- const char* dir_permissions,
+ std::string const& dest,
+ std::string file_permissions,
+ std::string dir_permissions,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
- bool exclude_from_all, const char* literal_args,
- bool optional = false);
+ std::string const& component,
+ MessageLevel message, bool exclude_from_all,
+ std::string literal_args, bool optional = false);
~cmInstallDirectoryGenerator() override;
bool Compute(cmLocalGenerator* lg) override;
@@ -41,11 +42,11 @@ protected:
Indent indent,
std::vector<std::string> const& dirs);
cmLocalGenerator* LocalGenerator;
- std::vector<std::string> Directories;
- std::string FilePermissions;
- std::string DirPermissions;
- std::string LiteralArguments;
- bool Optional;
+ std::vector<std::string> const Directories;
+ std::string const FilePermissions;
+ std::string const DirPermissions;
+ std::string const LiteralArguments;
+ bool const Optional;
};
#endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index cba68bed4b..2c53a2824a 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -18,16 +18,16 @@
#include "cmSystemTools.h"
cmInstallExportGenerator::cmInstallExportGenerator(
- 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, bool android)
+ cmExportSet* exportSet, std::string const& destination,
+ std::string file_permissions, std::vector<std::string> const& configurations,
+ std::string const& component, MessageLevel message, bool exclude_from_all,
+ std::string filename, std::string name_space, bool exportOld, bool android)
: cmInstallGenerator(destination, configurations, component, message,
exclude_from_all)
, ExportSet(exportSet)
- , FilePermissions(file_permissions)
- , FileName(filename)
- , Namespace(name_space)
+ , FilePermissions(std::move(file_permissions))
+ , FileName(std::move(filename))
+ , Namespace(std::move(name_space))
, ExportOld(exportOld)
, LocalGenerator(nullptr)
{
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index f44127e3d9..cf28b35d8d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -23,12 +23,12 @@ class cmLocalGenerator;
class cmInstallExportGenerator : public cmInstallGenerator
{
public:
- cmInstallExportGenerator(cmExportSet* exportSet, const char* dest,
- const char* file_permissions,
+ cmInstallExportGenerator(cmExportSet* exportSet, std::string const& dest,
+ std::string 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,
+ std::string const& component, MessageLevel message,
+ bool exclude_from_all, std::string filename,
+ std::string name_space, bool exportOld,
bool android);
~cmInstallExportGenerator() override;
@@ -52,11 +52,11 @@ protected:
void ComputeTempDir();
size_t GetMaxConfigLength() const;
- cmExportSet* ExportSet;
- std::string FilePermissions;
- std::string FileName;
- std::string Namespace;
- bool ExportOld;
+ cmExportSet* const ExportSet;
+ std::string const FilePermissions;
+ std::string const FileName;
+ std::string const Namespace;
+ bool const ExportOld;
cmLocalGenerator* LocalGenerator;
std::string TempDir;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index d623943117..3c59f0180a 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -2,16 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallFilesCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+class cmListFileBacktrace;
+
static std::string FindInstallSource(cmMakefile& makefile, const char* name);
static void CreateInstallGenerator(cmMakefile& makefile,
std::string const& dest,
@@ -43,9 +48,10 @@ bool cmInstallFilesCommand(std::vector<std::string> const& args,
CreateInstallGenerator(mf, dest, files);
} else {
std::vector<std::string> finalArgs(args.begin() + 1, args.end());
- mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
- FinalAction(makefile, dest, finalArgs);
- });
+ mf.AddGeneratorAction(
+ [dest, finalArgs](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), dest, finalArgs);
+ });
}
mf.GetGlobalGenerator()->AddInstallComponent(
@@ -109,17 +115,17 @@ static void CreateInstallGenerator(cmMakefile& makefile,
}
// Use a file install generator.
- const char* no_permissions = "";
- const char* no_rename = "";
+ const std::string no_permissions;
+ const std::string no_rename;
bool no_exclude_from_all = false;
std::string no_component =
makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
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));
+ makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
+ files, destination, false, no_permissions, no_configurations, no_component,
+ message, no_exclude_from_all, no_rename));
}
/**
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index f5b69a5d48..ad2f84e024 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallFilesGenerator.h"
+#include <utility>
+
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
#include "cmStringAlgorithms.h"
@@ -9,16 +11,17 @@
class cmLocalGenerator;
cmInstallFilesGenerator::cmInstallFilesGenerator(
- std::vector<std::string> const& files, const char* dest, bool programs,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
- const char* rename, bool optional)
+ std::vector<std::string> const& files, std::string const& dest,
+ bool programs, std::string file_permissions,
+ std::vector<std::string> const& configurations, std::string const& component,
+ MessageLevel message, bool exclude_from_all, std::string rename,
+ bool optional)
: cmInstallGenerator(dest, configurations, component, message,
exclude_from_all)
, LocalGenerator(nullptr)
, Files(files)
- , FilePermissions(file_permissions)
- , Rename(rename)
+ , FilePermissions(std::move(file_permissions))
+ , Rename(std::move(rename))
, Programs(programs)
, Optional(optional)
{
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index a6800375bb..82666033b8 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -21,11 +21,11 @@ class cmInstallFilesGenerator : public cmInstallGenerator
{
public:
cmInstallFilesGenerator(std::vector<std::string> const& files,
- const char* dest, bool programs,
- const char* file_permissions,
+ std::string const& dest, bool programs,
+ std::string file_permissions,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
- bool exclude_from_all, const char* rename,
+ std::string const& component, MessageLevel message,
+ bool exclude_from_all, std::string rename,
bool optional = false);
~cmInstallFilesGenerator() override;
@@ -42,11 +42,11 @@ protected:
std::vector<std::string> const& files);
cmLocalGenerator* LocalGenerator;
- std::vector<std::string> Files;
- std::string FilePermissions;
- std::string Rename;
- bool Programs;
- bool Optional;
+ std::vector<std::string> const Files;
+ std::string const FilePermissions;
+ std::string const Rename;
+ bool const Programs;
+ bool const Optional;
};
#endif
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index ec173619fb..0665895b77 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -3,16 +3,17 @@
#include "cmInstallGenerator.h"
#include <ostream>
+#include <utility>
#include "cmMakefile.h"
#include "cmSystemTools.h"
cmInstallGenerator::cmInstallGenerator(
- const char* destination, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all)
+ std::string destination, std::vector<std::string> const& configurations,
+ std::string component, MessageLevel message, bool exclude_from_all)
: cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations)
- , Destination(destination ? destination : "")
- , Component(component ? component : "")
+ , Destination(std::move(destination))
+ , Component(std::move(component))
, Message(message)
, ExcludeFromAll(exclude_from_all)
{
@@ -139,8 +140,8 @@ void cmInstallGenerator::AddInstallRule(
os << ")\n";
}
-std::string cmInstallGenerator::CreateComponentTest(const char* component,
- bool exclude_from_all)
+std::string cmInstallGenerator::CreateComponentTest(
+ const std::string& component, bool exclude_from_all)
{
std::string result = R"("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "x)";
result += component;
@@ -158,7 +159,7 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
// Begin this block of installation.
std::string component_test =
- this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll);
+ this->CreateComponentTest(this->Component, this->ExcludeFromAll);
os << indent << "if(" << component_test << ")\n";
// Generate the script possibly with per-configuration code.
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index 024027d4db..d786d24dbe 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -30,9 +30,9 @@ public:
MessageNever
};
- cmInstallGenerator(const char* destination,
+ cmInstallGenerator(std::string destination,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
+ std::string component, MessageLevel message,
bool exclude_from_all);
~cmInstallGenerator() override;
@@ -65,14 +65,14 @@ public:
protected:
void GenerateScript(std::ostream& os) override;
- std::string CreateComponentTest(const char* component,
+ std::string CreateComponentTest(const std::string& component,
bool exclude_from_all);
// Information shared by most generator types.
- std::string Destination;
- std::string Component;
- MessageLevel Message;
- bool ExcludeFromAll;
+ std::string const Destination;
+ std::string const Component;
+ MessageLevel const Message;
+ bool const ExcludeFromAll;
};
#endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 6bb4409d5a..be07fd4d4a 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -2,15 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallProgramsCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+class cmListFileBacktrace;
+
static void FinalAction(cmMakefile& makefile, std::string const& dest,
std::vector<std::string> const& args);
static std::string FindInstallSource(cmMakefile& makefile, const char* name);
@@ -33,9 +38,10 @@ bool cmInstallProgramsCommand(std::vector<std::string> const& args,
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);
- });
+ mf.AddGeneratorAction(
+ [dest, finalArgs](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), dest, finalArgs);
+ });
return true;
}
@@ -83,17 +89,17 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest,
}
// Use a file install generator.
- const char* no_permissions = "";
- const char* no_rename = "";
+ const std::string no_permissions;
+ const std::string no_rename;
bool no_exclude_from_all = false;
std::string no_component =
makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
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));
+ makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
+ files, destination, true, no_permissions, no_configurations, no_component,
+ message, no_exclude_from_all, no_rename));
}
/**
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index ea294556b2..7cdf3b45be 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmInstallScriptGenerator.h"
#include <ostream>
+#include <utility>
#include <vector>
#include "cmGeneratorExpression.h"
@@ -11,13 +12,12 @@
#include "cmPolicies.h"
#include "cmScriptGenerator.h"
-cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
- bool code,
- const char* component,
- bool exclude_from_all)
- : cmInstallGenerator(nullptr, std::vector<std::string>(), component,
+cmInstallScriptGenerator::cmInstallScriptGenerator(
+ std::string script, bool code, std::string const& component,
+ bool exclude_from_all)
+ : cmInstallGenerator("", std::vector<std::string>(), component,
MessageDefault, exclude_from_all)
- , Script(script)
+ , Script(std::move(script))
, Code(code)
, AllowGenex(false)
{
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 7efa321691..0a9c4ba69c 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -19,8 +19,9 @@ class cmLocalGenerator;
class cmInstallScriptGenerator : public cmInstallGenerator
{
public:
- cmInstallScriptGenerator(const char* script, bool code,
- const char* component, bool exclude_from_all);
+ cmInstallScriptGenerator(std::string script, bool code,
+ std::string const& component,
+ bool exclude_from_all);
~cmInstallScriptGenerator() override;
bool Compute(cmLocalGenerator* lg) override;
@@ -32,8 +33,8 @@ protected:
void AddScriptInstallRule(std::ostream& os, Indent indent,
std::string const& script);
- std::string Script;
- bool Code;
+ std::string const Script;
+ bool const Code;
cmLocalGenerator* LocalGenerator;
bool AllowGenex;
};
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index 8a0fefac2e..12bc92bbf4 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -2,7 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallSubdirectoryGenerator.h"
+#include <memory>
#include <sstream>
+#include <utility>
#include <vector>
#include "cmLocalGenerator.h"
@@ -12,11 +14,11 @@
#include "cmSystemTools.h"
cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator(
- cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll)
- : cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr,
- MessageDefault, excludeFromAll)
+ cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll)
+ : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault,
+ excludeFromAll)
, Makefile(makefile)
- , BinaryDirectory(binaryDirectory)
+ , BinaryDirectory(std::move(binaryDirectory))
{
}
@@ -24,7 +26,7 @@ cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() = default;
bool cmInstallSubdirectoryGenerator::HaveInstall()
{
- for (auto generator : this->Makefile->GetInstallGenerators()) {
+ for (const auto& generator : this->Makefile->GetInstallGenerators()) {
if (generator->HaveInstall()) {
return true;
}
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index b99bdd5ff8..f9cd0f1f9d 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -20,7 +20,7 @@ class cmInstallSubdirectoryGenerator : public cmInstallGenerator
{
public:
cmInstallSubdirectoryGenerator(cmMakefile* makefile,
- const char* binaryDirectory,
+ std::string binaryDirectory,
bool excludeFromAll);
~cmInstallSubdirectoryGenerator() override;
@@ -33,8 +33,8 @@ public:
protected:
void GenerateScript(std::ostream& os) override;
- cmMakefile* Makefile;
- std::string BinaryDirectory;
+ cmMakefile* const Makefile;
+ std::string const BinaryDirectory;
cmLocalGenerator* LocalGenerator;
};
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index aa92fa71ae..e05daa8d5b 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -25,15 +25,15 @@
#include "cmake.h"
cmInstallTargetGenerator::cmInstallTargetGenerator(
- std::string targetName, const char* dest, bool implib,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
+ std::string targetName, std::string const& dest, bool implib,
+ std::string file_permissions, std::vector<std::string> const& configurations,
+ std::string const& component, MessageLevel message, bool exclude_from_all,
bool optional, cmListFileBacktrace backtrace)
: cmInstallGenerator(dest, configurations, component, message,
exclude_from_all)
, TargetName(std::move(targetName))
, Target(nullptr)
- , FilePermissions(file_permissions)
+ , FilePermissions(std::move(file_permissions))
, ImportLibrary(implib)
, Optional(optional)
, Backtrace(std::move(backtrace))
@@ -554,7 +554,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule(
// components of the install_name field then we need to create a
// mapping to be applied after installation.
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
- std::string for_install = tgt->GetInstallNameDirForInstallTree();
+ std::string for_install = tgt->GetInstallNameDirForInstallTree(
+ config, "${CMAKE_INSTALL_PREFIX}");
if (for_build != for_install) {
// The directory portions differ. Append the filename to
// create the mapping.
@@ -577,7 +578,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule(
if (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string for_build =
this->Target->GetInstallNameDirForBuildTree(config);
- std::string for_install = this->Target->GetInstallNameDirForInstallTree();
+ std::string for_install = this->Target->GetInstallNameDirForInstallTree(
+ config, "${CMAKE_INSTALL_PREFIX}");
if (this->Target->IsFrameworkOnApple() && for_install.empty()) {
// Frameworks seem to have an id corresponding to their own full
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 8730454b12..e21001f888 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -23,11 +23,11 @@ class cmInstallTargetGenerator : public cmInstallGenerator
{
public:
cmInstallTargetGenerator(
- std::string targetName, const char* dest, bool implib,
- const char* file_permissions,
- std::vector<std::string> const& configurations, const char* component,
- MessageLevel message, bool exclude_from_all, bool optional,
- cmListFileBacktrace backtrace = cmListFileBacktrace());
+ std::string targetName, std::string const& dest, bool implib,
+ std::string file_permissions,
+ std::vector<std::string> const& configurations,
+ std::string const& component, MessageLevel message, bool exclude_from_all,
+ bool optional, cmListFileBacktrace backtrace = cmListFileBacktrace());
~cmInstallTargetGenerator() override;
/** Select the policy for installing shared library linkable name
@@ -106,13 +106,13 @@ protected:
const std::string& toDestDirPath);
void IssueCMP0095Warning(const std::string& unescapedRpath);
- std::string TargetName;
+ std::string const TargetName;
cmGeneratorTarget* Target;
- std::string FilePermissions;
+ std::string const FilePermissions;
NamelinkModeType NamelinkMode;
- bool ImportLibrary;
- bool Optional;
- cmListFileBacktrace Backtrace;
+ bool const ImportLibrary;
+ bool const Optional;
+ cmListFileBacktrace const Backtrace;
};
#endif
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index eabe5903bd..a65ae037e0 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -4,7 +4,6 @@
#include <utility>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
@@ -12,17 +11,11 @@
cmInstalledFile::cmInstalledFile() = default;
-cmInstalledFile::~cmInstalledFile()
-{
- delete NameExpression;
-}
+cmInstalledFile::~cmInstalledFile() = default;
cmInstalledFile::Property::Property() = default;
-cmInstalledFile::Property::~Property()
-{
- cmDeleteAll(this->ValueExpressions);
-}
+cmInstalledFile::Property::~Property() = default;
void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
{
@@ -30,7 +23,7 @@ void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
cmGeneratorExpression ge(backtrace);
this->Name = name;
- this->NameExpression = ge.Parse(name).release();
+ this->NameExpression = ge.Parse(name);
}
std::string const& cmInstalledFile::GetName() const
@@ -63,7 +56,7 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
cmGeneratorExpression ge(backtrace);
Property& property = this->Properties[prop];
- property.ValueExpressions.push_back(ge.Parse(value).release());
+ property.ValueExpressions.push_back(ge.Parse(value));
}
bool cmInstalledFile::HasProperty(const std::string& prop) const
@@ -84,7 +77,7 @@ bool cmInstalledFile::GetProperty(const std::string& prop,
std::string output;
std::string separator;
- for (auto ve : property.ValueExpressions) {
+ for (const auto& ve : property.ValueExpressions) {
output += separator;
output += ve->GetInput();
separator = ";";
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index ee809ee790..698151e3c8 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -24,7 +24,7 @@ public:
using CompiledGeneratorExpressionPtrType =
std::unique_ptr<cmCompiledGeneratorExpression>;
- using ExpressionVectorType = std::vector<cmCompiledGeneratorExpression*>;
+ using ExpressionVectorType = std::vector<CompiledGeneratorExpressionPtrType>;
struct Property
{
@@ -73,7 +73,7 @@ public:
private:
std::string Name;
- cmCompiledGeneratorExpression* NameExpression = nullptr;
+ CompiledGeneratorExpressionPtrType NameExpression;
PropertyMapType Properties;
};
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index b23ab43d82..dd3638654d 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -8,13 +8,15 @@
#include <functional>
#include <limits>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -43,7 +45,7 @@ namespace {
std::vector<std::string> getConfigurations(const cmake* cm)
{
std::vector<std::string> configurations;
- auto makefiles = cm->GetGlobalGenerator()->GetMakefiles();
+ const auto& makefiles = cm->GetGlobalGenerator()->GetMakefiles();
if (makefiles.empty()) {
return configurations;
}
@@ -82,8 +84,8 @@ void cmGetCMakeInputs(const cmGlobalGenerator* gg,
std::vector<std::string>* tmpFiles)
{
const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
- std::vector<cmMakefile*> const& makefiles = gg->GetMakefiles();
- for (cmMakefile const* mf : makefiles) {
+ auto const& makefiles = gg->GetMakefiles();
+ for (const auto& mf : makefiles) {
for (std::string const& lf : mf->GetListFiles()) {
const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
@@ -485,10 +487,10 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
result[kHAS_INSTALL_RULE] = true;
Json::Value installPaths = Json::arrayValue;
- auto targetGenerators = target->Makefile->GetInstallGenerators();
- for (auto installGenerator : targetGenerators) {
+ for (const auto& installGenerator :
+ target->Makefile->GetInstallGenerators()) {
auto installTargetGenerator =
- dynamic_cast<cmInstallTargetGenerator*>(installGenerator);
+ dynamic_cast<cmInstallTargetGenerator*>(installGenerator.get());
if (installTargetGenerator != nullptr &&
installTargetGenerator->GetTarget()->Target == target->Target) {
auto dest = installTargetGenerator->GetDestination(config);
@@ -601,7 +603,7 @@ static Json::Value DumpTargetsList(
std::vector<cmGeneratorTarget*> targetList;
for (auto const& lgIt : generators) {
- cmAppend(targetList, lgIt->GetGeneratorTargets());
+ cm::append(targetList, lgIt->GetGeneratorTargets());
}
std::sort(targetList.begin(), targetList.end());
@@ -641,9 +643,9 @@ static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
// associated generators.
bool hasInstallRule = false;
for (const auto generator : projectIt.second) {
- for (const auto installGen :
+ for (const auto& installGen :
generator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen)) {
+ if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen.get())) {
hasInstallRule = true;
break;
}
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx
index 91eb183379..4e50d7097f 100644
--- a/Source/cmLinkItem.cxx
+++ b/Source/cmLinkItem.cxx
@@ -8,14 +8,17 @@
cmLinkItem::cmLinkItem() = default;
-cmLinkItem::cmLinkItem(std::string n, cmListFileBacktrace bt)
+cmLinkItem::cmLinkItem(std::string n, bool c, cmListFileBacktrace bt)
: String(std::move(n))
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
-cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace bt)
+cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, bool c,
+ cmListFileBacktrace bt)
: Target(t)
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
@@ -39,12 +42,16 @@ bool operator<(cmLinkItem const& l, cmLinkItem const& r)
return false;
}
// Order among strings.
- return l.String < r.String;
+ if (l.String < r.String) {
+ return true;
+ }
+ // Order among cross-config.
+ return l.Cross < r.Cross;
}
bool operator==(cmLinkItem const& l, cmLinkItem const& r)
{
- return l.Target == r.Target && l.String == r.String;
+ return l.Target == r.Target && l.String == r.String && l.Cross == r.Cross;
}
std::ostream& operator<<(std::ostream& os, cmLinkItem const& item)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 2d9378bd56..0ea25c0aa7 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -24,10 +24,11 @@ class cmLinkItem
public:
cmLinkItem();
- cmLinkItem(std::string s, cmListFileBacktrace bt);
- cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace bt);
+ cmLinkItem(std::string s, bool c, cmListFileBacktrace bt);
+ cmLinkItem(cmGeneratorTarget const* t, bool c, cmListFileBacktrace bt);
std::string const& AsStr() const;
cmGeneratorTarget const* Target = nullptr;
+ bool Cross = false;
cmListFileBacktrace Backtrace;
friend bool operator<(cmLinkItem const& l, cmLinkItem const& r);
friend bool operator==(cmLinkItem const& l, cmLinkItem const& r);
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
new file mode 100644
index 0000000000..acc23c8db3
--- /dev/null
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -0,0 +1,142 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmLinkItemGraphVisitor.h"
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "cmGeneratorTarget.h"
+#include "cmLinkItem.h"
+#include "cmMakefile.h"
+
+void cmLinkItemGraphVisitor::VisitItem(cmLinkItem const& item)
+{
+ if (this->ItemVisited(item)) {
+ return;
+ }
+
+ this->OnItem(item);
+
+ this->VisitLinks(item, item);
+}
+
+void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
+ cmLinkItem const& rootItem)
+{
+ if (this->LinkVisited(item, rootItem)) {
+ return;
+ }
+
+ if (item.Target == nullptr) {
+ return;
+ }
+
+ for (auto const& config : item.Target->Makefile->GetGeneratorConfigs()) {
+ this->VisitLinks(item, rootItem, config);
+ }
+}
+
+void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
+ cmLinkItem const& rootItem,
+ std::string const& config)
+{
+ auto const& target = *item.Target;
+
+ DependencyMap dependencies;
+ cmLinkItemGraphVisitor::GetDependencies(target, config, dependencies);
+
+ for (auto const& d : dependencies) {
+ auto const& dependency = d.second;
+ auto const& dependencyType = dependency.first;
+ auto const& dependee = dependency.second;
+ this->VisitItem(dependee);
+
+ if (this->LinkVisited(item, dependee)) {
+ continue;
+ }
+
+ this->OnDirectLink(item, dependee, dependencyType);
+
+ if (rootItem.AsStr() != item.AsStr()) {
+ this->OnIndirectLink(rootItem, dependee);
+ }
+
+ // Visit all the direct and indirect links.
+ this->VisitLinks(dependee, dependee);
+ this->VisitLinks(dependee, item);
+ this->VisitLinks(dependee, rootItem);
+ }
+}
+
+bool cmLinkItemGraphVisitor::ItemVisited(cmLinkItem const& item)
+{
+ auto& collection = this->VisitedItems;
+
+ bool const visited = collection.find(item.AsStr()) != collection.cend();
+
+ if (!visited) {
+ collection.insert(item.AsStr());
+ }
+
+ return visited;
+}
+
+bool cmLinkItemGraphVisitor::LinkVisited(cmLinkItem const& depender,
+ cmLinkItem const& dependee)
+{
+ auto const link = std::make_pair<>(depender.AsStr(), dependee.AsStr());
+
+ bool const linkVisited =
+ this->VisitedLinks.find(link) != this->VisitedLinks.cend();
+
+ if (!linkVisited) {
+ this->VisitedLinks.insert(link);
+ }
+
+ return linkVisited;
+}
+
+void cmLinkItemGraphVisitor::GetDependencies(cmGeneratorTarget const& target,
+ std::string const& config,
+ DependencyMap& dependencies)
+{
+ auto implementationLibraries = target.GetLinkImplementationLibraries(config);
+ if (implementationLibraries != nullptr) {
+ for (auto const& lib : implementationLibraries->Libraries) {
+ auto const& name = lib.AsStr();
+ dependencies[name] = Dependency(DependencyType::LinkPrivate, lib);
+ }
+ }
+
+ auto interfaceLibraries =
+ target.GetLinkInterfaceLibraries(config, &target, true);
+ if (interfaceLibraries != nullptr) {
+ for (auto const& lib : interfaceLibraries->Libraries) {
+ auto const& name = lib.AsStr();
+ if (dependencies.find(name) != dependencies.cend()) {
+ dependencies[name] = Dependency(DependencyType::LinkPublic, lib);
+ } else {
+ dependencies[name] = Dependency(DependencyType::LinkInterface, lib);
+ }
+ }
+ }
+
+ std::vector<cmGeneratorTarget*> objectLibraries;
+ target.GetObjectLibrariesCMP0026(objectLibraries);
+ for (auto const& lib : objectLibraries) {
+ auto const& name = lib->GetName();
+ if (dependencies.find(name) == dependencies.cend()) {
+ auto objectItem = cmLinkItem(lib, false, lib->GetBacktrace());
+ dependencies[name] = Dependency(DependencyType::Object, objectItem);
+ }
+ }
+
+ auto const& utilityItems = target.GetUtilityItems();
+ for (auto const& item : utilityItems) {
+ auto const& name = item.AsStr();
+ if (dependencies.find(name) == dependencies.cend()) {
+ dependencies[name] = Dependency(DependencyType::Utility, item);
+ }
+ }
+}
diff --git a/Source/cmLinkItemGraphVisitor.h b/Source/cmLinkItemGraphVisitor.h
new file mode 100644
index 0000000000..21dc659ad3
--- /dev/null
+++ b/Source/cmLinkItemGraphVisitor.h
@@ -0,0 +1,75 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmLinkItemGraphVisitor_h
+#define cmLinkItemGraphVisitor_h
+
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "cmLinkItem.h"
+
+class cmGeneratorTarget;
+
+/** \class cmLinkItemGraphVisitor
+ * \brief Visits a graph of linked items.
+ *
+ * Allows to visit items and dependency links (direct and indirect) between
+ * those items.
+ * This abstract class takes care of the graph traversal, making sure that:
+ * - it terminates even in the presence of cycles;
+ * - it visits every object once (and only once);
+ * - it visits the objects in the same order every time.
+ *
+ * Children classes only have to implement OnItem() etc. to handle whatever
+ * logic they care about.
+ */
+class cmLinkItemGraphVisitor
+{
+public:
+ virtual ~cmLinkItemGraphVisitor() = default;
+
+ virtual void VisitGraph(std::string const& name) = 0;
+
+ void VisitItem(cmLinkItem const& item);
+
+protected:
+ enum class DependencyType
+ {
+ LinkInterface,
+ LinkPublic,
+ LinkPrivate,
+ Object,
+ Utility
+ };
+
+ virtual void OnItem(cmLinkItem const& item) = 0;
+
+ virtual void OnDirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee, DependencyType dt) = 0;
+
+ virtual void OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee) = 0;
+
+private:
+ std::set<std::string> VisitedItems;
+
+ std::set<std::pair<std::string, std::string>> VisitedLinks;
+
+ void VisitLinks(cmLinkItem const& item, cmLinkItem const& rootItem);
+ void VisitLinks(cmLinkItem const& item, cmLinkItem const& rootItem,
+ std::string const& config);
+
+ using Dependency = std::pair<DependencyType, cmLinkItem>;
+ using DependencyMap = std::map<std::string, Dependency>;
+
+ bool ItemVisited(cmLinkItem const& item);
+ bool LinkVisited(cmLinkItem const& depender, cmLinkItem const& dependee);
+
+ static void GetDependencies(cmGeneratorTarget const& target,
+ std::string const& config,
+ DependencyMap& dependencies);
+};
+
+#endif
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index cb63ceb03a..2b8f836227 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -32,7 +32,7 @@ bool cmLinkLibrariesCommand(std::vector<std::string> const& args,
}
mf.AppendProperty("LINK_LIBRARIES", "optimized");
}
- mf.AppendProperty("LINK_LIBRARIES", i->c_str());
+ mf.AppendProperty("LINK_LIBRARIES", *i);
}
return true;
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 3d516f8033..480c005cd3 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -22,6 +22,7 @@ cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
, OutputConverter(outputConverter)
, ForResponse(false)
, UseWatcomQuote(false)
+ , UseNinjaMulti(false)
, Relink(false)
{
}
@@ -33,6 +34,11 @@ void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote)
this->UseWatcomQuote = useWatcomQuote;
}
+void cmLinkLineComputer::SetUseNinjaMulti(bool useNinjaMulti)
+{
+ this->UseNinjaMulti = useNinjaMulti;
+}
+
void cmLinkLineComputer::SetForResponse(bool forResponse)
{
this->ForResponse = forResponse;
@@ -92,10 +98,14 @@ void cmLinkLineComputer::ComputeLinkLibs(
std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
{
- cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
- ? cmOutputConverter::RESPONSE
- : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
- : cmOutputConverter::SHELL);
+ cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
+ if (this->ForResponse) {
+ shellFormat = cmOutputConverter::RESPONSE;
+ } else if (this->UseWatcomQuote) {
+ shellFormat = cmOutputConverter::WATCOMQUOTE;
+ } else if (this->UseNinjaMulti) {
+ shellFormat = cmOutputConverter::NINJAMULTI;
+ }
return this->OutputConverter->ConvertToOutputFormat(input, shellFormat);
}
@@ -103,10 +113,14 @@ std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
std::string cmLinkLineComputer::ConvertToOutputForExisting(
std::string const& input)
{
- cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
- ? cmOutputConverter::RESPONSE
- : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
- : cmOutputConverter::SHELL);
+ cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
+ if (this->ForResponse) {
+ shellFormat = cmOutputConverter::RESPONSE;
+ } else if (this->UseWatcomQuote) {
+ shellFormat = cmOutputConverter::WATCOMQUOTE;
+ } else if (this->UseNinjaMulti) {
+ shellFormat = cmOutputConverter::NINJAMULTI;
+ }
return this->OutputConverter->ConvertToOutputForExisting(input, shellFormat);
}
@@ -142,9 +156,11 @@ void cmLinkLineComputer::ComputeLinkPath(
type = cmStateEnums::ImportLibraryArtifact;
}
- linkPathNoBT += cmStrCat(
- " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type),
- libPathTerminator, " ");
+ linkPathNoBT +=
+ cmStrCat(" ", libPathFlag,
+ this->ConvertToOutputForExisting(
+ item.Target->GetDirectory(cli.GetConfig(), type)),
+ libPathTerminator, " ");
}
}
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index f426976a2f..df424683fd 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -28,6 +28,7 @@ public:
cmLinkLineComputer& operator=(cmLinkLineComputer const&) = delete;
void SetUseWatcomQuote(bool useWatcomQuote);
+ void SetUseNinjaMulti(bool useNinjaMulti);
void SetForResponse(bool forResponse);
void SetRelink(bool relink);
@@ -69,6 +70,7 @@ protected:
bool ForResponse;
bool UseWatcomQuote;
+ bool UseNinjaMulti;
bool Relink;
};
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 1184bcb583..d49e7117c1 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -24,12 +24,20 @@ bool cmLoadCacheCommand(std::vector<std::string> const& args,
{
if (args.empty()) {
status.SetError("called with wrong number of arguments.");
+ return false;
}
if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") {
return ReadWithPrefix(args, status);
}
+ if (status.GetMakefile().GetCMakeInstance()->GetWorkingMode() ==
+ cmake::SCRIPT_MODE) {
+ status.SetError(
+ "Only load_cache(READ_WITH_PREFIX) may be used in script mode");
+ return false;
+ }
+
// Cache entries to be excluded from the import list.
// If this set is empty, all cache entries are brought in
// and they can not be overridden.
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 23ace649a8..92258e27be 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -14,6 +14,7 @@
#include "cmCommand.h"
#include "cmDynamicLoader.h"
#include "cmExecutionStatus.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -25,6 +26,8 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
+class cmListFileBacktrace;
+
namespace {
const char* LastName = nullptr;
@@ -158,8 +161,10 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
if (result) {
if (this->Impl->FinalPass) {
auto impl = this->Impl;
- this->Makefile->AddFinalAction(
- [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); });
+ this->Makefile->AddGeneratorAction(
+ [impl](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ impl->DoFinalPass(lg.GetMakefile());
+ });
}
return true;
}
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index f86955dd0c..025ef7e6bb 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -17,13 +17,9 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
: cmLocalGenerator(gg, mf)
, WorkingDirectory(std::move(wd))
{
- // Store the configuration name that will be generated.
- if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
- // Use the build type given by the user.
- this->ConfigName = config;
- } else {
- // No configuration type given.
- this->ConfigName.clear();
+ this->Makefile->GetConfigurations(this->ConfigNames);
+ if (this->ConfigNames.empty()) {
+ this->ConfigNames.emplace_back();
}
}
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index eaef6ab530..378ca634d1 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include <vector>
#include "cmLocalGenerator.h"
@@ -25,7 +26,10 @@ public:
std::string wd);
~cmLocalCommonGenerator() override;
- std::string const& GetConfigName() const { return this->ConfigName; }
+ std::vector<std::string> const& GetConfigNames() const
+ {
+ return this->ConfigNames;
+ }
std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
@@ -39,7 +43,7 @@ public:
protected:
std::string WorkingDirectory;
- std::string ConfigName;
+ std::vector<std::string> ConfigNames;
friend class cmCommonTargetGenerator;
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index ffd46d4544..cf6802db76 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2,6 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalGenerator.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <initializer_list>
+#include <iterator>
+#include <sstream>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
@@ -40,20 +56,6 @@
# include "cmCryptoHash.h"
#endif
-#include <algorithm>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <initializer_list>
-#include <iterator>
-#include <sstream>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include <cm/string_view>
-
#if defined(__HAIKU__)
# include <FindDirectory.h>
# include <StorageDefs.h>
@@ -181,11 +183,7 @@ cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
this->LinkerSysroot);
}
-cmLocalGenerator::~cmLocalGenerator()
-{
- cmDeleteAll(this->GeneratorTargets);
- cmDeleteAll(this->OwnedImportedGeneratorTargets);
-}
+cmLocalGenerator::~cmLocalGenerator() = default;
void cmLocalGenerator::IssueMessage(MessageType t,
std::string const& text) const
@@ -263,8 +261,8 @@ static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs,
void cmLocalGenerator::TraceDependencies()
{
// Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -317,9 +315,7 @@ void cmLocalGenerator::GenerateTestFiles()
}
// Ask each test generator to write its code.
- std::vector<cmTestGenerator*> const& testers =
- this->Makefile->GetTestGenerators();
- for (cmTestGenerator* tester : testers) {
+ for (const auto& tester : this->Makefile->GetTestGenerators()) {
tester->Compute(this);
tester->Generate(fout, config, configurationTypes);
}
@@ -365,9 +361,7 @@ void cmLocalGenerator::CreateEvaluationFileOutputs()
void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
{
- std::vector<cmGeneratorExpressionEvaluationFile*> ef =
- this->Makefile->GetEvaluationFiles();
- for (cmGeneratorExpressionEvaluationFile* geef : ef) {
+ for (const auto& geef : this->Makefile->GetEvaluationFiles()) {
geef->CreateOutputFile(this, config);
}
}
@@ -375,8 +369,7 @@ void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
void cmLocalGenerator::ProcessEvaluationFiles(
std::vector<std::string>& generatedFiles)
{
- for (cmGeneratorExpressionEvaluationFile* geef :
- this->Makefile->GetEvaluationFiles()) {
+ for (const auto& geef : this->Makefile->GetEvaluationFiles()) {
geef->Generate(this);
if (cmSystemTools::GetFatalErrorOccured()) {
return;
@@ -395,7 +388,7 @@ void cmLocalGenerator::ProcessEvaluationFiles(
return;
}
- cmAppend(generatedFiles, files);
+ cm::append(generatedFiles, files);
std::inplace_merge(generatedFiles.begin(),
generatedFiles.end() - files.size(),
generatedFiles.end());
@@ -559,18 +552,17 @@ void cmLocalGenerator::GenerateInstallRules()
// Ask each install generator to write its code.
cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082);
- std::vector<cmInstallGenerator*> const& installers =
- this->Makefile->GetInstallGenerators();
+ auto const& installers = this->Makefile->GetInstallGenerators();
bool haveSubdirectoryInstall = false;
bool haveInstallAfterSubdirectory = false;
if (status == cmPolicies::WARN) {
- for (cmInstallGenerator* installer : installers) {
+ for (const auto& installer : installers) {
installer->CheckCMP0082(haveSubdirectoryInstall,
haveInstallAfterSubdirectory);
installer->Generate(fout, config, configurationTypes);
}
} else {
- for (cmInstallGenerator* installer : installers) {
+ for (const auto& installer : installers) {
installer->Generate(fout, config, configurationTypes);
}
}
@@ -635,11 +627,14 @@ void cmLocalGenerator::GenerateInstallRules()
}
}
-void cmLocalGenerator::AddGeneratorTarget(cmGeneratorTarget* gt)
+void cmLocalGenerator::AddGeneratorTarget(
+ std::unique_ptr<cmGeneratorTarget> gt)
{
- this->GeneratorTargets.push_back(gt);
- this->GeneratorTargetSearchIndex.emplace(gt->GetName(), gt);
- this->GlobalGenerator->IndexGeneratorTarget(gt);
+ cmGeneratorTarget* gt_ptr = gt.get();
+
+ this->GeneratorTargets.push_back(std::move(gt));
+ this->GeneratorTargetSearchIndex.emplace(gt_ptr->GetName(), gt_ptr);
+ this->GlobalGenerator->IndexGeneratorTarget(gt_ptr);
}
void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt)
@@ -648,9 +643,10 @@ void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt)
this->GlobalGenerator->IndexGeneratorTarget(gt);
}
-void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt)
+void cmLocalGenerator::AddOwnedImportedGeneratorTarget(
+ std::unique_ptr<cmGeneratorTarget> gt)
{
- this->OwnedImportedGeneratorTargets.push_back(gt);
+ this->OwnedImportedGeneratorTargets.push_back(std::move(gt));
}
cmGeneratorTarget* cmLocalGenerator::FindLocalNonAliasGeneratorTarget(
@@ -673,8 +669,8 @@ void cmLocalGenerator::ComputeTargetManifest()
}
// Add our targets to the manifest for each configuration.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -695,17 +691,18 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
using LanguagePair = std::pair<std::string, std::string>;
std::vector<LanguagePair> pairedLanguages{ { "OBJC", "C" },
- { "OBJCXX", "CXX" } };
- std::set<LanguagePair> objcEnabledLanguages;
+ { "OBJCXX", "CXX" },
+ { "CUDA", "CXX" } };
+ std::set<LanguagePair> inferredEnabledLanguages;
for (auto const& lang : pairedLanguages) {
if (this->Makefile->GetState()->GetLanguageEnabled(lang.first)) {
- objcEnabledLanguages.insert(lang);
+ inferredEnabledLanguages.insert(lang);
}
}
// Process compile features of all targets.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
for (std::string const& c : configNames) {
if (!target->ComputeCompileFeatures(c)) {
return false;
@@ -738,12 +735,17 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
target->GetProperty(cmStrCat(lang.second, property)));
}
};
- for (auto const& lang : objcEnabledLanguages) {
+ for (auto const& lang : pairedLanguages) {
if (copyStandardToObjLang(lang)) {
copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
copyPropertyToObjLang(lang, "_EXTENSIONS");
}
}
+ if (const char* standard = target->GetProperty("CUDA_STANDARD")) {
+ if (std::string{ standard } == "98") {
+ target->Target->SetProperty("CUDA_STANDARD", "03");
+ }
+ }
}
}
@@ -988,6 +990,91 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
}
+cmTarget* cmLocalGenerator::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->Makefile->GetCustomCommandTarget(
+ target, objLibCommands, this->DirectoryBacktrace);
+ if (!t) {
+ return nullptr;
+ }
+
+ detail::AddCustomCommandToTarget(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts,
+ depends, commandLines, type, comment, workingDir, escapeOldStyle,
+ uses_terminal, depfile, job_pool, command_expand_lists);
+
+ return t;
+}
+
+cmSourceFile* cmLocalGenerator::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> no_byproducts;
+ cmImplicitDependsList no_implicit_depends;
+ return this->AddCustomCommandToOutput(
+ { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
+}
+
+cmSourceFile* cmLocalGenerator::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,
+ const std::string& job_pool)
+{
+ // Make sure there is at least one output.
+ if (outputs.empty()) {
+ cmSystemTools::Error("Attempt to add a custom rule with no output!");
+ return nullptr;
+ }
+
+ return detail::AddCustomCommandToOutput(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs,
+ byproducts, depends, main_dependency, implicit_depends, commandLines,
+ comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
+}
+
+cmTarget* cmLocalGenerator::AddUtilityCommand(
+ const std::string& utilityName, bool excludeFromAll, const char* workingDir,
+ 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)
+{
+ cmTarget* target =
+ this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll);
+ target->SetIsGeneratorProvided(true);
+
+ if (commandLines.empty() && depends.empty()) {
+ return target;
+ }
+
+ detail::AddUtilityCommand(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target,
+ this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends,
+ commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
+ job_pool);
+
+ return target;
+}
+
std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
cmGeneratorTarget const* target, std::string const& lang,
std::string const& config, bool stripImplicitDirs,
@@ -1084,7 +1171,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
}
for (std::string const& i : impDirVec) {
- if (implicitSet.insert(cmSystemTools::GetRealPath(i)).second) {
+ if (implicitSet.insert(this->GlobalGenerator->GetRealPath(i)).second) {
implicitDirs.emplace_back(i);
}
}
@@ -1095,7 +1182,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
&lang](std::string const& dir) {
return (
// Do not exclude directories that are not in an excluded set.
- ((!cmContains(implicitSet, cmSystemTools::GetRealPath(dir))) &&
+ ((!cmContains(implicitSet, this->GlobalGenerator->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
@@ -1685,10 +1772,18 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
const std::string& lang,
const std::string& config)
{
- // Only add macOS specific flags on Darwin platforms (macOS and iOS):
+ // Only add Apple specific flags on Apple platforms
if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
std::vector<std::string> archs;
target->GetAppleArchs(config, archs);
+ if (!archs.empty() && !lang.empty() &&
+ (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
+ for (std::string const& arch : archs) {
+ flags += " -arch ";
+ flags += arch;
+ }
+ }
+
const char* sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
if (sysroot && sysroot[0] == '/' && !sysroot[1]) {
sysroot = nullptr;
@@ -1696,27 +1791,37 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
std::string sysrootFlagVar =
std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
+ if (sysrootFlag && *sysrootFlag) {
+ std::vector<std::string> arch_sysroots;
+ if (const char* arch_sysroots_str =
+ this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) {
+ cmExpandList(std::string(arch_sysroots_str), arch_sysroots, true);
+ }
+ if (!arch_sysroots.empty()) {
+ assert(arch_sysroots.size() == archs.size());
+ for (size_t i = 0; i < archs.size(); ++i) {
+ if (arch_sysroots[i].empty()) {
+ continue;
+ }
+ flags += " -Xarch_" + archs[i] + " ";
+ // Combine sysroot flag and path to work with -Xarch
+ std::string arch_sysroot = sysrootFlag + arch_sysroots[i];
+ flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+ }
+ } else if (sysroot && *sysroot) {
+ flags += " ";
+ flags += sysrootFlag;
+ flags += " ";
+ flags += this->ConvertToOutputFormat(sysroot, SHELL);
+ }
+ }
+
const char* deploymentTarget =
this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
std::string deploymentTargetFlagVar =
std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
const char* deploymentTargetFlag =
this->Makefile->GetDefinition(deploymentTargetFlagVar);
- if (!archs.empty() && !lang.empty() &&
- (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
- for (std::string const& arch : archs) {
- flags += " -arch ";
- flags += arch;
- }
- }
-
- if (sysrootFlag && *sysrootFlag && sysroot && *sysroot) {
- flags += " ";
- flags += sysrootFlag;
- flags += " ";
- flags += this->ConvertToOutputFormat(sysroot, SHELL);
- }
-
if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget &&
*deploymentTarget) {
flags += " ";
@@ -1864,7 +1969,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::UNKNOWN_LIBRARY:
- dep = target->GetLocation(config);
+ dep = target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true);
return true;
case cmStateEnums::OBJECT_LIBRARY:
// An object library has no single file on which to depend.
@@ -1898,8 +2004,16 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
// Treat the name as relative to the source directory in which it
// was given.
- dep = cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentSource(), '/',
- inName);
+ dep = cmStrCat(this->GetCurrentSourceDirectory(), '/', inName);
+
+ // If the in-source path does not exist, assume it instead lives in the
+ // binary directory.
+ if (!cmSystemTools::FileExists(dep)) {
+ dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName);
+ }
+
+ dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory());
+
return true;
}
@@ -2004,17 +2118,22 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
langStdMap["OBJC"].emplace_back("99");
langStdMap["OBJC"].emplace_back("90");
+ langStdMap["CUDA"].emplace_back("20");
+ langStdMap["CUDA"].emplace_back("17");
langStdMap["CUDA"].emplace_back("14");
langStdMap["CUDA"].emplace_back("11");
- langStdMap["CUDA"].emplace_back("98");
+ langStdMap["CUDA"].emplace_back("03");
}
std::string standard(standardProp);
-
+ if (lang == "CUDA" && standard == "98") {
+ standard = "03";
+ }
std::vector<std::string>& stds = langStdMap[lang];
auto stdIt = std::find(stds.begin(), stds.end(), standard);
if (stdIt == stds.end()) {
+
std::string e =
lang + "_STANDARD is set to invalid value '" + standard + "'";
this->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
@@ -2296,175 +2415,177 @@ void cmLocalGenerator::AppendFlags(
void cmLocalGenerator::AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const
{
- this->AppendFlags(flags, this->EscapeForShell(rawFlag));
+ this->AppendFlags(
+ flags,
+ this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
}
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");
+ std::vector<std::string> configsList;
+ std::string configDefault = this->Makefile->GetConfigurations(configsList);
+ if (configsList.empty()) {
+ configsList.push_back(configDefault);
}
- const std::string buildType = cmSystemTools::UpperCase(config);
- // FIXME: Refactor collection of sources to not evaluate object libraries.
- 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;
- }
+ for (std::string const& config : configsList) {
+ const std::string buildType = cmSystemTools::UpperCase(config);
- const std::string pchSource = target->GetPchSource(config, lang);
- const std::string pchHeader = target->GetPchHeader(config, lang);
+ // FIXME: Refactor collection of sources to not evaluate object libraries.
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
- if (pchSource.empty() || pchHeader.empty()) {
- continue;
- }
-
- const std::string pchExtension =
- this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+ 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;
+ }
- if (pchExtension.empty()) {
- continue;
- }
+ const std::string pchSource = target->GetPchSource(config, lang);
+ const std::string pchHeader = target->GetPchHeader(config, lang);
- const char* pchReuseFrom =
- target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ if (pchSource.empty() || pchHeader.empty()) {
+ continue;
+ }
- auto pch_sf = this->Makefile->GetOrCreateSource(
- pchSource, false, cmSourceFileLocationKind::Known);
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
- if (!this->GetGlobalGenerator()->IsXcode()) {
- if (!pchReuseFrom) {
- target->AddSource(pchSource, true);
+ if (pchExtension.empty()) {
+ continue;
}
- const std::string pchFile = target->GetPchFile(config, lang);
+ const char* pchReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- // Exclude the pch files from linking
- if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
- if (!pchReuseFrom) {
- pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
- } else {
- auto reuseTarget =
- this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
- if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!pchReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
- const std::string pdb_prefix =
- this->GetGlobalGenerator()->IsMultiConfig()
- ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
- : "";
+ const std::string pchFile = target->GetPchFile(config, lang);
- const std::string target_compile_pdb_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/");
+ // Exclude the pch files from linking
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ if (!pchReuseFrom) {
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
- const std::string copy_script =
- cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
- cmGeneratedFileStream file(copy_script);
+ if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
- file << "# CMake generated file\n";
- for (auto extension : { ".pdb", ".idb" }) {
- const std::string from_file = cmStrCat(
- reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
- extension);
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig()
+ ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+ : "";
- const std::string to_dir = cmStrCat(
+ const std::string target_compile_pdb_dir = cmStrCat(
target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/${PDB_PREFIX}");
+ target->GetName(), ".dir/");
- const std::string to_file =
- cmStrCat(to_dir, pchReuseFrom, extension);
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
- std::string dest_file = to_file;
+ file << "# CMake generated file\n";
+ for (auto extension : { ".pdb", ".idb" }) {
+ const std::string from_file =
+ cmStrCat(reuseTarget->GetLocalGenerator()
+ ->GetCurrentBinaryDirectory(),
+ "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
+ pchReuseFrom, extension);
- const std::string prefix = target->GetSafeProperty("PREFIX");
- if (!prefix.empty()) {
- dest_file = cmStrCat(to_dir, prefix, pchReuseFrom, extension);
- }
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", target->GetName(), ".dir/${PDB_PREFIX}");
+
+ const std::string to_file =
+ cmStrCat(to_dir, pchReuseFrom, extension);
+
+ std::string dest_file = to_file;
+
+ const std::string prefix = target->GetSafeProperty("PREFIX");
+ if (!prefix.empty()) {
+ dest_file =
+ cmStrCat(to_dir, prefix, pchReuseFrom, extension);
+ }
- file << "if (EXISTS \"" << from_file << "\" AND \"" << from_file
- << "\" IS_NEWER_THAN \"" << dest_file << "\")\n";
- file << " file(COPY \"" << from_file << "\""
- << " DESTINATION \"" << to_dir << "\")\n";
- if (!prefix.empty()) {
- file << " file(REMOVE \"" << dest_file << "\")\n";
- file << " file(RENAME \"" << to_file << "\" \"" << dest_file
+ file << "if (EXISTS \"" << from_file << "\" AND \""
+ << from_file << "\" IS_NEWER_THAN \"" << dest_file
<< "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ if (!prefix.empty()) {
+ file << " file(REMOVE \"" << dest_file << "\")\n";
+ file << " file(RENAME \"" << to_file << "\" \"" << dest_file
+ << "\")\n";
+ }
+ file << "endif()\n";
}
- file << "endif()\n";
- }
- cmCustomCommandLines commandLines;
- 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(
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(),
+ cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
+
+ const std::string no_main_dependency;
+ const std::vector<std::string> no_deps;
+ const char* no_message = "";
+ const char* no_current_dir = nullptr;
+ std::vector<std::string> no_byproducts;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
+ pchReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ this->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
outputs, no_byproducts, no_deps, no_main_dependency,
no_implicit_depends, commandLines, no_message,
no_current_dir);
- if (copy_rule) {
- target->AddSource(copy_rule->ResolveFullPath());
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
}
- }
- target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- target_compile_pdb_dir.c_str());
- }
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir);
+ }
- std::string pchSourceObj =
- reuseTarget->GetPchFileObject(config, lang);
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang);
- // Link to the pch object file
- target->Target->AppendProperty(
- "LINK_FLAGS",
- cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL))
- .c_str(),
- true);
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ "LINK_FLAGS",
+ cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+ true);
+ }
+ } else {
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
}
- } else {
- pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
- }
- // Add pchHeader to source files, which will
- // be grouped as "Precompile Header File"
- auto pchHeader_sf = this->Makefile->GetOrCreateSource(
- pchHeader, false, cmSourceFileLocationKind::Known);
- std::string err;
- pchHeader_sf->ResolveFullPath(&err);
- target->AddSource(pchHeader);
+ // Add pchHeader to source files, which will
+ // be grouped as "Precompile Header File"
+ auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+ pchHeader, false, cmSourceFileLocationKind::Known);
+ std::string err;
+ pchHeader_sf->ResolveFullPath(&err);
+ target->AddSource(pchHeader);
+ }
}
}
}
@@ -2516,8 +2637,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
batchSize = filtered_sources.size();
}
- for (size_t itemsLeft = filtered_sources.size(), chunk = batchSize,
- batch = 0;
+ for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
itemsLeft > 0; itemsLeft -= chunk, ++batch) {
chunk = std::min(itemsLeft, batchSize);
@@ -2629,11 +2749,11 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
void cmLocalGenerator::AppendCompileOptions(std::string& options,
- const char* options_list,
+ std::string const& options_list,
const char* regex) const
{
// Short-circuit if there are no options.
- if (!options_list) {
+ if (options_list.empty()) {
return;
}
@@ -2687,11 +2807,11 @@ void cmLocalGenerator::AppendCompileOptions(
}
void cmLocalGenerator::AppendIncludeDirectories(
- std::vector<std::string>& includes, const char* includes_list,
+ std::vector<std::string>& includes, const std::string& includes_list,
const cmSourceFile& sourceFile) const
{
// Short-circuit if there are no includes.
- if (!includes_list) {
+ if (includes_list.empty()) {
return;
}
@@ -2885,7 +3005,7 @@ class cmInstallTargetGeneratorLocal : public cmInstallTargetGenerator
{
public:
cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
- const char* dest, bool implib)
+ std::string const& dest, bool implib)
: cmInstallTargetGenerator(
t, dest, implib, "", std::vector<std::string>(), "Unspecified",
cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()), false,
@@ -2901,15 +3021,15 @@ void cmLocalGenerator::GenerateTargetInstallRules(
{
// Convert the old-style install specification from each target to
// an install generator and run it.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
// Include the user-specified pre-install script for this target.
if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(preinstall, false, nullptr, false);
+ cmInstallScriptGenerator g(preinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
@@ -2930,8 +3050,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
// Use a target install generator.
- cmInstallTargetGeneratorLocal g(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+ false);
g.Generate(os, config, configurationTypes);
} break;
case cmStateEnums::SHARED_LIBRARY: {
@@ -2939,19 +3059,19 @@ void cmLocalGenerator::GenerateTargetInstallRules(
// Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime
// destination.
- cmInstallTargetGeneratorLocal g1(this, l->GetName(),
- destination.c_str(), true);
+ cmInstallTargetGeneratorLocal g1(this, l->GetName(), destination,
+ true);
g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user.
destination = l->Target->GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
- cmInstallTargetGeneratorLocal g2(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g2(this, l->GetName(), destination,
+ false);
g2.Generate(os, config, configurationTypes);
#else
// Use a target install generator.
- cmInstallTargetGeneratorLocal g(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+ false);
g.Generate(os, config, configurationTypes);
#endif
} break;
@@ -2962,7 +3082,7 @@ void cmLocalGenerator::GenerateTargetInstallRules(
// Include the user-specified post-install script for this target.
if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(postinstall, false, nullptr, false);
+ cmInstallScriptGenerator g(postinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
}
@@ -3118,6 +3238,11 @@ bool cmLocalGenerator::IsNMake() const
return this->GetState()->UseNMake();
}
+bool cmLocalGenerator::IsNinjaMulti() const
+{
+ return this->GetState()->UseNinjaMulti();
+}
+
std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
const cmSourceFile& source, std::string const& dir_max,
bool* hasSourceExtension, char const* customOutputExtension)
@@ -3446,3 +3571,245 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
mf->ConfigureFile(inFile, fname, false, false, false);
}
+
+namespace {
+void CreateGeneratedSource(cmLocalGenerator& lg, const std::string& output,
+ cmCommandOrigin origin,
+ const cmListFileBacktrace& lfbt)
+{
+ if (cmGeneratorExpression::Find(output) == std::string::npos) {
+ // Outputs without generator expressions from the project are already
+ // created and marked as generated. Do not mark them again, because
+ // other commands might have overwritten the property.
+ if (origin == cmCommandOrigin::Generator) {
+ lg.GetMakefile()->GetOrCreateGeneratedSource(output);
+ }
+ } else {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Generator expressions in custom command outputs are not implemented!",
+ lfbt);
+ }
+}
+
+void CreateGeneratedSources(cmLocalGenerator& lg,
+ const std::vector<std::string>& outputs,
+ cmCommandOrigin origin,
+ const cmListFileBacktrace& lfbt)
+{
+ for (std::string const& o : outputs) {
+ CreateGeneratedSource(lg, o, origin, lfbt);
+ }
+}
+
+cmSourceFile* AddCustomCommand(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ 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)
+{
+ cmMakefile* mf = lg.GetMakefile();
+
+ // Choose a source file on which to store the custom command.
+ cmSourceFile* file = nullptr;
+ if (!commandLines.empty() && !main_dependency.empty()) {
+ // The main dependency was specified. Use it unless a different
+ // custom command already used it.
+ file = mf->GetSource(main_dependency);
+ if (file && file->GetCustomCommand() && !replace) {
+ // The main dependency already has a custom command.
+ if (commandLines == file->GetCustomCommand()->GetCommandLines()) {
+ // The existing custom command is identical. Silently ignore
+ // the duplicate.
+ return file;
+ }
+ // The existing custom command is different. We need to
+ // generate a rule file for this new command.
+ file = nullptr;
+ } else if (!file) {
+ file = mf->CreateSource(main_dependency);
+ }
+ }
+
+ // Generate a rule file if the main dependency is not available.
+ if (!file) {
+ cmGlobalGenerator* gg = lg.GetGlobalGenerator();
+
+ // Construct a rule file associated with the first output produced.
+ std::string outName = gg->GenerateRuleFile(outputs[0]);
+
+ // Check if the rule file already exists.
+ file = mf->GetSource(outName, cmSourceFileLocationKind::Known);
+ if (file && file->GetCustomCommand() && !replace) {
+ // The rule file already exists.
+ if (commandLines != file->GetCustomCommand()->GetCommandLines()) {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Attempt to add a custom rule to output\n ", outName,
+ "\nwhich already has a custom rule."),
+ lfbt);
+ }
+ return file;
+ }
+
+ // Create a cmSourceFile for the rule file.
+ if (!file) {
+ file = mf->CreateSource(outName, true, cmSourceFileLocationKind::Known);
+ }
+ file->SetProperty("__CMAKE_RULE", "1");
+ }
+
+ // Attach the custom command to the file.
+ if (file) {
+ // Construct a complete list of dependencies.
+ std::vector<std::string> depends2(depends);
+ if (!main_dependency.empty()) {
+ depends2.push_back(main_dependency);
+ }
+
+ std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
+ outputs, byproducts, depends2, commandLines, lfbt, 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(std::move(cc));
+
+ mf->AddSourceOutputs(file, outputs, byproducts);
+ }
+ return file;
+}
+}
+
+namespace detail {
+void AddCustomCommandToTarget(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, 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)
+{
+ cmMakefile* mf = lg.GetMakefile();
+
+ // Always create the byproduct sources and mark them generated.
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ // Add the command to the appropriate build step for the target.
+ std::vector<std::string> no_output;
+ cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt,
+ comment, workingDir);
+ cc.SetEscapeOldStyle(escapeOldStyle);
+ cc.SetEscapeAllowMakeVars(true);
+ cc.SetUsesTerminal(uses_terminal);
+ cc.SetCommandExpandLists(command_expand_lists);
+ cc.SetDepfile(depfile);
+ cc.SetJobPool(job_pool);
+ switch (type) {
+ case cmCustomCommandType::PRE_BUILD:
+ target->AddPreBuildCommand(std::move(cc));
+ break;
+ case cmCustomCommandType::PRE_LINK:
+ target->AddPreLinkCommand(std::move(cc));
+ break;
+ case cmCustomCommandType::POST_BUILD:
+ target->AddPostBuildCommand(std::move(cc));
+ break;
+ }
+
+ mf->AddTargetByproducts(target, byproducts);
+}
+
+cmSourceFile* AddCustomCommandToOutput(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ 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)
+{
+ // Always create the output sources and mark them generated.
+ CreateGeneratedSources(lg, outputs, origin, lfbt);
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ return AddCustomCommand(
+ lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
+}
+
+void AppendCustomCommandToOutput(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ const std::string& output,
+ const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines)
+{
+ // Lookup an existing command.
+ if (cmSourceFile* sf = lg.GetMakefile()->GetSourceFileWithOutput(output)) {
+ if (cmCustomCommand* cc = sf->GetCustomCommand()) {
+ cc->AppendCommands(commandLines);
+ cc->AppendDepends(depends);
+ cc->AppendImplicitDepends(implicit_depends);
+ return;
+ }
+ }
+
+ // No existing command found.
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Attempt to append to output\n ", output,
+ "\nwhich is not already a custom command output."),
+ lfbt);
+}
+
+void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const cmUtilityOutput& force, const char* workingDir,
+ const 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)
+{
+ // Always create the byproduct sources and mark them generated.
+ CreateGeneratedSource(lg, force.Name, origin, lfbt);
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ // Use an empty comment to avoid generation of default comment.
+ if (!comment) {
+ comment = "";
+ }
+
+ std::string no_main_dependency;
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* rule = AddCustomCommand(
+ lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency,
+ no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false,
+ escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"",
+ job_pool);
+ if (rule) {
+ lg.GetMakefile()->AddTargetByproducts(target, byproducts);
+ }
+
+ if (!force.NameCMP0049.empty()) {
+ target->AddSource(force.NameCMP0049);
+ }
+}
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 12359dbddd..88194b7a29 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -7,6 +7,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
@@ -14,6 +15,7 @@
#include "cm_kwiml.h"
+#include "cmCustomCommandTypes.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -22,13 +24,16 @@
class cmComputeLinkInformation;
class cmCustomCommandGenerator;
+class cmCustomCommandLines;
class cmGeneratorTarget;
class cmGlobalGenerator;
+class cmImplicitDependsList;
class cmLinkLineComputer;
class cmMakefile;
class cmRulePlaceholderExpander;
class cmSourceFile;
class cmState;
+class cmTarget;
class cmake;
/** \class cmLocalGenerator
@@ -143,14 +148,16 @@ public:
bool forResponseFile = false,
const std::string& config = "");
- const std::vector<cmGeneratorTarget*>& GetGeneratorTargets() const
+ using GeneratorTargetVector =
+ std::vector<std::unique_ptr<cmGeneratorTarget>>;
+ const GeneratorTargetVector& GetGeneratorTargets() const
{
return this->GeneratorTargets;
}
- void AddGeneratorTarget(cmGeneratorTarget* gt);
+ void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
- void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt);
+ void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
const std::string& name) const;
@@ -160,15 +167,8 @@ public:
* Process a list of include directories
*/
void AppendIncludeDirectories(std::vector<std::string>& includes,
- const char* includes_list,
- const cmSourceFile& sourceFile) const;
- void AppendIncludeDirectories(std::vector<std::string>& includes,
std::string const& includes_list,
- const cmSourceFile& sourceFile) const
- {
- this->AppendIncludeDirectories(includes, includes_list.c_str(),
- sourceFile);
- }
+ const cmSourceFile& sourceFile) const;
void AppendIncludeDirectories(std::vector<std::string>& includes,
const std::vector<std::string>& includes_vec,
const cmSourceFile& sourceFile) const;
@@ -188,14 +188,9 @@ public:
* Encode a list of compile options for the compiler
* command line.
*/
- void AppendCompileOptions(std::string& options, const char* options_list,
- const char* regex = nullptr) const;
void AppendCompileOptions(std::string& options,
std::string const& options_list,
- const char* regex = nullptr) const
- {
- this->AppendCompileOptions(options, options_list.c_str(), regex);
- }
+ const char* regex = nullptr) const;
void AppendCompileOptions(std::string& options,
const std::vector<std::string>& options_vec,
const char* regex = nullptr) const;
@@ -292,6 +287,51 @@ public:
cmGeneratorTarget* target, const std::string& lang,
const std::string& config);
+ /**
+ * Add a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a target.
+ */
+ cmTarget* 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 = true,
+ bool uses_terminal = false, const std::string& depfile = "",
+ const std::string& job_pool = "", bool command_expand_lists = false,
+ cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
+
+ /**
+ * Add a custom command to a source file.
+ */
+ cmSourceFile* 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 = 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::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,
+ const std::string& depfile = "", const std::string& job_pool = "");
+
+ /**
+ * 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, bool excludeFromAll,
+ const char* workingDir, 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,
+ bool command_expand_lists = false, const std::string& job_pool = "");
+
std::string GetProjectName() const;
/** Compute the language used to compile the given source file. */
@@ -414,6 +454,7 @@ public:
bool IsWatcomWMake() const;
bool IsMinGWMake() const;
bool IsNMake() const;
+ bool IsNinjaMulti() const;
void IssueMessage(MessageType t, std::string const& text) const;
@@ -461,11 +502,11 @@ protected:
using GeneratorTargetMap =
std::unordered_map<std::string, cmGeneratorTarget*>;
GeneratorTargetMap GeneratorTargetSearchIndex;
- std::vector<cmGeneratorTarget*> GeneratorTargets;
+ GeneratorTargetVector GeneratorTargets;
std::set<cmGeneratorTarget const*> WarnCMP0063;
GeneratorTargetMap ImportedGeneratorTargets;
- std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets;
+ GeneratorTargetVector OwnedImportedGeneratorTargets;
std::map<std::string, std::string> AliasTargets;
std::map<std::string, std::string> Compilers;
@@ -494,4 +535,46 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName,
std::string::size_type max_total_len);
#endif
+namespace detail {
+void AddCustomCommandToTarget(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, 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* AddCustomCommandToOutput(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ 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 AppendCustomCommandToOutput(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ const std::string& output,
+ const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines);
+
+void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const cmUtilityOutput& force, const char* workingDir,
+ 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);
+}
+
#endif
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 4b10798e1f..098fa5a577 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -5,6 +5,8 @@
#include <algorithm>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGenerator.h"
@@ -50,10 +52,11 @@ void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
void cmLocalGhsMultiGenerator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cm::append(remaining, this->GetGeneratorTargets());
for (auto& t : remaining) {
if (t) {
- GenerateTargetsDepthFirst(t, remaining);
+ this->GenerateTargetsDepthFirst(t, remaining);
}
}
}
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 134bbe18af..be1dd0df53 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmake.h"
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
@@ -61,7 +62,12 @@ void cmLocalNinjaGenerator::Generate()
this->HomeRelativeOutputPath.clear();
}
- this->WriteProcessedMakefile(this->GetBuildFileStream());
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ this->WriteProcessedMakefile(this->GetImplFileStream(config));
+ }
+ }
+ this->WriteProcessedMakefile(this->GetCommonFileStream());
#ifdef NINJA_GEN_VERBOSE_FILES
this->WriteProcessedMakefile(this->GetRulesFileStream());
#endif
@@ -82,18 +88,26 @@ void cmLocalNinjaGenerator::Generate()
}
}
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- auto tg = cmNinjaTargetGenerator::New(target);
+ auto tg = cmNinjaTargetGenerator::New(target.get());
if (tg) {
- tg->Generate();
+ if (target->Target->IsPerConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ tg->Generate(config);
+ }
+ } else {
+ tg->Generate("");
+ }
}
}
- this->WriteCustomCommandBuildStatements();
- this->AdditionalCleanFiles();
+ for (auto const& config : this->GetConfigNames()) {
+ this->WriteCustomCommandBuildStatements(config);
+ this->AdditionalCleanFiles(config);
+ }
}
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
@@ -140,9 +154,15 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
// Private methods.
-cmGeneratedFileStream& cmLocalNinjaGenerator::GetBuildFileStream() const
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetImplFileStream(
+ const std::string& config) const
{
- return *this->GetGlobalNinjaGenerator()->GetBuildFileStream();
+ return *this->GetGlobalNinjaGenerator()->GetImplFileStream(config);
+}
+
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetCommonFileStream() const
+{
+ return *this->GetGlobalNinjaGenerator()->GetCommonFileStream();
}
cmGeneratedFileStream& cmLocalNinjaGenerator::GetRulesFileStream() const
@@ -162,10 +182,22 @@ cmake* cmLocalNinjaGenerator::GetCMakeInstance()
void cmLocalNinjaGenerator::WriteBuildFileTop()
{
- // For the build file.
- this->WriteProjectHeader(this->GetBuildFileStream());
- this->WriteNinjaRequiredVersion(this->GetBuildFileStream());
- this->WriteNinjaFilesInclusion(this->GetBuildFileStream());
+ this->WriteProjectHeader(this->GetCommonFileStream());
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ auto& stream = this->GetImplFileStream(config);
+ this->WriteProjectHeader(stream);
+ this->WriteNinjaRequiredVersion(stream);
+ this->WriteNinjaConfigurationVariable(stream, config);
+ this->WriteNinjaFilesInclusionConfig(stream);
+ }
+ } else {
+ this->WriteNinjaRequiredVersion(this->GetCommonFileStream());
+ this->WriteNinjaConfigurationVariable(this->GetCommonFileStream(),
+ this->GetConfigNames().front());
+ }
+ this->WriteNinjaFilesInclusionCommon(this->GetCommonFileStream());
// For the rule file.
this->WriteProjectHeader(this->GetRulesFileStream());
@@ -175,7 +207,8 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Project: " << this->GetProjectName() << std::endl
- << "# Configuration: " << this->ConfigName << std::endl;
+ << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ")
+ << std::endl;
cmGlobalNinjaGenerator::WriteDivider(os);
}
@@ -206,6 +239,14 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
<< std::endl;
}
+void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable(
+ std::ostream& os, const std::string& config)
+{
+ cmGlobalNinjaGenerator::WriteVariable(
+ os, "CONFIGURATION", config,
+ "Set configuration variable for custom commands.");
+}
+
void cmLocalNinjaGenerator::WritePools(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
@@ -235,7 +276,21 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
}
}
-void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
+void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os << "# Include auxiliary files.\n"
+ << "\n";
+ cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
+ std::string const ninjaCommonFile =
+ ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE);
+ std::string const commonFilePath = ng->EncodePath(ninjaCommonFile);
+ cmGlobalNinjaGenerator::WriteInclude(os, commonFilePath,
+ "Include common file.");
+ os << "\n";
+}
+
+void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Include auxiliary files.\n"
@@ -263,25 +318,30 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
}
void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
- cmNinjaDeps& outputs)
+ cmNinjaDeps& outputs,
+ const std::string& config)
{
- this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
+ this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
+ config);
}
void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
cmNinjaDeps& outputs,
+ const std::string& config,
+ const std::string& fileConfig,
cmNinjaTargetDepends depends)
{
- this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs,
- depends);
+ this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs, config,
+ fileConfig, depends);
}
void cmLocalNinjaGenerator::AppendCustomCommandDeps(
- cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps)
+ cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps,
+ const std::string& config)
{
for (std::string const& i : ccg.GetDepends()) {
std::string dep;
- if (this->GetRealDependency(i, this->GetConfigName(), dep)) {
+ if (this->GetRealDependency(i, config, dep)) {
ninjaDeps.push_back(
this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
}
@@ -416,6 +476,8 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
void cmLocalNinjaGenerator::AppendCustomCommandLines(
cmCustomCommandGenerator const& ccg, std::vector<std::string>& cmdLines)
{
+ auto* gg = this->GetGlobalNinjaGenerator();
+
if (ccg.GetNumberOfCommands() > 0) {
std::string wd = ccg.GetWorkingDirectory();
if (wd.empty()) {
@@ -437,8 +499,10 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
cmdLines.push_back(launcher +
- this->ConvertToOutputFormat(ccg.GetCommand(i),
- cmOutputConverter::SHELL));
+ this->ConvertToOutputFormat(
+ ccg.GetCommand(i),
+ gg->IsMultiConfig() ? cmOutputConverter::NINJAMULTI
+ : cmOutputConverter::SHELL));
std::string& cmd = cmdLines.back();
ccg.AppendArguments(i, cmd);
@@ -446,14 +510,15 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
}
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
- cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps)
+ cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps,
+ const std::string& config)
{
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
- if (gg->SeenCustomCommand(cc)) {
+ if (gg->SeenCustomCommand(cc, config)) {
return;
}
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
+ cmCustomCommandGenerator ccg(*cc, config, this);
const std::vector<std::string>& outputs = ccg.GetOutputs();
const std::vector<std::string>& byproducts = ccg.GetByproducts();
@@ -484,7 +549,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
}
cmNinjaDeps ninjaDeps;
- this->AppendCustomCommandDeps(ccg, ninjaDeps);
+ this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
std::vector<std::string> cmdLines;
this->AppendCustomCommandLines(ccg, cmdLines);
@@ -495,7 +560,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
build.Outputs = std::move(ninjaOutputs);
build.ExplicitDeps = std::move(ninjaDeps);
build.OrderOnlyDeps = orderOnlyDeps;
- gg->WriteBuild(this->GetBuildFileStream(), build);
+ gg->WriteBuild(this->GetImplFileStream(config), build);
} else {
std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
// Hash full path to make unique.
@@ -507,8 +572,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
this->BuildCommandLine(cmdLines, customStep),
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(),
- /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, ninjaDeps,
- orderOnlyDeps);
+ /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
+ ninjaDeps, orderOnlyDeps);
}
}
@@ -524,7 +589,8 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
ins.first->second.insert(target);
}
-void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
+void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
+ const std::string& config)
{
for (cmCustomCommand const* customCommand : this->CustomCommands) {
auto i = this->CustomCommandTargets.find(customCommand);
@@ -542,15 +608,16 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
auto j = i->second.begin();
assert(j != i->second.end());
std::vector<std::string> ccTargetDeps;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j,
- ccTargetDeps);
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
+ *j, ccTargetDeps, config);
std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
++j;
for (; j != i->second.end(); ++j) {
std::vector<std::string> jDeps;
std::vector<std::string> depsIntersection;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps);
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps,
+ config);
std::sort(jDeps.begin(), jDeps.end());
std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
jDeps.begin(), jDeps.end(),
@@ -558,7 +625,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
ccTargetDeps = depsIntersection;
}
- this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
+ this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config);
}
}
@@ -599,15 +666,13 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
return launcher;
}
-void cmLocalNinjaGenerator::AdditionalCleanFiles()
+void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
{
if (const char* prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
std::vector<std::string> cleanFiles;
{
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+ cmExpandList(cmGeneratorExpression::Evaluate(prop_value, this, config),
cleanFiles);
}
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
@@ -615,7 +680,7 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles()
for (std::string const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
- cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
+ cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
}
}
}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index f64534ce11..ef160e70f8 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -64,9 +64,11 @@ public:
std::string const& customStep = std::string(),
cmGeneratorTarget const* target = nullptr) const;
- void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
+ const std::string& config);
void AppendTargetDepends(
- cmGeneratorTarget* target, cmNinjaDeps& outputs,
+ cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
+ const std::string& fileConfig,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AddCustomCommandTarget(cmCustomCommand const* cc,
@@ -74,7 +76,8 @@ public:
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
std::vector<std::string>& cmdLines);
void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
- cmNinjaDeps& ninjaDeps);
+ cmNinjaDeps& ninjaDeps,
+ const std::string& config);
protected:
std::string ConvertToIncludeReference(
@@ -83,20 +86,25 @@ protected:
bool forceFullPaths = false) override;
private:
- cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
+ cmGeneratedFileStream& GetCommonFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
void WriteBuildFileTop();
void WriteProjectHeader(std::ostream& os);
void WriteNinjaRequiredVersion(std::ostream& os);
- void WriteNinjaFilesInclusion(std::ostream& os);
+ void WriteNinjaConfigurationVariable(std::ostream& os,
+ const std::string& config);
+ void WriteNinjaFilesInclusionConfig(std::ostream& os);
+ void WriteNinjaFilesInclusionCommon(std::ostream& os);
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
- const cmNinjaDeps& orderOnlyDeps);
+ const cmNinjaDeps& orderOnlyDeps,
+ const std::string& config);
- void WriteCustomCommandBuildStatements();
+ void WriteCustomCommandBuildStatements(const std::string& config);
std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
@@ -104,7 +112,7 @@ private:
std::string const& customStep,
cmGeneratorTarget const* target) const;
- void AdditionalCleanFiles();
+ void AdditionalCleanFiles(const std::string& config);
std::string HomeRelativeOutputPath;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 4a70248d6f..24a635183a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -3,16 +3,18 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include <algorithm>
+#include <cassert>
#include <cstdio>
#include <sstream>
#include <utility>
#include <cm/memory>
+#include <cm/vector>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmFileTimeCache.h"
@@ -106,6 +108,13 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default;
+std::string cmLocalUnixMakefileGenerator3::GetConfigName() const
+{
+ auto const& configNames = this->GetConfigNames();
+ assert(configNames.size() == 1);
+ return configNames.front();
+}
+
void cmLocalUnixMakefileGenerator3::Generate()
{
// Record whether some options are enabled to avoid checking many
@@ -121,12 +130,12 @@ void cmLocalUnixMakefileGenerator3::Generate()
// Generate the rule files for each target.
cmGlobalUnixMakefileGenerator3* gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::unique_ptr<cmMakefileTargetGenerator> tg(
- cmMakefileTargetGenerator::New(target));
+ cmMakefileTargetGenerator::New(target.get()));
if (tg) {
tg->WriteRuleFiles();
gg->RecordTargetProgress(tg.get());
@@ -157,15 +166,15 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
std::map<std::string, LocalObjectInfo>& localObjectFiles)
{
- for (cmGeneratorTarget* gt : this->GetGeneratorTargets()) {
+ for (const auto& gt : this->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, this->ConfigName);
+ gt->GetObjectSources(objectSources, this->GetConfigName());
// Compute full path to object file directory for this target.
std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
- '/', this->GetTargetDirectory(gt), '/');
+ '/', this->GetTargetDirectory(gt.get()), '/');
// Compute the name of each object file.
for (cmSourceFile const* sf : objectSources) {
bool hasSourceExtension = true;
@@ -176,7 +185,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
}
LocalObjectInfo& info = localObjectFiles[objectName];
info.HasSourceExtension = hasSourceExtension;
- info.emplace_back(gt, sf->GetLanguage());
+ info.emplace_back(gt.get(), sf->GetLanguage());
}
}
}
@@ -352,7 +361,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// for each target we just provide a rule to cd up to the top and do a make
// on the target
std::string localName;
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if ((target->GetType() == cmStateEnums::EXECUTABLE) ||
(target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
@@ -362,7 +371,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
emitted.insert(target->GetName());
// for subdirs add a rule to build this specific target by name.
- localName = cmStrCat(this->GetRelativeTargetDirectory(target), "/rule");
+ localName =
+ cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/rule");
commands.clear();
depends.clear();
@@ -383,11 +393,11 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
}
// Add a fast rule to build the target
- std::string makefileName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/build.make");
+ std::string makefileName = cmStrCat(
+ this->GetRelativeTargetDirectory(target.get()), "/build.make");
// make sure the makefile name is suitable for a makefile
std::string makeTargetName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/build");
+ cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/build");
localName = cmStrCat(target->GetName(), "/fast");
depends.clear();
commands.clear();
@@ -400,9 +410,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// Add a local name for the rule to relink the target before
// installation.
- if (target->NeedRelinkBeforeInstall(this->ConfigName)) {
- makeTargetName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/preinstall");
+ if (target->NeedRelinkBeforeInstall(this->GetConfigName())) {
+ makeTargetName = cmStrCat(
+ this->GetRelativeTargetDirectory(target.get()), "/preinstall");
localName = cmStrCat(target->GetName(), "/preinstall");
depends.clear();
commands.clear();
@@ -628,7 +638,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
<< "# The command to remove a file.\n"
<< "RM = "
<< cmakeShellCommand
- << " -E remove -f\n"
+ << " -E rm -f\n"
<< "\n";
makefileStream
<< "# Escaping for special characters.\n"
@@ -673,9 +683,15 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
if (!this->IsNMake() && !this->IsWatcomWMake() &&
!this->BorlandMakeCurlyHack) {
// turn off RCS and SCCS automatic stuff from gmake
- makefileStream
- << "# Remove some rules from gmake that .SUFFIXES does not remove.\n"
- << "SUFFIXES =\n\n";
+ constexpr const char* vcs_rules[] = {
+ "%,v", "RCS/%", "RCS/%,v", "SCCS/s.%", "s.%",
+ };
+ for (auto vcs_rule : vcs_rules) {
+ std::vector<std::string> vcs_depend;
+ vcs_depend.emplace_back(vcs_rule);
+ this->WriteMakeRule(makefileStream, "Disable VCS-based implicit rules.",
+ "%", vcs_depend, no_commands, false);
+ }
}
// Add a fake suffix to keep HP happy. Must be max 32 chars for SGI make.
std::vector<std::string> depends;
@@ -712,6 +728,10 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
;
/* clang-format on */
} else {
+ makefileStream << "# Command-line flag to silence nested $(MAKE).\n"
+ "$(VERBOSE)MAKESILENT = -s\n"
+ "\n";
+
// Write special target to silence make output. This must be after
// the default target in case VERBOSE is set (which changes the
// name). The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a
@@ -849,7 +869,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepends(
// Add a dependency on the rule file itself unless an option to skip
// it is specifically enabled by the user or project.
if (!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY")) {
- cmAppend(depends, ruleFiles);
+ cm::append(depends, ruleFiles);
}
}
@@ -857,7 +877,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepends(
std::vector<std::string>& depends, const std::vector<cmCustomCommand>& ccs)
{
for (cmCustomCommand const& cc : ccs) {
- cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+ cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
this->AppendCustomDepend(depends, ccg);
}
}
@@ -868,7 +888,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepend(
for (std::string const& d : ccg.GetDepends()) {
// Lookup the real name of the dependency in case it is a CMake target.
std::string dep;
- if (this->GetRealDependency(d, this->ConfigName, dep)) {
+ if (this->GetRealDependency(d, this->GetConfigName(), dep)) {
depends.push_back(std::move(dep));
}
}
@@ -879,7 +899,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommands(
cmGeneratorTarget* target, std::string const& relative)
{
for (cmCustomCommand const& cc : ccs) {
- cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+ cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
this->AppendCustomCommand(commands, ccg, target, relative, true);
}
}
@@ -1022,7 +1042,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
this->CreateCDCommand(commands1, dir, relative);
// push back the custom commands
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
}
void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
@@ -1093,8 +1113,7 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
return;
}
- cmLocalGenerator* rootLG =
- this->GetGlobalGenerator()->GetLocalGenerators().at(0);
+ const auto& rootLG = this->GetGlobalGenerator()->GetLocalGenerators().at(0);
std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory();
std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
std::string cleanfile =
@@ -1551,8 +1570,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
this->WriteDivider(ruleFileStream);
ruleFileStream << "# Targets provided globally by CMake.\n"
<< "\n";
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* gt : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& gt : targets) {
if (gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
std::string targetString =
"Special rule for the target " + gt->GetName();
@@ -1564,8 +1583,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
text = "Running external command ...";
}
depends.reserve(gt->GetUtilities().size());
- for (BT<std::string> const& u : gt->GetUtilities()) {
- depends.push_back(u.Value);
+ for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
+ depends.push_back(u.Value.first);
}
this->AppendEcho(commands, text,
cmLocalUnixMakefileGenerator3::EchoGlobal);
@@ -1573,10 +1592,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
// Global targets store their rules in pre- and post-build commands.
this->AppendCustomDepends(depends, gt->GetPreBuildCommands());
this->AppendCustomDepends(depends, gt->GetPostBuildCommands());
- this->AppendCustomCommands(commands, gt->GetPreBuildCommands(), gt,
- this->GetCurrentBinaryDirectory());
- this->AppendCustomCommands(commands, gt->GetPostBuildCommands(), gt,
+ this->AppendCustomCommands(commands, gt->GetPreBuildCommands(), gt.get(),
this->GetCurrentBinaryDirectory());
+ this->AppendCustomCommands(commands, gt->GetPostBuildCommands(),
+ gt.get(), this->GetCurrentBinaryDirectory());
std::string targetName = gt->GetName();
this->WriteMakeRule(ruleFileStream, targetString.c_str(), targetName,
depends, commands, true);
@@ -1839,7 +1858,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
// Build a list of preprocessor definitions for the target.
std::set<std::string> defines;
- this->GetTargetDefines(target, this->ConfigName, implicitLang.first,
+ this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
defines);
if (!defines.empty()) {
/* clang-format off */
@@ -1863,11 +1882,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
std::vector<std::string> includes;
this->GetIncludeDirectories(includes, target, implicitLang.first,
- this->ConfigName);
+ this->GetConfigName());
std::string binaryDir = this->GetState()->GetBinaryDirectory();
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
- cmEraseIf(includes, ::NotInProjectDir(sourceDir, binaryDir));
+ cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
}
for (std::string const& include : includes) {
cmakefileStream << " \""
@@ -1910,7 +1929,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
{
// Call make on the given file.
std::string cmd = cmStrCat(
- "$(MAKE) -f ",
+ "$(MAKE) $(MAKESILENT) -f ",
this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL), ' ');
cmGlobalUnixMakefileGenerator3* gg =
@@ -1957,18 +1976,18 @@ void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
}
void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
- const char* s)
+ const std::string& s)
{
// Write the given string to the stream with escaping to get it back
// into CMake through the lexical scanner.
os << "\"";
- for (const char* c = s; *c; ++c) {
- if (*c == '\\') {
+ for (char c : s) {
+ if (c == '\\') {
os << "\\\\";
- } else if (*c == '"') {
+ } else if (c == '"') {
os << "\\\"";
} else {
- os << *c;
+ os << c;
}
}
os << "\"";
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index f12ae8b161..68eeb29424 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -33,6 +33,8 @@ public:
cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
~cmLocalUnixMakefileGenerator3() override;
+ std::string GetConfigName() const;
+
void ComputeHomeRelativeOutputPath() override;
/**
@@ -75,7 +77,7 @@ public:
void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; }
// used in writing out Cmake files such as WriteDirectoryInformation
- static void WriteCMakeArgument(std::ostream& os, const char* s);
+ static void WriteCMakeArgument(std::ostream& os, const std::string& s);
/** creates the common disclaimer text at the top of each makefile */
void WriteDisclaimer(std::ostream& os);
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index f3d828b28e..02e2c6d161 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio10Generator.h"
+#include <cmext/algorithm>
+
#include "cm_expat.h"
+#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -101,10 +104,11 @@ void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
void cmLocalVisualStudio10Generator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cm::append(remaining, this->GetGeneratorTargets());
for (auto& t : remaining) {
if (t) {
- GenerateTargetsDepthFirst(t, remaining);
+ this->GenerateTargetsDepthFirst(t, remaining);
}
}
this->WriteStampFiles();
@@ -124,8 +128,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
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",
- cmStateEnums::INTERNAL);
+ guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
}
const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e771a4abab..9aa39914a2 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -64,8 +64,8 @@ cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
void cmLocalVisualStudio7Generator::AddHelperCommands()
{
// Now create GUIDs for targets
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget const* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -89,8 +89,8 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
// Visual Studio .NET 2003 Service Pack 1 will not run post-build
// commands for targets in which no sources are built. Add dummy
// rules to force these targets to build.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (auto& l : tgts) {
if (l->GetType() == cmStateEnums::GLOBAL_TARGET) {
std::vector<std::string> no_depends;
cmCustomCommandLines force_commands =
@@ -102,9 +102,9 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
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)) {
+ if (cmSourceFile* file = this->AddCustomCommandToOutput(
+ force, no_depends, no_main_dependency, force_commands, " ",
+ nullptr, true)) {
l->AddSource(file->ResolveFullPath());
}
}
@@ -125,17 +125,17 @@ void cmLocalVisualStudio7Generator::WriteProjectFiles()
}
// Get the set of targets in this directory.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
+ const auto& tgts = this->GetGeneratorTargets();
// Create the project file for each target.
- for (cmGeneratorTarget* l : tgts) {
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
// INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
// so don't build a projectfile for it
if (!l->GetProperty("EXTERNAL_MSPROJECT")) {
- this->CreateSingleVCProj(l->GetName(), l);
+ this->CreateSingleVCProj(l->GetName(), l.get());
}
}
}
@@ -146,7 +146,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
// out of date.
std::string stampName =
cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
- cmSystemTools::MakeDirectory(stampName.c_str());
+ cmSystemTools::MakeDirectory(stampName);
stampName += "/generate.stamp";
cmsys::ofstream stamp(stampName.c_str());
stamp << "# CMake generation timestamp file for this directory.\n";
@@ -194,7 +194,7 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(
}
// add to the list of projects
- target->Target->SetProperty("GENERATOR_FILE_NAME", lname.c_str());
+ target->Target->SetProperty("GENERATOR_FILE_NAME", lname);
// create the dsp.cmake file
std::string fname;
fname = cmStrCat(this->GetCurrentBinaryDirectory(), '/', lname);
@@ -257,12 +257,11 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
"--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(
- fullpathStampName, listFiles, makefileIn, commandLines, comment.c_str(),
- no_working_directory, true, false);
- if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
+ std::string fullpathStampName = cmSystemTools::CollapseFullPath(stampName);
+ this->AddCustomCommandToOutput(fullpathStampName, listFiles, makefileIn,
+ commandLines, comment.c_str(),
+ no_working_directory, true, false);
+ if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
// Finalize the source file path now since we're adding this after
// the generator validated all project-named sources.
file->ResolveFullPath();
@@ -279,7 +278,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(
{
fout << "\t<Configurations>\n";
for (std::string const& config : configs) {
- this->WriteConfiguration(fout, config.c_str(), libName, target);
+ this->WriteConfiguration(fout, config, libName, target);
}
fout << "\t</Configurations>\n";
}
@@ -580,7 +579,7 @@ public:
this->Stream << this->LG->EscapeForXML("\n");
}
std::string script = this->LG->ConstructScript(ccg);
- this->Stream << this->LG->EscapeForXML(script.c_str());
+ this->Stream << this->LG->EscapeForXML(script);
}
private:
@@ -733,13 +732,13 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
: target->GetDirectory(configName);
/* clang-format off */
fout << "\t\t\tOutputDirectory=\""
- << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(outDir) << "\"\n";
/* clang-format on */
}
/* clang-format off */
fout << "\t\t\tIntermediateDirectory=\""
- << this->ConvertToXMLOutputPath(intermediateDir.c_str())
+ << this->ConvertToXMLOutputPath(intermediateDir)
<< "\"\n"
<< "\t\t\tConfigurationType=\"" << configType << "\"\n"
<< "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
@@ -788,8 +787,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
} else {
modDir = ".";
}
- fout << "\t\t\t\tModulePath=\""
- << this->ConvertToXMLOutputPath(modDir.c_str())
+ fout << "\t\t\t\tModulePath=\"" << this->ConvertToXMLOutputPath(modDir)
<< "\\$(ConfigurationName)\"\n";
}
targetOptions.OutputAdditionalIncludeDirectories(
@@ -802,7 +800,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
std::string pdb = target->GetCompilePDBPath(configName);
if (!pdb.empty()) {
fout << "\t\t\t\tProgramDataBaseFileName=\""
- << this->ConvertToXMLOutputPathSingle(pdb.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(pdb) << "\"\n";
}
}
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
@@ -879,7 +877,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
for (cmSourceFile const* manifest : manifest_srcs) {
std::string m = manifest->GetFullPath();
- fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+ fout << this->ConvertToXMLOutputPath(m) << ";";
}
fout << "\"";
}
@@ -946,7 +944,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
- targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str());
+ targetLinkFlags = target->GetProperty(linkFlagsConfig);
if (targetLinkFlags) {
extraLinkOptions += " ";
extraLinkOptions += targetLinkFlags;
@@ -985,7 +983,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
break;
}
case cmStateEnums::STATIC_LIBRARY: {
@@ -1015,7 +1013,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
}
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
break;
}
case cmStateEnums::SHARED_LIBRARY:
@@ -1057,7 +1055,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
@@ -1066,7 +1064,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
fout << "\t\t\t\tProgramDatabaseFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
if (targetOptions.IsDebug()) {
fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
@@ -1078,7 +1076,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
}
std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ const char* stackVal = this->Makefile->GetDefinition(stackVar);
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
}
@@ -1086,7 +1084,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
'/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"";
if (this->FortranProject) {
fout << "\n\t\t\t\tLinkDLL=\"true\"";
}
@@ -1132,14 +1130,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n";
std::string path = this->ConvertToXMLOutputPathSingle(
- target->GetPDBDirectory(configName).c_str());
+ target->GetPDBDirectory(configName));
fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/"
<< targetNames.PDB << "\"\n";
if (targetOptions.IsDebug()) {
@@ -1167,7 +1165,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
<< "\"\n";
}
std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ const char* stackVal = this->Makefile->GetDefinition(stackVar);
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
}
@@ -1175,7 +1173,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
'/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"/>\n";
break;
}
case cmStateEnums::UTILITY:
@@ -1256,8 +1254,8 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
for (auto const& lib : libs) {
if (lib.IsPath) {
std::string rel =
- lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.Value.c_str());
- fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
+ lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.Value);
+ fout << lg->ConvertToXMLOutputPath(rel) << " ";
} else if (!lib.Target ||
lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
fout << lib.Value.Value << " ";
@@ -1282,7 +1280,7 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
if (!obj->GetObjectLibrary().empty()) {
std::string const& objFile = obj->GetFullPath();
std::string rel = lg->MaybeConvertToRelativePath(currentBinDir, objFile);
- fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
+ fout << sep << lg->ConvertToXMLOutputPath(rel);
sep = " ";
}
}
@@ -1303,9 +1301,8 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
}
// Switch to a relative path specification if it is shorter.
- if (cmSystemTools::FileIsFullPath(dir.c_str())) {
- std::string rel =
- this->MaybeConvertToRelativePath(currentBinDir, dir.c_str());
+ if (cmSystemTools::FileIsFullPath(dir)) {
+ std::string rel = this->MaybeConvertToRelativePath(currentBinDir, dir);
if (rel.size() < dir.size()) {
dir = rel;
}
@@ -1314,9 +1311,8 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
// First search a configuration-specific subdirectory and then the
// original directory.
fout << comma
- << this->ConvertToXMLOutputPath(
- (dir + "/$(ConfigurationName)").c_str())
- << "," << this->ConvertToXMLOutputPath(dir.c_str());
+ << this->ConvertToXMLOutputPath(dir + "/$(ConfigurationName)") << ","
+ << this->ConvertToXMLOutputPath(dir);
comma = ",";
}
}
@@ -1337,7 +1333,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- if (cmSourceFile const* sf = this->CreateVCProjBuildRule()) {
+ if (cmSourceFile* sf = this->CreateVCProjBuildRule()) {
cmGeneratorTarget::AllConfigSource acs;
acs.Source = sf;
acs.Kind = cmGeneratorTarget::SourceKindCustomCommand;
@@ -1518,13 +1514,13 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
for (std::vector<std::string>::iterator j = depends.begin();
j != depends.end(); ++j) {
fc.AdditionalDeps += sep;
- fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
+ fc.AdditionalDeps += lg->ConvertToXMLOutputPath(*j);
sep = ";";
needfc = true;
}
}
- const std::string& linkLanguage = gt->GetLinkerLanguage(config.c_str());
+ const std::string& linkLanguage = gt->GetLinkerLanguage(config);
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
@@ -1629,7 +1625,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
FCInfo fcinfo(this, target, acs, configs);
fout << "\t\t\t<File\n";
- std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
+ std::string d = this->ConvertToXMLOutputPathSingle(source);
// Tell MS-Dev what the source is. If the compiler knows how to
// build it, then it will.
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
@@ -1759,21 +1755,21 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << compileTool << "\"\n"
<< "\t\t\t\t\tAdditionalOptions=\""
- << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
+ << this->EscapeForXML(fc.CompileFlags) << "\"/>\n";
}
std::string comment = this->ConstructComment(ccg);
std::string script = this->ConstructScript(ccg);
if (this->FortranProject) {
- cmSystemTools::ReplaceString(script, "$(Configuration)", config.c_str());
+ cmSystemTools::ReplaceString(script, "$(Configuration)", config);
}
/* clang-format off */
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << customTool << "\"\n"
<< "\t\t\t\t\tDescription=\""
- << this->EscapeForXML(comment.c_str()) << "\"\n"
+ << this->EscapeForXML(comment) << "\"\n"
<< "\t\t\t\t\tCommandLine=\""
- << this->EscapeForXML(script.c_str()) << "\"\n"
+ << this->EscapeForXML(script) << "\"\n"
<< "\t\t\t\t\tAdditionalDependencies=\"";
/* clang-format on */
if (ccg.GetDepends().empty()) {
@@ -1789,8 +1785,8 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
for (std::string const& d : ccg.GetDepends()) {
// Get the real name of the dependency in case it is a CMake target.
std::string dep;
- if (this->GetRealDependency(d.c_str(), config.c_str(), dep)) {
- fout << this->ConvertToXMLOutputPath(dep.c_str()) << ";";
+ if (this->GetRealDependency(d, config, dep)) {
+ fout << this->ConvertToXMLOutputPath(dep) << ";";
}
}
}
@@ -1802,7 +1798,7 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
// Write a rule for the output generated by this command.
const char* sep = "";
for (std::string const& output : ccg.GetOutputs()) {
- fout << sep << this->ConvertToXMLOutputPathSingle(output.c_str());
+ fout << sep << this->ConvertToXMLOutputPathSingle(output);
sep = ";";
}
}
@@ -1948,7 +1944,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
this->WriteProjectSCC(fout, target);
/* clang-format off */
fout<< "\tKeyword=\"" << keyword << "\">\n"
- << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\">\n"
+ << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
<< "\t<Platforms>\n"
<< "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
@@ -1983,7 +1979,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
keyword = "Win32Proj";
}
fout << "\tName=\"" << projLabel << "\"\n";
- fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
+ fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
this->WriteProjectSCC(fout, target);
if (const char* targetFrameworkVersion =
target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
@@ -2037,7 +2033,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s)
}
std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
- const char* path)
+ const std::string& path)
{
std::string ret =
this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2049,7 +2045,7 @@ std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
}
std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
- const char* path)
+ const std::string& path)
{
std::string ret =
this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2061,7 +2057,7 @@ std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
}
void cmVS7GeneratorOptions::OutputFlag(std::ostream& fout, int indent,
- const char* flag,
+ const std::string& flag,
const std::string& content)
{
fout.fill('\t');
@@ -2130,8 +2126,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
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",
- cmStateEnums::INTERNAL);
+ guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
}
std::string cmLocalVisualStudio7Generator::GetTargetDirectory(
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 671783fa53..745766ce79 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -30,7 +30,7 @@ public:
: cmVisualStudioGeneratorOptions(lg, tool, table, extraTable)
{
}
- void OutputFlag(std::ostream& fout, int indent, const char* tag,
+ void OutputFlag(std::ostream& fout, int indent, const std::string& tag,
const std::string& content) override;
};
@@ -101,8 +101,8 @@ private:
void WriteConfiguration(std::ostream& fout, const std::string& configName,
const std::string& libName, cmGeneratorTarget* tgt);
std::string EscapeForXML(const std::string& s);
- std::string ConvertToXMLOutputPath(const char* path);
- std::string ConvertToXMLOutputPathSingle(const char* path);
+ std::string ConvertToXMLOutputPath(const std::string& path);
+ std::string ConvertToXMLOutputPathSingle(const std::string& path);
void OutputTargetRules(std::ostream& fout, const std::string& configName,
cmGeneratorTarget* target,
const std::string& libName);
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 336e3a5a17..8d508980e1 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -104,8 +104,8 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
std::vector<std::string> no_depends;
cmCustomCommandLines commands = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
- pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, no_depends,
- commands, 0, 0));
+ pcc.reset(new cmCustomCommand(no_output, no_byproducts, no_depends, commands,
+ cmListFileBacktrace(), nullptr, nullptr));
pcc->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true);
return pcc;
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 5a06d4a53b..ac0d35ea88 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -40,7 +40,7 @@ void cmLocalXCodeGenerator::Generate()
{
cmLocalGenerator::Generate();
- for (auto target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
}
@@ -49,7 +49,7 @@ void cmLocalXCodeGenerator::GenerateInstallRules()
{
cmLocalGenerator::GenerateInstallRules();
- for (auto target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
}
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index ba9947a335..0b0d9ac318 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -7,10 +7,10 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
@@ -167,7 +167,7 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& status)
{
cmMakefile& mf = status.GetMakefile();
- mf.AppendProperty("MACROS", this->Args[0].c_str());
+ mf.AppendProperty("MACROS", this->Args[0]);
// create a new command and add it to cmake
cmMacroHelperCommand f;
f.Args = this->Args;
@@ -190,7 +190,7 @@ bool cmMacroCommand(std::vector<std::string> const& args,
// create a function blocker
{
auto fb = cm::make_unique<cmMacroFunctionBlocker>();
- cmAppend(fb->Args, args);
+ cm::append(fb->Args, args);
status.GetMakefile().AddFunctionBlocker(std::move(fb));
}
return true;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f143ef704f..18689fa5f0 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -15,10 +15,15 @@
#include <cm/iterator>
#include <cm/memory>
+#include <cm/optional>
+#include <cm/vector>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
+#include "cm_jsoncpp_value.h"
+#include "cm_jsoncpp_writer.h"
#include "cm_sys_stat.h"
#include "cmAlgorithms.h"
@@ -27,6 +32,7 @@
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h" // IWYU pragma: keep
+#include "cmExportBuildFileGenerator.h"
#include "cmFileLockPool.h"
#include "cmFunctionBlocker.h"
#include "cmGeneratedFileStream.h"
@@ -36,6 +42,7 @@
#include "cmInstallGenerator.h" // IWYU pragma: keep
#include "cmInstallSubdirectoryGenerator.h"
#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSourceFile.h"
@@ -117,15 +124,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
#endif
}
-cmMakefile::~cmMakefile()
-{
- cmDeleteAll(this->InstallGenerators);
- cmDeleteAll(this->TestGenerators);
- cmDeleteAll(this->SourceFiles);
- cmDeleteAll(this->Tests);
- cmDeleteAll(this->ImportedTargetsOwned);
- cmDeleteAll(this->EvaluationFiles);
-}
+cmMakefile::~cmMakefile() = default;
cmDirectoryId cmMakefile::GetDirectoryId() const
{
@@ -133,7 +132,7 @@ cmDirectoryId cmMakefile::GetDirectoryId() const
// If we ever need to expose this to CMake language code we should
// add a read-only property in cmMakefile::GetProperty.
char buf[32];
- sprintf(buf, "<%p>",
+ sprintf(buf, "(%p)",
static_cast<void const*>(this)); // cast avoids format warning
return std::string(buf);
}
@@ -146,7 +145,7 @@ void cmMakefile::IssueMessage(MessageType t, std::string const& text) const
this->ExecutionStatusStack.back()->SetNestedError();
}
}
- this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
+ this->GetCMakeInstance()->IssueMessage(t, text, this->Backtrace);
}
bool cmMakefile::CheckCMP0037(std::string const& targetName,
@@ -313,21 +312,54 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
}
std::ostringstream msg;
- msg << full_path << "(" << lff.Line << "): ";
- msg << lff.Name.Original << "(";
- bool expand = this->GetCMakeInstance()->GetTraceExpand();
+ std::vector<std::string> args;
std::string temp;
+ bool expand = this->GetCMakeInstance()->GetTraceExpand();
+
+ args.reserve(lff.Arguments.size());
for (cmListFileArgument const& arg : lff.Arguments) {
if (expand) {
temp = arg.Value;
this->ExpandVariablesInString(temp);
- msg << temp;
+ args.push_back(temp);
} else {
- msg << arg.Value;
+ args.push_back(arg.Value);
}
- msg << " ";
}
- msg << ")";
+
+ switch (this->GetCMakeInstance()->GetTraceFormat()) {
+ case cmake::TraceFormat::TRACE_JSON_V1: {
+#ifndef CMAKE_BOOTSTRAP
+ Json::Value val;
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = "";
+ val["file"] = full_path;
+ val["line"] = static_cast<Json::Value::Int64>(lff.Line);
+ val["cmd"] = lff.Name.Original;
+ val["args"] = Json::Value(Json::arrayValue);
+ for (std::string const& arg : args) {
+ val["args"].append(arg);
+ }
+ val["time"] = cmSystemTools::GetTime();
+ val["frame"] =
+ static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size());
+ msg << Json::writeString(builder, val);
+#endif
+ break;
+ }
+ case cmake::TraceFormat::TRACE_HUMAN:
+ msg << full_path << "(" << lff.Line << "): ";
+ msg << lff.Name.Original << "(";
+
+ for (std::string const& arg : args) {
+ msg << arg << " ";
+ }
+ msg << ")";
+ break;
+ case cmake::TraceFormat::TRACE_UNDEFINED:
+ msg << "INTERNAL ERROR: Trace format is TRACE_UNDEFINED";
+ break;
+ }
auto& f = this->GetCMakeInstance()->GetTraceFile();
if (f) {
@@ -737,18 +769,19 @@ void cmMakefile::AddEvaluationFile(
std::unique_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent)
{
- this->EvaluationFiles.push_back(new cmGeneratorExpressionEvaluationFile(
- inputFile, std::move(outputName), std::move(condition), inputIsContent,
- this->GetPolicyStatus(cmPolicies::CMP0070)));
+ this->EvaluationFiles.push_back(
+ cm::make_unique<cmGeneratorExpressionEvaluationFile>(
+ inputFile, std::move(outputName), std::move(condition), inputIsContent,
+ this->GetPolicyStatus(cmPolicies::CMP0070)));
}
-std::vector<cmGeneratorExpressionEvaluationFile*>
+const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
cmMakefile::GetEvaluationFiles() const
{
return this->EvaluationFiles;
}
-std::vector<cmExportBuildFileGenerator*>
+std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
cmMakefile::GetExportBuildFileGenerators() const
{
return this->ExportBuildFileGenerators;
@@ -757,16 +790,21 @@ cmMakefile::GetExportBuildFileGenerators() const
void cmMakefile::RemoveExportBuildFileGeneratorCMP0024(
cmExportBuildFileGenerator* gen)
{
- auto it = std::find(this->ExportBuildFileGenerators.begin(),
- this->ExportBuildFileGenerators.end(), gen);
+ auto it =
+ std::find_if(this->ExportBuildFileGenerators.begin(),
+ this->ExportBuildFileGenerators.end(),
+ [gen](std::unique_ptr<cmExportBuildFileGenerator> const& p) {
+ return p.get() == gen;
+ });
if (it != this->ExportBuildFileGenerators.end()) {
this->ExportBuildFileGenerators.erase(it);
}
}
-void cmMakefile::AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen)
+void cmMakefile::AddExportBuildFileGenerator(
+ std::unique_ptr<cmExportBuildFileGenerator> gen)
{
- this->ExportBuildFileGenerators.push_back(gen);
+ this->ExportBuildFileGenerators.emplace_back(std::move(gen));
}
namespace {
@@ -780,38 +818,42 @@ struct file_not_persistent
};
}
-void cmMakefile::AddFinalAction(FinalAction action)
+void cmMakefile::AddGeneratorAction(GeneratorAction action)
{
- this->FinalActions.push_back(std::move(action));
+ assert(!this->GeneratorActionsInvoked);
+ this->GeneratorActions.emplace_back(std::move(action), this->Backtrace);
}
-void cmMakefile::FinalPass()
+void cmMakefile::DoGenerate(cmLocalGenerator& lg)
{
// do all the variable expansions here
this->ExpandVariablesCMP0019();
// give all the commands a chance to do something
// after the file has been parsed before generation
- for (FinalAction& action : this->FinalActions) {
- action(*this);
+ for (const BT<GeneratorAction>& action : this->GeneratorActions) {
+ action.Value(lg, action.Backtrace);
}
+ this->GeneratorActionsInvoked = true;
+ this->DelayedOutputFiles.clear();
+ this->DelayedOutputFilesHaveGenex = false;
// go through all configured files and see which ones still exist.
// we don't want cmake to re-run if a configured file is created and deleted
// during processing as that would make it a transient file that can't
// influence the build process
- cmEraseIf(this->OutputFiles, file_not_persistent());
+ cm::erase_if(this->OutputFiles, file_not_persistent());
// if a configured file is used as input for another configured file,
// and then deleted it will show up in the input list files so we
// need to scan those too
- cmEraseIf(this->ListFiles, file_not_persistent());
+ cm::erase_if(this->ListFiles, file_not_persistent());
}
// Generate the output file
-void cmMakefile::ConfigureFinalPass()
+void cmMakefile::Generate(cmLocalGenerator& lg)
{
- this->FinalPass();
+ this->DoGenerate(lg);
const char* oldValue = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
if (oldValue &&
cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, oldValue, "2.4")) {
@@ -825,6 +867,39 @@ void cmMakefile::ConfigureFinalPass()
}
}
+namespace {
+// There are still too many implicit backtraces through cmMakefile. As a
+// workaround we reset the backtrace temporarily.
+struct BacktraceGuard
+{
+ BacktraceGuard(cmListFileBacktrace& lfbt, cmListFileBacktrace current)
+ : Backtrace(lfbt)
+ , Previous(lfbt)
+ {
+ this->Backtrace = std::move(current);
+ }
+
+ ~BacktraceGuard() { this->Backtrace = std::move(Previous); }
+
+private:
+ cmListFileBacktrace& Backtrace;
+ cmListFileBacktrace Previous;
+};
+
+cm::optional<std::string> MakeOptionalString(const char* str)
+{
+ if (str) {
+ return str;
+ }
+ return cm::nullopt;
+}
+
+const char* GetCStrOrNull(const cm::optional<std::string>& str)
+{
+ return str ? str->c_str() : nullptr;
+}
+}
+
bool cmMakefile::ValidateCustomCommand(
const cmCustomCommandLines& commandLines) const
{
@@ -842,7 +917,8 @@ bool cmMakefile::ValidateCustomCommand(
}
cmTarget* cmMakefile::GetCustomCommandTarget(
- const std::string& target, cmObjectLibraryCommands objLibCommands) const
+ const std::string& target, cmObjectLibraryCommands objLibCommands,
+ const cmListFileBacktrace& lfbt) const
{
// Find the target to which to add the custom command.
auto ti = this->Targets.find(target);
@@ -876,7 +952,7 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
e << "No TARGET '" << target
<< "' has been created in this directory.";
}
- this->IssueMessage(messageType, e.str());
+ this->GetCMakeInstance()->IssueMessage(messageType, e.str(), lfbt);
}
return nullptr;
@@ -889,7 +965,8 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
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());
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
+ lfbt);
return nullptr;
}
if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -897,7 +974,8 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
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());
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
+ lfbt);
return nullptr;
}
@@ -910,9 +988,10 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
const cmCustomCommandLines& commandLines, cmCustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile, const std::string& job_pool,
- bool command_expand_lists, cmObjectLibraryCommands objLibCommands)
+ bool command_expand_lists)
{
- cmTarget* t = this->GetCustomCommandTarget(target, objLibCommands);
+ cmTarget* t = this->GetCustomCommandTarget(
+ target, cmObjectLibraryCommands::Reject, this->Backtrace);
// Validate custom commands.
if (!t || !this->ValidateCustomCommand(commandLines)) {
@@ -920,175 +999,83 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
}
// 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);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction([=](cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AddCustomCommandToTarget(
+ lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends, commandLines,
+ type, GetCStrOrNull(commentStr), GetCStrOrNull(workingStr),
+ escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists);
+ });
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,
- comment, workingDir);
- cc.SetEscapeOldStyle(escapeOldStyle);
- cc.SetEscapeAllowMakeVars(true);
- cc.SetUsesTerminal(uses_terminal);
- cc.SetCommandExpandLists(command_expand_lists);
- cc.SetDepfile(depfile);
- cc.SetJobPool(job_pool);
- switch (type) {
- case cmCustomCommandType::PRE_BUILD:
- target->AddPreBuildCommand(std::move(cc));
- break;
- case cmCustomCommandType::PRE_LINK:
- target->AddPreLinkCommand(std::move(cc));
- break;
- case cmCustomCommandType::POST_BUILD:
- target->AddPostBuildCommand(std::move(cc));
- break;
- }
-
- this->AddTargetByproducts(target, byproducts);
-}
-
-cmSourceFile* cmMakefile::AddCustomCommandToOutput(
+void 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)
+ const char* comment, const char* workingDir,
+ const CommandSourceCallback& callback, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool)
{
- 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);
+ this->AddCustomCommandToOutput(
+ { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
+ commandLines, comment, workingDir, callback, replace, escapeOldStyle,
+ uses_terminal, command_expand_lists, depfile, job_pool);
}
-cmSourceFile* cmMakefile::AddCustomCommandToOutput(
+void 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,
- const std::string& job_pool)
+ const char* workingDir, const CommandSourceCallback& callback, bool replace,
+ bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
+ const std::string& depfile, const std::string& job_pool)
{
// Make sure there is at least one output.
if (outputs.empty()) {
cmSystemTools::Error("Attempt to add a custom rule with no output!");
- return nullptr;
+ return;
}
// Validate custom commands.
if (!this->ValidateCustomCommand(commandLines)) {
- return nullptr;
+ return;
}
// 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()) {
- // The main dependency was specified. Use it unless a different
- // custom command already used it.
- file = this->GetSource(main_dependency);
- if (file && file->GetCustomCommand() && !replace) {
- // The main dependency already has a custom command.
- if (commandLines == file->GetCustomCommand()->GetCommandLines()) {
- // The existing custom command is identical. Silently ignore
- // the duplicate.
- return file;
- }
- // The existing custom command is different. We need to
- // generate a rule file for this new command.
- file = nullptr;
- } else if (!file) {
- file = this->CreateSource(main_dependency);
- }
- }
-
- // Generate a rule file if the main dependency is not available.
- if (!file) {
- cmGlobalGenerator* gg = this->GetGlobalGenerator();
-
- // Construct a rule file associated with the first output produced.
- std::string outName = gg->GenerateRuleFile(outputs[0]);
-
- // Check if the rule file already exists.
- file = this->GetSource(outName, cmSourceFileLocationKind::Known);
- if (file && file->GetCustomCommand() && !replace) {
- // The rule file already exists.
- if (commandLines != file->GetCustomCommand()->GetCommandLines()) {
- cmSystemTools::Error("Attempt to add a custom rule to output \"" +
- outName + "\" which already has a custom rule.");
- }
- return file;
+ this->CreateGeneratedOutputs(outputs);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction([=](cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ cmSourceFile* sf = detail::AddCustomCommandToOutput(
+ lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
+ main_dependency, implicit_depends, commandLines,
+ GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
+ escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool);
+ if (callback && sf) {
+ callback(sf);
}
-
- // Create a cmSourceFile for the rule file.
- if (!file) {
- file =
- this->CreateSource(outName, true, cmSourceFileLocationKind::Known);
- }
- file->SetProperty("__CMAKE_RULE", "1");
- }
-
- // Attach the custom command to the file.
- if (file) {
- // Construct a complete list of dependencies.
- std::vector<std::string> depends2(depends);
- if (!main_dependency.empty()) {
- depends2.push_back(main_dependency);
- }
-
- 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(std::move(cc));
-
- this->AddSourceOutputs(file, outputs, byproducts);
- }
- return file;
+ });
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1136,11 +1123,8 @@ void cmMakefile::AddCustomCommandOldStyle(
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);
- }
+ this->AddCustomCommandToOutput(output, depends, source, commandLines,
+ comment, nullptr, addRuleFileToTarget);
}
} else {
std::string no_main_dependency;
@@ -1149,11 +1133,9 @@ void cmMakefile::AddCustomCommandOldStyle(
// 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);
- }
+ this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
+ commandLines, comment, nullptr,
+ addRuleFileToTarget);
}
}
}
@@ -1170,29 +1152,18 @@ bool cmMakefile::AppendCustomCommandToOutput(
// Validate custom commands.
if (this->ValidateCustomCommand(commandLines)) {
- // Add command factory to allow generator expressions in output.
- this->CommitAppendCustomCommandToOutput(output, depends, implicit_depends,
- commandLines);
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AppendCustomCommandToOutput(lg, lfbt, output, depends,
+ implicit_depends, commandLines);
+ });
}
return true;
}
-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::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
@@ -1215,15 +1186,14 @@ cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
}
cmTarget* cmMakefile::AddUtilityCommand(
- const std::string& utilityName, cmCommandOrigin origin, bool excludeFromAll,
- const char* workingDirectory, const std::vector<std::string>& byproducts,
+ const std::string& utilityName, bool excludeFromAll, const char* workingDir,
+ 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)
{
- cmTarget* target =
- this->AddNewUtilityTarget(utilityName, origin, excludeFromAll);
+ cmTarget* target = this->AddNewUtilityTarget(utilityName, excludeFromAll);
// Validate custom commands.
if ((commandLines.empty() && depends.empty()) ||
@@ -1236,45 +1206,26 @@ cmTarget* cmMakefile::AddUtilityCommand(
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 = "";
- }
-
- this->CommitUtilityCommand(target, force, workingDirectory, byproducts,
- depends, commandLines, escapeOldStyle, comment,
- uses_terminal, command_expand_lists, job_pool);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AddUtilityCommand(lg, lfbt, cmCommandOrigin::Project, target,
+ force, GetCStrOrNull(workingStr), byproducts,
+ depends, commandLines, escapeOldStyle,
+ GetCStrOrNull(commentStr), uses_terminal,
+ command_expand_lists, job_pool);
+ });
return target;
}
-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);
- }
-}
-
static void s_AddDefineFlag(std::string const& flag, std::string& dflags)
{
// remove any \n\r
@@ -1342,28 +1293,27 @@ void cmMakefile::RemoveDefineFlag(std::string const& flag)
void cmMakefile::AddCompileDefinition(std::string const& option)
{
- this->AppendProperty("COMPILE_DEFINITIONS", option.c_str());
+ this->AppendProperty("COMPILE_DEFINITIONS", option);
}
void cmMakefile::AddCompileOption(std::string const& option)
{
- this->AppendProperty("COMPILE_OPTIONS", option.c_str());
+ this->AppendProperty("COMPILE_OPTIONS", option);
}
void cmMakefile::AddLinkOption(std::string const& option)
{
- this->AppendProperty("LINK_OPTIONS", option.c_str());
+ this->AppendProperty("LINK_OPTIONS", option);
}
void cmMakefile::AddLinkDirectory(std::string const& directory, bool before)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
if (before) {
- this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry(directory,
- lfbt);
+ this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry(
+ directory, this->Backtrace);
} else {
- this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry(directory,
- lfbt);
+ this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry(
+ directory, this->Backtrace);
}
}
@@ -1476,6 +1426,20 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
this->RecursionDepth = parent->RecursionDepth;
}
+void cmMakefile::AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g)
+{
+ if (g) {
+ this->InstallGenerators.push_back(std::move(g));
+ }
+}
+
+void cmMakefile::AddTestGenerator(std::unique_ptr<cmTestGenerator> g)
+{
+ if (g) {
+ this->TestGenerators.push_back(std::move(g));
+ }
+}
+
void cmMakefile::PushFunctionScope(std::string const& fileName,
const cmPolicies::PolicyMap& pm)
{
@@ -1776,8 +1740,10 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
cmSystemTools::MakeDirectory(binPath);
- cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
- this->GetGlobalGenerator()->AddMakefile(subMf);
+ auto subMfu =
+ cm::make_unique<cmMakefile>(this->GlobalGenerator, newSnapshot);
+ auto subMf = subMfu.get();
+ this->GetGlobalGenerator()->AddMakefile(std::move(subMfu));
if (excludeFromAll) {
subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
@@ -1789,8 +1755,8 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
this->UnConfiguredDirectories.push_back(subMf);
}
- this->AddInstallGenerator(new cmInstallSubdirectoryGenerator(
- subMf, binPath.c_str(), excludeFromAll));
+ this->AddInstallGenerator(cm::make_unique<cmInstallSubdirectoryGenerator>(
+ subMf, binPath, excludeFromAll));
}
const std::string& cmMakefile::GetCurrentSourceDirectory() const
@@ -1820,20 +1786,19 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string>& incs,
return;
}
- cmListFileBacktrace lfbt = this->GetBacktrace();
std::string entryString = cmJoin(incs, ";");
if (before) {
this->StateSnapshot.GetDirectory().PrependIncludeDirectoriesEntry(
- entryString, lfbt);
+ entryString, this->Backtrace);
} else {
this->StateSnapshot.GetDirectory().AppendIncludeDirectoriesEntry(
- entryString, lfbt);
+ entryString, this->Backtrace);
}
// Property on each target:
for (auto& target : this->Targets) {
cmTarget& t = target.second;
- t.InsertInclude(entryString, lfbt, before);
+ t.InsertInclude(entryString, this->Backtrace, before);
}
}
@@ -2027,7 +1992,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
target.AddLinkLibrary(*this, libraryName, libType);
target.AppendProperty(
"INTERFACE_LINK_LIBRARIES",
- target.GetDebugGeneratorExpressions(libraryName, libType).c_str());
+ target.GetDebugGeneratorExpressions(libraryName, libType));
}
}
}
@@ -2080,7 +2045,8 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
{
auto it =
this->Targets
- .emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this))
+ .emplace(name,
+ cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
.first;
this->OrderedTargets.push_back(&it->second);
this->GetGlobalGenerator()->IndexTarget(&it->second);
@@ -2089,11 +2055,9 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
}
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");
}
@@ -2155,18 +2119,18 @@ cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
// 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) {
+ for (const auto& src : this->SourceFiles) {
// Does this source file have a custom command?
if (src->GetCustomCommand()) {
// Does the output of the custom command match the source file name?
if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
// Return the first matching output.
- return src;
+ return src.get();
}
if (kind == cmSourceOutputKind::OutputOrByproduct) {
if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
// Do not return the source yet as there might be a matching output.
- fallback = src;
+ fallback = src.get();
}
}
}
@@ -2211,8 +2175,8 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput(
(!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.
+ // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
+ // command of a target, or a not yet created custom command.
return o->second.Sources.Source;
}
return nullptr;
@@ -2220,12 +2184,20 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput(
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;
- }
+ if (this->DelayedOutputFilesHaveGenex ||
+ cmGeneratorExpression::Find(name) != std::string::npos) {
+ // Could be more restrictive, but for now we assume that there could always
+ // be a match when generator expressions are involved.
+ return true;
+ }
+ // Also see LinearGetSourceFileWithOutput.
+ if (!cmSystemTools::FileIsFullPath(name)) {
+ return AnyOutputMatches(name, this->DelayedOutputFiles);
+ }
+ // Otherwise we use an efficient lookup map.
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end()) {
+ return o->second.SourceMightBeOutput;
}
return false;
}
@@ -2278,6 +2250,7 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
SourceEntry entry;
entry.Sources.Source = source;
entry.Sources.SourceIsByproduct = byproduct;
+ entry.SourceMightBeOutput = !byproduct;
auto pr = this->OutputToSource.emplace(output, entry);
if (!pr.second) {
@@ -2287,6 +2260,7 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
(current.Sources.SourceIsByproduct && !byproduct)) {
current.Sources.Source = source;
current.Sources.SourceIsByproduct = false;
+ current.SourceMightBeOutput = true;
} else {
// Multiple custom commands produce the same output but may
// be attached to a different source file (MAIN_DEPENDENCY).
@@ -2478,7 +2452,7 @@ void cmMakefile::ExpandVariablesCMP0019()
<< " " << dirs << "\n";
/* clang-format on */
}
- t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
+ t.SetProperty("INCLUDE_DIRECTORIES", dirs);
}
}
@@ -2739,7 +2713,7 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
std::vector<std::string> cmMakefile::GetDefinitions() const
{
std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
- cmAppend(res, this->GetState()->GetCacheEntryKeys());
+ cm::append(res, this->GetState()->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
return res;
}
@@ -3514,24 +3488,25 @@ cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
bool generated,
cmSourceFileLocationKind kind)
{
- cmSourceFile* sf = new cmSourceFile(this, sourceName, kind);
+ auto sf = cm::make_unique<cmSourceFile>(this, sourceName, kind);
if (generated) {
sf->SetProperty("GENERATED", "1");
}
- this->SourceFiles.push_back(sf);
auto name =
this->GetCMakeInstance()->StripExtension(sf->GetLocation().GetName());
#if defined(_WIN32) || defined(__APPLE__)
name = cmSystemTools::LowerCase(name);
#endif
- this->SourceFileSearchIndex[name].push_back(sf);
+ this->SourceFileSearchIndex[name].push_back(sf.get());
// for "Known" paths add direct lookup (used for faster lookup in GetSource)
if (kind == cmSourceFileLocationKind::Known) {
- this->KnownFileSearchIndex[sourceName] = sf;
+ this->KnownFileSearchIndex[sourceName] = sf.get();
}
- return sf;
+ this->SourceFiles.push_back(std::move(sf));
+
+ return this->SourceFiles.back().get();
}
cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
@@ -3553,11 +3528,41 @@ cmSourceFile* cmMakefile::GetOrCreateGeneratedSource(
return sf;
}
-void cmMakefile::CreateGeneratedSources(
+void cmMakefile::CreateGeneratedOutputs(
const std::vector<std::string>& outputs)
{
- for (std::string const& output : outputs) {
- this->GetOrCreateGeneratedSource(output);
+ for (std::string const& o : outputs) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->GetOrCreateGeneratedSource(o);
+ this->AddDelayedOutput(o);
+ } else {
+ this->DelayedOutputFilesHaveGenex = true;
+ }
+ }
+}
+
+void cmMakefile::CreateGeneratedByproducts(
+ const std::vector<std::string>& byproducts)
+{
+ for (std::string const& o : byproducts) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->GetOrCreateGeneratedSource(o);
+ }
+ }
+}
+
+void cmMakefile::AddDelayedOutput(std::string const& output)
+{
+ // Note that this vector might contain the output names in a different order
+ // than in source file iteration order.
+ this->DelayedOutputFiles.push_back(output);
+
+ SourceEntry entry;
+ entry.SourceMightBeOutput = true;
+
+ auto pr = this->OutputToSource.emplace(output, entry);
+ if (!pr.second) {
+ pr.first->second.SourceMightBeOutput = true;
}
}
@@ -3630,8 +3635,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// be run that way but the cmake object requires a vailid path
cmake cm(cmake::RoleProject, cmState::Project);
cm.SetIsInTryCompile(true);
- cmGlobalGenerator* gg =
- cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
+ auto gg = cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
if (!gg) {
this->IssueMessage(MessageType::INTERNAL_ERROR,
"Global generator '" +
@@ -3642,7 +3646,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
return 1;
}
gg->RecursionDepth = this->RecursionDepth;
- cm.SetGlobalGenerator(gg);
+ cm.SetGlobalGenerator(std::move(gg));
// do a configure
cm.SetHomeDirectory(srcdir);
@@ -3651,7 +3655,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cm.SetGeneratorPlatform(this->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM"));
cm.SetGeneratorToolset(this->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET"));
cm.LoadCache();
- if (!gg->IsMultiConfig()) {
+ if (!cm.GetGlobalGenerator()->IsMultiConfig()) {
if (const char* config =
this->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION")) {
// Tell the single-configuration generator which one to use.
@@ -3697,7 +3701,8 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cm.SetCacheArgs(*cmakeArgs);
}
// to save time we pass the EnableLanguage info directly
- gg->EnableLanguagesFromGenerator(this->GetGlobalGenerator(), this);
+ cm.GetGlobalGenerator()->EnableLanguagesFromGenerator(
+ this->GetGlobalGenerator(), this);
if (this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE", "",
cmStateEnums::INTERNAL);
@@ -3777,7 +3782,8 @@ void cmMakefile::DisplayStatus(const std::string& message, float s) const
}
std::string cmMakefile::GetModulesFile(const std::string& filename,
- bool& system) const
+ bool& system, bool debug,
+ std::string& debugBuffer) const
{
std::string result;
@@ -3808,6 +3814,9 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
moduleInCMakeModulePath = itempl;
break;
}
+ if (debug) {
+ debugBuffer = cmStrCat(debugBuffer, " ", itempl, "\n");
+ }
}
}
@@ -3816,6 +3825,9 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/", filename);
cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
if (!cmSystemTools::FileExists(moduleInCMakeRoot)) {
+ if (debug) {
+ debugBuffer = cmStrCat(debugBuffer, " ", moduleInCMakeRoot, "\n");
+ }
moduleInCMakeRoot.clear();
}
@@ -4029,16 +4041,14 @@ int cmMakefile::ConfigureFile(const std::string& infile,
void cmMakefile::SetProperty(const std::string& prop, const char* value)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->StateSnapshot.GetDirectory().SetProperty(prop, value, lfbt);
+ this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace);
}
-void cmMakefile::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmMakefile::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
this->StateSnapshot.GetDirectory().AppendProperty(prop, value, asString,
- lfbt);
+ this->Backtrace);
}
const char* cmMakefile::GetProperty(const std::string& prop) const
@@ -4090,9 +4100,10 @@ cmTest* cmMakefile::CreateTest(const std::string& testName)
if (test) {
return test;
}
- test = new cmTest(this);
- test->SetName(testName);
- this->Tests[testName] = test;
+ auto newTest = cm::make_unique<cmTest>(this);
+ test = newTest.get();
+ newTest->SetName(testName);
+ this->Tests[testName] = std::move(newTest);
return test;
}
@@ -4100,7 +4111,7 @@ cmTest* cmMakefile::GetTest(const std::string& testName) const
{
auto mi = this->Tests.find(testName);
if (mi != this->Tests.end()) {
- return mi->second;
+ return mi->second.get();
}
return nullptr;
}
@@ -4108,7 +4119,7 @@ cmTest* cmMakefile::GetTest(const std::string& testName) const
void cmMakefile::GetTests(const std::string& config,
std::vector<cmTest*>& tests)
{
- for (auto generator : this->GetTestGenerators()) {
+ for (const auto& generator : this->GetTestGenerators()) {
if (generator->TestsForConfig(config)) {
tests.push_back(generator->GetTest());
}
@@ -4214,15 +4225,15 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
new cmTarget(name, type,
global ? cmTarget::VisibilityImportedGlobally
: cmTarget::VisibilityImported,
- this));
+ this, true));
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
this->GetGlobalGenerator()->IndexTarget(target.get());
// Transfer ownership to this cmMakefile object.
- this->ImportedTargetsOwned.push_back(target.get());
- return target.release();
+ this->ImportedTargetsOwned.push_back(std::move(target));
+ return this->ImportedTargetsOwned.back().get();
}
cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
@@ -4487,7 +4498,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::CMP0067 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0069 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4587,17 +4598,21 @@ static const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
FEATURE_STRING) };
+
+static const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
+ FEATURE_STRING) };
#undef FEATURE_STRING
static const char* const C_STANDARDS[] = { "90", "99", "11" };
static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
+static const char* const CUDA_STANDARDS[] = { "03", "11", "14", "17", "20" };
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
const std::string& feature,
std::string* error) const
{
if (cmGeneratorExpression::Find(feature) != std::string::npos) {
- target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ target->AppendProperty("COMPILE_FEATURES", feature);
return true;
}
@@ -4628,11 +4643,15 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
return false;
}
- target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ target->AppendProperty("COMPILE_FEATURES", feature);
- return lang == "C" || lang == "OBJC"
- ? this->AddRequiredTargetCFeature(target, feature, lang, error)
- : this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+ if (lang == "C" || lang == "OBJC") {
+ return this->AddRequiredTargetCFeature(target, feature, lang, error);
+ }
+ if (lang == "CUDA") {
+ return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
+ }
+ return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
}
bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
@@ -4656,6 +4675,13 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
lang = "CXX";
return true;
}
+ bool isCudaFeature =
+ std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
+ cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
+ if (isCudaFeature) {
+ lang = "CUDA";
+ return true;
+ }
std::ostringstream e;
if (error) {
e << "specified";
@@ -4724,9 +4750,13 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
std::string const& lang,
const std::string& feature) const
{
- return lang == "C" || lang == "OBJC"
- ? this->HaveCStandardAvailable(target, feature, lang)
- : this->HaveCxxStandardAvailable(target, feature, lang);
+ if (lang == "C" || lang == "OBJC") {
+ return this->HaveCStandardAvailable(target, feature, lang);
+ }
+ if (lang == "CUDA") {
+ return this->HaveCudaStandardAvailable(target, feature, lang);
+ }
+ return this->HaveCxxStandardAvailable(target, feature, lang);
}
bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
@@ -4809,6 +4839,14 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) !=
cm::cend(C_STANDARDS);
}
+ if (lang == "CUDA") {
+ const char* const* rhsIt = std::find_if(
+ cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), cmStrCmp(rhs));
+
+ return std::find_if(rhsIt, cm::cend(CUDA_STANDARDS), cmStrCmp(lhs)) !=
+ cm::cend(CUDA_STANDARDS);
+ }
+
const char* const* rhsIt = std::find_if(
cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs));
@@ -4953,27 +4991,6 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
}
}
- const char* existingCudaStandard = target->GetProperty("CUDA_STANDARD");
- const char* const* existingCudaLevel = nullptr;
- if (existingCudaStandard) {
- existingCudaLevel =
- std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCudaStandard));
- if (existingCudaLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CUDA_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCudaStandard
- << "\".";
- if (error) {
- *error = e.str();
- } else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
- }
- return false;
- }
- }
-
/* clang-format off */
const char* const* needCxxLevel =
needCxx20 ? &CXX_STANDARDS[4]
@@ -4990,11 +5007,164 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
}
+ }
+
+ return true;
+}
+
+bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
+ const std::string& feature,
+ std::string const& lang) const
+{
+ const char* defaultCudaStandard =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (!defaultCudaStandard) {
+ 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(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(defaultCudaStandard)) ==
+ cm::cend(CUDA_STANDARDS)) {
+ const std::string e =
+ cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
+ "invalid value: \"", defaultCudaStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
+ return false;
+ }
+
+ bool needCuda03 = false;
+ bool needCuda11 = false;
+ bool needCuda14 = false;
+ bool needCuda17 = false;
+ bool needCuda20 = false;
+ this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
+ needCuda14, needCuda17, needCuda20);
+
+ const char* existingCudaStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ if (!existingCudaStandard) {
+ existingCudaStandard = defaultCudaStandard;
+ }
+
+ const char* const* existingCudaLevel =
+ std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(existingCudaStandard));
+ if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCudaStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
+ return false;
+ }
+
+ /* clang-format off */
+ const char* const* needCudaLevel =
+ needCuda20 ? &CUDA_STANDARDS[4]
+ : needCuda17 ? &CUDA_STANDARDS[3]
+ : needCuda14 ? &CUDA_STANDARDS[2]
+ : needCuda11 ? &CUDA_STANDARDS[1]
+ : needCuda03 ? &CUDA_STANDARDS[0]
+ : nullptr;
+ /* clang-format on */
+
+ return !needCudaLevel || needCudaLevel <= existingCudaLevel;
+}
+
+void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
+ std::string const& lang,
+ bool& needCuda03, bool& needCuda11,
+ bool& needCuda14, bool& needCuda17,
+ bool& needCuda20) const
+{
+ if (const char* propCuda03 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda03);
+ needCuda03 = cmContains(props, feature);
+ }
+ if (const char* propCuda11 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda11);
+ needCuda11 = cmContains(props, feature);
+ }
+ if (const char* propCuda14 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda14);
+ needCuda14 = cmContains(props, feature);
+ }
+ if (const char* propCuda17 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda17);
+ needCuda17 = cmContains(props, feature);
+ }
+ if (const char* propCuda20 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda20);
+ needCuda20 = cmContains(props, feature);
+ }
+}
+
+bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
+ const std::string& feature,
+ std::string const& lang,
+ std::string* error) const
+{
+ bool needCuda03 = false;
+ bool needCuda11 = false;
+ bool needCuda14 = false;
+ bool needCuda17 = false;
+ bool needCuda20 = false;
+
+ this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
+ needCuda14, needCuda17, needCuda20);
+
+ const char* existingCudaStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ if (existingCudaStandard == nullptr) {
+ const char* defaultCudaStandard =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCudaStandard && *defaultCudaStandard) {
+ existingCudaStandard = defaultCudaStandard;
+ }
+ }
+ const char* const* existingCudaLevel = nullptr;
+ if (existingCudaStandard) {
+ existingCudaLevel =
+ std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(existingCudaStandard));
+ if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", existingCudaStandard, "\".");
+ if (error) {
+ *error = e;
+ } else {
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
+ }
+ return false;
+ }
+ }
+
+ /* clang-format off */
+ const char* const* needCudaLevel =
+ needCuda20 ? &CUDA_STANDARDS[4]
+ : needCuda17 ? &CUDA_STANDARDS[3]
+ : needCuda14 ? &CUDA_STANDARDS[2]
+ : needCuda11 ? &CUDA_STANDARDS[1]
+ : needCuda03 ? &CUDA_STANDARDS[0]
+ : nullptr;
+ /* clang-format on */
+ if (needCudaLevel) {
// Ensure the CUDA language level is high enough to support
- // the needed C++ features.
- if (!existingCudaLevel || existingCudaLevel < needCxxLevel) {
- target->SetProperty("CUDA_STANDARD", *needCxxLevel);
+ // the needed CUDA features.
+ if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
+ target->SetProperty("CUDA_STANDARD", *needCudaLevel);
}
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 6e59494049..d918abe36c 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -49,6 +49,7 @@ class cmGeneratorExpressionEvaluationFile;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmInstallGenerator;
+class cmLocalGenerator;
class cmMessenger;
class cmSourceFile;
class cmState;
@@ -134,7 +135,7 @@ public:
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
/**
- * Try running cmake and building a file. This is used for dynalically
+ * Try running cmake and building a file. This is used for dynamically
* loaded commands, not as part of the usual build process.
*/
int TryCompile(const std::string& srcdir, const std::string& bindir,
@@ -151,54 +152,64 @@ public:
bool EnforceUniqueName(std::string const& name, std::string& msg,
bool isCustom = false) const;
- using FinalAction = std::function<void(cmMakefile&)>;
+ using GeneratorAction =
+ std::function<void(cmLocalGenerator&, const cmListFileBacktrace&)>;
/**
- * Register an action that is executed during FinalPass
+ * Register an action that is executed during Generate
*/
- void AddFinalAction(FinalAction action);
+ void AddGeneratorAction(GeneratorAction action);
/**
- * Perform FinalPass, Library dependency analysis etc before output of the
- * makefile.
+ * Perform generate actions, Library dependency analysis etc before output of
+ * the makefile.
*/
- void ConfigureFinalPass();
+ void Generate(cmLocalGenerator& lg);
/**
- * run all FinalActions.
+ * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
*/
- void FinalPass();
+ cmTarget* GetCustomCommandTarget(const std::string& target,
+ cmObjectLibraryCommands objLibCommands,
+ const cmListFileBacktrace& lfbt) const;
/**
- * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
+ * Dispatch adding a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a
+ * target.
*/
- cmTarget* GetCustomCommandTarget(
- const std::string& target, cmObjectLibraryCommands objLibCommands) const;
-
- /** Add a custom command to the build. */
cmTarget* 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 = true,
bool uses_terminal = false, const std::string& depfile = "",
- const std::string& job_pool = "", bool command_expand_lists = false,
- cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
- cmSourceFile* AddCustomCommandToOutput(
+ const std::string& job_pool = "", bool command_expand_lists = false);
+
+ /**
+ * Called for each file with custom command.
+ */
+ using CommandSourceCallback = std::function<void(cmSourceFile*)>;
+
+ /**
+ * Dispatch adding a custom command to a source file.
+ */
+ void 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 = false, bool escapeOldStyle = true,
+ const char* workingDir, const CommandSourceCallback& callback = nullptr,
+ bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
const std::string& depfile = "", const std::string& job_pool = "");
- cmSourceFile* AddCustomCommandToOutput(
+ void 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 = false, bool escapeOldStyle = true,
+ const char* workingDir, const CommandSourceCallback& callback = nullptr,
+ bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
const std::string& depfile = "", const std::string& job_pool = "");
void AddCustomCommandOldStyle(const std::string& target,
@@ -244,7 +255,7 @@ public:
/** Create a target instance for the utility. */
cmTarget* AddNewUtilityTarget(const std::string& utilityName,
- cmCommandOrigin origin, bool excludeFromAll);
+ bool excludeFromAll);
/**
* Add an executable to the build.
@@ -259,13 +270,12 @@ public:
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.
+ * Dispatch adding 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, cmCommandOrigin origin,
- bool excludeFromAll, const char* workingDirectory,
- const std::vector<std::string>& byproducts,
+ const std::string& utilityName, bool excludeFromAll,
+ const char* workingDir, 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,
@@ -409,9 +419,9 @@ public:
{
this->ComplainFileRegularExpression = regex;
}
- const char* GetComplainRegularExpression() const
+ const std::string& GetComplainRegularExpression() const
{
- return this->ComplainFileRegularExpression.c_str();
+ return this->ComplainFileRegularExpression;
}
// -- List of targets
@@ -421,7 +431,7 @@ public:
/** Get the target map - const version */
cmTargetMap const& GetTargets() const { return this->Targets; }
- const std::vector<cmTarget*>& GetOwnedImportedTargets() const
+ const std::vector<std::unique_ptr<cmTarget>>& GetOwnedImportedTargets() const
{
return this->ImportedTargetsOwned;
}
@@ -717,7 +727,7 @@ public:
/**
* Get all the source files this makefile knows about
*/
- const std::vector<cmSourceFile*>& GetSourceFiles() const
+ const std::vector<std::unique_ptr<cmSourceFile>>& GetSourceFiles() const
{
return this->SourceFiles;
}
@@ -756,14 +766,25 @@ public:
std::string GetModulesFile(const std::string& name) const
{
bool system;
- return this->GetModulesFile(name, system);
+ std::string debugBuffer;
+ return this->GetModulesFile(name, system, false, debugBuffer);
}
- std::string GetModulesFile(const std::string& name, bool& system) const;
+ /**
+ * Return a location of a file in cmake or custom modules directory
+ */
+ std::string GetModulesFile(const std::string& name, bool& system) const
+ {
+ std::string debugBuffer;
+ return this->GetModulesFile(name, system, false, debugBuffer);
+ }
+
+ std::string GetModulesFile(const std::string& name, bool& system, bool debug,
+ std::string& debugBuffer) const;
//! Set/Get a property of this directory
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
const char* GetProperty(const std::string& prop) const;
const char* GetProperty(const std::string& prop, bool chain) const;
@@ -773,28 +794,22 @@ public:
//! Initialize a makefile from its parent
void InitializeFromParent(cmMakefile* parent);
- void AddInstallGenerator(cmInstallGenerator* g)
- {
- if (g) {
- this->InstallGenerators.push_back(g);
- }
- }
- std::vector<cmInstallGenerator*>& GetInstallGenerators()
+ void AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g);
+
+ std::vector<std::unique_ptr<cmInstallGenerator>>& GetInstallGenerators()
{
return this->InstallGenerators;
}
- const std::vector<cmInstallGenerator*>& GetInstallGenerators() const
+ const std::vector<std::unique_ptr<cmInstallGenerator>>&
+ GetInstallGenerators() const
{
return this->InstallGenerators;
}
- void AddTestGenerator(cmTestGenerator* g)
- {
- if (g) {
- this->TestGenerators.push_back(g);
- }
- }
- const std::vector<cmTestGenerator*>& GetTestGenerators() const
+ void AddTestGenerator(std::unique_ptr<cmTestGenerator> g);
+
+ const std::vector<std::unique_ptr<cmTestGenerator>>& GetTestGenerators()
+ const
{
return this->TestGenerators;
}
@@ -927,12 +942,14 @@ public:
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent);
- std::vector<cmGeneratorExpressionEvaluationFile*> GetEvaluationFiles() const;
+ const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
+ GetEvaluationFiles() const;
- std::vector<cmExportBuildFileGenerator*> GetExportBuildFileGenerators()
- const;
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
+ GetExportBuildFileGenerators() const;
void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
- void AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen);
+ void AddExportBuildFileGenerator(
+ std::unique_ptr<cmExportBuildFileGenerator> gen);
// Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
// searches
@@ -962,8 +979,7 @@ protected:
using TargetsVec = std::vector<cmTarget*>;
TargetsVec OrderedTargets;
- using SourceFileVec = std::vector<cmSourceFile*>;
- SourceFileVec SourceFiles;
+ std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
// Because cmSourceFile names are compared in a fuzzy way (see
// cmSourceFileLocation::Match()) we can't have a straight mapping from
@@ -971,14 +987,15 @@ 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.
- using SourceFileMap = std::unordered_map<std::string, SourceFileVec>;
+ using SourceFileMap =
+ std::unordered_map<std::string, std::vector<cmSourceFile*>>;
SourceFileMap SourceFileSearchIndex;
// For "Known" paths we can store a direct filename to cmSourceFile map
std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
// Tests
- std::map<std::string, cmTest*> Tests;
+ std::map<std::string, std::unique_ptr<cmTest>> Tests;
// The set of include directories that are marked as system include
// directories.
@@ -987,8 +1004,8 @@ protected:
std::vector<std::string> ListFiles;
std::vector<std::string> OutputFiles;
- std::vector<cmInstallGenerator*> InstallGenerators;
- std::vector<cmTestGenerator*> TestGenerators;
+ std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
+ std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
std::string ComplainFileRegularExpression;
std::string DefineFlags;
@@ -1001,7 +1018,6 @@ protected:
size_t ObjectLibrariesSourceGroupIndex;
#endif
- std::vector<FinalAction> FinalActions;
cmGlobalGenerator* GlobalGenerator;
bool IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus& status);
@@ -1011,6 +1027,8 @@ private:
cmListFileBacktrace Backtrace;
int RecursionDepth;
+ void DoGenerate(cmLocalGenerator& lg);
+
void ReadListFile(cmListFile const& listFile,
const std::string& filenametoread);
@@ -1036,15 +1054,17 @@ private:
mutable cmsys::RegularExpression cmNamedCurly;
std::vector<cmMakefile*> UnConfiguredDirectories;
- std::vector<cmExportBuildFileGenerator*> ExportBuildFileGenerators;
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
+ ExportBuildFileGenerators;
- std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
+ EvaluationFiles;
std::vector<cmExecutionStatus*> ExecutionStatusStack;
friend class cmMakefileCall;
friend class cmParseFileScope;
- std::vector<cmTarget*> ImportedTargetsOwned;
+ std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
using TargetMap = std::unordered_map<std::string, cmTarget*>;
TargetMap ImportedTargets;
@@ -1080,38 +1100,15 @@ private:
bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
- void CreateGeneratedSources(const std::vector<std::string>& outputs);
+ void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
+ void CreateGeneratedByproducts(const std::vector<std::string>& byproducts);
- 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);
+ std::vector<BT<GeneratorAction>> GeneratorActions;
+ bool GeneratorActionsInvoked = false;
+ bool DelayedOutputFilesHaveGenex = false;
+ std::vector<std::string> DelayedOutputFiles;
- 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);
+ void AddDelayedOutput(std::string const& output);
/**
* See LinearGetSourceFileWithOutput for background information
@@ -1131,6 +1128,7 @@ private:
struct SourceEntry
{
cmSourcesWithOutput Sources;
+ bool SourceMightBeOutput = false;
};
// A map for fast output to input look up.
@@ -1149,11 +1147,14 @@ private:
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;
+ bool AddRequiredTargetCudaFeature(cmTarget* target,
+ const std::string& feature,
+ std::string const& lang,
+ std::string* error = nullptr) const;
void CheckNeededCLanguage(const std::string& feature,
std::string const& lang, bool& needC90,
@@ -1162,6 +1163,10 @@ private:
std::string const& lang, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
bool& needCxx17, bool& needCxx20) const;
+ void CheckNeededCudaLanguage(const std::string& feature,
+ std::string const& lang, bool& needCuda03,
+ bool& needCuda11, bool& needCuda14,
+ bool& needCuda17, bool& needCuda20) const;
bool HaveCStandardAvailable(cmTarget const* target,
const std::string& feature,
@@ -1169,6 +1174,9 @@ private:
bool HaveCxxStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const;
+ bool HaveCudaStandardAvailable(cmTarget const* target,
+ const std::string& feature,
+ std::string const& lang) const;
void CheckForUnusedVariables() const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 40265ff656..0471a459e0 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -9,8 +9,8 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -35,10 +35,9 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
{
this->CustomCommandDriver = OnDepends;
this->TargetNames =
- this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+ this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -64,7 +63,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
// write the link rules
this->WriteExecutableRule(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteExecutableRule(true);
}
@@ -85,7 +84,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
{
#ifndef CMAKE_BOOTSTRAP
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (!requiresDeviceLinking) {
return;
}
@@ -141,10 +140,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
- flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- linkLanguage, this->ConfigName);
+ this->LocalGenerator->AddArchitectureFlags(
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
// Add target-specific linker flags.
this->GetTargetLinkFlags(linkFlags, linkLanguage);
@@ -197,6 +196,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
buildObjs, depends, useWatcomQuote);
+ std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
+
cmRulePlaceholderExpander::RuleVariables vars;
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -213,12 +214,14 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
output);
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
std::string targetOutPathCompilePDB =
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
cmOutputConverter::SHELL);
vars.Language = linkLanguage.c_str();
+ vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
vars.ObjectDir = objectDir.c_str();
vars.Target = target.c_str();
@@ -263,7 +266,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Write the build rule.
@@ -287,12 +290,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the name of the executable to generate.
cmGeneratorTarget::Names targetNames =
- this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+ this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
// Construct the full path version of the names.
- std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ std::string outpath =
+ this->GeneratorTarget->GetDirectory(this->GetConfigName());
if (this->GeneratorTarget->IsAppBundleOnApple()) {
- this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath);
+ this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath,
+ this->GetConfigName());
}
outpath += '/';
std::string outpathImp;
@@ -308,18 +313,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmSystemTools::MakeDirectory(outpath);
if (!targetNames.ImportLibrary.empty()) {
outpathImp = this->GeneratorTarget->GetDirectory(
- this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+ this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
outpathImp += '/';
}
}
std::string compilePdbOutputPath =
- this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
std::string pdbOutputPath =
- this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(pdbOutputPath);
pdbOutputPath += '/';
@@ -347,7 +352,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the language to use for linking this executable.
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
// Make sure we have a link language.
if (linkLanguage.empty()) {
@@ -380,7 +385,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add flags to create an executable.
this->LocalGenerator->AddConfigVariableFlags(
- linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->ConfigName);
+ linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
this->LocalGenerator->AppendFlags(
@@ -409,25 +414,26 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
- flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- linkLanguage, this->ConfigName);
+ this->LocalGenerator->AddArchitectureFlags(
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
// Add target-specific linker flags.
this->GetTargetLinkFlags(linkFlags, linkLanguage);
{
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags,
+ this->GetConfigName());
}
- this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
- this->ConfigName, linkLanguage);
+ this->LocalGenerator->AppendIPOLinkerFlags(
+ linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
// Construct a list of files associated with this executable that
// may need to be cleaned.
@@ -451,7 +457,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(
- this->ConfigName, targetFullPathImport, implib)) {
+ this->GetConfigName(), targetFullPathImport, implib)) {
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
@@ -479,7 +485,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Construct the main link rule.
std::vector<std::string> real_link_commands;
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
- linkLanguage, this->ConfigName);
+ linkLanguage, this->GetConfigName());
std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
cmExpandList(linkRule, real_link_commands);
@@ -506,10 +512,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
@@ -536,7 +542,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// maybe create .def file from list of objects
this->GenDefFile(real_link_commands);
- std::string manifests = this->GetManifests();
+ std::string manifests = this->GetManifests(this->GetConfigName());
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
@@ -627,7 +633,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Add a rule to create necessary symlinks for the library.
@@ -639,7 +645,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 54a66065c2..d3f3a4ff0a 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -9,8 +9,8 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -36,11 +36,10 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
this->CustomCommandDriver = OnDepends;
if (this->GeneratorTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
this->TargetNames =
- this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+ this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
}
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -69,14 +68,16 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
break;
case cmStateEnums::SHARED_LIBRARY:
this->WriteSharedLibraryRules(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+ this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteSharedLibraryRules(true);
}
break;
case cmStateEnums::MODULE_LIBRARY:
this->WriteModuleLibraryRules(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+ this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteModuleLibraryRules(true);
}
@@ -126,21 +127,21 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, false);
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
- linkLanguage, this->ConfigName);
+ linkLanguage, this->GetConfigName());
std::string extraFlags;
this->LocalGenerator->GetStaticLibraryFlags(
- extraFlags, cmSystemTools::UpperCase(this->ConfigName), linkLanguage,
+ extraFlags, cmSystemTools::UpperCase(this->GetConfigName()), linkLanguage,
this->GeneratorTarget);
this->WriteLibraryRules(linkRuleVar, extraFlags, false);
}
@@ -154,7 +155,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
if (!relink) {
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -162,21 +163,22 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+ this->GetConfigName());
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
@@ -188,7 +190,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
if (!relink) {
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -196,21 +198,22 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+ this->GetConfigName());
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -218,14 +221,14 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -331,7 +334,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
output);
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
std::string targetOutPathCompilePDB =
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
cmOutputConverter::SHELL);
@@ -347,7 +351,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
// Add language-specific flags.
std::string langFlags;
this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
vars.LanguageCompileFlags = langFlags.c_str();
@@ -393,7 +397,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Compute the list of outputs.
@@ -420,7 +424,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Get the language to use for linking this library.
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
// Make sure we have a link language.
if (linkLanguage.empty()) {
@@ -439,8 +443,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Create set of linking flags.
std::string linkFlags;
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
- this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
- this->ConfigName, linkLanguage);
+ this->LocalGenerator->AppendIPOLinkerFlags(
+ linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
// Add OSX version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -450,20 +454,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Construct the name of the library.
- this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+ this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
// Construct the full path version of the names.
std::string outpath;
std::string outpathImp;
if (this->GeneratorTarget->IsFrameworkOnApple()) {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
- outpath);
+ outpath, this->GetConfigName());
outpath += '/';
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
- this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
- outpath);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
+ this->GetConfigName());
outpath += '/';
} else if (relink) {
outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
@@ -474,23 +478,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
outpathImp = outpath;
}
} else {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(outpath);
outpath += '/';
if (!this->TargetNames.ImportLibrary.empty()) {
outpathImp = this->GeneratorTarget->GetDirectory(
- this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+ this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
outpathImp += '/';
}
}
std::string compilePdbOutputPath =
- this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
std::string pdbOutputPath =
- this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(pdbOutputPath);
pdbOutputPath += "/";
@@ -567,7 +571,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
@@ -586,7 +590,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(
- this->ConfigName, targetFullPathImport, implib)) {
+ this->GetConfigName(), targetFullPathImport, implib)) {
libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
@@ -638,7 +642,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arCreateVar, linkLanguage, this->ConfigName);
+ arCreateVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
cmExpandList(rule, archiveCreateCommands);
@@ -647,7 +651,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arAppendVar, linkLanguage, this->ConfigName);
+ arAppendVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
cmExpandList(rule, archiveAppendCommands);
@@ -656,7 +660,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arFinishVar, linkLanguage, this->ConfigName);
+ arFinishVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
cmExpandList(rule, archiveFinishCommands);
@@ -696,10 +700,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string linkLibs;
if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
@@ -723,10 +727,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmOutputConverter::SHELL);
}
+ std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
+
// maybe create .def file from list of objects
this->GenDefFile(real_link_commands);
- std::string manifests = this->GetManifests();
+ std::string manifests = this->GetManifests(this->GetConfigName());
cmRulePlaceholderExpander::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -752,6 +758,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
vars.Language = linkLanguage.c_str();
+ vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -771,7 +778,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
- if (this->GeneratorTarget->HasSOName(this->ConfigName)) {
+ if (this->GeneratorTarget->HasSOName(this->GetConfigName())) {
vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
vars.TargetSOName = this->TargetNames.SharedObject.c_str();
}
@@ -783,8 +790,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string install_name_dir;
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY) {
// Get the install_name directory for the build tree.
- install_name_dir =
- this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
+ install_name_dir = this->GeneratorTarget->GetInstallNameDirForBuildTree(
+ this->GetConfigName());
// Set the rule variable replacement value.
if (install_name_dir.empty()) {
@@ -800,10 +807,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Add language-specific flags.
std::string langFlags;
this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
this->LocalGenerator->AddArchitectureFlags(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
vars.LanguageCompileFlags = langFlags.c_str();
@@ -903,7 +910,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Add a rule to create necessary symlinks for the library.
@@ -917,7 +924,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index dd8a389cbe..d7e2de6c86 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -2,12 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileTargetGenerator.h"
+#include <cassert>
#include <cstdio>
-#include <memory>
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -15,6 +17,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -35,12 +38,7 @@
cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
: cmCommonTargetGenerator(target)
- , OSXBundleGenerator(nullptr)
- , MacOSXContentGenerator(nullptr)
{
- this->BuildFileStream = nullptr;
- this->InfoFileStream = nullptr;
- this->FlagFileStream = nullptr;
this->CustomCommandDriver = OnBuild;
this->LocalGenerator =
static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
@@ -52,31 +50,28 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
this->NoRuleMessages = cmIsOff(ruleStatus);
}
- MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
+ MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
}
-cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
-{
- delete MacOSXContentGenerator;
-}
+cmMakefileTargetGenerator::~cmMakefileTargetGenerator() = default;
-cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
+std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
cmGeneratorTarget* tgt)
{
- cmMakefileTargetGenerator* result = nullptr;
+ std::unique_ptr<cmMakefileTargetGenerator> result;
switch (tgt->GetType()) {
case cmStateEnums::EXECUTABLE:
- result = new cmMakefileExecutableTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileExecutableTargetGenerator>(tgt);
break;
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY:
- result = new cmMakefileLibraryTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
break;
case cmStateEnums::UTILITY:
- result = new cmMakefileUtilityTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
break;
default:
return result;
@@ -85,6 +80,13 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
return result;
}
+std::string cmMakefileTargetGenerator::GetConfigName()
+{
+ auto const& configNames = this->LocalGenerator->GetConfigNames();
+ assert(configNames.size() == 1);
+ return configNames.front();
+}
+
void cmMakefileTargetGenerator::GetTargetLinkFlags(
std::string& flags, const std::string& linkLanguage)
{
@@ -92,17 +94,18 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
flags, this->GeneratorTarget->GetSafeProperty("LINK_FLAGS"));
std::string linkFlagsConfig =
- cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName));
+ cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->GetConfigName()));
this->LocalGenerator->AppendFlags(
flags, this->GeneratorTarget->GetSafeProperty(linkFlagsConfig));
std::vector<std::string> opts;
- this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
+ this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(),
+ linkLanguage);
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
- flags, this->GeneratorTarget, this->ConfigName, linkLanguage);
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
@@ -128,9 +131,9 @@ void cmMakefileTargetGenerator::CreateRuleFile()
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
- this->BuildFileStream =
- new cmGeneratedFileStream(this->BuildFileNameFull, false,
- this->GlobalGenerator->GetMakefileEncoding());
+ this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
+ this->BuildFileNameFull, false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!this->BuildFileStream) {
return;
}
@@ -154,10 +157,10 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
auto evaluatedFiles =
[this](const char* prop_value) -> std::vector<std::string> {
std::vector<std::string> files;
- cmExpandList(
- cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator,
- this->ConfigName, this->GeneratorTarget),
- files);
+ cmExpandList(cmGeneratorExpression::Evaluate(
+ prop_value, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget),
+ files);
return files;
};
@@ -187,12 +190,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// 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, this->ConfigName);
+ this->GeneratorTarget->GetCustomCommands(customCommands,
+ this->GetConfigName());
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (cmSourceFile const* sf : customCommands) {
- cmCustomCommandGenerator ccg(*sf->GetCustomCommand(), this->ConfigName,
- this->LocalGenerator);
+ cmCustomCommandGenerator ccg(*sf->GetCustomCommand(),
+ this->GetConfigName(), this->LocalGenerator);
this->GenerateCustomRuleFile(ccg);
if (clean) {
const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -215,12 +219,14 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
std::vector<cmCustomCommand> buildEventCommands =
this->GeneratorTarget->GetPreBuildCommands();
- cmAppend(buildEventCommands, this->GeneratorTarget->GetPreLinkCommands());
- cmAppend(buildEventCommands,
- this->GeneratorTarget->GetPostBuildCommands());
+ cm::append(buildEventCommands,
+ this->GeneratorTarget->GetPreLinkCommands());
+ cm::append(buildEventCommands,
+ this->GeneratorTarget->GetPostBuildCommands());
for (const auto& be : buildEventCommands) {
- cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator);
+ cmCustomCommandGenerator beg(be, this->GetConfigName(),
+ this->LocalGenerator);
const std::vector<std::string>& byproducts = beg.GetByproducts();
for (std::string const& byproduct : byproducts) {
this->CleanFiles.insert(
@@ -230,17 +236,19 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+ this->GeneratorTarget->GetHeaderSources(headerSources,
+ this->GetConfigName());
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- headerSources, this->MacOSXContentGenerator);
+ headerSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+ this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName());
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- extraSources, this->MacOSXContentGenerator);
+ extraSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
const char* pchExtension =
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName);
+ this->GeneratorTarget->GetExternalObjects(externalObjects,
+ this->GetConfigName());
for (cmSourceFile const* sf : externalObjects) {
auto const& objectFileName = sf->GetFullPath();
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
@@ -248,7 +256,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+ this->GeneratorTarget->GetObjectSources(objectSources,
+ this->GetConfigName());
for (cmSourceFile const* sf : objectSources) {
// Generate this object file's rule file.
this->WriteObjectRuleFiles(*sf);
@@ -299,9 +308,9 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// rules may depend on this file itself.
this->FlagFileNameFull =
cmStrCat(this->TargetBuildDirectoryFull, "/flags.make");
- this->FlagFileStream =
- new cmGeneratedFileStream(this->FlagFileNameFull, false,
- this->GlobalGenerator->GetMakefileEncoding());
+ this->FlagFileStream = cm::make_unique<cmGeneratedFileStream>(
+ this->FlagFileNameFull, false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!this->FlagFileStream) {
return;
}
@@ -334,9 +343,9 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
}
for (std::string const& language : languages) {
- std::string flags = this->GetFlags(language);
- std::string defines = this->GetDefines(language);
- std::string includes = this->GetIncludes(language);
+ std::string flags = this->GetFlags(language, this->GetConfigName());
+ std::string defines = this->GetDefines(language, this->GetConfigName());
+ std::string includes = this->GetIncludes(language, this->GetConfigName());
// Escape comment characters so they do not terminate assignment.
cmSystemTools::ReplaceString(flags, "#", "\\#");
cmSystemTools::ReplaceString(defines, "#", "\\#");
@@ -348,7 +357,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
}
void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile const& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc, const std::string& config)
{
// Skip OS X content when not building a Framework or Bundle.
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -356,7 +365,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
}
std::string macdir =
- this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+ config);
// Get the input file location.
std::string const& input = source.GetFullPath();
@@ -451,7 +461,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// generate the depend scanning rule
this->WriteObjectDependRules(source, depends);
- std::string config = this->LocalGenerator->GetConfigName();
+ std::string config = this->GetConfigName();
std::string configUpper = cmSystemTools::UpperCase(config);
// Add precompile headers dependencies
@@ -593,16 +603,17 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
{
std::string targetFullPathReal;
std::string targetFullPathPDB;
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
targetFullPathReal = this->GeneratorTarget->GetFullPath(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true);
- targetFullPathPDB =
- cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/',
- this->GeneratorTarget->GetPDBName(this->ConfigName));
+ this->GetConfigName(), cmStateEnums::RuntimeBinaryArtifact, true);
+ targetFullPathPDB = cmStrCat(
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
+ this->GeneratorTarget->GetPDBName(this->GetConfigName()));
}
targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
@@ -708,13 +719,15 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string workingDirectory = cmSystemTools::CollapseFullPath(
this->LocalGenerator->GetCurrentBinaryDirectory());
compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
- this->GetFlags(lang));
+ this->GetFlags(lang, this->GetConfigName()));
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
compileCommand.replace(compileCommand.find(langDefines),
- langDefines.size(), this->GetDefines(lang));
+ langDefines.size(),
+ this->GetDefines(lang, this->GetConfigName()));
std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
compileCommand.replace(compileCommand.find(langIncludes),
- langIncludes.size(), this->GetIncludes(lang));
+ langIncludes.size(),
+ this->GetIncludes(lang, this->GetConfigName()));
const char* eliminate[] = {
this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
@@ -769,7 +782,13 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
if (tidy && *tidy) {
run_iwyu += " --tidy=";
- run_iwyu += this->LocalGenerator->EscapeForShell(tidy);
+ const char* driverMode = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
+ if (!(driverMode && *driverMode)) {
+ driverMode = lang == "C" ? "gcc" : "g++";
+ }
+ run_iwyu += this->LocalGenerator->EscapeForShell(
+ cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
if (cpplint && *cpplint) {
run_iwyu += " --cpplint=";
@@ -823,7 +842,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->LocalGenerator->CreateCDCommand(
compileCommands, this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, compileCommands);
+ cm::append(commands, compileCommands);
}
// Check for extra outputs created by the compilation.
@@ -882,7 +901,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
preprocessCommands,
this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, preprocessCommands);
+ cm::append(commands, preprocessCommands);
} else {
std::string cmd =
cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
@@ -926,7 +945,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->LocalGenerator->CreateCDCommand(
assemblyCommands, this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, assemblyCommands);
+ cm::append(commands, assemblyCommands);
} else {
std::string cmd =
cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
@@ -1036,7 +1055,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake");
this->InfoFileNameFull =
this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
- this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull);
+ this->InfoFileStream =
+ cm::make_unique<cmGeneratedFileStream>(this->InfoFileNameFull);
if (!this->InfoFileStream) {
return;
}
@@ -1068,7 +1088,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "# Targets to which this target links.\n"
<< "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
/* clang-format on */
- std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+ std::vector<std::string> dirs =
+ this->GetLinkedTargetDirectories(this->GetConfigName());
for (std::string const& d : dirs) {
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
}
@@ -1171,9 +1192,9 @@ void cmMakefileTargetGenerator::DriveCustomCommands(
sources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* source : sources) {
if (cmCustomCommand* cc = source->GetCustomCommand()) {
- cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
this->LocalGenerator);
- cmAppend(depends, ccg.GetOutputs());
+ cm::append(depends, ccg.GetOutputs());
}
}
}
@@ -1410,7 +1431,7 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
}
// Make sure the extra files are built.
- cmAppend(depends, this->ExtraFiles);
+ cm::append(depends, this->ExtraFiles);
}
// Write the driver rule.
@@ -1429,10 +1450,10 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
}
// Loop over all library dependencies.
- const std::string& cfg = this->LocalGenerator->GetConfigName();
+ const std::string& cfg = this->GetConfigName();
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
- cmAppend(depends, cli->GetDepends());
+ cm::append(depends, cli->GetDepends());
}
}
@@ -1448,7 +1469,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends(
}
// Add dependencies on the external object files.
- cmAppend(depends, this->ExternalObjects);
+ cm::append(depends, this->ExternalObjects);
// Add a dependency on the rule file itself.
this->LocalGenerator->AppendRuleDepend(depends,
@@ -1474,13 +1495,13 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
// Add a dependency on user-specified manifest files, if any.
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->GetConfigName());
for (cmSourceFile const* manifest_src : manifest_srcs) {
depends.push_back(manifest_src->GetFullPath());
}
// Add user-specified dependencies.
- this->GeneratorTarget->GetLinkDepends(depends, this->ConfigName,
+ this->GeneratorTarget->GetLinkDepends(depends, this->GetConfigName(),
linkLanguage);
}
@@ -1488,10 +1509,11 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
const std::string& linkRuleVar)
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_GNUtoMS_RULE");
+ if (this->GeneratorTarget->HasImplibGNUtoMS(this->GetConfigName())) {
+ std::string ruleVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkRule += rule;
}
@@ -1501,9 +1523,9 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
void cmMakefileTargetGenerator::CloseFileStreams()
{
- delete this->BuildFileStream;
- delete this->InfoFileStream;
- delete this->FlagFileStream;
+ this->BuildFileStream.reset();
+ this->InfoFileStream.reset();
+ this->FlagFileStream.reset();
}
void cmMakefileTargetGenerator::CreateLinkScript(
@@ -1612,7 +1634,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
return responseFileName;
}
-cmLinkLineComputer* cmMakefileTargetGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmMakefileTargetGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir)
{
if (this->Makefile->IsOn("MSVC60")) {
@@ -1630,7 +1653,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
std::string frameworkPath;
std::string linkPath;
cmComputeLinkInformation* pcli =
- this->GeneratorTarget->GetLinkInformation(this->ConfigName);
+ this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
linkLibs = frameworkPath + linkPath + linkLibs;
@@ -1638,9 +1661,10 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
if (useResponseFile &&
linkLibs.find_first_not_of(' ') != std::string::npos) {
// Lookup the response file reference flag.
- std::string responseFlagVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_RESPONSE_FILE_LINK_FLAG");
+ std::string responseFlagVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1675,9 +1699,10 @@ void cmMakefileTargetGenerator::CreateObjectLists(
this->WriteObjectsStrings(object_strings, responseFileLimit);
// Lookup the response file reference flag.
- std::string responseFlagVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_RESPONSE_FILE_LINK_FLAG");
+ std::string responseFlagVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1716,7 +1741,8 @@ void cmMakefileTargetGenerator::CreateObjectLists(
}
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
- const std::string& lang)
+ const std::string& lang,
+ const std::string& /*config*/)
{
std::string responseVar =
cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES");
@@ -1724,11 +1750,11 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- lang, this->ConfigName);
+ lang, this->GetConfigName());
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, lang, false, useResponseFile,
- this->ConfigName);
+ this->GetConfigName());
if (includeFlags.empty()) {
return;
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 7b9c7a5ffe..ec6b314389 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -34,10 +34,15 @@ class cmMakefileTargetGenerator : public cmCommonTargetGenerator
public:
// constructor to set the ivars
cmMakefileTargetGenerator(cmGeneratorTarget* target);
+ cmMakefileTargetGenerator(const cmMakefileTargetGenerator&) = delete;
~cmMakefileTargetGenerator() override;
+ cmMakefileTargetGenerator& operator=(const cmMakefileTargetGenerator&) =
+ delete;
+
// construct using this factory call
- static cmMakefileTargetGenerator* New(cmGeneratorTarget* tgt);
+ static std::unique_ptr<cmMakefileTargetGenerator> New(
+ cmGeneratorTarget* tgt);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -52,6 +57,8 @@ public:
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
+ std::string GetConfigName();
+
protected:
void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
@@ -81,7 +88,8 @@ protected:
{
}
- void operator()(cmSourceFile const& source, const char* pkgloc) override;
+ void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) override;
private:
cmMakefileTargetGenerator* Generator;
@@ -137,7 +145,7 @@ protected:
std::vector<std::string>& makefile_commands,
std::vector<std::string>& makefile_depends);
- cmLinkLineComputer* CreateLinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir);
/** Create a response file with the given set of options. Returns
@@ -163,7 +171,8 @@ protected:
/** Add commands for generate def files */
void GenDefFile(std::vector<std::string>& real_link_commands);
- void AddIncludeFlags(std::string& flags, const std::string& lang) override;
+ void AddIncludeFlags(std::string& flags, const std::string& lang,
+ const std::string& config) override;
virtual void CloseFileStreams();
cmLocalUnixMakefileGenerator3* LocalGenerator;
@@ -191,11 +200,11 @@ protected:
std::string TargetBuildDirectoryFull;
// the stream for the build file
- cmGeneratedFileStream* BuildFileStream;
+ std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
// the stream for the flag file
std::string FlagFileNameFull;
- cmGeneratedFileStream* FlagFileStream;
+ std::unique_ptr<cmGeneratedFileStream> FlagFileStream;
class StringList : public std::vector<std::string>
{
};
@@ -203,7 +212,7 @@ protected:
// the stream for the info file
std::string InfoFileNameFull;
- cmGeneratedFileStream* InfoFileStream;
+ std::unique_ptr<cmGeneratedFileStream> InfoFileStream;
// files to clean
std::set<std::string> CleanFiles;
@@ -232,7 +241,7 @@ protected:
// macOS content info.
std::set<std::string> MacContentFolders;
std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
- MacOSXContentGeneratorType* MacOSXContentGenerator;
+ std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
};
#endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 1625e4fdb0..6c18e482e6 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -22,8 +22,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
: cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index ca46e14c2b..45043faa5d 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -4,8 +4,11 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -28,14 +31,63 @@ bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
}
i = 1;
}
+
+ cmMakefile& mf = status.GetMakefile();
+ cmState* state = mf.GetState();
+
for (; i < args.size(); ++i) {
std::string const& variable = args[i];
- cmState* state = status.GetMakefile().GetState();
- if (!state->GetCacheEntryValue(variable)) {
- status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
- variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
- overwrite = true;
+
+ bool issueMessage = false;
+ bool oldBehavior = false;
+ bool ignoreVariable = false;
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0102)) {
+ case cmPolicies::WARN:
+ if (mf.PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0102")) {
+ if (!state->GetCacheEntryValue(variable)) {
+ issueMessage = true;
+ }
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ oldBehavior = true;
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ if (!state->GetCacheEntryValue(variable)) {
+ ignoreVariable = true;
+ }
+ break;
+ }
+
+ // First see if we should issue a message about CMP0102
+ if (issueMessage) {
+ std::string err = cmStrCat(
+ "Policy CMP0102 is not set: The variable named \"", variable,
+ "\" is not in the cache. This results in an empty cache entry which "
+ "is no longer created when policy CMP0102 is set to NEW. Run \"cmake "
+ "--help-policy CMP0102\" for policy details. Use the cmake_policy "
+ "command to set the policy and suppress this warning.");
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, err);
}
+
+ // If it's not in the cache and we're using the new behavior, nothing to
+ // see here.
+ if (ignoreVariable) {
+ continue;
+ }
+
+ // Check if we want the old behavior of making a dummy cache entry.
+ if (oldBehavior) {
+ if (!state->GetCacheEntryValue(variable)) {
+ status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
+ variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
+ overwrite = true;
+ }
+ }
+
+ // We need a cache entry to do this.
if (!state->GetCacheEntryValue(variable)) {
cmSystemTools::Error("This should never happen...");
return false;
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 96a6386bf1..bf8183bbf1 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -3,6 +3,11 @@
#include "cmMessageCommand.h"
#include <cassert>
+#include <utility>
+
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -13,6 +18,55 @@
#include "cmSystemTools.h"
#include "cmake.h"
+namespace {
+
+enum class CheckingType
+{
+ UNDEFINED,
+ CHECK_START,
+ CHECK_PASS,
+ CHECK_FAIL
+};
+
+std::string IndentText(std::string text, cmMakefile& mf)
+{
+ auto indent =
+ cmJoin(cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT")), "");
+
+ const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
+ mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
+ if (showContext) {
+ auto context = cmJoin(
+ cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT")), ".");
+ if (!context.empty()) {
+ indent.insert(0u, cmStrCat("["_s, context, "] "_s));
+ }
+ }
+
+ if (!indent.empty()) {
+ cmSystemTools::ReplaceString(text, "\n", "\n" + indent);
+ text.insert(0u, indent);
+ }
+ return text;
+}
+
+void ReportCheckResult(cm::string_view what, std::string result,
+ cmMakefile& mf)
+{
+ if (mf.GetCMakeInstance()->HasCheckInProgress()) {
+ auto text = mf.GetCMakeInstance()->GetTopCheckInProgressMessage() + " - " +
+ std::move(result);
+ mf.DisplayStatus(IndentText(std::move(text), mf), -1);
+ } else {
+ mf.GetMessenger()->DisplayMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("Ignored "_s, what, " without CHECK_START"_s),
+ mf.GetBacktrace());
+ }
+}
+
+} // anonymous namespace
+
// cmLibraryCommand
bool cmMessageCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -21,11 +75,15 @@ bool cmMessageCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments");
return false;
}
+
+ auto& mf = status.GetMakefile();
+
auto i = args.cbegin();
auto type = MessageType::MESSAGE;
auto fatal = false;
auto level = cmake::LogLevel::LOG_UNDEFINED;
+ auto checkingType = CheckingType::UNDEFINED;
if (*i == "SEND_ERROR") {
type = MessageType::FATAL_ERROR;
level = cmake::LogLevel::LOG_ERROR;
@@ -40,19 +98,30 @@ bool cmMessageCommand(std::vector<std::string> const& args,
level = cmake::LogLevel::LOG_WARNING;
++i;
} else if (*i == "AUTHOR_WARNING") {
- if (status.GetMakefile().IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
- !status.GetMakefile().IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
+ if (mf.IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+ !mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
fatal = true;
type = MessageType::AUTHOR_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if (!status.GetMakefile().IsOn(
- "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
+ } else if (!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
type = MessageType::AUTHOR_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
return true;
}
++i;
+ } else if (*i == "CHECK_START") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_START;
+ ++i;
+ } else if (*i == "CHECK_PASS") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_PASS;
+ ++i;
+ } else if (*i == "CHECK_FAIL") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_FAIL;
+ ++i;
} else if (*i == "STATUS") {
level = cmake::LogLevel::LOG_STATUS;
++i;
@@ -66,12 +135,12 @@ bool cmMessageCommand(std::vector<std::string> const& args,
level = cmake::LogLevel::LOG_TRACE;
++i;
} else if (*i == "DEPRECATION") {
- if (status.GetMakefile().IsOn("CMAKE_ERROR_DEPRECATED")) {
+ if (mf.IsOn("CMAKE_ERROR_DEPRECATED")) {
fatal = true;
type = MessageType::DEPRECATION_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if (!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
- status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED")) {
+ } else if (!mf.IsSet("CMAKE_WARN_DEPRECATED") ||
+ mf.IsOn("CMAKE_WARN_DEPRECATED")) {
type = MessageType::DEPRECATION_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
@@ -89,10 +158,19 @@ bool cmMessageCommand(std::vector<std::string> const& args,
assert("Message log level expected to be set" &&
level != cmake::LogLevel::LOG_UNDEFINED);
- auto desiredLevel = status.GetMakefile().GetCMakeInstance()->GetLogLevel();
+ auto desiredLevel = mf.GetCMakeInstance()->GetLogLevel();
assert("Expected a valid log level here" &&
desiredLevel != cmake::LogLevel::LOG_UNDEFINED);
+ // Command line option takes precedence over the cache variable
+ if (!mf.GetCMakeInstance()->WasLogLevelSetViaCLI()) {
+ const auto desiredLevelFromCache =
+ cmake::StringToLogLevel(mf.GetSafeDefinition("CMAKE_MESSAGE_LOG_LEVEL"));
+ if (desiredLevelFromCache != cmake::LogLevel::LOG_UNDEFINED) {
+ desiredLevel = desiredLevelFromCache;
+ }
+ }
+
if (desiredLevel < level) {
// Suppress the message
return true;
@@ -100,37 +178,42 @@ bool cmMessageCommand(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
- 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());
+ mf.GetMessenger()->DisplayMessage(type, message, mf.GetBacktrace());
break;
case cmake::LogLevel::LOG_NOTICE:
- cmSystemTools::Message(message);
+ cmSystemTools::Message(IndentText(message, mf));
break;
case cmake::LogLevel::LOG_STATUS:
+ switch (checkingType) {
+ case CheckingType::CHECK_START:
+ mf.DisplayStatus(IndentText(message, mf), -1);
+ mf.GetCMakeInstance()->PushCheckInProgressMessage(message);
+ break;
+
+ case CheckingType::CHECK_PASS:
+ ReportCheckResult("CHECK_PASS"_s, message, mf);
+ break;
+
+ case CheckingType::CHECK_FAIL:
+ ReportCheckResult("CHECK_FAIL"_s, message, mf);
+ break;
+
+ default:
+ mf.DisplayStatus(IndentText(message, mf), -1);
+ break;
+ }
+ break;
+
case cmake::LogLevel::LOG_VERBOSE:
case cmake::LogLevel::LOG_DEBUG:
case cmake::LogLevel::LOG_TRACE:
- status.GetMakefile().DisplayStatus(message, -1);
+ mf.DisplayStatus(IndentText(message, mf), -1);
break;
default:
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index a458caccf7..885703fb32 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -11,8 +11,8 @@
#include <utility>
#include <cm/memory>
+#include <cm/vector>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
@@ -41,33 +41,25 @@
cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
cmGeneratorTarget* target)
: cmNinjaTargetGenerator(target)
- , TargetLinkLanguage("")
{
- this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
- if (target->GetType() == cmStateEnums::EXECUTABLE) {
- this->TargetNames = this->GetGeneratorTarget()->GetExecutableNames(
- GetLocalGenerator()->GetConfigName());
- } else {
- this->TargetNames = this->GetGeneratorTarget()->GetLibraryNames(
- GetLocalGenerator()->GetConfigName());
- }
-
if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
// on Windows the output dir is already needed at compile time
// ensure the directory exists (OutDir test)
- EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
+ for (auto const& config : this->GetConfigNames()) {
+ EnsureDirectoryExists(target->GetDirectory(config));
+ }
}
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
-void cmNinjaNormalTargetGenerator::Generate()
+void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
{
- if (this->TargetLinkLanguage.empty()) {
+ std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
+ if (this->TargetLinkLanguage(config).empty()) {
cmSystemTools::Error("CMake can not determine linker language for "
"target: " +
this->GetGeneratorTarget()->GetName());
@@ -75,25 +67,48 @@ void cmNinjaNormalTargetGenerator::Generate()
}
// Write the rules for each language.
- this->WriteLanguagesRules();
+ this->WriteLanguagesRules(config);
// Write the build statements
- this->WriteObjectBuildStatements();
+ bool firstForConfig = true;
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ this->WriteObjectBuildStatements(config, fileConfig, firstForConfig);
+ firstForConfig = false;
+ }
if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- this->WriteObjectLibStatement();
+ this->WriteObjectLibStatement(config);
} else {
- // If this target has cuda language link inputs, and we need to do
- // device linking
- this->WriteDeviceLinkStatement();
- this->WriteLinkStatement();
+ firstForConfig = true;
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ // If this target has cuda language link inputs, and we need to do
+ // device linking
+ this->WriteDeviceLinkStatement(config, fileConfig, firstForConfig);
+ this->WriteLinkStatement(config, fileConfig, firstForConfig);
+ firstForConfig = false;
+ }
+ }
+ if (this->GetGlobalGenerator()->EnableCrossConfigBuild()) {
+ this->GetGlobalGenerator()->AddTargetAlias(
+ this->GetTargetName(), this->GetGeneratorTarget(), "all");
}
// Find ADDITIONAL_CLEAN_FILES
- this->AdditionalCleanFiles();
+ this->AdditionalCleanFiles(config);
}
-void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
+void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
+ const std::string& config)
{
#ifdef NINJA_GEN_VERBOSE_FILES
cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
@@ -106,8 +121,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
// Write rules for languages compiled in this target.
std::set<std::string> languages;
std::vector<cmSourceFile const*> sourceFiles;
- this->GetGeneratorTarget()->GetObjectSources(
- sourceFiles, this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
for (cmSourceFile const* sf : sourceFiles) {
std::string const lang = sf->GetLanguage();
if (!lang.empty()) {
@@ -115,7 +129,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
}
}
for (std::string const& language : languages) {
- this->WriteLanguageRules(language);
+ this->WriteLanguageRules(language, config);
}
}
@@ -139,22 +153,26 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
}
}
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
+ const std::string& config) const
{
- return this->TargetLinkLanguage + "_" +
+ return this->TargetLinkLanguage(config) + "_" +
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
"_LINKER__" +
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName());
+ this->GetGeneratorTarget()->GetName()) +
+ "_" + config;
}
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
+ const std::string& config) const
{
- return this->TargetLinkLanguage + "_" +
+ return this->TargetLinkLanguage(config) + "_" +
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
"_DEVICE_LINKER__" +
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName());
+ this->GetGeneratorTarget()->GetName()) +
+ "_" + config;
}
struct cmNinjaRemoveNoOpCommands
@@ -165,9 +183,10 @@ struct cmNinjaRemoveNoOpCommands
}
};
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
+ bool useResponseFile, const std::string& config)
{
- cmNinjaRule rule(this->LanguageLinkerDeviceRule());
+ cmNinjaRule rule(this->LanguageLinkerDeviceRule(config));
if (!this->GetGlobalGenerator()->HasRule(rule.Name)) {
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
@@ -236,35 +255,40 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
}
// If there is no ranlib the command will be ":". Skip it.
- cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
+ cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), '.');
- rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), " $TARGET_FILE");
+ rule.Comment =
+ cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description =
+ cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
}
-void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
+ const std::string& config)
{
cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
- std::string linkRuleName = this->LanguageLinkerRule();
+ std::string linkRuleName = this->LanguageLinkerRule(config);
if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) {
cmNinjaRule rule(std::move(linkRuleName));
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType = cmState::GetTargetTypeName(targetType);
- vars.Language = this->TargetLinkLanguage.c_str();
+ std::string lang = this->TargetLinkLanguage(config);
+ vars.Language = config.c_str();
+ vars.AIXExports = "$AIX_EXPORTS";
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
vars.SwiftModule = "$SWIFT_MODULE";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
@@ -278,7 +302,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::string responseFlag;
- std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+ std::string cmakeVarLang =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -304,7 +329,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
rule.RspContent = "$in_newline";
}
rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftSources = responseFlag.c_str();
} else {
vars.Objects = responseFlag.c_str();
@@ -359,7 +384,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
// Rule for linking library/executable.
- std::vector<std::string> linkCmds = this->ComputeLinkCmd();
+ std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
for (std::string& linkCmd : linkCmds) {
linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
@@ -367,22 +392,25 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
}
// If there is no ranlib the command will be ":". Skip it.
- cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
+ cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.emplace_back("$POST_BUILD");
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), '.');
- rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), " $TARGET_FILE");
+ rule.Comment =
+ cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description =
+ cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
- if (this->TargetNames.Output != this->TargetNames.Real &&
+ auto const tgtNames = this->TargetNames(config);
+ if (tgtNames.Output != tgtNames.Real &&
!this->GetGeneratorTarget()->IsFrameworkOnApple()) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -441,7 +469,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
return linkCmds;
}
-std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
+std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
+ const std::string& config)
{
std::vector<std::string> linkCmds;
cmMakefile* mf = this->GetMakefile();
@@ -450,14 +479,14 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
// this occurs when things like IPO is enabled, and we need to use the
// CMAKE_<lang>_CREATE_STATIC_LIBRARY_IPO define instead.
std::string linkCmdVar = this->GetGeneratorTarget()->GetCreateRuleVariable(
- this->TargetLinkLanguage, this->GetConfigName());
+ this->TargetLinkLanguage(config), config);
const char* linkCmd = mf->GetDefinition(linkCmdVar);
if (linkCmd) {
std::string linkCmdStr = linkCmd;
- if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_GNUtoMS_RULE");
+ if (this->GetGeneratorTarget()->HasImplibGNUtoMS(config)) {
+ std::string ruleVar =
+ cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(config),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkCmdStr += rule;
}
@@ -469,9 +498,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
" -E __run_co_compile --lwyu=");
cmGeneratorTarget& gt = *this->GetGeneratorTarget();
- const std::string cfgName = this->GetConfigName();
std::string targetOutputReal = this->ConvertToNinjaPath(
- gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+ gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
/*realname=*/true));
cmakeCommand += targetOutputReal;
linkCmds.push_back(std::move(cmakeCommand));
@@ -486,25 +514,25 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- linkCmds.push_back(cmakeCommand + " -E remove $TARGET_FILE");
+ linkCmds.push_back(cmakeCommand + " -E rm -f $TARGET_FILE");
}
// TODO: Use ARCHIVE_APPEND for archives over a certain size.
{
- std::string linkCmdVar =
- cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE");
+ std::string linkCmdVar = cmStrCat(
+ "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_CREATE");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+ linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmExpandList(linkCmd, linkCmds);
}
{
- std::string linkCmdVar =
- cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH");
+ std::string linkCmdVar = cmStrCat(
+ "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_FINISH");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+ linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmExpandList(linkCmd, linkCmds);
@@ -523,19 +551,28 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
linkCmds.push_back(cmakeCommand + " -E touch $TARGET_FILE");
}
#endif
- return linkCmds;
- }
+ } break;
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
+ break;
case cmStateEnums::EXECUTABLE:
+ if (this->TargetLinkLanguage(config) == "Swift") {
+ if (this->GeneratorTarget->IsExecutableWithExports()) {
+ const std::string flags =
+ this->Makefile->GetSafeDefinition("CMAKE_EXE_EXPORTS_Swift_FLAG");
+ cmExpandList(flags, linkCmds);
+ }
+ }
break;
default:
assert(false && "Unexpected target type");
}
- return std::vector<std::string>();
+ return linkCmds;
}
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
if (!globalGen->GetLanguageEnabled("CUDA")) {
@@ -545,7 +582,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName);
+ *this->GeneratorTarget, *this->GetLocalGenerator(), config);
if (!requiresDeviceLinking) {
return;
}
@@ -558,24 +595,53 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
std::string const& objExt =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
- std::string const cfgName = this->GetConfigName();
- std::string const targetOutputReal = ConvertToNinjaPath(
- genTarget->ObjectDirectory + "cmake_device_link" + objExt);
+ std::string targetOutputDir =
+ cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+ globalGen->ConfigDirectory(config), "/");
+ targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
- std::string const targetOutputImplib = ConvertToNinjaPath(
- genTarget->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+ std::string targetOutputReal =
+ ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt);
+ std::string targetOutputImplib = ConvertToNinjaPath(
+ genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+
+ if (config != fileConfig) {
+ std::string targetOutputFileConfigDir =
+ cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+ globalGen->ConfigDirectory(fileConfig), "/");
+ targetOutputFileConfigDir =
+ globalGen->ExpandCFGIntDir(targetOutputDir, fileConfig);
+ if (targetOutputDir == targetOutputFileConfigDir) {
+ return;
+ }
+
+ if (!genTarget->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ !genTarget
+ ->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ targetOutputImplib ==
+ ConvertToNinjaPath(genTarget->GetFullPath(
+ fileConfig, cmStateEnums::ImportLibraryArtifact))) {
+ return;
+ }
+ }
+
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
+ }
this->DeviceLinkObject = targetOutputReal;
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ cmGlobalNinjaGenerator::WriteDivider(this->GetCommonFileStream());
const cmStateEnums::TargetType targetType = genTarget->GetType();
- this->GetBuildFileStream() << "# Device Link build statements for "
- << cmState::GetTargetTypeName(targetType)
- << " target " << this->GetTargetName() << "\n\n";
+ this->GetCommonFileStream() << "# Device Link build statements for "
+ << cmState::GetTargetTypeName(targetType)
+ << " target " << this->GetTargetName() << "\n\n";
// Compute the comment.
- cmNinjaBuild build(this->LanguageLinkerDeviceRule());
+ cmNinjaBuild build(this->LanguageLinkerDeviceRule(config));
build.Comment =
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
@@ -584,14 +650,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// Compute outputs.
build.Outputs.push_back(targetOutputReal);
// Compute specific libraries to link with.
- build.ExplicitDeps = this->GetObjects();
- build.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+ build.ExplicitDeps = this->GetObjects(config);
+ build.ImplicitDeps =
+ this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
std::string frameworkPath;
std::string linkPath;
- std::string createRule = genTarget->GetCreateRuleVariable(
- this->TargetLinkLanguage, this->GetConfigName());
+ std::string createRule =
+ genTarget->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
const bool useWatcomQuote =
this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE");
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
@@ -605,17 +672,17 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(),
globalGen));
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
localGen.GetTargetFlags(
- linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
- vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
+ linkLineComputer.get(), config, vars["LINK_LIBRARIES"], vars["FLAGS"],
+ vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
- vars["LINK_FLAGS"] =
- cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
+ vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
- vars["MANIFESTS"] = this->GetManifests();
+ vars["MANIFESTS"] = this->GetManifests(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
@@ -624,24 +691,25 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// code between the Makefile executable and library generators.
if (targetType == cmStateEnums::EXECUTABLE) {
std::string t = vars["FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
vars["FLAGS"] = t;
} else {
std::string t = vars["ARCH_FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
vars["ARCH_FLAGS"] = t;
t.clear();
localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
- cfgName);
+ config);
vars["LANGUAGE_COMPILE_FLAGS"] = t;
}
- if (genTarget->HasSOName(cfgName)) {
+ auto const tgtNames = this->TargetNames(config);
+ if (genTarget->HasSOName(config)) {
vars["SONAME_FLAG"] =
- this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
- vars["SONAME"] = this->TargetNames.SharedObject;
+ this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config));
+ vars["SONAME"] = tgtNames.SharedObject;
if (targetType == cmStateEnums::SHARED_LIBRARY) {
std::string install_dir =
- this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
+ this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config);
if (!install_dir.empty()) {
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
install_dir, cmOutputConverter::SHELL);
@@ -649,25 +717,28 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
}
}
- if (!this->TargetNames.ImportLibrary.empty()) {
+ if (!tgtNames.ImportLibrary.empty()) {
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
}
- const std::string objPath = GetGeneratorTarget()->GetSupportDirectory();
+ const std::string objPath =
+ cmStrCat(GetGeneratorTarget()->GetSupportDirectory(),
+ globalGen->ConfigDirectory(config));
+
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
EnsureDirectoryExists(objPath);
- this->SetMsvcTargetPdbVariable(vars);
+ this->SetMsvcTargetPdbVariable(vars, config);
+ std::string& linkLibraries = vars["LINK_LIBRARIES"];
+ std::string& link_path = vars["LINK_PATH"];
if (globalGen->IsGCCOnWindows()) {
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
- std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
- std::string& link_path = vars["LINK_PATH"];
std::replace(link_path.begin(), link_path.end(), '\\', '/');
}
@@ -675,65 +746,88 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// do not check if the user has explicitly forced a response file.
int const commandLineLengthLimit =
static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
- globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule());
+ globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
genTarget->GetName() + ".rsp");
// Gather order-only dependencies.
- this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
- build.OrderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(
+ this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config);
// Write the build statement for this target.
bool usedResponseFile = false;
- globalGen->WriteBuild(this->GetBuildFileStream(), build,
+ globalGen->WriteBuild(this->GetCommonFileStream(), build,
commandLineLengthLimit, &usedResponseFile);
- this->WriteDeviceLinkRule(usedResponseFile);
+ this->WriteDeviceLinkRule(usedResponseFile, config);
}
-void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteLinkStatement(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
cmMakefile* mf = this->GetMakefile();
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
cmGeneratorTarget* gt = this->GetGeneratorTarget();
- const std::string cfgName = this->GetConfigName();
- std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(cfgName));
+ std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config));
std::string targetOutputReal = ConvertToNinjaPath(
- gt->GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+ gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
/*realname=*/true));
std::string targetOutputImplib = ConvertToNinjaPath(
- gt->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+ gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+
+ if (config != fileConfig) {
+ if (targetOutput == ConvertToNinjaPath(gt->GetFullPath(fileConfig))) {
+ return;
+ }
+ if (targetOutputReal ==
+ ConvertToNinjaPath(gt->GetFullPath(fileConfig,
+ cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true))) {
+ return;
+ }
+ if (!gt->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ !gt->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ targetOutputImplib ==
+ ConvertToNinjaPath(gt->GetFullPath(
+ fileConfig, cmStateEnums::ImportLibraryArtifact))) {
+ return;
+ }
+ }
+ auto const tgtNames = this->TargetNames(config);
if (gt->IsAppBundleOnApple()) {
// Create the app bundle
- std::string outpath = gt->GetDirectory(cfgName);
- this->OSXBundleGenerator->CreateAppBundle(this->TargetNames.Output,
- outpath);
+ std::string outpath = gt->GetDirectory(config);
+ this->OSXBundleGenerator->CreateAppBundle(tgtNames.Output, outpath,
+ config);
// Calculate the output path
- targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output);
+ targetOutput = cmStrCat(outpath, '/', tgtNames.Output);
targetOutput = this->ConvertToNinjaPath(targetOutput);
- targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real);
+ targetOutputReal = cmStrCat(outpath, '/', tgtNames.Real);
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
} else if (gt->IsFrameworkOnApple()) {
// Create the library framework.
- this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
- gt->GetDirectory(cfgName));
+ this->OSXBundleGenerator->CreateFramework(
+ tgtNames.Output, gt->GetDirectory(config), config);
} else if (gt->IsCFBundleOnApple()) {
// Create the core foundation bundle.
- this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
- gt->GetDirectory(cfgName));
+ this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
+ gt->GetDirectory(config), config);
}
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
const cmStateEnums::TargetType targetType = gt->GetType();
- this->GetBuildFileStream()
+ this->GetImplFileStream(fileConfig)
<< "# Link build statements for " << cmState::GetTargetTypeName(targetType)
<< " target " << this->GetTargetName() << "\n\n";
- cmNinjaBuild linkBuild(this->LanguageLinkerRule());
+ cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
cmNinjaVars& vars = linkBuild.Variables;
// Compute the comment.
@@ -742,11 +836,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Compute outputs.
linkBuild.Outputs.push_back(targetOutputReal);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
+ }
- if (this->TargetLinkLanguage == "Swift") {
- vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
+ if (this->TargetLinkLanguage(config) == "Swift") {
+ vars["SWIFT_LIBRARY_NAME"] = [this, config]() -> std::string {
cmGeneratorTarget::Names targetNames =
- this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+ this->GetGeneratorTarget()->GetLibraryNames(config);
return targetNames.Base;
}();
@@ -776,18 +873,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmOutputConverter::SHELL);
}(vars["SWIFT_MODULE_NAME"]);
+ const std::string map = cmStrCat(gt->GetSupportDirectory(), '/', config,
+ '/', "output-file-map.json");
vars["SWIFT_OUTPUT_FILE_MAP"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->ConvertToNinjaPath(gt->GetSupportDirectory() +
- "/output-file-map.json"),
- cmOutputConverter::SHELL);
+ this->ConvertToNinjaPath(map), cmOutputConverter::SHELL);
- vars["SWIFT_SOURCES"] = [this]() -> std::string {
+ vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
std::vector<cmSourceFile const*> sources;
std::stringstream oss;
- this->GetGeneratorTarget()->GetObjectSources(sources,
- this->GetConfigName());
+ this->GetGeneratorTarget()->GetObjectSources(sources, config);
cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
for (const auto& source : sources) {
oss << " "
@@ -801,27 +897,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Since we do not perform object builds, compute the
// defines/flags/includes here so that they can be passed along
// appropriately.
- vars["DEFINES"] = this->GetDefines("Swift");
- vars["FLAGS"] = this->GetFlags("Swift");
- vars["INCLUDES"] = this->GetIncludes("Swift");
+ vars["DEFINES"] = this->GetDefines("Swift", config);
+ vars["FLAGS"] = this->GetFlags("Swift", config);
+ vars["INCLUDES"] = this->GetIncludes("Swift", config);
}
// Compute specific libraries to link with.
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
std::vector<cmSourceFile const*> sources;
- gt->GetObjectSources(sources, this->GetConfigName());
+ gt->GetObjectSources(sources, config);
for (const auto& source : sources) {
linkBuild.Outputs.push_back(
- this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)));
linkBuild.ExplicitDeps.push_back(
this->ConvertToNinjaPath(this->GetSourceFilePath(source)));
}
linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
} else {
- linkBuild.ExplicitDeps = this->GetObjects();
+ linkBuild.ExplicitDeps = this->GetObjects(config);
}
- linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+ linkBuild.ImplicitDeps =
+ this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
if (!this->DeviceLinkObject.empty()) {
linkBuild.ExplicitDeps.push_back(this->DeviceLinkObject);
@@ -831,39 +928,42 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string linkPath;
std::string createRule =
- gt->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
+ gt->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE");
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
vars["TARGET_FILE"] =
localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
globalGen->CreateLinkLineComputer(
this->GetLocalGenerator(),
- this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
+ this->GetLocalGenerator()->GetStateSnapshot().GetDirectory());
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
- localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
+ localGen.GetTargetFlags(linkLineComputer.get(), config,
vars["LINK_LIBRARIES"], vars["FLAGS"],
vars["LINK_FLAGS"], frameworkPath, linkPath, gt);
// Add OS X version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
- this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
- "COMPATIBILITY", true);
- this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
- "CURRENT", false);
+ this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+ this->TargetLinkLanguage(config), "COMPATIBILITY",
+ true);
+ this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+ this->TargetLinkLanguage(config), "CURRENT", false);
}
this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars);
- this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
- vars["LINK_FLAGS"] =
- cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
+ config);
+ vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
- vars["MANIFESTS"] = this->GetManifests();
+ vars["MANIFESTS"] = this->GetManifests(config);
+ vars["AIX_EXPORTS"] = this->GetAIXExports(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
std::string lwyuFlags;
@@ -876,23 +976,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// code between the Makefile executable and library generators.
if (targetType == cmStateEnums::EXECUTABLE) {
std::string t = vars["FLAGS"];
- localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+ config);
t += lwyuFlags;
vars["FLAGS"] = t;
} else {
std::string t = vars["ARCH_FLAGS"];
- localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+ config);
vars["ARCH_FLAGS"] = t;
t.clear();
t += lwyuFlags;
- localGen.AddLanguageFlagsForLinking(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddLanguageFlagsForLinking(
+ t, gt, this->TargetLinkLanguage(config), config);
vars["LANGUAGE_COMPILE_FLAGS"] = t;
}
- if (gt->HasSOName(cfgName)) {
- vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
- vars["SONAME"] = this->TargetNames.SharedObject;
+ if (gt->HasSOName(config)) {
+ vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage(config));
+ vars["SONAME"] = tgtNames.SharedObject;
if (targetType == cmStateEnums::SHARED_LIBRARY) {
- std::string install_dir = gt->GetInstallNameDirForBuildTree(cfgName);
+ std::string install_dir = gt->GetInstallNameDirForBuildTree(config);
if (!install_dir.empty()) {
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
install_dir, cmOutputConverter::SHELL);
@@ -902,17 +1005,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaDeps byproducts;
- if (!this->TargetNames.ImportLibrary.empty()) {
+ if (!tgtNames.ImportLibrary.empty()) {
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
- if (gt->HasImportLibrary(cfgName)) {
+ if (gt->HasImportLibrary(config)) {
byproducts.push_back(targetOutputImplib);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(
+ targetOutputImplib);
+ }
}
}
- if (!this->SetMsvcTargetPdbVariable(vars)) {
+ if (!this->SetMsvcTargetPdbVariable(vars, config)) {
// It is common to place debug symbols at a specific place,
// so we need a plain target name in the rule available.
std::string prefix;
@@ -927,16 +1034,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
- const std::string objPath = gt->GetSupportDirectory();
+ const std::string objPath =
+ cmStrCat(gt->GetSupportDirectory(), globalGen->ConfigDirectory(config));
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
EnsureDirectoryExists(objPath);
+ std::string& linkLibraries = vars["LINK_LIBRARIES"];
+ std::string& link_path = vars["LINK_PATH"];
if (globalGen->IsGCCOnWindows()) {
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
- std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
- std::string& link_path = vars["LINK_PATH"];
std::replace(link_path.begin(), link_path.end(), '\\', '/');
}
@@ -947,23 +1055,30 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::vector<std::string> preLinkCmdLines;
std::vector<std::string> postBuildCmdLines;
- std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
- &preLinkCmdLines,
- &postBuildCmdLines };
-
- for (unsigned i = 0; i != 3; ++i) {
- for (cmCustomCommand const& cc : *cmdLists[i]) {
- cmCustomCommandGenerator ccg(cc, cfgName, this->GetLocalGenerator());
- localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
- std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
- std::transform(ccByproducts.begin(), ccByproducts.end(),
- std::back_inserter(byproducts), MapToNinjaPath());
+
+ if (config == fileConfig) {
+ std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
+ &preLinkCmdLines,
+ &postBuildCmdLines };
+
+ for (unsigned i = 0; i != 3; ++i) {
+ for (cmCustomCommand const& cc : *cmdLists[i]) {
+ cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator());
+ localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
+ std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
+ std::transform(ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(byproducts), MapToNinjaPath());
+ std::transform(
+ ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(globalGen->GetByproductsForCleanTarget()),
+ MapToNinjaPath());
+ }
}
}
// maybe create .def file from list of objects
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- gt->GetModuleDefinitionInfo(this->GetConfigName());
+ gt->GetModuleDefinitionInfo(config);
if (mdi && mdi->DefFileGenerated) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -989,7 +1104,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmGeneratedFileStream fout(obj_list_file);
if (mdi->WindowsExportAllSymbols) {
- cmNinjaDeps objs = this->GetObjects();
+ cmNinjaDeps objs = this->GetObjects(config);
for (std::string const& obj : objs) {
if (cmHasLiteralSuffix(obj, ".obj")) {
fout << obj << "\n";
@@ -1024,7 +1139,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
symlinkVars["POST_BUILD"] = postBuildCmdLine;
}
- std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+ std::string cmakeVarLang =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -1032,8 +1148,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
bool const lang_supports_response =
- !(this->TargetLinkLanguage == "RC" ||
- (this->TargetLinkLanguage == "CUDA" && !flag));
+ !(this->TargetLinkLanguage(config) == "RC" ||
+ (this->TargetLinkLanguage(config) == "CUDA" && !flag));
int commandLineLengthLimit = -1;
if (!lang_supports_response || !this->ForceResponseFile()) {
commandLineLengthLimit =
@@ -1045,18 +1161,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
gt->GetName() + ".rsp");
// Gather order-only dependencies.
- this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
+ config, fileConfig);
// Add order-only dependencies on versioning symlinks of shared libs we link.
if (!this->GeneratorTarget->IsDLLPlatform()) {
if (cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
+ this->GeneratorTarget->GetLinkInformation(config)) {
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()));
+ std::string const& lib =
+ this->ConvertToNinjaPath(item.Target->GetFullPath(config));
if (std::find(linkBuild.ImplicitDeps.begin(),
linkBuild.ImplicitDeps.end(),
lib) == linkBuild.ImplicitDeps.end()) {
@@ -1077,24 +1194,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Write the build statement for this target.
bool usedResponseFile = false;
- globalGen->WriteBuild(this->GetBuildFileStream(), linkBuild,
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), linkBuild,
commandLineLengthLimit, &usedResponseFile);
- this->WriteLinkRule(usedResponseFile);
+ this->WriteLinkRule(usedResponseFile, config);
if (symlinkNeeded) {
if (targetType == cmStateEnums::EXECUTABLE) {
cmNinjaBuild build("CMAKE_SYMLINK_EXECUTABLE");
build.Comment = "Create executable symlink " + targetOutput;
build.Outputs.push_back(targetOutput);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
+ }
build.ExplicitDeps.push_back(targetOutputReal);
build.Variables = std::move(symlinkVars);
- globalGen->WriteBuild(this->GetBuildFileStream(), build);
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
} else {
cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY");
build.Comment = "Create library symlink " + targetOutput;
std::string const soName = this->ConvertToNinjaPath(
- this->GetTargetFilePath(this->TargetNames.SharedObject));
+ this->GetTargetFilePath(tgtNames.SharedObject, config));
// If one link has to be created.
if (targetOutputReal == soName || targetOutput == soName) {
symlinkVars["SONAME"] =
@@ -1103,33 +1223,58 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
} else {
symlinkVars["SONAME"].clear();
build.Outputs.push_back(soName);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(soName);
+ }
}
build.Outputs.push_back(targetOutput);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
+ }
build.ExplicitDeps.push_back(targetOutputReal);
build.Variables = std::move(symlinkVars);
- globalGen->WriteBuild(this->GetBuildFileStream(), build);
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
}
}
// Add aliases for the file name and the target name.
- globalGen->AddTargetAlias(this->TargetNames.Output, gt);
- globalGen->AddTargetAlias(this->GetTargetName(), gt);
+ globalGen->AddTargetAlias(tgtNames.Output, gt, config);
+ globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
}
-void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
+void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
+ const std::string& config)
{
// Write a phony output that depends on all object files.
{
cmNinjaBuild build("phony");
build.Comment = "Object library " + this->GetTargetName();
this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
- build.Outputs);
- build.ExplicitDeps = this->GetObjects();
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ build.Outputs, config);
+ this->GetLocalGenerator()->AppendTargetOutputs(
+ this->GetGeneratorTarget(),
+ this->GetGlobalGenerator()->GetByproductsForCleanTarget(config), config);
+ build.ExplicitDeps = this->GetObjects(config);
+ this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build);
}
// Add aliases for the target name.
- this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
- this->GetGeneratorTarget());
+ this->GetGlobalGenerator()->AddTargetAlias(
+ this->GetTargetName(), this->GetGeneratorTarget(), config);
+}
+
+cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames(
+ const std::string& config) const
+{
+ if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+ return this->GeneratorTarget->GetExecutableNames(config);
+ }
+ return this->GeneratorTarget->GetLibraryNames(config);
+}
+
+std::string cmNinjaNormalTargetGenerator::TargetLinkLanguage(
+ const std::string& config) const
+{
+ return this->GeneratorTarget->GetLinkerLanguage(config);
}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index ebc1268232..9de99b9d5f 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -17,30 +17,33 @@ public:
cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
~cmNinjaNormalTargetGenerator() override;
- void Generate() override;
+ void Generate(const std::string& config) override;
private:
- std::string LanguageLinkerRule() const;
- std::string LanguageLinkerDeviceRule() const;
+ std::string LanguageLinkerRule(const std::string& config) const;
+ std::string LanguageLinkerDeviceRule(const std::string& config) const;
const char* GetVisibleTypeName() const;
- void WriteLanguagesRules();
+ void WriteLanguagesRules(const std::string& config);
- void WriteLinkRule(bool useResponseFile);
- void WriteDeviceLinkRule(bool useResponseFile);
+ void WriteLinkRule(bool useResponseFile, const std::string& config);
+ void WriteDeviceLinkRule(bool useResponseFile, const std::string& config);
- void WriteLinkStatement();
- void WriteDeviceLinkStatement();
+ void WriteLinkStatement(const std::string& config,
+ const std::string& fileConfig, bool firstForConfig);
+ void WriteDeviceLinkStatement(const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
- void WriteObjectLibStatement();
+ void WriteObjectLibStatement(const std::string& config);
- std::vector<std::string> ComputeLinkCmd();
+ std::vector<std::string> ComputeLinkCmd(const std::string& config);
std::vector<std::string> ComputeDeviceLinkCmd();
private:
// Target name info.
- cmGeneratorTarget::Names TargetNames;
- std::string TargetLinkLanguage;
+ cmGeneratorTarget::Names TargetNames(const std::string& config) const;
+ std::string TargetLinkLanguage(const std::string& config) const;
std::string DeviceLinkObject;
};
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 0aab9127b6..abf12f82ed 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -10,11 +10,11 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -58,19 +58,27 @@ std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
: cmCommonTargetGenerator(target)
- , MacOSXContentGenerator(nullptr)
, OSXBundleGenerator(nullptr)
, LocalGenerator(
static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator()))
{
- MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
+ for (auto const& fileConfig : target->Makefile->GetGeneratorConfigs()) {
+ this->Configs[fileConfig].MacOSXContentGenerator =
+ cm::make_unique<MacOSXContentGeneratorType>(this, fileConfig);
+ }
}
cmNinjaTargetGenerator::~cmNinjaTargetGenerator() = default;
-cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetImplFileStream(
+ const std::string& config) const
+{
+ return *this->GetGlobalGenerator()->GetImplFileStream(config);
+}
+
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetCommonFileStream() const
{
- return *this->GetGlobalGenerator()->GetBuildFileStream();
+ return *this->GetGlobalGenerator()->GetCommonFileStream();
}
cmGeneratedFileStream& cmNinjaTargetGenerator::GetRulesFileStream() const
@@ -84,17 +92,19 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
}
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
- const std::string& lang) const
+ const std::string& lang, const std::string& config) const
{
return lang + "_COMPILER__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
+ "_" + config;
}
std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
return lang + "_PREPROCESS__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
+ "_" + config;
}
bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
@@ -117,10 +127,11 @@ bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
}
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
- const std::string& lang) const
+ const std::string& lang, const std::string& config) const
{
return lang + "_DYNDEP__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
+ "_" + config;
}
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
@@ -128,9 +139,11 @@ bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
return lang == "Fortran";
}
-std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
+std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
+ const std::string& config)
{
- return "cmake_object_order_depends_target_" + this->GetTargetName();
+ return cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
+ this->GeneratorTarget, config);
}
// TODO: Most of the code is picked up from
@@ -138,10 +151,10 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// Refactor it.
std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
- cmSourceFile const* source, const std::string& language)
+ cmSourceFile const* source, const std::string& language,
+ const std::string& config)
{
- std::string flags = this->GetFlags(language);
- const std::string configName = this->LocalGenerator->GetConfigName();
+ std::string flags = this->GetFlags(language, config);
// Add Fortran format flags.
if (language == "Fortran") {
@@ -150,7 +163,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(
- this->LocalGenerator, configName, this->GeneratorTarget, language);
+ this->LocalGenerator, config, this->GeneratorTarget, language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
@@ -166,16 +179,16 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add precompile headers compile options.
const std::string pchSource =
- this->GeneratorTarget->GetPchSource(configName, language);
+ this->GeneratorTarget->GetPchSource(config, language);
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
if (source->GetFullPath() == pchSource) {
- pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
- configName, language);
+ pchOptions =
+ this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
} else {
pchOptions =
- this->GeneratorTarget->GetPchUseCompileOptions(configName, language);
+ this->GeneratorTarget->GetPchUseCompileOptions(config, language);
}
this->LocalGenerator->AppendCompileOptions(
@@ -186,16 +199,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
- std::string const& language)
+ std::string const& language,
+ const std::string& config)
{
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- language, this->GetConfigName());
+ language, config);
// Add include directory flags.
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, language,
language == "RC", // full include paths for RC needed by cmcldeps
- false, this->GetConfigName());
+ false, config);
if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/');
}
@@ -232,13 +246,18 @@ bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
// TODO: Refactor with
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
- const std::string& language)
+ const std::string& language,
+ const std::string& config)
{
std::set<std::string> defines;
- const std::string config = this->LocalGenerator->GetConfigName();
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, config, this->GeneratorTarget, language);
+ // Seriously??
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ defines.insert(cmStrCat("CMAKE_INTDIR=\"", config, '"'));
+ }
+
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
this->LocalGenerator->AppendDefines(
@@ -253,17 +272,17 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
}
- std::string definesString = this->GetDefines(language);
+ std::string definesString = this->GetDefines(language, config);
this->LocalGenerator->JoinDefines(defines, definesString, language);
return definesString;
}
std::string cmNinjaTargetGenerator::ComputeIncludes(
- cmSourceFile const* source, const std::string& language)
+ cmSourceFile const* source, const std::string& language,
+ const std::string& config)
{
std::vector<std::string> includes;
- const std::string config = this->LocalGenerator->GetConfigName();
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, config, this->GeneratorTarget, language);
@@ -277,13 +296,13 @@ std::string cmNinjaTargetGenerator::ComputeIncludes(
std::string includesString = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, language, true, false, config);
this->LocalGenerator->AppendFlags(includesString,
- this->GetIncludes(language));
+ this->GetIncludes(language, config));
return includesString;
}
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
- const std::string& linkLanguage) const
+ const std::string& linkLanguage, const std::string& config) const
{
// Static libraries never depend on other targets for linking.
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -292,7 +311,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
}
cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
+ this->GeneratorTarget->GetLinkInformation(config);
if (!cli) {
return cmNinjaDeps();
}
@@ -303,8 +322,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
// Add a dependency on the link definitions file, if any.
if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(
- this->GetConfigName())) {
+ this->GeneratorTarget->GetModuleDefinitionInfo(config)) {
for (cmSourceFile const* src : mdi->Sources) {
result.push_back(this->ConvertToNinjaPath(src->GetFullPath()));
}
@@ -312,15 +330,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
// Add a dependency on user-specified manifest files, if any.
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
for (cmSourceFile const* manifest_src : manifest_srcs) {
result.push_back(this->ConvertToNinjaPath(manifest_src->GetFullPath()));
}
// Add user-specified dependencies.
std::vector<std::string> linkDeps;
- this->GeneratorTarget->GetLinkDepends(linkDeps, this->ConfigName,
- linkLanguage);
+ this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage);
std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result),
MapToNinjaPath());
@@ -334,7 +351,7 @@ std::string cmNinjaTargetGenerator::GetSourceFilePath(
}
std::string cmNinjaTargetGenerator::GetObjectFilePath(
- cmSourceFile const* source) const
+ cmSourceFile const* source, const std::string& config) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
@@ -342,13 +359,14 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
}
std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ path += this->GetGlobalGenerator()->ConfigDirectory(config);
path += "/";
path += objectName;
return path;
}
std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
- cmSourceFile const* source) const
+ cmSourceFile const* source, const std::string& config) const
{
// Choose an extension to compile already-preprocessed source.
std::string ppExt = source->GetExtension();
@@ -378,19 +396,21 @@ std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
path += "/";
}
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ path += this->GetGlobalGenerator()->ConfigDirectory(config);
path += "/";
path += ppName;
return path;
}
std::string cmNinjaTargetGenerator::GetDyndepFilePath(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
path += "/";
}
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ path += this->GetGlobalGenerator()->ConfigDirectory(config);
path += "/";
path += lang;
path += ".dd";
@@ -398,25 +418,27 @@ std::string cmNinjaTargetGenerator::GetDyndepFilePath(
}
std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
std::string path =
cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
- '/', lang, "DependInfo.json");
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang,
+ "DependInfo.json");
return path;
}
-std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
+std::string cmNinjaTargetGenerator::GetTargetOutputDir(
+ const std::string& config) const
{
- std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ std::string dir = this->GeneratorTarget->GetDirectory(config);
return ConvertToNinjaPath(dir);
}
std::string cmNinjaTargetGenerator::GetTargetFilePath(
- const std::string& name) const
+ const std::string& name, const std::string& config) const
{
- std::string path = this->GetTargetOutputDir();
+ std::string path = this->GetTargetOutputDir(config);
if (path.empty() || path == ".") {
return name;
}
@@ -430,21 +452,21 @@ std::string cmNinjaTargetGenerator::GetTargetName() const
return this->GeneratorTarget->GetName();
}
-bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
+bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
+ cmNinjaVars& vars, const std::string& config) const
{
cmMakefile* mf = this->GetMakefile();
if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) {
std::string pdbPath;
- std::string compilePdbPath = this->ComputeTargetCompilePDB();
+ std::string compilePdbPath = this->ComputeTargetCompilePDB(config);
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
- pdbPath = cmStrCat(
- this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
- this->GeneratorTarget->GetPDBName(this->GetConfigName()));
+ pdbPath = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config), '/',
+ this->GeneratorTarget->GetPDBName(config));
}
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -460,15 +482,17 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
return false;
}
-void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language)
+void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
+ const std::string& config)
{
#ifdef NINJA_GEN_VERBOSE_FILES
this->GetRulesFileStream() << "# Rules for language " << language << "\n\n";
#endif
- this->WriteCompileRule(language);
+ this->WriteCompileRule(language, config);
}
-void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
+void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
+ const std::string& config)
{
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
@@ -509,7 +533,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(this->GetTargetDependInfoPath(lang)),
+ ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
cmLocalGenerator::SHELL);
std::string launcher;
@@ -524,7 +548,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (explicitPP) {
- cmNinjaRule rule(this->LanguagePreprocessRule(lang));
+ cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
// Explicit preprocessing always uses a depfile.
rule.DepType = ""; // no deps= for multiple outputs
rule.DepFile = "$DEP_FILE";
@@ -604,7 +628,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
if (needDyndep) {
// Write the rule for ninja dyndep file generation.
- cmNinjaRule rule(this->LanguageDyndepRule(lang));
+ cmNinjaRule rule(this->LanguageDyndepRule(lang, config));
// Command line length is almost always limited -> use response file for
// dyndep rules
rule.RspFile = "$out.rsp";
@@ -628,7 +652,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetGlobalGenerator()->AddRule(rule);
}
- cmNinjaRule rule(this->LanguageCompilerRule(lang));
+ cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
@@ -737,7 +761,13 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
}
if (tidy && *tidy) {
run_iwyu += " --tidy=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(tidy);
+ const char* driverMode = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
+ if (!(driverMode && *driverMode)) {
+ driverMode = lang == "C" ? "gcc" : "g++";
+ }
+ run_iwyu += this->GetLocalGenerator()->EscapeForShell(
+ cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
if (cpplint && *cpplint) {
run_iwyu += " --cpplint=";
@@ -788,50 +818,54 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetGlobalGenerator()->AddRule(rule);
}
-void cmNinjaTargetGenerator::WriteObjectBuildStatements()
+void cmNinjaTargetGenerator::WriteObjectBuildStatements(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
- this->GetBuildFileStream()
+ cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
+ this->GetImplFileStream(fileConfig)
<< "# Object build statements for "
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target " << this->GetTargetName() << "\n\n";
{
std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+ this->GeneratorTarget->GetCustomCommands(customCommands, config);
for (cmSourceFile const* sf : customCommands) {
cmCustomCommand const* cc = sf->GetCustomCommand();
this->GetLocalGenerator()->AddCustomCommandTarget(
cc, this->GetGeneratorTarget());
// Record the custom commands for this target. The container is used
// in WriteObjectBuildStatement when called in a loop below.
- this->CustomCommands.push_back(cc);
+ this->Configs[config].CustomCommands.push_back(cc);
}
}
{
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+ this->GeneratorTarget->GetHeaderSources(headerSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- headerSources, this->MacOSXContentGenerator.get());
+ headerSources, this->Configs[fileConfig].MacOSXContentGenerator.get(),
+ config);
}
{
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+ this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- extraSources, this->MacOSXContentGenerator.get());
+ extraSources, this->Configs[fileConfig].MacOSXContentGenerator.get(),
+ config);
}
- {
+ if (firstForConfig) {
const char* pchExtension =
GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects,
- this->ConfigName);
+ this->GeneratorTarget->GetExternalObjects(externalObjects, config);
for (cmSourceFile const* sf : externalObjects) {
- const auto objectFileName = this->GetSourceFilePath(sf);
+ auto objectFileName = this->GetGlobalGenerator()->ExpandCFGIntDir(
+ this->GetSourceFilePath(sf), config);
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
- this->Objects.push_back(objectFileName);
+ this->Configs[config].Objects.push_back(objectFileName);
}
}
}
@@ -839,19 +873,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
{
cmNinjaBuild build("phony");
build.Comment = "Order-only phony target for " + this->GetTargetName();
- build.Outputs.push_back(this->OrderDependsTargetForTarget());
+ build.Outputs.push_back(this->OrderDependsTargetForTarget(config));
cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
this->GetLocalGenerator()->AppendTargetDepends(
- this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering);
+ this->GeneratorTarget, orderOnlyDeps, config, fileConfig,
+ DependOnTargetOrdering);
// Add order-only dependencies on other files associated with the target.
- cmAppend(orderOnlyDeps, this->ExtraFiles);
+ cm::append(orderOnlyDeps, this->Configs[config].ExtraFiles);
// Add order-only dependencies on custom command outputs.
- for (cmCustomCommand const* cc : this->CustomCommands) {
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
- this->GetLocalGenerator());
+ for (cmCustomCommand const* cc : this->Configs[config].CustomCommands) {
+ cmCustomCommandGenerator ccg(*cc, config, this->GetLocalGenerator());
const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
const std::vector<std::string>& ccbyproducts = ccg.GetByproducts();
std::transform(ccoutputs.begin(), ccoutputs.end(),
@@ -877,26 +911,27 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
}
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
{
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
for (cmSourceFile const* sf : objectSources) {
- this->WriteObjectBuildStatement(sf);
+ this->WriteObjectBuildStatement(sf, config, fileConfig, firstForConfig);
}
}
- for (auto const& langDDIFiles : this->DDIFiles) {
+ for (auto const& langDDIFiles : this->Configs[config].DDIFiles) {
std::string const& language = langDDIFiles.first;
cmNinjaDeps const& ddiFiles = langDDIFiles.second;
- cmNinjaBuild build(this->LanguageDyndepRule(language));
- build.Outputs.push_back(this->GetDyndepFilePath(language));
+ cmNinjaBuild build(this->LanguageDyndepRule(language, config));
+ build.Outputs.push_back(this->GetDyndepFilePath(language, config));
build.ExplicitDeps = ddiFiles;
- this->WriteTargetDependInfo(language);
+ this->WriteTargetDependInfo(language, config);
// Make sure dyndep files for all our dependencies have already
// been generated so that the '<LANG>Modules.json' files they
@@ -907,46 +942,52 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
// refactoring the Ninja generator to generate targets in
// dependency order so that we can collect the needed information.
this->GetLocalGenerator()->AppendTargetDepends(
- this->GeneratorTarget, build.OrderOnlyDeps, DependOnTargetArtifact);
+ this->GeneratorTarget, build.OrderOnlyDeps, config, fileConfig,
+ DependOnTargetArtifact);
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
- this->GetBuildFileStream() << "\n";
+ this->GetImplFileStream(fileConfig) << "\n";
- if (!this->SwiftOutputMap.empty()) {
+ if (!this->Configs[config].SwiftOutputMap.empty()) {
std::string const mapFilePath =
- this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json";
- std::string const targetSwiftDepsPath = [this]() -> std::string {
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
+ "output-file-map.json");
+ std::string const targetSwiftDepsPath = [this, config]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
return name;
}
return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
- target->GetName() + ".swiftdeps");
+ config + "/" + target->GetName() +
+ ".swiftdeps");
}();
// build the global target dependencies
// https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
Json::Value deps(Json::objectValue);
deps["swift-dependencies"] = targetSwiftDepsPath;
- this->SwiftOutputMap[""] = deps;
+ this->Configs[config].SwiftOutputMap[""] = deps;
cmGeneratedFileStream output(mapFilePath);
- output << this->SwiftOutputMap;
+ output << this->Configs[config].SwiftOutputMap;
}
}
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
- cmSourceFile const* source)
+ cmSourceFile const* source, const std::string& config,
+ const std::string& fileConfig, bool firstForConfig)
{
std::string const language = source->GetLanguage();
std::string const sourceFileName =
language == "RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
- std::string const objectDir =
- this->ConvertToNinjaPath(this->GeneratorTarget->GetSupportDirectory());
+ std::string const objectDir = this->ConvertToNinjaPath(
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
+ this->GetGlobalGenerator()->ConfigDirectory(config)));
std::string const objectFileName =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
@@ -962,11 +1003,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
int const commandLineLengthLimit =
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
- cmNinjaBuild objBuild(this->LanguageCompilerRule(language));
+ cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
cmNinjaVars& vars = objBuild.Variables;
- vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
- vars["DEFINES"] = this->ComputeDefines(source, language);
- vars["INCLUDES"] = this->ComputeIncludes(source, language);
+ vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
+ vars["DEFINES"] = this->ComputeDefines(source, language, config);
+ vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
if (!this->NeedDepTypeMSVC(language)) {
bool replaceExt(false);
@@ -994,11 +1035,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
objBuild.Outputs.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);
+ if (firstForConfig) {
+ const char* pchExtension =
+ this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ // Add this object to the list of object files.
+ this->Configs[config].Objects.push_back(objectFileName);
+ }
}
objBuild.ExplicitDeps.push_back(sourceFileName);
@@ -1007,13 +1050,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::vector<std::string> depList;
const std::string pchSource =
- this->GeneratorTarget->GetPchSource(this->GetConfigName(), language);
+ this->GeneratorTarget->GetPchSource(config, language);
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- depList.push_back(
- this->GeneratorTarget->GetPchHeader(this->GetConfigName(), language));
+ depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
if (source->GetFullPath() != pchSource) {
- depList.push_back(
- this->GeneratorTarget->GetPchFile(this->GetConfigName(), language));
+ depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
}
}
@@ -1034,7 +1075,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
MapToNinjaPath());
}
- objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
+ objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
// If the source file is GENERATED and does not have a custom command
// (either attached to this source file or another one), assume that one of
@@ -1054,10 +1095,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(language);
if (explicitPP) {
- cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language));
+ cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
std::string const ppFileName =
- this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source));
+ this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
ppBuild.Outputs.push_back(ppFileName);
ppBuild.RspFile = ppFileName + ".rsp";
@@ -1115,7 +1156,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
sourceDirectory, this->GeneratorTarget, language, false, false,
- this->GetConfigName());
+ config);
vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
}
@@ -1139,17 +1180,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const ddiFile = objectFileName + ".ddi";
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
ppBuild.ImplicitOuts.push_back(ddiFile);
- this->DDIFiles[language].push_back(ddiFile);
+ if (firstForConfig) {
+ this->Configs[config].DDIFiles[language].push_back(ddiFile);
+ }
}
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
ppBuild.Variables);
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), ppBuild,
- commandLineLengthLimit);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ ppBuild, commandLineLengthLimit);
}
if (needDyndep) {
- std::string const dyndep = this->GetDyndepFilePath(language);
+ std::string const dyndep = this->GetDyndepFilePath(language, config);
objBuild.OrderOnlyDeps.push_back(dyndep);
vars["dyndep"] = dyndep;
}
@@ -1164,14 +1207,21 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
vars);
- this->SetMsvcTargetPdbVariable(vars);
+ if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (source->GetFullPath() == pchSource) {
+ this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
+ this->GetGeneratorTarget(), vars);
+ }
+ }
+
+ this->SetMsvcTargetPdbVariable(vars, config);
objBuild.RspFile = objectFileName + ".rsp";
if (language == "Swift") {
- this->EmitSwiftDependencyInfo(source);
+ this->EmitSwiftDependencyInfo(source, config);
} else {
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
objBuild, commandLineLengthLimit);
}
@@ -1182,11 +1232,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
}
-void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
+void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
+ const std::string& config)
{
Json::Value tdi(Json::objectValue);
tdi["language"] = lang;
@@ -1214,7 +1266,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
Json::Value& tdi_include_dirs = tdi["include-dirs"] = Json::arrayValue;
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- lang, this->GetConfigName());
+ lang, config);
for (std::string const& i : includes) {
// Convert the include directories the same way we do for -I flags.
// See upstream ninja issue 1251.
@@ -1223,22 +1275,22 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] =
Json::arrayValue;
- for (std::string const& l : this->GetLinkedTargetDirectories()) {
+ for (std::string const& l : this->GetLinkedTargetDirectories(config)) {
tdi_linked_target_dirs.append(l);
}
- std::string const tdin = this->GetTargetDependInfoPath(lang);
+ std::string const tdin = this->GetTargetDependInfoPath(lang, config);
cmGeneratedFileStream tdif(tdin);
tdif << tdi;
}
void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
- cmSourceFile const* source)
+ cmSourceFile const* source, const std::string& config)
{
std::string const sourceFilePath =
this->ConvertToNinjaPath(this->GetSourceFilePath(source));
std::string const objectFilePath =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
return name;
@@ -1251,10 +1303,10 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
}
return objectFilePath + ".dia";
}();
- std::string const makeDepsPath = [this, source]() -> std::string {
+ std::string const makeDepsPath = [this, source, config]() -> std::string {
cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
std::string const objectFileName =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
@@ -1275,7 +1327,7 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
entry["dependencies"] = makeDepsPath;
entry["swift-dependencies"] = swiftDepsPath;
entry["diagnostics"] = swiftDiaPath;
- SwiftOutputMap[sourceFilePath] = entry;
+ this->Configs[config].SwiftOutputMap[sourceFilePath] = entry;
}
void cmNinjaTargetGenerator::ExportObjectCompileCommand(
@@ -1350,27 +1402,34 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
}
-void cmNinjaTargetGenerator::AdditionalCleanFiles()
+void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
{
if (const char* prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
std::vector<std::string> cleanFiles;
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, lg,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
- this->GeneratorTarget),
+ cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
+ this->GeneratorTarget),
cleanFiles);
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
for (std::string const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
- cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
+ cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
}
}
}
+cmNinjaDeps cmNinjaTargetGenerator::GetObjects(const std::string& config) const
+{
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end()) {
+ return it->second.Objects;
+ }
+ return {};
+}
+
void cmNinjaTargetGenerator::EnsureDirectoryExists(
const std::string& path) const
{
@@ -1393,7 +1452,7 @@ void cmNinjaTargetGenerator::EnsureParentDirectoryExists(
}
void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile const& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc, const std::string& config)
{
// Skip OS X content when not building a Framework or Bundle.
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -1401,7 +1460,18 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
}
std::string macdir =
- this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+ config);
+
+ // Reject files that collide with files from the Ninja file's native config.
+ if (config != this->FileConfig) {
+ std::string nativeMacdir =
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(
+ pkgloc, this->FileConfig);
+ if (macdir == nativeMacdir) {
+ return;
+ }
+ }
// Get the input file location.
std::string input = source.GetFullPath();
@@ -1413,11 +1483,11 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
output = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
// Write a build statement to copy the content into the bundle.
- this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
- output);
+ this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(
+ input, output, this->FileConfig);
// Add as a dependency to the target so that it gets called.
- this->Generator->ExtraFiles.push_back(std::move(output));
+ this->Generator->Configs[config].ExtraFiles.push_back(std::move(output));
}
void cmNinjaTargetGenerator::addPoolNinjaVariable(
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4627bcdc6f..8678dc3f66 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "cm_jsoncpp_value.h"
@@ -38,16 +39,17 @@ public:
/// Destructor.
~cmNinjaTargetGenerator() override;
- virtual void Generate() = 0;
+ virtual void Generate(const std::string& config) = 0;
std::string GetTargetName() const;
bool NeedDepTypeMSVC(const std::string& lang) const;
protected:
- bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;
+ bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
- cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
+ cmGeneratedFileStream& GetCommonFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
cmGeneratorTarget* GetGeneratorTarget() const
@@ -64,15 +66,18 @@ protected:
cmMakefile* GetMakefile() const { return this->Makefile; }
- std::string LanguageCompilerRule(const std::string& lang) const;
- std::string LanguagePreprocessRule(std::string const& lang) const;
+ std::string LanguageCompilerRule(const std::string& lang,
+ const std::string& config) const;
+ std::string LanguagePreprocessRule(std::string const& lang,
+ const std::string& config) const;
bool NeedExplicitPreprocessing(std::string const& lang) const;
- std::string LanguageDyndepRule(std::string const& lang) const;
+ std::string LanguageDyndepRule(std::string const& lang,
+ const std::string& config) const;
bool NeedDyndep(std::string const& lang) const;
bool UsePreprocessedSource(std::string const& lang) const;
bool CompilePreprocessedSourceWithDefines(std::string const& lang) const;
- std::string OrderDependsTargetForTarget();
+ std::string OrderDependsTargetForTarget(const std::string& config);
std::string ComputeOrderDependsForTarget();
@@ -82,15 +87,19 @@ protected:
* by LanguageFlagsVarName().
*/
std::string ComputeFlagsForObject(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
- void AddIncludeFlags(std::string& flags, std::string const& lang) override;
+ void AddIncludeFlags(std::string& flags, std::string const& lang,
+ const std::string& config) override;
std::string ComputeDefines(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
std::string ComputeIncludes(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
std::string ConvertToNinjaPath(const std::string& path) const
{
@@ -102,36 +111,51 @@ protected:
}
/// @return the list of link dependency for the given target @a target.
- cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage) const;
+ cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage,
+ const std::string& config) const;
/// @return the source file path for the given @a source.
std::string GetSourceFilePath(cmSourceFile const* source) const;
/// @return the object file path for the given @a source.
- std::string GetObjectFilePath(cmSourceFile const* source) const;
+ std::string GetObjectFilePath(cmSourceFile const* source,
+ const std::string& config) const;
/// @return the preprocessed source file path for the given @a source.
- std::string GetPreprocessedFilePath(cmSourceFile const* source) const;
+ std::string GetPreprocessedFilePath(cmSourceFile const* source,
+ const std::string& config) const;
/// @return the dyndep file path for this target.
- std::string GetDyndepFilePath(std::string const& lang) const;
+ std::string GetDyndepFilePath(std::string const& lang,
+ const std::string& config) const;
/// @return the target dependency scanner info file path
- std::string GetTargetDependInfoPath(std::string const& lang) const;
+ std::string GetTargetDependInfoPath(std::string const& lang,
+ const std::string& config) const;
/// @return the file path where the target named @a name is generated.
- std::string GetTargetFilePath(const std::string& name) const;
+ std::string GetTargetFilePath(const std::string& name,
+ const std::string& config) const;
/// @return the output path for the target.
- virtual std::string GetTargetOutputDir() const;
-
- void WriteLanguageRules(const std::string& language);
- void WriteCompileRule(const std::string& language);
- void WriteObjectBuildStatements();
- void WriteObjectBuildStatement(cmSourceFile const* source);
- void WriteTargetDependInfo(std::string const& lang);
-
- void EmitSwiftDependencyInfo(cmSourceFile const* source);
+ virtual std::string GetTargetOutputDir(const std::string& config) const;
+
+ void WriteLanguageRules(const std::string& language,
+ const std::string& config);
+ void WriteCompileRule(const std::string& language,
+ const std::string& config);
+ void WriteObjectBuildStatements(const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
+ void WriteObjectBuildStatement(cmSourceFile const* source,
+ const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
+ void WriteTargetDependInfo(std::string const& lang,
+ const std::string& config);
+
+ void EmitSwiftDependencyInfo(cmSourceFile const* source,
+ const std::string& config);
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
@@ -139,9 +163,9 @@ protected:
std::string const& objectFileDir, std::string const& flags,
std::string const& defines, std::string const& includes);
- void AdditionalCleanFiles();
+ void AdditionalCleanFiles(const std::string& config);
- cmNinjaDeps GetObjects() const { return this->Objects; }
+ cmNinjaDeps GetObjects(const std::string& config) const;
void EnsureDirectoryExists(const std::string& dir) const;
void EnsureParentDirectoryExists(const std::string& path) const;
@@ -150,19 +174,22 @@ protected:
struct MacOSXContentGeneratorType
: cmOSXBundleGenerator::MacOSXContentGeneratorType
{
- MacOSXContentGeneratorType(cmNinjaTargetGenerator* g)
+ MacOSXContentGeneratorType(cmNinjaTargetGenerator* g,
+ std::string fileConfig)
: Generator(g)
+ , FileConfig(std::move(fileConfig))
{
}
- void operator()(cmSourceFile const& source, const char* pkgloc) override;
+ void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) override;
private:
cmNinjaTargetGenerator* Generator;
+ std::string FileConfig;
};
friend struct MacOSXContentGeneratorType;
- std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
// Properly initialized by sub-classes.
std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
std::set<std::string> MacContentFolders;
@@ -174,14 +201,21 @@ protected:
private:
cmLocalNinjaGenerator* LocalGenerator;
- /// List of object files for this target.
- cmNinjaDeps Objects;
- // Fortran Support
- std::map<std::string, cmNinjaDeps> DDIFiles;
- // Swift Support
- Json::Value SwiftOutputMap;
- std::vector<cmCustomCommand const*> CustomCommands;
- cmNinjaDeps ExtraFiles;
+
+ struct ByConfig
+ {
+ /// List of object files for this target.
+ cmNinjaDeps Objects;
+ // Fortran Support
+ std::map<std::string, cmNinjaDeps> DDIFiles;
+ // Swift Support
+ Json::Value SwiftOutputMap;
+ std::vector<cmCustomCommand const*> CustomCommands;
+ cmNinjaDeps ExtraFiles;
+ std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
+ };
+
+ std::map<std::string, ByConfig> Configs;
};
#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 5259037bfd..a42d65d3de 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -15,13 +15,13 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmLocalNinjaGenerator.h"
-#include "cmMakefile.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmGeneratorTarget* target)
@@ -31,14 +31,18 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default;
-void cmNinjaUtilityTargetGenerator::Generate()
+void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
{
cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
+ std::string configDir;
+ if (genTarget->Target->IsPerConfig()) {
+ configDir = gg->ConfigDirectory(config);
+ }
std::string utilCommandName =
- cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/",
this->GetTargetName(), ".util");
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
@@ -55,8 +59,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
for (std::vector<cmCustomCommand> const* cmdList : cmdLists) {
for (cmCustomCommand const& ci : *cmdList) {
- cmCustomCommandGenerator ccg(ci, this->GetConfigName(), lg);
- lg->AppendCustomCommandDeps(ccg, deps);
+ cmCustomCommandGenerator ccg(ci, config, lg);
+ lg->AppendCustomCommandDeps(ccg, deps, config);
lg->AppendCustomCommandLines(ccg, commands);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -69,13 +73,11 @@ void cmNinjaUtilityTargetGenerator::Generate()
}
{
- std::string const& config =
- this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::vector<cmSourceFile*> sources;
genTarget->GetSourceFiles(sources, config);
for (cmSourceFile const* source : sources) {
if (cmCustomCommand const* cc = source->GetCustomCommand()) {
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), lg);
+ cmCustomCommandGenerator ccg(*cc, config, lg);
lg->AddCustomCommandTarget(cc, genTarget);
// Depend on all custom command outputs.
@@ -89,13 +91,21 @@ void cmNinjaUtilityTargetGenerator::Generate()
}
}
- lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs);
- lg->AppendTargetDepends(genTarget, deps);
+ std::string outputConfig;
+ if (genTarget->Target->IsPerConfig()) {
+ outputConfig = config;
+ }
+ lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs, outputConfig);
+ if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
+ config);
+ }
+ lg->AppendTargetDepends(genTarget, deps, config, config);
if (commands.empty()) {
phonyBuild.Comment = "Utility command for " + this->GetTargetName();
phonyBuild.ExplicitDeps = std::move(deps);
- gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
} else {
std::string command =
lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
@@ -118,6 +128,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
cmOutputConverter::SHELL));
cmSystemTools::ReplaceString(command, "$(ARGS)", "");
+ command = gg->ExpandCFGIntDir(command, config);
if (command.find('$') != std::string::npos) {
return;
@@ -127,22 +138,32 @@ void cmNinjaUtilityTargetGenerator::Generate()
gg->SeenCustomCommandOutput(util_output);
}
+ std::string ccConfig;
+ if (genTarget->Target->IsPerConfig() &&
+ genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ ccConfig = config;
+ }
gg->WriteCustomCommandBuild(command, desc,
"Utility command for " + this->GetTargetName(),
/*depfile*/ "", /*job_pool*/ "", uses_terminal,
- /*restat*/ true, util_outputs, deps);
+ /*restat*/ true, util_outputs, ccConfig, deps);
phonyBuild.ExplicitDeps.push_back(utilCommandName);
- gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
}
// Find ADDITIONAL_CLEAN_FILES
- this->AdditionalCleanFiles();
+ this->AdditionalCleanFiles(config);
// Add an alias for the logical target name regardless of what directory
// contains it. Skip this for GLOBAL_TARGET because they are meant to
// be per-directory and have one at the top-level anyway.
if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
- gg->AddTargetAlias(this->GetTargetName(), genTarget);
+ gg->AddTargetAlias(this->GetTargetName(), genTarget, config);
+ } else if (gg->IsMultiConfig() && genTarget->Target->IsPerConfig()) {
+ cmNinjaBuild phonyAlias("phony");
+ gg->AppendTargetOutputs(genTarget, phonyAlias.Outputs, "");
+ phonyAlias.ExplicitDeps = phonyBuild.Outputs;
+ gg->WriteBuild(this->GetImplFileStream(config), phonyAlias);
}
}
diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
index 01cc4595fe..ca3f0a4648 100644
--- a/Source/cmNinjaUtilityTargetGenerator.h
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmNinjaTargetGenerator.h"
class cmGeneratorTarget;
@@ -15,7 +17,7 @@ public:
cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
~cmNinjaUtilityTargetGenerator() override;
- void Generate() override;
+ void Generate(const std::string& config) override;
};
#endif // ! cmNinjaUtilityTargetGenerator_h
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index a6f4e512ea..382b563e20 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -3,7 +3,6 @@
#include "cmOSXBundleGenerator.h"
#include <cassert>
-#include <utility>
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -15,12 +14,10 @@
class cmSourceFile;
-cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
- std::string configName)
+cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target)
: GT(target)
, Makefile(target->Target->GetMakefile())
, LocalGenerator(target->GetLocalGenerator())
- , ConfigName(std::move(configName))
, MacContentFolders(nullptr)
{
if (this->MustSkip()) {
@@ -34,34 +31,34 @@ bool cmOSXBundleGenerator::MustSkip()
}
void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
- std::string& outpath)
+ std::string& outpath,
+ const std::string& config)
{
if (this->MustSkip()) {
return;
}
// Compute bundle directory names.
- std::string out =
- cmStrCat(outpath, '/',
- this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel));
+ std::string out = cmStrCat(
+ outpath, '/',
+ this->GT->GetAppBundleDirectory(config, 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 =
- cmStrCat(outpath, '/',
- this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- "/Info.plist");
+ std::string plist = cmStrCat(
+ outpath, '/',
+ this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
this->Makefile->AddCMakeOutputFile(plist);
outpath = out;
}
void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
- const std::string& outpath)
+ const std::string& outpath,
+ const std::string& config)
{
if (this->MustSkip()) {
return;
@@ -70,15 +67,13 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
assert(this->MacContentFolders);
// Compute the location of the top-level foo.framework directory.
- std::string contentdir =
- cmStrCat(outpath, '/',
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- '/');
+ std::string contentdir = cmStrCat(
+ outpath, '/',
+ this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::ContentLevel),
+ '/');
std::string newoutpath = outpath + "/" +
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
+ this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::FullLevel);
std::string frameworkVersion = this->GT->GetFrameworkVersion();
@@ -156,27 +151,26 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
}
void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
- const std::string& root)
+ const std::string& root,
+ const std::string& config)
{
if (this->MustSkip()) {
return;
}
// Compute bundle directory names.
- std::string out =
- cmStrCat(root, '/',
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel));
+ std::string out = cmStrCat(
+ root, '/',
+ this->GT->GetCFBundleDirectory(config, 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 =
- cmStrCat(root, '/',
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- "/Info.plist");
+ std::string plist = cmStrCat(
+ root, '/',
+ this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
std::string name = cmSystemTools::GetFilenameName(targetName);
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
this->Makefile->AddCMakeOutputFile(plist);
@@ -184,7 +178,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
std::vector<cmSourceFile const*> const& sources,
- MacOSXContentGeneratorType* generator)
+ MacOSXContentGeneratorType* generator, const std::string& config)
{
if (this->MustSkip()) {
return;
@@ -194,20 +188,19 @@ void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
cmGeneratorTarget::SourceFileFlags tsFlags =
this->GT->GetTargetSourceFileFlags(source);
if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
- (*generator)(*source, tsFlags.MacFolder);
+ (*generator)(*source, tsFlags.MacFolder, config);
}
}
}
std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
- const char* pkgloc)
+ const char* pkgloc, const std::string& config)
{
// Construct the full path to the content subdirectory.
- std::string macdir =
- cmStrCat(this->GT->GetMacContentDirectory(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact),
- '/', pkgloc);
+ std::string macdir = cmStrCat(this->GT->GetMacContentDirectory(
+ config, cmStateEnums::RuntimeBinaryArtifact),
+ '/', pkgloc);
cmSystemTools::MakeDirectory(macdir);
// Record use of this content location. Only the first level
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 3dea6cc8a8..232be48834 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -17,29 +17,33 @@ class cmSourceFile;
class cmOSXBundleGenerator
{
public:
- cmOSXBundleGenerator(cmGeneratorTarget* target, std::string configName);
+ cmOSXBundleGenerator(cmGeneratorTarget* target);
// create an app bundle at a given root, and return
// the directory within the bundle that contains the executable
- void CreateAppBundle(const std::string& targetName, std::string& root);
+ void CreateAppBundle(const std::string& targetName, std::string& root,
+ const std::string& config);
// create a framework at a given root
- void CreateFramework(const std::string& targetName, const std::string& root);
+ void CreateFramework(const std::string& targetName, const std::string& root,
+ const std::string& config);
// create a cf bundle at a given root
- void CreateCFBundle(const std::string& targetName, const std::string& root);
+ void CreateCFBundle(const std::string& targetName, const std::string& root,
+ const std::string& config);
struct MacOSXContentGeneratorType
{
virtual ~MacOSXContentGeneratorType() = default;
- virtual void operator()(cmSourceFile const& source,
- const char* pkgloc) = 0;
+ virtual void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) = 0;
};
void GenerateMacOSXContentStatements(
std::vector<cmSourceFile const*> const& sources,
- MacOSXContentGeneratorType* generator);
- std::string InitMacOSXContentDirectory(const char* pkgloc);
+ MacOSXContentGeneratorType* generator, const std::string& config);
+ std::string InitMacOSXContentDirectory(const char* pkgloc,
+ const std::string& config);
void SetMacContentFolders(std::set<std::string>* macContentFolders)
{
@@ -53,7 +57,6 @@ private:
cmGeneratorTarget* GT;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
- std::string ConfigName;
std::set<std::string>* MacContentFolders;
};
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 073222cd80..0369af0021 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -8,7 +8,9 @@
#include <sstream>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmMessageType.h"
@@ -248,11 +250,7 @@ cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
this->Computed = false;
}
-cmOrderDirectories::~cmOrderDirectories()
-{
- cmDeleteAll(this->ConstraintEntries);
- cmDeleteAll(this->ImplicitDirEntries);
-}
+cmOrderDirectories::~cmOrderDirectories() = default;
std::vector<std::string> const& cmOrderDirectories::GetOrderedDirectories()
{
@@ -286,14 +284,16 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
- new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ cm::make_unique<cmOrderDirectoriesConstraintSOName>(this, fullPath,
+ soname));
return;
}
}
// Construct the runtime information entry for this library.
this->ConstraintEntries.push_back(
- new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ cm::make_unique<cmOrderDirectoriesConstraintSOName>(this, fullPath,
+ soname));
} else {
// This can happen if the same library is linked multiple times.
// In that case the runtime information check need be done only
@@ -314,27 +314,28 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
- new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ cm::make_unique<cmOrderDirectoriesConstraintLibrary>(this,
+ fullPath));
return;
}
}
// Construct the link library entry.
this->ConstraintEntries.push_back(
- new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ cm::make_unique<cmOrderDirectoriesConstraintLibrary>(this, fullPath));
}
}
void cmOrderDirectories::AddUserDirectories(
std::vector<std::string> const& extra)
{
- cmAppend(this->UserDirectories, extra);
+ cm::append(this->UserDirectories, extra);
}
void cmOrderDirectories::AddLanguageDirectories(
std::vector<std::string> const& dirs)
{
- cmAppend(this->LanguageDirectories, dirs);
+ cm::append(this->LanguageDirectories, dirs);
}
void cmOrderDirectories::SetImplicitDirectories(
@@ -369,7 +370,7 @@ void cmOrderDirectories::CollectOriginalDirectories()
this->AddOriginalDirectories(this->UserDirectories);
// Add directories containing constraints.
- for (cmOrderDirectoriesConstraint* entry : this->ConstraintEntries) {
+ for (const auto& entry : this->ConstraintEntries) {
entry->AddDirectory();
}
@@ -454,7 +455,7 @@ void cmOrderDirectories::FindImplicitConflicts()
// Check for items in implicit link directories that have conflicts
// in the explicit directories.
std::ostringstream conflicts;
- for (cmOrderDirectoriesConstraint* entry : this->ImplicitDirEntries) {
+ for (const auto& entry : this->ImplicitDirEntries) {
entry->FindImplicitConflicts(conflicts);
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 23c5145009..8ce53e075c 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -46,8 +47,9 @@ private:
std::vector<std::string> OrderedDirectories;
- std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
- std::vector<cmOrderDirectoriesConstraint*> ImplicitDirEntries;
+ std::vector<std::unique_ptr<cmOrderDirectoriesConstraint>> ConstraintEntries;
+ std::vector<std::unique_ptr<cmOrderDirectoriesConstraint>>
+ ImplicitDirEntries;
std::vector<std::string> UserDirectories;
std::vector<std::string> LanguageDirectories;
cmsys::RegularExpression RemoveLibraryExtension;
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index e602a6d0ab..1c6fad1482 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -43,9 +43,10 @@ std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
{
std::string result(source);
// Convert it to an output path.
- if (output == SHELL || output == WATCOMQUOTE) {
+ if (output == SHELL || output == WATCOMQUOTE || output == NINJAMULTI) {
result = this->ConvertDirectorySeparatorsForShell(source);
- result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
+ result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE,
+ output == NINJAMULTI);
} else if (output == RESPONSE) {
result = this->EscapeForShell(result, false, false, false);
}
@@ -79,9 +80,9 @@ static bool cmOutputConverterIsShellOperator(cm::string_view str)
return (shellOperators.count(str) != 0);
}
-std::string cmOutputConverter::EscapeForShell(cm::string_view str,
- bool makeVars, bool forEcho,
- bool useWatcomQuote) const
+std::string cmOutputConverter::EscapeForShell(
+ cm::string_view str, bool makeVars, bool forEcho, bool useWatcomQuote,
+ bool unescapeNinjaConfiguration) const
{
// Do not escape shell operators.
if (cmOutputConverterIsShellOperator(str)) {
@@ -95,6 +96,9 @@ std::string cmOutputConverter::EscapeForShell(cm::string_view str,
} else if (!this->LinkScriptShell) {
flags |= Shell_Flag_Make;
}
+ if (unescapeNinjaConfiguration) {
+ flags |= Shell_Flag_UnescapeNinjaConfiguration;
+ }
if (makeVars) {
flags |= Shell_Flag_AllowMakeVariables;
}
@@ -511,5 +515,14 @@ std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
}
}
+ if (flags & Shell_Flag_UnescapeNinjaConfiguration) {
+ std::string ninjaConfigReplace;
+ if (flags & Shell_Flag_IsUnix) {
+ ninjaConfigReplace += '\\';
+ }
+ ninjaConfigReplace += "$${CONFIGURATION}";
+ cmSystemTools::ReplaceString(out, ninjaConfigReplace, "${CONFIGURATION}");
+ }
+
return out;
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 349a069d61..6583ab5cb9 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -22,6 +22,7 @@ public:
{
SHELL,
WATCOMQUOTE,
+ NINJAMULTI,
RESPONSE
};
std::string ConvertToOutputFormat(cm::string_view source,
@@ -70,12 +71,14 @@ public:
/** The target shell quoting uses extra single Quotes for Watcom tools. */
Shell_Flag_WatcomQuote = (1 << 7),
- Shell_Flag_IsUnix = (1 << 8)
+ Shell_Flag_IsUnix = (1 << 8),
+
+ Shell_Flag_UnescapeNinjaConfiguration = (1 << 9),
};
std::string EscapeForShell(cm::string_view str, bool makeVars = false,
- bool forEcho = false,
- bool useWatcomQuote = false) const;
+ bool forEcho = false, bool useWatcomQuote = false,
+ bool unescapeNinjaConfiguration = false) const;
static std::string EscapeForCMake(cm::string_view str);
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index e093be019c..147f97f731 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -7,10 +7,11 @@
#include <set>
#include <utility>
+#include <cm/memory>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
@@ -94,7 +95,7 @@ public:
/**
* Destructor.
*/
- ~cmLBDepend() { cmDeleteAll(this->DependInformationMap); }
+ ~cmLBDepend() = default;
cmLBDepend(const cmLBDepend&) = delete;
cmLBDepend& operator=(const cmLBDepend&) = delete;
@@ -152,9 +153,9 @@ public:
* Generate dependencies for the file given. Returns a pointer to
* the cmDependInformation object for the file.
*/
- const cmDependInformation* FindDependencies(const char* file)
+ const cmDependInformation* FindDependencies(const std::string& file)
{
- cmDependInformation* info = this->GetDependInformation(file, nullptr);
+ cmDependInformation* info = this->GetDependInformation(file, "");
this->GenerateDependInformation(info);
return info;
}
@@ -203,7 +204,7 @@ protected:
}
// Add this file and all its dependencies.
- this->AddDependency(info, includeFile.c_str());
+ this->AddDependency(info, includeFile);
/// add the cxx file if it exists
std::string cxxFile = includeFile;
std::string::size_type pos = cxxFile.rfind('.');
@@ -254,7 +255,7 @@ protected:
}
}
if (found) {
- this->AddDependency(info, cxxFile.c_str());
+ this->AddDependency(info, cxxFile);
}
}
}
@@ -264,10 +265,10 @@ protected:
/**
* Add a dependency. Possibly walk it for more dependencies.
*/
- void AddDependency(cmDependInformation* info, const char* file)
+ void AddDependency(cmDependInformation* info, const std::string& file)
{
cmDependInformation* dependInfo =
- this->GetDependInformation(file, info->PathOnly.c_str());
+ this->GetDependInformation(file, info->PathOnly);
this->GenerateDependInformation(dependInfo);
info->AddDependencies(dependInfo);
}
@@ -313,7 +314,7 @@ protected:
// Dependency hints have been given. Use them to begin the
// recursion.
for (std::string const& file : cFile.GetDepends()) {
- this->AddDependency(info, file.c_str());
+ this->AddDependency(info, file);
}
// Found dependency information. We are done.
@@ -361,8 +362,8 @@ protected:
* Get an instance of cmDependInformation corresponding to the given file
* name.
*/
- cmDependInformation* GetDependInformation(const char* file,
- const char* extraPath)
+ cmDependInformation* GetDependInformation(const std::string& file,
+ const std::string& extraPath)
{
// Get the full path for the file so that lookup is unambiguous.
std::string fullPath = this->FullPath(file, extraPath);
@@ -371,15 +372,16 @@ protected:
auto result = this->DependInformationMap.find(fullPath);
if (result != this->DependInformationMap.end()) {
// Found an instance, return it.
- return result->second;
+ return result->second.get();
}
// Didn't find an instance. Create a new one and save it.
- cmDependInformation* info = new cmDependInformation;
+ auto info = cm::make_unique<cmDependInformation>();
+ auto ptr = info.get();
info->FullPath = fullPath;
info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
info->IncludeName = file;
- this->DependInformationMap[fullPath] = info;
- return info;
+ this->DependInformationMap[fullPath] = std::move(info);
+ return ptr;
}
/**
@@ -387,14 +389,9 @@ protected:
* This uses the include directories.
* TODO: Cache path conversions to reduce FileExists calls.
*/
- std::string FullPath(const char* fname, const char* extraPath)
+ std::string FullPath(const std::string& fname, const std::string& extraPath)
{
- DirectoryToFileToPathMapType::iterator m;
- if (extraPath) {
- m = this->DirectoryToFileToPathMap.find(extraPath);
- } else {
- m = this->DirectoryToFileToPathMap.find("");
- }
+ auto m = this->DirectoryToFileToPathMap.find(extraPath);
if (m != this->DirectoryToFileToPathMap.end()) {
FileToPathMapType& map = m->second;
@@ -406,7 +403,7 @@ protected:
if (cmSystemTools::FileExists(fname, true)) {
std::string fp = cmSystemTools::CollapseFullPath(fname);
- this->DirectoryToFileToPathMap[extraPath ? extraPath : ""][fname] = fp;
+ this->DirectoryToFileToPathMap[extraPath][fname] = fp;
return fp;
}
@@ -418,12 +415,12 @@ protected:
if (cmSystemTools::FileExists(path, true) &&
!cmSystemTools::FileIsDirectory(path)) {
std::string fp = cmSystemTools::CollapseFullPath(path);
- this->DirectoryToFileToPathMap[extraPath ? extraPath : ""][fname] = fp;
+ this->DirectoryToFileToPathMap[extraPath][fname] = fp;
return fp;
}
}
- if (extraPath) {
+ if (!extraPath.empty()) {
std::string path = extraPath;
if (!path.empty() && path.back() != '/') {
path = path + "/";
@@ -438,7 +435,7 @@ protected:
}
// Couldn't find the file.
- return std::string(fname);
+ return fname;
}
cmMakefile* Makefile;
@@ -449,7 +446,8 @@ protected:
using FileToPathMapType = std::map<std::string, std::string>;
using DirectoryToFileToPathMapType =
std::map<std::string, FileToPathMapType>;
- using DependInformationMapType = std::map<std::string, cmDependInformation*>;
+ using DependInformationMapType =
+ std::map<std::string, std::unique_ptr<cmDependInformation>>;
DependInformationMapType DependInformationMap;
DirectoryToFileToPathMapType DirectoryToFileToPathMap;
};
@@ -476,7 +474,7 @@ bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
md.SetMakefile(&status.GetMakefile());
md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory());
// find the depends for a file
- const cmDependInformation* info = md.FindDependencies(file.c_str());
+ const cmDependInformation* info = md.FindDependencies(file);
if (info) {
// write them out
FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w");
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 92c80bb4c1..1366ff089b 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -290,7 +290,22 @@ class cmMakefile;
SELECT(POLICY, CMP0097, \
"ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \
"submodules.", \
- 3, 16, 0, cmPolicies::WARN)
+ 3, 16, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0098, \
+ "FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0099, \
+ "Link properties are transitive over private dependency on static " \
+ "libraries.", \
+ 3, 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0101, \
+ "target_compile_options honors BEFORE keyword in all scopes.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0102, \
+ "mark_as_advanced() does nothing if a cache entry does not exist.", \
+ 3, 17, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -319,7 +334,8 @@ class cmMakefile;
F(CMP0076) \
F(CMP0081) \
F(CMP0083) \
- F(CMP0095)
+ F(CMP0095) \
+ F(CMP0099)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 7bb5209da0..a25fd42d10 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -39,6 +39,11 @@ bool cmProjectCommand(std::vector<std::string> const& args,
std::string const& projectName = args[0];
+ if (!IncludeByVariable(status,
+ "CMAKE_PROJECT_" + projectName + "_INCLUDE_BEFORE")) {
+ return false;
+ }
+
mf.SetProjectName(projectName);
mf.AddCacheDefinition(projectName + "_BINARY_DIR",
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index a3d49460b3..d4b35523fe 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -20,11 +20,11 @@ void cmPropertyMap::SetProperty(const std::string& name, const char* value)
Map_[name] = value;
}
-void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
- bool asString)
+void cmPropertyMap::AppendProperty(const std::string& name,
+ const std::string& value, bool asString)
{
// Skip if nothing to append.
- if (!value || !*value) {
+ if (value.empty()) {
return;
}
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 9aed34960e..bea4372843 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -27,7 +27,7 @@ public:
void SetProperty(const std::string& name, const char* value);
//! Append to the property value
- void AppendProperty(const std::string& name, const char* value,
+ void AppendProperty(const std::string& name, const std::string& value,
bool asString = false);
//! Get the property value
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index eb7c900c3d..d5891c4470 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -8,6 +8,8 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -67,7 +69,7 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Append options
- cmAppend(baseOpts, extraOpts);
+ cm::append(baseOpts, extraOpts);
}
// - Class definitions
@@ -328,7 +330,7 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
{
std::vector<std::string> cmd;
cmd.emplace_back(this->RccExcutable_);
- cmAppend(cmd, this->ListOptions_);
+ cm::append(cmd, this->ListOptions_);
cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile));
// Log command
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index ef6b886364..7a6cb4219e 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -7,7 +7,6 @@
#include <cm/memory>
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmDuration.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -41,9 +40,9 @@ cmQtAutoGenGlobalInitializer::Keywords::Keywords()
}
cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
- std::vector<cmLocalGenerator*> const& localGenerators)
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators)
{
- for (cmLocalGenerator* localGen : localGenerators) {
+ for (const auto& localGen : localGenerators) {
// Detect global autogen and autorcc target names
bool globalAutoGenTarget = false;
bool globalAutoRccTarget = false;
@@ -56,7 +55,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autogen";
}
- GlobalAutoGenTargets_.emplace(localGen, std::move(targetName));
+ GlobalAutoGenTargets_.emplace(localGen.get(), std::move(targetName));
globalAutoGenTarget = true;
}
@@ -67,13 +66,13 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autorcc";
}
- GlobalAutoRccTargets_.emplace(localGen, std::move(targetName));
+ GlobalAutoRccTargets_.emplace(localGen.get(), std::move(targetName));
globalAutoRccTarget = true;
}
}
// Find targets that require AUTOMOC/UIC/RCC processing
- for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ for (const auto& target : localGen->GetGeneratorTargets()) {
// Process only certain target types
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
@@ -104,7 +103,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
target->GetSafeProperty(kw().AUTORCC_EXECUTABLE);
// We support Qt4, Qt5 and Qt6
- auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
+ auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get());
bool const validQt = (qtVersion.first.Major == 4) ||
(qtVersion.first.Major == 5) || (qtVersion.first.Major == 6);
@@ -135,8 +134,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (mocIsValid || uicIsValid || rccIsValid) {
// Create autogen target initializer
Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- this, target, qtVersion.first, mocIsValid, uicIsValid, rccIsValid,
- globalAutoGenTarget, globalAutoRccTarget));
+ this, target.get(), qtVersion.first, mocIsValid, uicIsValid,
+ rccIsValid, globalAutoGenTarget, globalAutoRccTarget));
}
}
}
@@ -154,13 +153,14 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
cmMakefile* makefile = localGen->GetMakefile();
// Create utility target
- cmTarget* target = makefile->AddUtilityCommand(
- name, cmCommandOrigin::Generator, true,
- makefile->GetHomeOutputDirectory().c_str() /*work dir*/,
- std::vector<std::string>() /*output*/,
- std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
- comment.c_str());
- localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen));
+ std::vector<std::string> no_byproducts;
+ std::vector<std::string> no_depends;
+ cmCustomCommandLines no_commands;
+ cmTarget* target = localGen->AddUtilityCommand(
+ name, true, makefile->GetHomeOutputDirectory().c_str(), no_byproducts,
+ no_depends, no_commands, false, comment.c_str());
+ localGen->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(target, localGen));
// Set FOLDER property in the target
{
@@ -180,7 +180,7 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
if (it != GlobalAutoGenTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
- target->Target->AddUtility(targetName, localGen->GetMakefile());
+ target->Target->AddUtility(targetName, false, localGen->GetMakefile());
}
}
}
@@ -192,7 +192,7 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
if (it != GlobalAutoRccTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
- target->Target->AddUtility(targetName, localGen->GetMakefile());
+ target->Target->AddUtility(targetName, false, localGen->GetMakefile());
}
}
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index 806725a01b..2f6e581852 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -48,7 +48,7 @@ public:
public:
cmQtAutoGenGlobalInitializer(
- std::vector<cmLocalGenerator*> const& localGenerators);
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators);
~cmQtAutoGenGlobalInitializer();
Keywords const& kw() const { return Keywords_; };
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 5eb04f704c..629367d8c6 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -25,7 +25,6 @@
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -355,24 +354,38 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
}
- // Check status of policy CMP0071
- {
- cmPolicies::PolicyStatus const CMP0071_status =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0071);
- switch (CMP0071_status) {
- case cmPolicies::WARN:
- this->CMP0071Warn = true;
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- // Ignore GENERATED file
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Process GENERATED file
- this->CMP0071Accept = true;
- break;
- }
+ // Check status of policy CMP0071 regarding handling of GENERATED files
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0071)) {
+ case cmPolicies::WARN:
+ // Ignore GENERATED files but warn
+ this->CMP0071Warn = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // Ignore GENERATED files
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Process GENERATED files
+ this->CMP0071Accept = true;
+ break;
+ }
+
+ // Check status of policy CMP0100 regarding handling of .hh headers
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0100)) {
+ case cmPolicies::WARN:
+ // Ignore but .hh files but warn
+ this->CMP0100Warn = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // Ignore .hh files
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Process .hh file
+ this->CMP0100Accept = true;
+ break;
}
// Common directories
@@ -734,15 +747,26 @@ bool cmQtAutoGenInitializer::InitScanFiles()
return muf;
};
- auto addMUFile = [&](MUFileHandle&& muf, bool isHeader) {
+ auto addMUHeader = [this](MUFileHandle&& muf, cm::string_view extension) {
+ cmSourceFile* sf = muf->SF;
+ const bool muIt = (muf->MocIt || muf->UicIt);
+ if (this->CMP0100Accept || (extension != "hh")) {
+ // Accept
+ if (muIt && muf->Generated) {
+ this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
+ }
+ this->AutogenTarget.Headers.emplace(sf, std::move(muf));
+ } else if (muIt && this->CMP0100Warn) {
+ // Store file for warning message
+ this->AutogenTarget.CMP0100HeadersWarn.push_back(sf);
+ }
+ };
+
+ auto addMUSource = [this](MUFileHandle&& muf) {
if ((muf->MocIt || muf->UicIt) && muf->Generated) {
this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
}
- if (isHeader) {
- this->AutogenTarget.Headers.emplace(muf->SF, std::move(muf));
- } else {
- this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
- }
+ this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
};
// Scan through target files
@@ -764,11 +788,10 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
- // FIXME: Add a policy to include .hh files.
- if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
- addMUFile(makeMUFile(sf, fullPath, true), true);
+ if (cm->IsHeaderExtension(extLower)) {
+ addMUHeader(makeMUFile(sf, fullPath, true), extLower);
} else if (cm->IsSourceExtension(extLower)) {
- addMUFile(makeMUFile(sf, fullPath, true), false);
+ addMUSource(makeMUFile(sf, fullPath, true));
}
}
@@ -802,8 +825,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// 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
static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
auto const& exts = cm->GetHeaderExtensions();
@@ -848,16 +869,12 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!muf.UicIt) {
eMuf->UicIt = false;
}
- extraHeaders.emplace_back(std::move(eMuf));
+ addMUHeader(std::move(eMuf), ext);
}
}
}
}
}
- // Move generated files to main headers list
- for (auto& eMuf : extraHeaders) {
- addMUFile(std::move(eMuf), true);
- }
}
// Scan through all source files in the makefile to extract moc and uic
@@ -865,7 +882,7 @@ 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 : this->Makefile->GetSourceFiles()) {
+ for (const auto& 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).
@@ -877,19 +894,18 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::string const& extLower =
cmSystemTools::LowerCase(sf->GetExtension());
- // FIXME: Add a policy to include .hh files.
- if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
- if (!cmContains(this->AutogenTarget.Headers, sf)) {
- auto muf = makeMUFile(sf, fullPath, false);
+ if (cm->IsHeaderExtension(extLower)) {
+ if (!cmContains(this->AutogenTarget.Headers, sf.get())) {
+ auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
- this->AutogenTarget.Headers.emplace(sf, std::move(muf));
+ addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsSourceExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Headers, sf)) {
- auto muf = makeMUFile(sf, fullPath, false);
+ if (!cmContains(this->AutogenTarget.Sources, sf.get())) {
+ auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
- this->AutogenTarget.Sources.emplace(sf, std::move(muf));
+ addMUSource(std::move(muf));
}
}
} else if (this->Uic.Enabled && (extLower == kw.ui)) {
@@ -947,6 +963,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
}
+ // Generate CMP0100 warning
+ if (this->MocOrUicEnabled() &&
+ !this->AutogenTarget.CMP0100HeadersWarn.empty()) {
+ cm::string_view property;
+ if (this->Moc.Enabled && this->Uic.Enabled) {
+ property = "SKIP_AUTOGEN";
+ } else if (this->Moc.Enabled) {
+ property = "SKIP_AUTOMOC";
+ } else if (this->Uic.Enabled) {
+ property = "SKIP_AUTOUIC";
+ }
+ std::string files;
+ for (cmSourceFile* sf : this->AutogenTarget.CMP0100HeadersWarn) {
+ files += cmStrCat(" ", Quoted(sf->GetFullPath()), '\n');
+ }
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0100), '\n',
+ "For compatibility, CMake is excluding the header 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 CMP0100 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.hh PROPERTY ", property,
+ " ON)\n"));
+ }
+
// Process qrc files
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
@@ -1045,9 +1090,16 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Compose command lines
- cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
- { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
- this->AutogenTarget.InfoFile, "$<CONFIGURATION>" });
+ // TODO: Refactor autogen to output a per-config mocs_compilation.cpp instead
+ // of fiddling with the include directories
+ std::vector<std::string> configs;
+ this->GlobalGen->GetQtAutoGenConfigs(configs);
+ cmCustomCommandLines commandLines;
+ for (auto const& config : configs) {
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
+ this->AutogenTarget.InfoFile, config }));
+ }
// Use PRE_BUILD on demand
bool usePRE_BUILD = false;
@@ -1073,7 +1125,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (usePRE_BUILD) {
// Add additional autogen target dependencies to origin target
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- this->GenTarget->Target->AddUtility(depTarget->GetName(),
+ this->GenTarget->Target->AddUtility(depTarget->GetName(), false,
this->Makefile);
}
@@ -1084,8 +1136,8 @@ 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(this->Makefile, no_output, autogenProvides, no_deps,
- commandLines, autogenComment.c_str(),
+ cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
+ this->Makefile->GetBacktrace(), autogenComment.c_str(),
this->Dir.Work.c_str());
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
@@ -1119,35 +1171,83 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
}
+ std::vector<std::string> dependencies(
+ this->AutogenTarget.DependFiles.begin(),
+ this->AutogenTarget.DependFiles.end());
+
+ const bool useNinjaDepfile = this->QtVersion >= IntegerVersion(5, 15) &&
+ this->GlobalGen->GetName().find("Ninja") != std::string::npos;
+ if (useNinjaDepfile) {
+ // Create a custom command that generates a timestamp file and
+ // has a depfile assigned. The depfile is created by JobDepFilesMergeT.
+
+ // Add additional autogen target dependencies
+ for (const cmTarget* t : this->AutogenTarget.DependTargets) {
+ dependencies.push_back(t->GetName());
+ }
+ const char timestampFileName[] = "timestamp";
+ const std::string outputFile =
+ cmStrCat(this->Dir.Build, "/", timestampFileName);
+ this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps");
+ auto relativeBinaryDir = cmSystemTools::RelativePath(
+ this->LocalGen->GetBinaryDirectory(),
+ this->LocalGen->GetCurrentBinaryDirectory());
+ if (!relativeBinaryDir.empty()) {
+ relativeBinaryDir = cmStrCat(relativeBinaryDir, "/");
+ }
+ this->AutogenTarget.DepFileRuleName =
+ cmStrCat(relativeBinaryDir, this->GenTarget->GetName(), "_autogen/",
+ timestampFileName);
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
+
+ this->AddGeneratedSource(outputFile, this->Moc);
+ const std::string no_main_dependency;
+ this->LocalGen->AddCustomCommandToOutput(
+ outputFile, dependencies, no_main_dependency, commandLines,
+ autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false,
+ /*escapeOldStyle=*/false,
+ /*uses_terminal=*/false,
+ /*command_expand_lists=*/false, this->AutogenTarget.DepFile);
+
+ // Alter variables for the autogen target which now merely wraps the
+ // custom command
+ dependencies.clear();
+ dependencies.push_back(outputFile);
+ commandLines.clear();
+ autogenComment.clear();
+ }
+
// Create autogen target
- 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());
+ cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
+ this->AutogenTarget.Name, true, this->Dir.Work.c_str(),
+ /*byproducts=*/autogenProvides,
+ /*depends=*/dependencies, commandLines, false, autogenComment.c_str());
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
- new cmGeneratorTarget(autogenTarget, this->LocalGen));
+ cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen));
// Forward origin utilities to autogen target
if (this->AutogenTarget.DependOrigin) {
- for (BT<std::string> const& depName : this->GenTarget->GetUtilities()) {
- autogenTarget->AddUtility(depName.Value, this->Makefile);
+ for (BT<std::pair<std::string, bool>> const& depName :
+ this->GenTarget->GetUtilities()) {
+ autogenTarget->AddUtility(depName.Value.first, false, this->Makefile);
}
}
- // Add additional autogen target dependencies to autogen target
- for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
+ if (!useNinjaDepfile) {
+ // Add additional autogen target dependencies to autogen target
+ for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
+ autogenTarget->AddUtility(depTarget->GetName(), false, this->Makefile);
+ }
}
// Set FOLDER property in autogen target
if (!this->TargetsFolder.empty()) {
- autogenTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
+ autogenTarget->SetProperty("FOLDER", this->TargetsFolder);
}
// Add autogen target to the origin target dependencies
- this->GenTarget->Target->AddUtility(this->AutogenTarget.Name,
+ this->GenTarget->Target->AddUtility(this->AutogenTarget.Name, false,
this->Makefile);
// Add autogen target to the global autogen target dependencies
@@ -1205,25 +1305,25 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccName += cmStrCat('_', qrc.QrcPathChecksum);
}
- cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand(
- ccName, cmCommandOrigin::Generator, true, this->Dir.Work.c_str(),
- ccOutput, ccDepends, commandLines, false, ccComment.c_str());
+ cmTarget* autoRccTarget = this->LocalGen->AddUtilityCommand(
+ ccName, true, this->Dir.Work.c_str(), ccOutput, ccDepends,
+ commandLines, false, ccComment.c_str());
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
- new cmGeneratorTarget(autoRccTarget, this->LocalGen));
+ cm::make_unique<cmGeneratorTarget>(autoRccTarget, this->LocalGen));
// Set FOLDER property in autogen target
if (!this->TargetsFolder.empty()) {
- autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
+ autoRccTarget->SetProperty("FOLDER", this->TargetsFolder);
}
if (!this->Rcc.ExecutableTargetName.empty()) {
- autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName,
+ autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, false,
this->Makefile);
}
}
// Add autogen target to the origin target dependencies
- this->GenTarget->Target->AddUtility(ccName, this->Makefile);
+ this->GenTarget->Target->AddUtility(ccName, false, this->Makefile);
// Add autogen target to the global autogen target dependencies
if (this->Rcc.GlobalTarget) {
@@ -1244,7 +1344,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
}
std::string no_main_dependency;
cmImplicitDependsList no_implicit_depends;
- this->Makefile->AddCustomCommandToOutput(
+ this->LocalGen->AddCustomCommandToOutput(
ccOutput, ccByproducts, ccDepends, no_main_dependency,
no_implicit_depends, commandLines, ccComment.c_str(),
this->Dir.Work.c_str());
@@ -1356,12 +1456,15 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
+ info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor);
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.Set("DEP_FILE", this->AutogenTarget.DepFile);
+ info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
info.SetArrayArray(
@@ -1528,8 +1631,8 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
{
- this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES",
- fileName.c_str(), false);
+ this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName,
+ false);
}
void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString,
@@ -1632,21 +1735,39 @@ std::string cmQtAutoGenInitializer::GetMocBuildPath(MUFile const& muf)
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);
+
+ std::string basePath =
+ cmStrCat(this->PathCheckSum.getPart(muf.FullPath), "/moc_",
+ FileNameWithoutLastExtension(muf.FullPath));
+
+ res = cmStrCat(basePath, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
+ }
+
+ // File name already emitted.
+ // Try appending the header suffix to the base path.
+ basePath = cmStrCat(basePath, '_', muf.SF->GetExtension());
+ res = cmStrCat(basePath, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
+ }
+
+ // File name with header extension already emitted.
+ // Try adding a number to the base path.
+ constexpr std::size_t number_begin = 2;
+ constexpr std::size_t number_end = 256;
+ for (std::size_t ii = number_begin; ii != number_end; ++ii) {
+ res = cmStrCat(basePath, '_', ii, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
}
}
+
+ // Output file name conflict (unlikely, but still...)
+ cmSystemTools::Error(
+ cmStrCat("moc output file name conflict for ", muf.FullPath));
+
return res;
}
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index d55259c5eb..48ec1a0177 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -160,6 +160,8 @@ private:
bool MultiConfig = false;
bool CMP0071Accept = false;
bool CMP0071Warn = false;
+ bool CMP0100Accept = false;
+ bool CMP0100Warn = false;
std::string ConfigDefault;
std::vector<std::string> ConfigsList;
std::string TargetsFolder;
@@ -189,10 +191,13 @@ private:
bool DependOrigin = false;
std::set<std::string> DependFiles;
std::set<cmTarget*> DependTargets;
+ std::string DepFile;
+ std::string DepFileRuleName;
// Sources to process
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
std::vector<MUFile*> FilesGenerated;
+ std::vector<cmSourceFile*> CMP0100HeadersWarn;
} AutogenTarget;
/** moc variables. */
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index f8b8981524..893bd6b5db 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -16,15 +16,17 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cm_jsoncpp_value.h"
-#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileTime.h"
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
@@ -170,7 +172,7 @@ public:
// -- Attributes
// - Config
bool MultiConfig = false;
- unsigned int QtVersionMajor = 4;
+ IntegerVersion QtVersion = { 4, 0 };
unsigned int ThreadCount = 0;
// - Directories
std::string AutogenBuildDir;
@@ -179,6 +181,8 @@ public:
std::string CMakeExecutable;
cmFileTime CMakeExecutableTime;
std::string ParseCacheFile;
+ std::string DepFile;
+ std::string DepFileRuleName;
std::vector<std::string> HeaderExtensions;
};
@@ -216,6 +220,7 @@ public:
bool SettingsChanged = false;
bool RelaxedMode = false;
bool PathPrefix = false;
+ bool CanOutputDependencies = false;
cmFileTime ExecutableTime;
std::string Executable;
std::string CompFileAbs;
@@ -485,8 +490,17 @@ public:
class JobCompileMocT : public JobCompileT
{
public:
- using JobCompileT::JobCompileT;
+ JobCompileMocT(MappingHandleT uicMapping,
+ std::unique_ptr<std::string> reason,
+ ParseCacheT::FileHandleT cacheEntry)
+ : JobCompileT(std::move(uicMapping), std::move(reason))
+ , CacheEntry(std::move(cacheEntry))
+ {
+ }
void Process() override;
+
+ protected:
+ ParseCacheT::FileHandleT CacheEntry;
};
/** uic compiles a file. */
@@ -504,6 +518,12 @@ public:
void Process() override;
};
+ class JobDepFilesMergeT : public JobFenceT
+ {
+ private:
+ void Process() override;
+ };
+
/** @brief The last job. */
class JobFinishT : public JobFenceT
{
@@ -546,6 +566,9 @@ private:
void Abort(bool error);
// -- Generation
bool CreateDirectories();
+ // -- Support for depfiles
+ static std::vector<std::string> dependenciesFromDepFile(
+ const char* filePath);
private:
// -- Settings
@@ -808,9 +831,9 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
// Compose command
std::vector<std::string> cmd = MocConst().PredefsCmd;
// Add definitions
- cmAppend(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, MocConst().OptionsDefinitions);
// Add includes
- cmAppend(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, MocConst().OptionsIncludes);
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
LogCommandError(GenT::MOC,
@@ -951,7 +974,7 @@ void cmQtAutoMocUicT::JobParseT::MocMacro()
void cmQtAutoMocUicT::JobParseT::MocDependecies()
{
- if (MocConst().DependFilters.empty()) {
+ if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) {
return;
}
@@ -1674,8 +1697,13 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
if (Probe(*mapping, reason.get())) {
// Register the parent directory for creation
MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
+ // Fetch the cache entry for the source file
+ std::string const& sourceFile = mapping->SourceFile->FileName;
+ ParseCacheT::GetOrInsertT cacheEntry =
+ BaseEval().ParseCache.GetOrInsert(sourceFile);
// Add moc job
- Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason));
+ Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
+ mapping, std::move(reason), std::move(cacheEntry.first));
// Check if a moc job for a mocs_compilation.cpp entry was generated
if (compFile) {
MocEval().CompUpdated = true;
@@ -1779,6 +1807,14 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
std::string const& sourceDir, std::string const& includeString) const
{
using ResPair = std::pair<std::string, cmFileTime>;
+ // moc's dependency file contains absolute paths
+ if (MocConst().CanOutputDependencies) {
+ ResPair res{ includeString, {} };
+ if (res.second.Load(res.first)) {
+ return res;
+ }
+ return {};
+ }
// Search in vicinity of the source
{
ResPair res{ sourceDir + includeString, {} };
@@ -1898,6 +1934,11 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process()
Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
}
+ if (!BaseConst().DepFile.empty()) {
+ // Add job to merge dep files
+ Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>();
+ }
+
// Add finish job
Gen()->WorkerPool().EmplaceJob<JobFinishT>();
}
@@ -1916,9 +1957,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
MocConst().OptionsExtra.size() + 16);
cmd.push_back(MocConst().Executable);
// Add definitions
- cmAppend(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, MocConst().OptionsDefinitions);
// Add includes
- cmAppend(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, MocConst().OptionsIncludes);
// Add predefs include
if (!MocConst().PredefsFileAbs.empty()) {
cmd.emplace_back("--include");
@@ -1946,7 +1987,10 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
}
// Add extra options
- cmAppend(cmd, MocConst().OptionsExtra);
+ cm::append(cmd, MocConst().OptionsExtra);
+ if (MocConst().CanOutputDependencies) {
+ cmd.emplace_back("--output-dep-file");
+ }
// Add output file
cmd.emplace_back("-o");
cmd.push_back(outputFile);
@@ -1956,12 +2000,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
// Execute moc command
cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
- // Moc command success. Print moc output.
- if (!result.StdOut.empty()) {
- Log().Info(GenT::MOC, result.StdOut);
- }
- } else {
+ if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) {
// Moc command failed
std::string includers;
if (!Mapping->IncluderFiles.empty()) {
@@ -1976,6 +2015,28 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
MessagePath(outputFile), '\n', includers,
result.ErrorMessage),
cmd, result.StdOut);
+ return;
+ }
+
+ // Moc command success. Print moc output.
+ if (!result.StdOut.empty()) {
+ Log().Info(GenT::MOC, result.StdOut);
+ }
+
+ // Extract dependencies from the dep file moc generated for us
+ if (MocConst().CanOutputDependencies) {
+ const std::string depfile = outputFile + ".d";
+ if (Log().Verbose()) {
+ Log().Info(GenT::MOC,
+ "Reading dependencies from " + MessagePath(depfile));
+ }
+ if (!cmSystemTools::FileExists(depfile)) {
+ Log().Warning(GenT::MOC,
+ "Dependency file " + MessagePath(depfile) +
+ " does not exist.");
+ return;
+ }
+ CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
}
}
@@ -1992,9 +2053,9 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
auto optionIt = UicConst().UiFiles.find(sourceFile);
if (optionIt != UicConst().UiFiles.end()) {
UicMergeOptions(allOpts, optionIt->second.Options,
- (BaseConst().QtVersionMajor == 5));
+ (BaseConst().QtVersion.Major == 5));
}
- cmAppend(cmd, allOpts);
+ cm::append(cmd, allOpts);
}
cmd.emplace_back("-o");
cmd.emplace_back(outputFile);
@@ -2067,6 +2128,106 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process()
}
}
+/*
+ * Escapes paths for Ninja depfiles.
+ * This is a re-implementation of what moc does when writing depfiles.
+ */
+std::string escapeDependencyPath(cm::string_view path)
+{
+ std::string escapedPath;
+ escapedPath.reserve(path.size());
+ const size_t s = path.size();
+ int backslashCount = 0;
+ for (size_t i = 0; i < s; ++i) {
+ if (path[i] == '\\') {
+ ++backslashCount;
+ } else {
+ if (path[i] == '$') {
+ escapedPath.push_back('$');
+ } else if (path[i] == '#') {
+ escapedPath.push_back('\\');
+ } else if (path[i] == ' ') {
+ // Double the amount of written backslashes,
+ // and add one more to escape the space.
+ while (backslashCount-- >= 0) {
+ escapedPath.push_back('\\');
+ }
+ }
+ backslashCount = 0;
+ }
+ escapedPath.push_back(path[i]);
+ }
+ return escapedPath;
+}
+
+void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
+{
+ if (Log().Verbose()) {
+ Log().Info(GenT::MOC, "Merging MOC dependencies");
+ }
+ auto processDepFile =
+ [](const std::string& mocOutputFile) -> std::vector<std::string> {
+ std::string f = mocOutputFile + ".d";
+ if (!cmSystemTools::FileExists(f)) {
+ return {};
+ }
+ return dependenciesFromDepFile(f.c_str());
+ };
+
+ std::vector<std::string> dependencies;
+ ParseCacheT& parseCache = BaseEval().ParseCache;
+ auto processMappingEntry = [&](const MappingMapT::value_type& m) {
+ auto cacheEntry = parseCache.GetOrInsert(m.first);
+ if (cacheEntry.first->Moc.Depends.empty()) {
+ cacheEntry.first->Moc.Depends = processDepFile(m.second->OutputFile);
+ }
+ dependencies.insert(dependencies.end(),
+ cacheEntry.first->Moc.Depends.begin(),
+ cacheEntry.first->Moc.Depends.end());
+ };
+
+ std::for_each(MocEval().HeaderMappings.begin(),
+ MocEval().HeaderMappings.end(), processMappingEntry);
+ std::for_each(MocEval().SourceMappings.begin(),
+ MocEval().SourceMappings.end(), processMappingEntry);
+
+ // Remove duplicates to make the depfile smaller
+ std::sort(dependencies.begin(), dependencies.end());
+ dependencies.erase(std::unique(dependencies.begin(), dependencies.end()),
+ dependencies.end());
+
+ // Add form files
+ for (const auto& uif : UicEval().UiFiles) {
+ dependencies.push_back(uif.first);
+ }
+
+ // Write the file
+ cmsys::ofstream ofs;
+ ofs.open(BaseConst().DepFile.c_str(),
+ (std::ios::out | std::ios::binary | std::ios::trunc));
+ if (!ofs) {
+ LogError(GenT::GEN,
+ cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile),
+ " for writing."));
+ return;
+ }
+ ofs << BaseConst().DepFileRuleName << ": \\" << std::endl;
+ for (const std::string& file : dependencies) {
+ ofs << '\t' << escapeDependencyPath(file) << " \\" << std::endl;
+ if (!ofs.good()) {
+ LogError(GenT::GEN,
+ cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
+ " failed."));
+ return;
+ }
+ }
+
+ // Add the CMake executable to re-new cache data if necessary.
+ // Also, this is the last entry, so don't add a backslash.
+ ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable)
+ << std::endl;
+}
+
void cmQtAutoMocUicT::JobFinishT::Process()
{
Gen()->AbortSuccess();
@@ -2082,7 +2243,8 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
// -- Required settings
if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
- !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
+ !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) ||
+ !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) ||
!info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
!info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
!info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
@@ -2090,6 +2252,9 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
!info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
!info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile,
true) ||
+ !info.GetString("DEP_FILE", BaseConst_.DepFile, false) ||
+ !info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
+ false) ||
!info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
!info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
!info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
@@ -2143,8 +2308,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
- // Dependency filters
- {
+ // Can moc output dependencies or do we need to setup dependency filters?
+ if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
+ MocConst_.CanOutputDependencies = true;
+ } else {
Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
if (!val.isArray()) {
return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array.");
@@ -2660,6 +2827,19 @@ bool cmQtAutoMocUicT::CreateDirectories()
return true;
}
+std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
+ const char* filePath)
+{
+ cmGccDepfileContent content = cmReadGccDepfile(filePath);
+ if (content.empty()) {
+ return {};
+ }
+
+ // Moc outputs a depfile with exactly one rule.
+ // Discard the rule and return the dependencies.
+ return content.front().paths;
+}
+
void cmQtAutoMocUicT::Abort(bool error)
{
if (error) {
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 3af81ad38a..08eb4b5e28 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -6,7 +6,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCryptoHash.h"
#include "cmDuration.h"
#include "cmFileLock.h"
@@ -405,7 +406,7 @@ bool cmQtAutoRccT::GenerateRcc()
// Compose rcc command
std::vector<std::string> cmd;
cmd.push_back(RccExecutable_);
- cmAppend(cmd, Options_);
+ cm::append(cmd, Options_);
cmd.emplace_back("-o");
cmd.push_back(RccFileOutput_);
cmd.push_back(QrcFile_);
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 0a1d109d56..5ab1b3ac14 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -85,6 +85,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.ObjectsQuoted;
}
}
+ if (replaceValues.AIXExports) {
+ if (variable == "AIX_EXPORTS") {
+ return replaceValues.AIXExports;
+ }
+ }
if (replaceValues.Defines && variable == "DEFINES") {
return replaceValues.Defines;
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 8f361967b1..09e8a3b1c0 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -36,6 +36,7 @@ public:
const char* TargetVersionMajor;
const char* TargetVersionMinor;
const char* Language;
+ const char* AIXExports;
const char* Objects;
const char* Target;
const char* LinkLibraries;
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index c8bb1ab15c..7d676c9c33 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -71,7 +71,7 @@ protected:
std::string CreateConfigTest(const std::string& config);
std::string CreateConfigTest(std::vector<std::string> const& configs);
- std::string CreateComponentTest(const char* component);
+ std::string CreateComponentTest(const std::string& component);
// Information shared by most generator types.
std::string RuntimeConfigVariable;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index d15ce57499..766d3478b3 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -181,7 +181,13 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
const char* arch =
this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
if (arch && *arch) {
- this->AddPathInternal(dir + subdir + "/" + arch, base);
+ if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
+ this->FC->Makefile->IsDefinitionSet(
+ "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
+ this->AddPathInternal(cmStrCat('/', arch, dir, subdir), base);
+ } else {
+ this->AddPathInternal(cmStrCat(dir, subdir, '/', arch), base);
+ }
}
}
std::string add = dir + subdir;
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index 2a576ed59b..3ecc73bca2 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <set>
#include <string>
#include <vector>
@@ -27,6 +28,7 @@ public:
~cmSearchPath();
const std::vector<std::string>& GetPaths() const { return this->Paths; }
+ std::size_t size() const { return this->Paths.size(); }
void ExtractWithout(const std::set<std::string>& ignore,
std::vector<std::string>& outPaths,
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 56003df75f..1d4ea01534 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -744,7 +744,7 @@ void cmServerProtocol1::GeneratorInformation::SetupGenerator(
cm->SetHomeDirectory(SourceDirectory);
cm->SetHomeOutputDirectory(BuildDirectory);
- cmGlobalGenerator* gg = cm->CreateGlobalGenerator(fullGeneratorName);
+ auto gg = cm->CreateGlobalGenerator(fullGeneratorName);
if (!gg) {
setErrorMessage(
errorMessage,
@@ -753,7 +753,7 @@ void cmServerProtocol1::GeneratorInformation::SetupGenerator(
return;
}
- cm->SetGlobalGenerator(gg);
+ cm->SetGlobalGenerator(std::move(gg));
cm->SetGeneratorToolset(Toolset);
cm->SetGeneratorPlatform(Platform);
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 8c3a4cb486..5e2a1462c4 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -121,7 +121,7 @@ bool cmSetCommand(std::vector<std::string> const& args,
if (cache) {
std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
- if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) {
+ if (!cmState::StringToCacheEntryType(args[cacheStart + 1], type)) {
std::string m = "implicitly converting '" + args[cacheStart + 1] +
"' to 'STRING' type.";
status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 112d832e63..3705727d87 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -194,9 +194,8 @@ 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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (!names.empty()) {
status.SetError("given names for GLOBAL scope.");
@@ -205,14 +204,14 @@ bool HandleGlobalMode(cmExecutionStatus& status,
// Set or append the property.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- cm->AppendProperty(propertyName, value ? value : "", appendAsString);
+ cm->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- cm->SetProperty(propertyName, value);
+ if (remove) {
+ cm->SetProperty(propertyName, nullptr);
+ } else {
+ cm->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -221,9 +220,8 @@ bool HandleGlobalMode(cmExecutionStatus& status,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (names.size() > 1) {
status.SetError("allows at most one name for DIRECTORY scope.");
@@ -258,14 +256,14 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
}
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- mf->AppendProperty(propertyName, value ? value : "", appendAsString);
+ mf->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- mf->SetProperty(propertyName, value);
+ if (remove) {
+ mf->SetProperty(propertyName, nullptr);
+ } else {
+ mf->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -274,9 +272,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
for (std::string const& name : names) {
if (status.GetMakefile().IsAlias(name)) {
@@ -300,18 +297,18 @@ bool HandleTargetMode(cmExecutionStatus& status,
bool HandleTarget(cmTarget* target, cmMakefile& makefile,
const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- target->AppendProperty(propertyName, value, appendAsString);
+ target->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- target->SetProperty(propertyName, value);
+ if (remove) {
+ target->SetProperty(propertyName, nullptr);
+ } else {
+ target->SetProperty(propertyName, propertyValue.c_str());
+ }
}
// Check the resulting value.
@@ -323,9 +320,8 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
for (std::string const& name : names) {
// Get the source file.
@@ -344,28 +340,26 @@ bool HandleSourceMode(cmExecutionStatus& status,
}
bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
-
if (appendMode) {
- sf->AppendProperty(propertyName, value, appendAsString);
+ sf->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- sf->SetProperty(propertyName, value);
+ if (remove) {
+ sf->SetProperty(propertyName, nullptr);
+ } else {
+ sf->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
}
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Look for tests with all names given.
std::set<std::string>::iterator next;
@@ -396,18 +390,18 @@ bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
}
bool HandleTest(cmTest* test, const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- test->AppendProperty(propertyName, value, appendAsString);
+ test->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- test->SetProperty(propertyName, value);
+ if (remove) {
+ test->SetProperty(propertyName, nullptr);
+ } else {
+ test->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -416,9 +410,8 @@ bool HandleTest(cmTest* test, const std::string& propertyName,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (propertyName == "ADVANCED") {
if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
@@ -463,9 +456,8 @@ bool HandleCacheMode(cmExecutionStatus& status,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
const char* value = propertyValue.c_str();
@@ -486,9 +478,8 @@ bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
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)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
cmake* cm = status.GetMakefile().GetCMakeInstance();
@@ -510,8 +501,8 @@ bool HandleInstallMode(cmExecutionStatus& status,
bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
const char* value = propertyValue.c_str();
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index 8d917dbe57..cd0fa402a2 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -4,7 +4,8 @@
#include <iterator>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -33,7 +34,7 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments.");
return false;
}
- cmAppend(propertyPairs, j, args.end());
+ cm::append(propertyPairs, j, args.end());
break;
}
numFiles++;
@@ -70,7 +71,7 @@ static bool SetOneTarget(const std::string& tname,
// now loop through all the props and set them
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2) {
- target->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+ target->SetProperty(propertyPairs[k], propertyPairs[k + 1]);
target->CheckProperty(propertyPairs[k], mf);
}
}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index de61edaf0d..2e7aecabc9 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -4,7 +4,8 @@
#include <iterator>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -36,7 +37,7 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments.");
return false;
}
- cmAppend(propertyPairs, j, args.end());
+ cm::append(propertyPairs, j, args.end());
break;
}
numFiles++;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 2a345eb851..fd9cacdbfe 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -128,7 +128,7 @@ bool cmSourceFile::FindFullPath(std::string* error)
// The file is not generated. It must exist on disk.
cmMakefile const* makefile = this->Location.GetMakefile();
// Location path
- std::string const lPath = this->Location.GetFullPath();
+ std::string const& lPath = this->Location.GetFullPath();
// List of extension lists
std::array<std::vector<std::string> const*, 2> const extsLists = {
{ &makefile->GetCMakeInstance()->GetSourceExtensions(),
@@ -145,7 +145,7 @@ bool cmSourceFile::FindFullPath(std::string* error)
return true;
}
// Try full path with extension
- for (auto exts : extsLists) {
+ for (auto& exts : extsLists) {
for (std::string const& ext : *exts) {
if (!ext.empty()) {
std::string extPath = cmStrCat(fullPath, '.', ext);
@@ -260,21 +260,21 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
}
}
-void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmSourceFile::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
if (prop == propINCLUDE_DIRECTORIES) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->IncludeDirectories.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_OPTIONS) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->CompileOptions.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_DEFINITIONS) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->CompileDefinitions.emplace_back(value, lfbt);
}
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 82a3625b8b..e22829f186 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -42,7 +42,7 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
const char* GetProperty(const std::string& prop) const;
@@ -154,9 +154,8 @@ private:
#define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"
#define CM_SOURCE_REGEX \
- "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|rc|def|r|odl|idl|" \
- "hpj" \
- "|bat)$"
+ "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
+ "rc|def|r|odl|idl|hpj|bat)$"
#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index df702b050f..5f807b87f1 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -31,7 +31,8 @@ cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
this->AmbiguousExtension = true;
this->Directory = cmSystemTools::GetFilenamePath(name);
if (cmSystemTools::FileIsFullPath(this->Directory)) {
- this->Directory = cmSystemTools::CollapseFullPath(this->Directory);
+ this->Directory = cmSystemTools::CollapseFullPath(
+ this->Directory, mf->GetHomeOutputDirectory());
}
this->Name = cmSystemTools::GetFilenameName(name);
if (kind == cmSourceFileLocationKind::Known) {
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index f9b5ed1c08..9fc76152fe 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -3,9 +3,9 @@
#include "cmState.h"
#include <algorithm>
+#include <array>
#include <cassert>
#include <cstdlib>
-#include <cstring>
#include <utility>
#include <cm/memory>
@@ -60,43 +60,44 @@ const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
return nullptr;
}
-const char* cmCacheEntryTypes[] = { "BOOL", "PATH", "FILEPATH",
- "STRING", "INTERNAL", "STATIC",
- "UNINITIALIZED", nullptr };
+static const std::array<std::string, 7> cmCacheEntryTypes = {
+ { "BOOL", "PATH", "FILEPATH", "STRING", "INTERNAL", "STATIC",
+ "UNINITIALIZED" }
+};
-const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
+const std::string& cmState::CacheEntryTypeToString(
+ cmStateEnums::CacheEntryType type)
{
- if (type > 6) {
- return cmCacheEntryTypes[6];
+ if (type < cmStateEnums::BOOL || type > cmStateEnums::UNINITIALIZED) {
+ type = cmStateEnums::UNINITIALIZED;
}
return cmCacheEntryTypes[type];
}
-cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
+cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(
+ const std::string& s)
{
cmStateEnums::CacheEntryType type = cmStateEnums::STRING;
StringToCacheEntryType(s, type);
return type;
}
-bool cmState::StringToCacheEntryType(const char* s,
+bool cmState::StringToCacheEntryType(const std::string& s,
cmStateEnums::CacheEntryType& type)
{
- int i = 0;
- while (cmCacheEntryTypes[i]) {
- if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
+ for (size_t i = 0; i < cmCacheEntryTypes.size(); ++i) {
+ if (s == cmCacheEntryTypes[i]) {
type = static_cast<cmStateEnums::CacheEntryType>(i);
return true;
}
- ++i;
}
return false;
}
bool cmState::IsCacheEntryType(std::string const& key)
{
- for (int i = 0; cmCacheEntryTypes[i]; ++i) {
- if (key == cmCacheEntryTypes[i]) {
+ for (const std::string& i : cmCacheEntryTypes) {
+ if (key == i) {
return true;
}
}
@@ -140,6 +141,16 @@ const char* cmState::GetCacheEntryValue(std::string const& key) const
return e->Value.c_str();
}
+std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
+{
+ std::string retval;
+ auto val = this->GetCacheEntryValue(key);
+ if (val) {
+ retval = val;
+ }
+ return retval;
+}
+
const std::string* cmState::GetInitializedCacheValue(
std::string const& key) const
{
@@ -149,8 +160,7 @@ const std::string* cmState::GetInitializedCacheValue(
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
std::string const& key) const
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
return it.GetType();
}
@@ -164,8 +174,7 @@ void cmState::SetCacheEntryProperty(std::string const& key,
std::string const& propertyName,
std::string const& value)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
it.SetProperty(propertyName, value.c_str());
}
@@ -173,24 +182,21 @@ void cmState::SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName,
bool value)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
it.SetProperty(propertyName, value);
}
std::vector<std::string> cmState::GetCacheEntryPropertyList(
const std::string& key)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
return it.GetPropertyList();
}
const char* cmState::GetCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
+ cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
if (!it.PropertyExists(propertyName)) {
return nullptr;
}
@@ -200,8 +206,8 @@ const char* cmState::GetCacheEntryProperty(std::string const& key,
bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName)
{
- return this->CacheManager->GetCacheIterator(key.c_str())
- .GetPropertyAsBool(propertyName);
+ return this->CacheManager->GetCacheIterator(key).GetPropertyAsBool(
+ propertyName);
}
void cmState::AddCacheEntry(const std::string& key, const char* value,
@@ -253,15 +259,14 @@ void cmState::AppendCacheEntryProperty(const std::string& key,
const std::string& property,
const std::string& value, bool asString)
{
- this->CacheManager->GetCacheIterator(key.c_str())
- .AppendProperty(property, value.c_str(), asString);
+ this->CacheManager->GetCacheIterator(key).AppendProperty(property, value,
+ asString);
}
void cmState::RemoveCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
- this->CacheManager->GetCacheIterator(key.c_str())
- .SetProperty(propertyName, nullptr);
+ this->CacheManager->GetCacheIterator(key).SetProperty(propertyName, nullptr);
}
cmStateSnapshot cmState::Reset()
@@ -562,8 +567,8 @@ void cmState::SetGlobalProperty(const std::string& prop, const char* value)
this->GlobalProperties.SetProperty(prop, value);
}
-void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
- bool asString)
+void cmState::AppendGlobalProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
this->GlobalProperties.AppendProperty(prop, value, asString);
}
@@ -615,6 +620,9 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1];
}
+ if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
+ return &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1];
+ }
#undef STRING_LIST_ELEMENT
return this->GlobalProperties.GetPropertyValue(prop);
@@ -712,6 +720,16 @@ bool cmState::UseMSYSShell() const
return this->MSYSShell;
}
+void cmState::SetNinjaMulti(bool ninjaMulti)
+{
+ this->NinjaMulti = ninjaMulti;
+}
+
+bool cmState::UseNinjaMulti() const
+{
+ return this->NinjaMulti;
+}
+
unsigned int cmState::GetCacheMajorVersion() const
{
return this->CacheManager->GetCacheMajorVersion();
@@ -993,12 +1011,12 @@ bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
bool flag = false;
if (regQuoted.find(entry)) {
var = regQuoted.match(1);
- type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
+ type = cmState::StringToCacheEntryType(regQuoted.match(2));
value = regQuoted.match(3);
flag = true;
} else if (reg.find(entry)) {
var = reg.match(1);
- type = cmState::StringToCacheEntryType(reg.match(2).c_str());
+ type = cmState::StringToCacheEntryType(reg.match(2));
value = reg.match(3);
flag = true;
}
diff --git a/Source/cmState.h b/Source/cmState.h
index a7ca015c1c..6ee2b0c802 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -70,10 +70,12 @@ public:
cmStateSnapshot const& originSnapshot);
cmStateSnapshot Pop(cmStateSnapshot const& originSnapshot);
- static cmStateEnums::CacheEntryType StringToCacheEntryType(const char*);
- static bool StringToCacheEntryType(const char*,
+ static cmStateEnums::CacheEntryType StringToCacheEntryType(
+ const std::string&);
+ static bool StringToCacheEntryType(const std::string&,
cmStateEnums::CacheEntryType& type);
- static const char* CacheEntryTypeToString(cmStateEnums::CacheEntryType);
+ static const std::string& CacheEntryTypeToString(
+ cmStateEnums::CacheEntryType);
static bool IsCacheEntryType(std::string const& key);
bool LoadCache(const std::string& path, bool internal,
@@ -86,6 +88,7 @@ public:
std::vector<std::string> GetCacheEntryKeys() const;
const char* GetCacheEntryValue(std::string const& key) const;
+ std::string GetSafeCacheEntryValue(std::string const& key) const;
const std::string* GetInitializedCacheValue(std::string const& key) const;
cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const;
void SetCacheEntryValue(std::string const& key, std::string const& value);
@@ -166,7 +169,7 @@ public:
std::vector<std::string> GetCommandNames() const;
void SetGlobalProperty(const std::string& prop, const char* value);
- void AppendGlobalProperty(const std::string& prop, const char* value,
+ void AppendGlobalProperty(const std::string& prop, const std::string& value,
bool asString = false);
const char* GetGlobalProperty(const std::string& prop);
bool GetGlobalPropertyAsBool(const std::string& prop);
@@ -190,6 +193,8 @@ public:
bool UseNMake() const;
void SetMSYSShell(bool mSYSShell);
bool UseMSYSShell() const;
+ void SetNinjaMulti(bool ninjaMulti);
+ bool UseNinjaMulti() const;
unsigned int GetCacheMajorVersion() const;
unsigned int GetCacheMinorVersion() const;
@@ -245,6 +250,7 @@ private:
bool MinGWMake = false;
bool NMake = false;
bool MSYSShell = false;
+ bool NinjaMulti = false;
Mode CurrentMode = Unknown;
};
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 1262f53d97..4f003ed8f1 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -8,6 +8,7 @@
#include <vector>
#include <cm/iterator>
+#include <cmext/algorithm>
#include "cmAlgorithms.h"
#include "cmProperty.h"
@@ -520,7 +521,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
}
void cmStateDirectory::AppendProperty(const std::string& prop,
- const char* value, bool asString,
+ const std::string& value, bool asString,
cmListFileBacktrace const& lfbt)
{
if (prop == "INCLUDE_DIRECTORIES") {
@@ -607,7 +608,7 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
}
if (prop == "VARIABLES") {
std::vector<std::string> res = this->Snapshot_.ClosureKeys();
- cmAppend(res, this->Snapshot_.State->GetCacheEntryKeys());
+ cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
output = cmJoin(res, ";");
return output.c_str();
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index fe15563cbb..53a2d546d8 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -84,7 +84,7 @@ public:
void SetProperty(const std::string& prop, const char* value,
cmListFileBacktrace const& lfbt);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString, cmListFileBacktrace const& lfbt);
const char* GetProperty(const std::string& prop) const;
const char* GetProperty(const std::string& prop, bool chain) const;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 645907c21e..832e74ec7f 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -315,10 +315,14 @@ void cmStateSnapshot::SetDefaultDefinitions()
this->SetDefinition("UNIX", "1");
this->SetDefinition("CMAKE_HOST_UNIX", "1");
+# if defined(__ANDROID__)
+ this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", "Android");
+# else
struct utsname uts_name;
if (uname(&uts_name) >= 0) {
this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", uts_name.sysname);
}
+# endif
#endif
#if defined(__CYGWIN__)
std::string legacy;
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index 073f4c940a..9e9198650b 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -88,18 +88,6 @@ struct IntoString<std::string> : std::true_type
};
template <>
-struct IntoString<string_view> : std::true_type
-{
- static std::string into_string(string_view s) { return std::string(s); }
-};
-
-template <>
-struct IntoString<static_string_view> : std::true_type
-{
- static string_view into_string(static_string_view s) { return s; }
-};
-
-template <>
struct IntoString<char> : std::true_type
{
static std::string into_string(char const& c) { return std::string(1, c); }
@@ -239,6 +227,25 @@ public:
{
}
+ /**
+ * Construct via static_string_view constructor.
+ * explicit is required to avoid ambiguous overloaded operators (i.e ==,
+ * etc...) with the ones provided by string_view.
+ */
+ explicit String(static_string_view s)
+ : String(s, Private())
+ {
+ }
+ /**
+ * Construct via string_view constructor.
+ * explicit is required to avoid ambiguous overloaded operators (i.e ==,
+ * etc...) with the ones provided by string_view.
+ */
+ explicit String(string_view s)
+ : String(std::string(s), Private())
+ {
+ }
+
/** Construct via std::string initializer list constructor. */
String(std::initializer_list<char> il)
: String(std::string(il))
@@ -306,6 +313,17 @@ public:
This shares ownership of the other string's buffer. */
String& operator=(String const&) noexcept = default;
+ String& operator=(static_string_view s)
+ {
+ *this = String(s);
+ return *this;
+ }
+ String& operator=(string_view s)
+ {
+ *this = String(s);
+ return *this;
+ }
+
/** Assign from any type implementing the IntoString trait. */
template <typename T>
typename // NOLINT(*)
@@ -328,6 +346,7 @@ public:
/** Return a view of the string. */
string_view view() const noexcept { return view_; }
+ operator string_view() const noexcept { return this->view(); }
/** Return true if the instance is an empty stringn or null string. */
bool empty() const noexcept { return view_.empty(); }
@@ -638,58 +657,155 @@ private:
string_view view_;
};
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator==(L&& l, R&& r)
+/**
+ * Trait for comparable types.
+ */
+template <typename T>
+struct IsComparable : std::false_type
+{
+};
+
+template <typename T>
+struct IsComparable<T&> : IsComparable<T>
+{
+};
+
+template <typename T>
+struct IsComparable<T const> : IsComparable<T>
+{
+};
+
+template <typename T>
+struct IsComparable<T const*> : IsComparable<T*>
+{
+};
+
+template <typename T, std::string::size_type N>
+struct IsComparable<T const[N]> : IsComparable<T[N]>
+{
+};
+
+template <>
+struct IsComparable<char*> : std::true_type
{
- return (AsStringView<L>::view(std::forward<L>(l)) ==
- AsStringView<R>::view(std::forward<R>(r)));
+};
+
+template <std::string::size_type N>
+struct IsComparable<char[N]> : std::true_type
+{
+};
+
+template <>
+struct IsComparable<std::string> : std::true_type
+{
+};
+
+template <>
+struct IsComparable<char> : std::true_type
+{
+};
+
+/** comparison operators */
+inline bool operator==(const String& l, const String& r)
+{
+ return l.view() == r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator==(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) == r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator==(
+ const String& l, R&& r)
+{
+ return l.view() == AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator!=(L&& l, R&& r)
+inline bool operator!=(const String& l, const String& r)
+{
+ return l.view() != r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator!=(
+ L&& l, const String& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) !=
- AsStringView<R>::view(std::forward<R>(r)));
+ return AsStringView<L>::view(std::forward<L>(l)) != r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator!=(
+ const String& l, R&& r)
+{
+ return l.view() != AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator<(L&& l, R&& r)
+inline bool operator<(const String& l, const String& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) <
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() < r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator<(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) < r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator<(
+ const String& l, R&& r)
+{
+ return l.view() < AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator<=(L&& l, R&& r)
+inline bool operator<=(const String& l, const String& r)
+{
+ return l.view() <= r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator<=(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) <= r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator<=(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) <=
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() <= AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator>(L&& l, R&& r)
+inline bool operator>(const String& l, const String& r)
+{
+ return l.view() > r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator>(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) > r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator>(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) >
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() > AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator>=(L&& l, R&& r)
+inline bool operator>=(const String& l, const String& r)
+{
+ return l.view() >= r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator>=(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) >= r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator>=(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) >=
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() >= AsStringView<R>::view(std::forward<R>(r));
}
std::ostream& operator<<(std::ostream& os, String const& s);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index c4a4220f81..9127c50e91 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2,9 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSystemTools.h"
+#include <cmext/algorithm>
+
#include "cm_uv.h"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
@@ -360,7 +361,7 @@ std::vector<std::string> cmSystemTools::HandleResponseFile(
#else
cmSystemTools::ParseUnixCommandLine(line.c_str(), args2);
#endif
- cmAppend(arg_full, args2);
+ cm::append(arg_full, args2);
}
} else {
arg_full.push_back(arg);
@@ -585,7 +586,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
cmSystemTools::Stdout(strdata);
}
if (captureStdOut) {
- cmAppend(tempStdOut, data, data + length);
+ cm::append(tempStdOut, data, data + length);
}
} else if (pipe == cmsysProcess_Pipe_STDERR) {
if (outputflag != OUTPUT_NONE) {
@@ -593,7 +594,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
cmSystemTools::Stderr(strdata);
}
if (captureStdErr) {
- cmAppend(tempStdErr, data, data + length);
+ cm::append(tempStdErr, data, data + length);
}
}
}
@@ -814,6 +815,8 @@ void cmSystemTools::InitializeLibUV()
# else
_fmode = _O_TEXT;
# endif
+ // Replace libuv's report handler with our own to suppress popups.
+ cmSystemTools::EnableMSVCDebugHook();
#endif
}
@@ -1710,26 +1713,26 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
processOutput.DecodeText(data, length, strdata, 1);
// Append to the stdout buffer.
std::vector<char>::size_type size = out.size();
- cmAppend(out, strdata);
+ cm::append(out, strdata);
outiter = out.begin() + size;
} else if (pipe == cmsysProcess_Pipe_STDERR) {
processOutput.DecodeText(data, length, strdata, 2);
// Append to the stderr buffer.
std::vector<char>::size_type size = err.size();
- cmAppend(err, strdata);
+ cm::append(err, strdata);
erriter = err.begin() + size;
} else if (pipe == cmsysProcess_Pipe_None) {
// Both stdout and stderr pipes have broken. Return leftover data.
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
std::vector<char>::size_type size = out.size();
- cmAppend(out, strdata);
+ cm::append(out, strdata);
outiter = out.begin() + size;
}
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
std::vector<char>::size_type size = err.size();
- cmAppend(err, strdata);
+ cm::append(err, strdata);
erriter = err.begin() + size;
}
if (!out.empty()) {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 80986fca44..97d7fcea3d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -12,6 +12,7 @@
#include <unordered_set>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -38,13 +39,13 @@
#include "cmake.h"
template <>
-const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
+const std::string& cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
cmTarget const* tgt)
{
static std::string loc;
if (tgt->IsImported()) {
loc = tgt->ImportedGetFullPath("", cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
@@ -53,18 +54,18 @@ const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
}
cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
loc = gt->GetLocationForBuild();
- return loc.c_str();
+ return loc;
}
template <>
-const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
+const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>(
cmTarget const* tgt, const std::string& config)
{
static std::string loc;
if (tgt->IsImported()) {
loc =
tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
@@ -73,7 +74,7 @@ const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
}
cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
loc = gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
template <>
@@ -176,7 +177,8 @@ public:
bool IsImportedTarget;
bool ImportedGloballyVisible;
bool BuildInterfaceIncludesAppended;
- std::set<BT<std::string>> Utilities;
+ bool PerConfig;
+ std::set<BT<std::pair<std::string, bool>>> Utilities;
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
@@ -213,7 +215,7 @@ public:
};
cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf)
+ Visibility vis, cmMakefile* mf, bool perConfig)
: impl(cm::make_unique<cmTargetInternals>())
{
assert(mf);
@@ -229,6 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
impl->BuildInterfaceIncludesAppended = false;
+ impl->PerConfig = perConfig;
// Check whether this is a DLL platform.
impl->IsDLLPlatform =
@@ -355,9 +358,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("CUDA_COMPILER_LAUNCHER");
initProp("CUDA_SEPARABLE_COMPILATION");
initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
+ initProp("CUDA_RUNTIME_LIBRARY");
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");
@@ -373,6 +376,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("XCODE_SCHEME_THREAD_SANITIZER_STOP");
initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER");
initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP");
+ initProp("XCODE_SCHEME_WORKING_DIRECTORY");
initProp("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER");
initProp("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP");
initProp("XCODE_SCHEME_MALLOC_SCRIBBLE");
@@ -382,11 +386,14 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("XCODE_SCHEME_MALLOC_STACK");
initProp("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE");
initProp("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS");
+ initProp("XCODE_SCHEME_ENVIRONMENT");
}
#endif
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ initProp("FOLDER");
+
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_GENERATE_SCHEME");
}
@@ -437,30 +444,30 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (!this->IsImported()) {
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- cmAppend(impl->IncludeDirectoriesEntries,
- impl->Makefile->GetIncludeDirectoriesEntries());
- cmAppend(impl->IncludeDirectoriesBacktraces,
- impl->Makefile->GetIncludeDirectoriesBacktraces());
+ cm::append(impl->IncludeDirectoriesEntries,
+ impl->Makefile->GetIncludeDirectoriesEntries());
+ cm::append(impl->IncludeDirectoriesBacktraces,
+ impl->Makefile->GetIncludeDirectoriesBacktraces());
{
auto const& sysInc = impl->Makefile->GetSystemIncludeDirectories();
impl->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end());
}
- cmAppend(impl->CompileOptionsEntries,
- impl->Makefile->GetCompileOptionsEntries());
- cmAppend(impl->CompileOptionsBacktraces,
- impl->Makefile->GetCompileOptionsBacktraces());
+ cm::append(impl->CompileOptionsEntries,
+ impl->Makefile->GetCompileOptionsEntries());
+ cm::append(impl->CompileOptionsBacktraces,
+ impl->Makefile->GetCompileOptionsBacktraces());
- cmAppend(impl->LinkOptionsEntries,
- impl->Makefile->GetLinkOptionsEntries());
- cmAppend(impl->LinkOptionsBacktraces,
- impl->Makefile->GetLinkOptionsBacktraces());
+ cm::append(impl->LinkOptionsEntries,
+ impl->Makefile->GetLinkOptionsEntries());
+ cm::append(impl->LinkOptionsBacktraces,
+ impl->Makefile->GetLinkOptionsBacktraces());
- cmAppend(impl->LinkDirectoriesEntries,
- impl->Makefile->GetLinkDirectoriesEntries());
- cmAppend(impl->LinkDirectoriesBacktraces,
- impl->Makefile->GetLinkDirectoriesBacktraces());
+ cm::append(impl->LinkDirectoriesEntries,
+ impl->Makefile->GetLinkDirectoriesEntries());
+ cm::append(impl->LinkDirectoriesBacktraces,
+ impl->Makefile->GetLinkDirectoriesBacktraces());
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
@@ -484,6 +491,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
impl->TargetType == cmStateEnums::EXECUTABLE) {
+ initProp("AIX_EXPORT_ALL_SYMBOLS");
initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
}
@@ -507,14 +515,15 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->GetType() != cmStateEnums::UTILITY) {
initProp("JOB_POOL_COMPILE");
initProp("JOB_POOL_LINK");
+ initProp("JOB_POOL_PRECOMPILE_HEADER");
}
if (impl->TargetType <= cmStateEnums::UTILITY) {
+ initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
- if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
- this->GetType() != cmStateEnums::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
// check for "CMAKE_VS_GLOBALS" variable and set up target properties
// if any
@@ -574,13 +583,14 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
return impl->Makefile->GetGlobalGenerator();
}
-void cmTarget::AddUtility(std::string const& name, cmMakefile* mf)
+void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
{
- impl->Utilities.insert(
- BT<std::string>(name, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
+ impl->Utilities.insert(BT<std::pair<std::string, bool>>(
+ { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
}
-std::set<BT<std::string>> const& cmTarget::GetUtilities() const
+std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
+ const
{
return impl->Utilities;
}
@@ -932,14 +942,7 @@ cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries()
return impl->OriginalLinkLibraries;
}
-void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
- cmTargetLinkLibraryType llt)
-{
- this->AddLinkLibrary(mf, lib, lib, llt);
-}
-
void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
- std::string const& libRef,
cmTargetLinkLibraryType llt)
{
cmTarget* tgt = mf.FindTargetToUse(lib);
@@ -948,14 +951,13 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
const std::string libName =
(isNonImportedTarget && llt != GENERAL_LibraryType)
- ? targetNameGenex(libRef)
- : libRef;
- this->AppendProperty(
- "LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(libName, llt).c_str());
+ ? targetNameGenex(lib)
+ : lib;
+ this->AppendProperty("LINK_LIBRARIES",
+ this->GetDebugGeneratorExpressions(libName, llt));
}
- if (cmGeneratorExpression::Find(lib) != std::string::npos || lib != libRef ||
+ if (cmGeneratorExpression::Find(lib) != std::string::npos ||
(tgt &&
(tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
@@ -1286,20 +1288,20 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
impl->Properties.SetProperty(prop, reusedFrom.c_str());
- reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str());
+ reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- cmStrCat(reusedFrom, ".dir/").c_str());
+ cmStrCat(reusedFrom, ".dir/"));
this->SetProperty("COMPILE_PDB_NAME",
reusedTarget->GetProperty("COMPILE_PDB_NAME"));
- this->AddUtility(reusedFrom, impl->Makefile);
+ this->AddUtility(reusedFrom, false, impl->Makefile);
} else {
impl->Properties.SetProperty(prop, value);
}
}
-void cmTarget::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmTarget::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
if (!cmTargetPropertyComputer::PassesWhitelist(
this->GetType(), prop, impl->Makefile->GetMessenger(),
@@ -1334,37 +1336,37 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
return;
}
if (prop == "INCLUDE_DIRECTORIES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->IncludeDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->IncludeDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_OPTIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_FEATURES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileFeaturesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileFeaturesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_DEFINITIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileDefinitionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileDefinitionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_OPTIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->LinkOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_DIRECTORIES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->LinkDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
@@ -1378,13 +1380,13 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
- if (value && *value) {
+ if (!value.empty()) {
impl->PrecompileHeadersEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->PrecompileHeadersBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_LIBRARIES") {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkImplementationPropertyEntries.emplace_back(value);
impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
@@ -1423,7 +1425,7 @@ void cmTarget::AppendBuildInterfaceIncludes()
dirs += impl->Makefile->GetCurrentSourceDirectory();
if (!dirs.empty()) {
this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
- ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+ ("$<BUILD_INTERFACE:" + dirs + ">"));
}
}
}
@@ -1558,8 +1560,12 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
cmMakefile* context)
{
- std::vector<cmTarget*> targets = context->GetOwnedImportedTargets();
- auto it = std::find(targets.begin(), targets.end(), target);
+ const auto& targets = context->GetOwnedImportedTargets();
+ auto it =
+ std::find_if(targets.begin(), targets.end(),
+ [&](const std::unique_ptr<cmTarget>& importTarget) -> bool {
+ return target == importTarget.get();
+ });
if (it == targets.end()) {
std::ostringstream e;
e << "Attempt to promote imported target \"" << target->GetName()
@@ -1715,7 +1721,14 @@ const char* cmTarget::GetProperty(const std::string& prop) const
}
static std::string output;
- output = cmJoin(impl->Utilities, ";");
+ static std::vector<std::string> utilities;
+ utilities.resize(impl->Utilities.size());
+ std::transform(
+ impl->Utilities.cbegin(), impl->Utilities.cend(), utilities.begin(),
+ [](const BT<std::pair<std::string, bool>>& item) -> std::string {
+ return item.Value.first;
+ });
+ output = cmJoin(utilities, ";");
return output.c_str();
}
if (prop == propPRECOMPILE_HEADERS) {
@@ -1801,6 +1814,11 @@ bool cmTarget::IsImportedGloballyVisible() const
return impl->ImportedGloballyVisible;
}
+bool cmTarget::IsPerConfig() const
+{
+ return impl->PerConfig;
+}
+
const char* cmTarget::GetSuffixVariableInternal(
cmStateEnums::ArtifactType artifact) const
{
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 65a1ce36fd..286933b515 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -44,7 +44,7 @@ public:
};
cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf);
+ Visibility vis, cmMakefile* mf, bool perConfig);
cmTarget(cmTarget const&) = delete;
cmTarget(cmTarget&&) noexcept;
@@ -110,10 +110,8 @@ public:
//! Clear the dependency information recorded for this target, if any.
void ClearDependencyInformation(cmMakefile& mf);
- void AddLinkLibrary(cmMakefile& mf, const std::string& lib,
- cmTargetLinkLibraryType llt);
void AddLinkLibrary(cmMakefile& mf, std::string const& lib,
- std::string const& libRef, cmTargetLinkLibraryType llt);
+ cmTargetLinkLibraryType llt);
enum TLLSignature
{
@@ -158,13 +156,18 @@ public:
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
* commands. It is not a full path nor does it have an extension.
*/
- void AddUtility(std::string const& name, cmMakefile* mf = nullptr);
+ void AddUtility(std::string const& name, bool cross,
+ cmMakefile* mf = nullptr);
//! Get the utilities used by this target
- std::set<BT<std::string>> const& GetUtilities() const;
+ std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ SetProperty(prop, value.c_str());
+ }
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
const char* GetProperty(const std::string& prop) const;
@@ -186,6 +189,7 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
+ bool IsPerConfig() const;
bool GetMappedConfig(std::string const& desired_config, const char** loc,
const char** imp, std::string& suffix) const;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index edee167004..b56b245de5 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -28,7 +28,7 @@ private:
const std::vector<std::string>& content,
bool /*prepend*/, bool /*system*/) override
{
- tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+ tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content));
return true; // Successfully handled.
}
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index e39b726705..dee2c10a39 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -5,6 +5,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmTargetPropCommandBase.h"
@@ -27,10 +28,16 @@ private:
bool HandleDirectContent(cmTarget* tgt,
const std::vector<std::string>& content,
- bool /*prepend*/, bool /*system*/) override
+ bool prepend, bool /*system*/) override
{
+ cmPolicies::PolicyStatus policyStatus =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0101);
+ if (policyStatus == cmPolicies::OLD || policyStatus == cmPolicies::WARN) {
+ prepend = false;
+ }
+
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- tgt->InsertCompileOption(this->Join(content), lfbt);
+ tgt->InsertCompileOption(this->Join(content), lfbt, prepend);
return true; // Successfully handled.
}
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 4ca78faa9a..5452cc7fba 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -19,6 +19,7 @@ class cmTargetDepend
// mutable members to achieve a map with set syntax.
mutable bool Link;
mutable bool Util;
+ mutable bool Cross;
mutable cmListFileBacktrace Backtrace;
public:
@@ -26,6 +27,7 @@ public:
: Target(t)
, Link(false)
, Util(false)
+ , Cross(false)
{
}
operator cmGeneratorTarget const*() const { return this->Target; }
@@ -43,12 +45,14 @@ public:
this->Link = true;
}
}
+ void SetCross(bool cross) const { this->Cross = cross; }
void SetBacktrace(cmListFileBacktrace const& bt) const
{
this->Backtrace = bt;
}
bool IsLink() const { return this->Link; }
bool IsUtil() const { return this->Util; }
+ bool IsCross() const { return this->Cross; }
cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; }
};
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 95b69f3998..35635b94b8 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -88,8 +88,7 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
system);
if (system) {
std::string joined = this->Join(content);
- tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
- joined.c_str());
+ tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined);
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 0d2383a1cd..df751da080 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -3,7 +3,10 @@
#include "cmTargetLinkLibrariesCommand.h"
#include <cstring>
+#include <memory>
#include <sstream>
+#include <unordered_set>
+#include <utility>
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -34,15 +37,30 @@ enum ProcessingState
const char* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" };
+struct TLL
+{
+ cmMakefile& Makefile;
+ cmTarget* Target;
+ bool WarnRemoteInterface = false;
+ bool RejectRemoteLinking = false;
+ bool EncodeRemoteReference = false;
+ std::string DirectoryId;
+ std::unordered_set<std::string> Props;
+
+ TLL(cmMakefile& mf, cmTarget* target);
+ ~TLL();
+
+ bool HandleLibrary(ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt);
+ void AppendProperty(std::string const& prop, std::string const& value);
+ void AffectsProperty(std::string const& prop);
+};
+
} // 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)
{
@@ -64,11 +82,9 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
cmTarget* target =
mf.GetCMakeInstance()->GetGlobalGenerator()->FindTarget(args[0]);
if (!target) {
- const std::vector<cmTarget*>& importedTargets =
- mf.GetOwnedImportedTargets();
- for (cmTarget* importedTarget : importedTargets) {
+ for (const auto& importedTarget : mf.GetOwnedImportedTargets()) {
if (importedTarget->GetName() == args[0]) {
- target = importedTarget;
+ target = importedTarget.get();
break;
}
}
@@ -149,6 +165,8 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
return true;
}
+ TLL tll(mf, target);
+
// Keep track of link configuration specifiers.
cmTargetLinkLibraryType llt = GENERAL_LibraryType;
bool haveLLT = false;
@@ -247,7 +265,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
} else if (haveLLT) {
// The link type was specified by the previous argument.
haveLLT = false;
- if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
+ if (!tll.HandleLibrary(currentProcessingState, args[i], llt)) {
return false;
}
} else {
@@ -268,7 +286,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
llt = OPTIMIZED_LibraryType;
}
}
- if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
+ if (!tll.HandleLibrary(currentProcessingState, args[i], llt)) {
return false;
}
}
@@ -311,21 +329,48 @@ static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
"\" instead of a library name. The first specifier will be ignored."));
}
-static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
- ProcessingState currentProcessingState,
- const std::string& lib, cmTargetLinkLibraryType llt)
+namespace {
+
+TLL::TLL(cmMakefile& mf, cmTarget* target)
+ : Makefile(mf)
+ , Target(target)
+{
+ if (&this->Makefile != this->Target->GetMakefile()) {
+ // The LHS target was created in another directory.
+ switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0079)) {
+ case cmPolicies::WARN:
+ this->WarnRemoteInterface = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ this->RejectRemoteLinking = true;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ this->EncodeRemoteReference = true;
+ break;
+ }
+ }
+ if (this->EncodeRemoteReference) {
+ cmDirectoryId const dirId = this->Makefile.GetDirectoryId();
+ this->DirectoryId = cmStrCat(CMAKE_DIRECTORY_ID_SEP, dirId.String);
+ }
+}
+
+bool TLL::HandleLibrary(ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt)
{
- if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
+ if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
currentProcessingState != ProcessingKeywordLinkInterface) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
"INTERFACE library can only be used with the INTERFACE keyword of "
"target_link_libraries");
return false;
}
- if (target->IsImported() &&
+ if (this->Target->IsImported() &&
currentProcessingState != ProcessingKeywordLinkInterface) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
"IMPORTED library can only be used with the INTERFACE keyword of "
"target_link_libraries");
@@ -340,11 +385,12 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
currentProcessingState == ProcessingKeywordLinkInterface)
? cmTarget::KeywordTLLSignature
: cmTarget::PlainTLLSignature;
- if (!target->PushTLLCommandTrace(sig, mf.GetExecutionContext())) {
+ if (!this->Target->PushTLLCommandTrace(
+ sig, this->Makefile.GetExecutionContext())) {
std::ostringstream e;
const char* modal = nullptr;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (mf.GetPolicyStatus(cmPolicies::CMP0023)) {
+ switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0023)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
modal = "should";
@@ -365,73 +411,38 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
e << "The " << existingSig
<< " signature for target_link_libraries has "
"already been used with the target \""
- << target->GetName()
+ << this->Target->GetName()
<< "\". All uses of target_link_libraries with a target " << modal
<< " be either all-keyword or all-plain.\n";
- target->GetTllSignatureTraces(e,
- sig == cmTarget::KeywordTLLSignature
- ? cmTarget::PlainTLLSignature
- : cmTarget::KeywordTLLSignature);
- mf.IssueMessage(messageType, e.str());
+ this->Target->GetTllSignatureTraces(e,
+ sig == cmTarget::KeywordTLLSignature
+ ? cmTarget::PlainTLLSignature
+ : cmTarget::KeywordTLLSignature);
+ this->Makefile.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
}
}
- bool warnRemoteInterface = false;
- bool rejectRemoteLinking = false;
- bool encodeRemoteReference = false;
- if (&mf != target->GetMakefile()) {
- // The LHS target was created in another directory.
- switch (mf.GetPolicyStatus(cmPolicies::CMP0079)) {
- case cmPolicies::WARN:
- warnRemoteInterface = true;
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- rejectRemoteLinking = true;
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- encodeRemoteReference = true;
- break;
- }
- }
-
- std::string libRef;
- if (encodeRemoteReference && !cmSystemTools::FileIsFullPath(lib)) {
- // This is a library name added by a caller that is not in the
- // 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 = mf.GetDirectoryId();
- libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String;
- } else {
- // This is an absolute path or a library name added by a caller
- // in the same directory as the target was created. We can use
- // the original name directly.
- libRef = 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 (currentProcessingState != ProcessingKeywordLinkInterface &&
currentProcessingState != ProcessingPlainLinkInterface) {
- if (rejectRemoteLinking) {
- mf.IssueMessage(
+ if (this->RejectRemoteLinking) {
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Attempt to add link library \"", lib, "\" to target \"",
- target->GetName(),
+ this->Target->GetName(),
"\" which is not built in this "
"directory.\nThis is allowed only when policy CMP0079 "
"is set to NEW."));
return false;
}
- cmTarget* tgt = mf.GetGlobalGenerator()->FindTarget(lib);
+ cmTarget* tgt = this->Makefile.GetGlobalGenerator()->FindTarget(lib);
if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
(tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
@@ -439,7 +450,7 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
(tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
(tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
!tgt->IsExecutableWithExports()) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
"Target \"", lib, "\" of type ",
@@ -449,15 +460,16 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
"executables with the ENABLE_EXPORTS property set."));
}
- target->AddLinkLibrary(mf, lib, libRef, llt);
+ this->AffectsProperty("LINK_LIBRARIES");
+ this->Target->AddLinkLibrary(this->Makefile, lib, llt);
}
- if (warnRemoteInterface) {
- mf.IssueMessage(
+ if (this->WarnRemoteInterface) {
+ this->Makefile.IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n ",
- target->GetName(),
+ this->Target->GetName(),
"\nis not created in this "
"directory. For compatibility with older versions of CMake, link "
"library\n ",
@@ -472,15 +484,15 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// STATIC library.)
if (currentProcessingState == ProcessingKeywordPrivateInterface ||
currentProcessingState == ProcessingPlainPrivateInterface) {
- if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
- target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::string configLib =
- target->GetDebugGeneratorExpressions(libRef, llt);
+ this->Target->GetDebugGeneratorExpressions(lib, llt);
if (cmGeneratorExpression::IsValidTargetName(lib) ||
cmGeneratorExpression::Find(lib) != std::string::npos) {
configLib = "$<LINK_ONLY:" + configLib + ">";
}
- target->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str());
+ this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib);
}
return true;
}
@@ -488,9 +500,8 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// 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.)
- target->AppendProperty(
- "INTERFACE_LINK_LIBRARIES",
- target->GetDebugGeneratorExpressions(libRef, llt).c_str());
+ this->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ this->Target->GetDebugGeneratorExpressions(lib, llt));
// Stop processing if called without any keyword.
if (currentProcessingState == ProcessingLinkLibraries) {
@@ -498,13 +509,13 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
}
// Stop processing if policy CMP0022 is set to NEW.
const cmPolicies::PolicyStatus policy22Status =
- target->GetPolicyStatusCMP0022();
+ this->Target->GetPolicyStatusCMP0022();
if (policy22Status != cmPolicies::OLD &&
policy22Status != cmPolicies::WARN) {
return true;
}
// Stop processing if called with an INTERFACE library on the LHS.
- if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
@@ -514,7 +525,7 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
{
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> debugConfigs =
- mf.GetCMakeInstance()->GetDebugConfigs();
+ this->Makefile.GetCMakeInstance()->GetDebugConfigs();
std::string prop;
// Include this library in the link interface for the target.
@@ -522,22 +533,49 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// Put in the DEBUG configuration interfaces.
for (std::string const& dc : debugConfigs) {
prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
- target->AppendProperty(prop, libRef.c_str());
+ this->AppendProperty(prop, lib);
}
}
if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
// Put in the non-DEBUG configuration interfaces.
- target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str());
+ this->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
// 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 = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
- if (!target->GetProperty(prop)) {
- target->SetProperty(prop, "");
+ if (!this->Target->GetProperty(prop)) {
+ this->Target->SetProperty(prop, "");
}
}
}
}
return true;
}
+
+void TLL::AppendProperty(std::string const& prop, std::string const& value)
+{
+ this->AffectsProperty(prop);
+ this->Target->AppendProperty(prop, value);
+}
+
+void TLL::AffectsProperty(std::string const& prop)
+{
+ if (!this->EncodeRemoteReference) {
+ return;
+ }
+ // Add a wrapper to the expression to tell LookupLinkItems to look up
+ // names in the caller's directory.
+ if (this->Props.insert(prop).second) {
+ this->Target->AppendProperty(prop, this->DirectoryId);
+ }
+}
+
+TLL::~TLL()
+{
+ for (std::string const& prop : this->Props) {
+ this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP);
+ }
+}
+
+} // namespace
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index c6e2e5c4fe..0670bd962a 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -47,9 +47,8 @@ private:
bool /*prepend*/, bool /*system*/) override
{
std::string const& base = this->Makefile->GetCurrentSourceDirectory();
- tgt->AppendProperty(
- "PRECOMPILE_HEADERS",
- this->Join(ConvertToAbsoluteContent(content, base)).c_str());
+ tgt->AppendProperty("PRECOMPILE_HEADERS",
+ this->Join(ConvertToAbsoluteContent(content, base)));
return true;
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index bbc1e16f76..0de8d6d05a 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -84,9 +84,7 @@ bool cmTargetPropCommandBase::HandleArguments(
}
++argIndex;
- this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM",
- args[argIndex].c_str());
-
+ this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", args[argIndex]);
++argIndex;
}
@@ -162,9 +160,8 @@ void cmTargetPropCommandBase::HandleInterfaceContent(
const char* propValue = tgt->GetProperty(propName);
const std::string totalContent = this->Join(content) +
(propValue ? std::string(";") + propValue : std::string());
- tgt->SetProperty(propName, totalContent.c_str());
+ tgt->SetProperty(propName, totalContent);
} else {
- tgt->AppendProperty("INTERFACE_" + this->Property,
- this->Join(content).c_str());
+ tgt->AppendProperty("INTERFACE_" + this->Property, this->Join(content));
}
}
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index baab8da0ad..f37995c23d 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -62,6 +62,7 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
"COMPATIBLE_INTERFACE_NUMBER_MAX",
"COMPATIBLE_INTERFACE_NUMBER_MIN",
"COMPATIBLE_INTERFACE_STRING",
+ "DEPRECATION",
"EXPORT_NAME",
"EXPORT_PROPERTIES",
"IMPORTED",
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index 3b11acdc13..df34f188d3 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -46,10 +46,10 @@ private:
cmListFileBacktrace const& context);
template <typename Target>
- static const char* ComputeLocationForBuild(Target const* tgt);
+ static const std::string& ComputeLocationForBuild(Target const* tgt);
template <typename Target>
- static const char* ComputeLocation(Target const* tgt,
- std::string const& config);
+ static const std::string& ComputeLocation(Target const* tgt,
+ std::string const& config);
template <typename Target>
static const char* GetLocation(Target const* tgt, std::string const& prop,
@@ -71,7 +71,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocationForBuild(tgt);
+ return ComputeLocationForBuild(tgt).c_str();
}
// Support "LOCATION_<CONFIG>".
@@ -82,7 +82,7 @@ private:
return nullptr;
}
std::string configName = prop.substr(9);
- return ComputeLocation(tgt, configName);
+ return ComputeLocation(tgt, configName).c_str();
}
// Support "<CONFIG>_LOCATION".
@@ -95,7 +95,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocation(tgt, configName);
+ return ComputeLocation(tgt, configName).c_str();
}
}
}
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index c2e0b28fe1..a1fbc9b9b0 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -43,8 +43,7 @@ private:
bool /*prepend*/, bool /*system*/) override
{
tgt->AppendProperty(
- "SOURCES",
- this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
+ "SOURCES", this->Join(ConvertToAbsoluteContent(tgt, content, false)));
return true; // Successfully handled.
}
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index d5c61c1736..3b731cc5bc 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -55,7 +55,7 @@ void cmTest::SetProperty(const std::string& prop, const char* value)
this->Properties.SetProperty(prop, value);
}
-void cmTest::AppendProperty(const std::string& prop, const char* value,
+void cmTest::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
{
this->Properties.AppendProperty(prop, value, asString);
diff --git a/Source/cmTest.h b/Source/cmTest.h
index dd246c4e6b..72d4ed9165 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -35,7 +35,7 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
const char* GetProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 4995da972f..35e1c8c56f 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -2,19 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableWatch.h"
+#include <array>
#include <memory>
#include <utility>
#include <vector>
-static const char* const cmVariableWatchAccessStrings[] = {
- "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
- "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS"
-};
-
-const char* cmVariableWatch::GetAccessAsString(int access_type)
+const std::string& cmVariableWatch::GetAccessAsString(int access_type)
{
+ static const std::array<std::string, 6> cmVariableWatchAccessStrings = {
+ { "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
+ "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS" }
+ };
if (access_type < 0 || access_type >= cmVariableWatch::NO_ACCESS) {
- return "NO_ACCESS";
+ access_type = cmVariableWatch::NO_ACCESS;
}
return cmVariableWatchAccessStrings[access_type];
}
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index e4b3b7c47f..6c418ed0ab 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -46,7 +46,7 @@ public:
*/
enum
{
- VARIABLE_READ_ACCESS = 0,
+ VARIABLE_READ_ACCESS,
UNKNOWN_VARIABLE_READ_ACCESS,
UNKNOWN_VARIABLE_DEFINED_ACCESS,
VARIABLE_MODIFIED_ACCESS,
@@ -57,7 +57,7 @@ public:
/**
* Return the access as string
*/
- static const char* GetAccessAsString(int access_type);
+ static const std::string& GetAccessAsString(int access_type);
protected:
struct Pair
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index f2c8f3cdb9..35b9a1d5b7 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableWatchCommand.h"
+#include <limits>
#include <memory>
#include <utility>
@@ -14,17 +15,19 @@
#include "cmVariableWatch.h"
#include "cmake.h"
+class cmLocalGenerator;
+
+namespace {
struct cmVariableWatchCallbackData
{
bool InCallback;
std::string Command;
};
-static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
- int access_type,
- void* client_data,
- const char* newValue,
- const cmMakefile* mf)
+void cmVariableWatchCommandVariableAccessed(const std::string& variable,
+ int access_type, void* client_data,
+ const char* newValue,
+ const cmMakefile* mf)
{
cmVariableWatchCallbackData* data =
static_cast<cmVariableWatchCallbackData*>(client_data);
@@ -34,40 +37,35 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
}
data->InCallback = true;
- cmListFileFunction newLFF;
- cmListFileArgument arg;
- bool processed = false;
- const char* accessString = cmVariableWatch::GetAccessAsString(access_type);
- const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+ auto accessString = cmVariableWatch::GetAccessAsString(access_type);
/// Ultra bad!!
cmMakefile* makefile = const_cast<cmMakefile*>(mf);
std::string stack = makefile->GetProperty("LISTFILE_STACK");
if (!data->Command.empty()) {
- newLFF.Arguments.clear();
- newLFF.Arguments.emplace_back(variable, cmListFileArgument::Quoted, 9999);
- newLFF.Arguments.emplace_back(accessString, cmListFileArgument::Quoted,
- 9999);
- newLFF.Arguments.emplace_back(newValue ? newValue : "",
- cmListFileArgument::Quoted, 9999);
- newLFF.Arguments.emplace_back(currentListFile, cmListFileArgument::Quoted,
- 9999);
- newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
+ cmListFileFunction newLFF;
+ const char* const currentListFile =
+ mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+ const auto fakeLineNo =
+ std::numeric_limits<decltype(cmListFileArgument::Line)>::max();
+ newLFF.Arguments = {
+ { variable, cmListFileArgument::Quoted, fakeLineNo },
+ { accessString, cmListFileArgument::Quoted, fakeLineNo },
+ { newValue ? newValue : "", cmListFileArgument::Quoted, fakeLineNo },
+ { currentListFile, cmListFileArgument::Quoted, fakeLineNo },
+ { stack, cmListFileArgument::Quoted, fakeLineNo }
+ };
newLFF.Name = data->Command;
- newLFF.Line = 9999;
+ newLFF.Line = fakeLineNo;
cmExecutionStatus status(*makefile);
if (!makefile->ExecuteCommand(newLFF, status)) {
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) {
+ } else {
makefile->IssueMessage(
MessageType::LOG,
cmStrCat("Variable \"", variable, "\" was accessed using ", accessString,
@@ -77,7 +75,7 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
data->InCallback = false;
}
-static void deleteVariableWatchCallbackData(void* client_data)
+void deleteVariableWatchCallbackData(void* client_data)
{
cmVariableWatchCallbackData* data =
static_cast<cmVariableWatchCallbackData*>(client_data);
@@ -91,18 +89,18 @@ class FinalAction
public:
/* NOLINTNEXTLINE(performance-unnecessary-value-param) */
FinalAction(cmMakefile* makefile, std::string variable)
- : Action(std::make_shared<Impl>(makefile, std::move(variable)))
+ : Action{ std::make_shared<Impl>(makefile, std::move(variable)) }
{
}
- void operator()(cmMakefile&) const {}
+ void operator()(cmLocalGenerator&, const cmListFileBacktrace&) const {}
private:
struct Impl
{
Impl(cmMakefile* makefile, std::string variable)
- : Makefile(makefile)
- , Variable(std::move(variable))
+ : Makefile{ makefile }
+ , Variable{ std::move(variable) }
{
}
@@ -112,12 +110,13 @@ private:
this->Variable, cmVariableWatchCommandVariableAccessed);
}
- cmMakefile* Makefile;
- std::string Variable;
+ cmMakefile* const Makefile;
+ std::string const Variable;
};
std::shared_ptr<Impl const> Action;
};
+} // anonymous namespace
bool cmVariableWatchCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -136,10 +135,10 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args,
return false;
}
- cmVariableWatchCallbackData* data = new cmVariableWatchCallbackData;
+ auto* const data = new cmVariableWatchCallbackData;
data->InCallback = false;
- data->Command = command;
+ data->Command = std::move(command);
if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch(
variable, cmVariableWatchCommandVariableAccessed, data,
@@ -148,7 +147,7 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args,
return false;
}
- status.GetMakefile().AddFinalAction(
- FinalAction(&status.GetMakefile(), variable));
+ status.GetMakefile().AddGeneratorAction(
+ FinalAction{ &status.GetMakefile(), variable });
return true;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index f220ea5727..8da113e728 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -6,6 +6,7 @@
#include <set>
#include <cm/memory>
+#include <cm/vector>
#include "windows.h"
@@ -52,7 +53,7 @@ struct cmVisualStudio10TargetGenerator::Elem
bool HasContent = false;
std::string Tag;
- Elem(std::ostream& s, const char* tag)
+ Elem(std::ostream& s, const std::string& tag)
: S(s)
, Indent(0)
, Tag(tag)
@@ -60,7 +61,7 @@ struct cmVisualStudio10TargetGenerator::Elem
this->StartElement();
}
Elem(const Elem&) = delete;
- Elem(Elem& par, const char* tag)
+ Elem(Elem& par, const std::string& tag)
: S(par.S)
, Indent(par.Indent + 1)
, Tag(tag)
@@ -71,13 +72,13 @@ struct cmVisualStudio10TargetGenerator::Elem
void SetHasElements()
{
if (!HasElements) {
- this->S << ">\n";
+ this->S << ">";
HasElements = true;
}
}
std::ostream& WriteString(const char* line);
void StartElement() { this->WriteString("<") << this->Tag; }
- void Element(const char* tag, const std::string& val)
+ void Element(const std::string& tag, const std::string& val)
{
Elem(*this, tag).Content(val);
}
@@ -103,19 +104,14 @@ struct cmVisualStudio10TargetGenerator::Elem
if (HasElements) {
this->WriteString("</") << this->Tag << ">";
- if (this->Indent > 0) {
- this->S << '\n';
- } else {
- // special case: don't print EOL at EOF
- }
} else if (HasContent) {
- this->S << "</" << this->Tag << ">\n";
+ this->S << "</" << this->Tag << ">";
} else {
- this->S << " />\n";
+ this->S << " />";
}
}
- void WritePlatformConfigTag(const char* tag, const std::string& cond,
+ void WritePlatformConfigTag(const std::string& tag, const std::string& cond,
const std::string& content);
};
@@ -131,8 +127,8 @@ public:
{
}
- void OutputFlag(std::ostream& /*fout*/, int /*indent*/, const char* tag,
- const std::string& content) override
+ void OutputFlag(std::ostream& /*fout*/, int /*indent*/,
+ const std::string& tag, const std::string& content) override
{
if (!this->GetConfiguration().empty()) {
// if there are configuration specific flags, then
@@ -274,7 +270,7 @@ std::string cmVisualStudio10TargetGenerator::CalcCondition(
}
void cmVisualStudio10TargetGenerator::Elem::WritePlatformConfigTag(
- const char* tag, const std::string& cond, const std::string& content)
+ const std::string& tag, const std::string& cond, const std::string& content)
{
Elem(*this, tag).Attribute("Condition", cond).Content(content);
}
@@ -282,6 +278,7 @@ void cmVisualStudio10TargetGenerator::Elem::WritePlatformConfigTag(
std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
const char* line)
{
+ this->S << '\n';
this->S.fill(' ');
this->S.width(this->Indent * 2);
// write an empty string to get the fill level indent to print
@@ -334,9 +331,9 @@ void cmVisualStudio10TargetGenerator::Generate()
}
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
- this->Name.c_str());
+ this->Name);
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
- ProjectFileExtension.c_str());
+ ProjectFileExtension);
this->DotNetHintReferences.clear();
this->AdditionalUsingDirectories.clear();
if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
@@ -376,8 +373,7 @@ void cmVisualStudio10TargetGenerator::Generate()
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
BuildFileStream.write(magic, 3);
BuildFileStream << "<?xml version=\"1.0\" encoding=\""
- << this->GlobalGenerator->Encoding() << "\"?>"
- << "\n";
+ << this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(BuildFileStream, "Project");
e0.Attribute("DefaultTargets", "Build");
@@ -488,23 +484,33 @@ void cmVisualStudio10TargetGenerator::Generate()
}
e1.Element("ProjectName", projLabel);
{
- // TODO: add deprecation warning for VS_* property?
- const char* targetFrameworkVersion =
- this->GeneratorTarget->GetProperty(
- "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
- if (!targetFrameworkVersion) {
- targetFrameworkVersion = this->GeneratorTarget->GetProperty(
- "DOTNET_TARGET_FRAMEWORK_VERSION");
- }
- if (!targetFrameworkVersion && this->ProjectType == csproj &&
- this->GlobalGenerator->TargetsWindowsCE() &&
- this->GlobalGenerator->GetVersion() ==
- cmGlobalVisualStudioGenerator::VS12) {
- // VS12 .NETCF default to .NET framework 3.9
- targetFrameworkVersion = "v3.9";
- }
- if (targetFrameworkVersion) {
- e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
+ const char* targetFramework =
+ this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
+ if (targetFramework) {
+ if (std::strchr(targetFramework, ';') != nullptr) {
+ e1.Element("TargetFrameworks", targetFramework);
+ } else {
+ e1.Element("TargetFramework", targetFramework);
+ }
+ } else {
+ // TODO: add deprecation warning for VS_* property?
+ const char* targetFrameworkVersion =
+ this->GeneratorTarget->GetProperty(
+ "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
+ if (!targetFrameworkVersion) {
+ targetFrameworkVersion = this->GeneratorTarget->GetProperty(
+ "DOTNET_TARGET_FRAMEWORK_VERSION");
+ }
+ if (!targetFrameworkVersion && this->ProjectType == csproj &&
+ this->GlobalGenerator->TargetsWindowsCE() &&
+ this->GlobalGenerator->GetVersion() ==
+ cmGlobalVisualStudioGenerator::VS12) {
+ // VS12 .NETCF default to .NET framework 3.9
+ targetFrameworkVersion = "v3.9";
+ }
+ if (targetFrameworkVersion) {
+ e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
+ }
}
if (this->ProjectType == vcxproj &&
this->GlobalGenerator->TargetsWindowsCE()) {
@@ -543,6 +549,11 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("VCProjectUpgraderObjectName", "NoUpgrade");
}
+ if (const char* vcTargetsPath =
+ this->GlobalGenerator->GetCustomVCTargetsPath()) {
+ e1.Element("VCTargetsPath", vcTargetsPath);
+ }
+
std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
for (std::string const& keyIt : keys) {
static const char* prefix = "VS_GLOBAL_";
@@ -557,7 +568,7 @@ void cmVisualStudio10TargetGenerator::Generate()
const char* value = this->GeneratorTarget->GetProperty(keyIt);
if (!value)
continue;
- e1.Element(globalKey.c_str(), value);
+ e1.Element(globalKey, value);
}
if (this->Managed) {
@@ -676,6 +687,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WritePlatformExtensions(e1);
}
+
+ this->WriteDotNetDocumentationFile(e0);
Elem(e0, "PropertyGroup").Attribute("Label", "UserMacros");
this->WriteWinRTPackageCertificateKeyFile(e0);
this->WritePathAndIncrementalLinkOptions(e0);
@@ -906,7 +919,19 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
}
}
for (auto const& tag : tags) {
- e2.Element(tag.first.c_str(), tag.second);
+ e2.Element(tag.first, tag.second);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
+{
+ std::string const documentationFile =
+ this->GeneratorTarget->GetSafeProperty("VS_DOTNET_DOCUMENTATION_FILE");
+
+ if (this->ProjectType == csproj && !documentationFile.empty()) {
+ Elem e1(e0, "PropertyGroup");
+ Elem e2(e1, "DocumentationFile");
+ e2.Content(documentationFile);
}
}
@@ -1000,7 +1025,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
if (!tagName.empty()) {
std::string value = props.GetPropertyValue(p);
if (!value.empty()) {
- e2.Element(tagName.c_str(), value);
+ e2.Element(tagName, value);
}
}
}
@@ -1598,8 +1623,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
fout.write(magic, 3);
fout << "<?xml version=\"1.0\" encoding=\""
- << this->GlobalGenerator->Encoding() << "\"?>"
- << "\n";
+ << this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(fout, "Project");
e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
@@ -1738,7 +1762,7 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
std::string const& filter = sourceGroup->GetFullName();
std::string path = this->ConvertPath(source, s.RelativePath);
ConvertToWindowsSlash(path);
- Elem e2(e1, name.c_str());
+ Elem e2(e1, name);
e2.Attribute("Include", path);
if (!filter.empty()) {
e2.Element("Filter", filter);
@@ -2624,9 +2648,9 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
// Some link options belong here. Use them now and remove them so that
// WriteLinkOptions does not use them.
- const char* flags[] = { "LinkDelaySign", "LinkKeyFile", 0 };
- for (const char** f = flags; *f; ++f) {
- const char* flag = *f;
+ static const std::vector<std::string> flags{ "LinkDelaySign",
+ "LinkKeyFile" };
+ for (const std::string& flag : flags) {
if (const char* value = linkOptions.GetFlag(flag)) {
e1.WritePlatformConfigTag(flag, cond, value);
linkOptions.RemoveFlag(flag);
@@ -2790,6 +2814,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
case csproj:
this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
"CSharp");
+ cm::erase_if(targetDefines, [](std::string const& def) {
+ return def.find('=') != std::string::npos;
+ });
break;
}
clOptions.AddDefines(targetDefines);
@@ -2818,10 +2845,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
if (this->MSTools) {
- // If we have the VS_WINRT_COMPONENT or CMAKE_VS_WINRT_BY_DEFAULT
- // set then force Compile as WinRT.
- if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
- this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) {
+ // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT
+ if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT")) {
clOptions.AddFlag("CompileAsWinRT", "true");
// For WinRT components, add the _WINRT_DLL define to produce a lib
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -2829,7 +2854,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.AddDefine("_WINRT_DLL");
}
} else if (this->GlobalGenerator->TargetsWindowsStore() ||
- this->GlobalGenerator->TargetsWindowsPhone()) {
+ this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) {
if (!clOptions.IsWinRt()) {
clOptions.AddFlag("CompileAsWinRT", "false");
}
@@ -3626,18 +3652,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
this->AddLibraries(cli, libVec, vsTargetVec, config);
if (cmContains(linkClosure->Languages, "CUDA") &&
this->CudaOptions[config] != nullptr) {
- switch (this->CudaOptions[config]->GetCudaRuntime()) {
- case cmVisualStudioGeneratorOptions::CudaRuntimeStatic:
- libVec.push_back("cudadevrt.lib");
- libVec.push_back("cudart_static.lib");
- break;
- case cmVisualStudioGeneratorOptions::CudaRuntimeShared:
- libVec.push_back("cudadevrt.lib");
- libVec.push_back("cudart.lib");
- break;
- case cmVisualStudioGeneratorOptions::CudaRuntimeNone:
- break;
- }
+ this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
}
std::string standardLibsVar =
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
@@ -4027,8 +4042,8 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
}
void cmVisualStudio10TargetGenerator::WriteEvent(
- Elem& e1, const char* name, std::vector<cmCustomCommand> const& commands,
- std::string const& configName)
+ Elem& e1, const std::string& name,
+ std::vector<cmCustomCommand> const& commands, std::string const& configName)
{
if (commands.empty()) {
return;
@@ -4100,6 +4115,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}");
e2.Element("Name", name);
this->WriteDotNetReferenceCustomTags(e2, name);
+ if (dt->IsCSharpOnly() || cmHasLiteralSuffix(path, "csproj")) {
+ e2.Element("SkipGetTargetFrameworkProperties", "true");
+ }
// Don't reference targets that don't produce any output.
if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
@@ -4847,7 +4865,7 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties(
Elem& e2, const std::map<std::string, std::string>& tags)
{
for (const auto& i : tags) {
- e2.Element(i.first.c_str(), i.second);
+ e2.Element(i.first, i.second);
}
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index a18a33dd89..30027c9e72 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -79,6 +79,7 @@ private:
void WriteDotNetReference(Elem& e1, std::string const& ref,
std::string const& hint,
std::string const& config);
+ void WriteDotNetDocumentationFile(Elem& e0);
void WriteImports(Elem& e0);
void WriteDotNetReferenceCustomTags(Elem& e2, std::string const& ref);
void WriteEmbeddedResourceGroup(Elem& e0);
@@ -164,7 +165,7 @@ private:
void WriteLibOptions(Elem& e1, std::string const& config);
void WriteManifestOptions(Elem& e1, std::string const& config);
void WriteEvents(Elem& e1, std::string const& configName);
- void WriteEvent(Elem& e1, const char* name,
+ void WriteEvent(Elem& e1, std::string const& name,
std::vector<cmCustomCommand> const& commands,
std::string const& configName);
void WriteGroupSources(Elem& e0, std::string const& name,
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 1139aa9745..4004b66485 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -3,6 +3,8 @@
#include <cm/iterator>
#include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmOutputConverter.h"
#include "cmSystemTools.h"
@@ -149,25 +151,33 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const
return false;
}
-cmVisualStudioGeneratorOptions::CudaRuntime
-cmVisualStudioGeneratorOptions::GetCudaRuntime() const
+void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target)
{
std::map<std::string, FlagValue>::const_iterator i =
this->FlagMap.find("CudaRuntime");
- if (i != this->FlagMap.end() && i->second.size() == 1) {
- std::string const& cudaRuntime = i->second[0];
- if (cudaRuntime == "Static") {
- return CudaRuntimeStatic;
- }
- if (cudaRuntime == "Shared") {
- return CudaRuntimeShared;
- }
- if (cudaRuntime == "None") {
- return CudaRuntimeNone;
+ if (i == this->FlagMap.end()) {
+ // User didn't provide am override so get the property value
+ const char* runtimeLibraryValue =
+ target->GetProperty("CUDA_RUNTIME_LIBRARY");
+ if (runtimeLibraryValue) {
+ std::string cudaRuntime =
+ cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+ runtimeLibraryValue, this->LocalGenerator, this->Configuration,
+ target));
+ if (cudaRuntime == "STATIC") {
+ this->AddFlag("CudaRuntime", "Static");
+ }
+ if (cudaRuntime == "SHARED") {
+ this->AddFlag("CudaRuntime", "Shared");
+ }
+ if (cudaRuntime == "NONE") {
+ this->AddFlag("CudaRuntime", "None");
+ }
+ } else {
+ // nvcc default is static
+ this->AddFlag("CudaRuntime", "Static");
}
}
- // nvcc default is static
- return CudaRuntimeStatic;
}
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
@@ -431,7 +441,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
if (this->Defines.empty()) {
return;
}
- const char* tag = "PreprocessorDefinitions";
+ std::string tag = "PreprocessorDefinitions";
if (lang == "CUDA") {
tag = "Defines";
}
@@ -473,7 +483,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
return;
}
- const char* tag = "AdditionalIncludeDirectories";
+ std::string tag = "AdditionalIncludeDirectories";
if (lang == "CUDA") {
tag = "Include";
} else if (lang == "ASM_MASM" || lang == "ASM_NASM") {
@@ -528,6 +538,6 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
sep = ";";
}
- this->OutputFlag(fout, indent, m.first.c_str(), oss.str());
+ this->OutputFlag(fout, indent, m.first, oss.str());
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 560593e011..b335694f28 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -13,6 +13,7 @@
#include "cmIDEOptions.h"
class cmLocalVisualStudioGenerator;
+class cmGeneratorTarget;
using cmVS7FlagTable = cmIDEFlagTable;
@@ -61,15 +62,8 @@ public:
bool UsingUnicode() const;
bool UsingSBCS() const;
- enum CudaRuntime
- {
- CudaRuntimeStatic,
- CudaRuntimeShared,
- CudaRuntimeNone
- };
- CudaRuntime GetCudaRuntime() const;
-
void FixCudaCodeGeneration();
+ void FixCudaRuntime(cmGeneratorTarget* target);
void FixManifestUACFlags();
@@ -86,7 +80,8 @@ public:
const std::string& GetConfiguration() const;
protected:
- virtual void OutputFlag(std::ostream& fout, int indent, const char* tag,
+ virtual void OutputFlag(std::ostream& fout, int indent,
+ const std::string& tag,
const std::string& content) = 0;
private:
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index afc95f56c5..b34c2f6e14 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -8,13 +8,16 @@
#include <utility>
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmXMLSafe.h"
-cmXCodeScheme::cmXCodeScheme(cmXCodeObject* xcObj, TestObjects tests,
+cmXCodeScheme::cmXCodeScheme(cmLocalGenerator* lg, cmXCodeObject* xcObj,
+ TestObjects tests,
const std::vector<std::string>& configList,
unsigned int xcVersion)
- : Target(xcObj)
+ : LocalGenerator(lg)
+ , Target(xcObj)
, Tests(std::move(tests))
, TargetName(xcObj->GetTarget()->GetName())
, ConfigList(configList)
@@ -135,7 +138,8 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
xout.Attribute("selectedLauncherIdentifier",
"Xcode.DebuggerFoundation.Launcher.LLDB");
xout.Attribute("launchStyle", "0");
- xout.Attribute("useCustomWorkingDirectory", "NO");
+ WriteCustomWorkingDirectory(xout, configuration);
+
xout.Attribute("ignoresPersistentStateOnLaunch", "NO");
WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
"XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
@@ -355,7 +359,7 @@ void cmXCodeScheme::WriteProfileAction(cmXMLWriter& xout,
xout.Attribute("buildConfiguration", configuration);
xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
xout.Attribute("savedToolIdentifier", "");
- xout.Attribute("useCustomWorkingDirectory", "NO");
+ WriteCustomWorkingDirectory(xout, configuration);
WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
"XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
true);
@@ -395,6 +399,22 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
xout.EndElement();
}
+void cmXCodeScheme::WriteCustomWorkingDirectory(
+ cmXMLWriter& xout, const std::string& configuration)
+{
+ std::string propertyValue = this->Target->GetTarget()->GetSafeProperty(
+ "XCODE_SCHEME_WORKING_DIRECTORY");
+ if (propertyValue.empty()) {
+ xout.Attribute("useCustomWorkingDirectory", "NO");
+ } else {
+ xout.Attribute("useCustomWorkingDirectory", "YES");
+
+ auto customWorkingDirectory = cmGeneratorExpression::Evaluate(
+ propertyValue, this->LocalGenerator, configuration);
+ xout.Attribute("customWorkingDirectory", customWorkingDirectory);
+ }
+}
+
std::string cmXCodeScheme::WriteVersionString()
{
std::ostringstream v;
diff --git a/Source/cmXCodeScheme.h b/Source/cmXCodeScheme.h
index dff5e35e39..da4085669f 100644
--- a/Source/cmXCodeScheme.h
+++ b/Source/cmXCodeScheme.h
@@ -20,7 +20,7 @@ class cmXCodeScheme
public:
using TestObjects = std::vector<const cmXCodeObject*>;
- cmXCodeScheme(cmXCodeObject* xcObj, TestObjects tests,
+ cmXCodeScheme(cmLocalGenerator* lg, cmXCodeObject* xcObj, TestObjects tests,
const std::vector<std::string>& configList,
unsigned int xcVersion);
@@ -28,6 +28,7 @@ public:
const std::string& container);
private:
+ cmLocalGenerator* const LocalGenerator;
const cmXCodeObject* const Target;
const TestObjects Tests;
const std::string& TargetName;
@@ -63,6 +64,9 @@ private:
void WriteBuildableReference(cmXMLWriter& xout, const cmXCodeObject* xcObj,
const std::string& container);
+ void WriteCustomWorkingDirectory(cmXMLWriter& xout,
+ const std::string& configuration);
+
std::string WriteVersionString();
std::string FindConfiguration(const std::string& name);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f63a264006..a99d9a633f 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2,12 +2,27 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmake.h"
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <initializer_list>
+#include <iostream>
+#include <sstream>
+#include <utility>
+
#include <cm/memory>
#include <cm/string_view>
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
# include <cm/iterator>
#endif
+#include <cmext/algorithm>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cm_sys_stat.h"
#include "cmAlgorithms.h"
@@ -56,6 +71,8 @@
// include the generator
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
+# include <cmext/memory>
+
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalJOMMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
@@ -106,19 +123,6 @@
# include <sys/time.h>
#endif
-#include <algorithm>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <initializer_list>
-#include <iostream>
-#include <sstream>
-#include <utility>
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-
namespace {
#if !defined(CMAKE_BOOTSTRAP)
@@ -201,14 +205,7 @@ cmake::cmake(Role role, cmState::Mode mode)
}
}
-cmake::~cmake()
-{
- if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
- }
- cmDeleteAll(this->Generators);
-}
+cmake::~cmake() = default;
#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmake::ReportVersionJson() const
@@ -330,9 +327,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
} else {
- std::cerr << "Parse error in command line argument: " << arg << "\n"
- << "Should be: VAR:type=value\n";
- cmSystemTools::Error("No cmake script provided.");
+ cmSystemTools::Error("Parse error in command line argument: " + arg +
+ "\n" + "Should be: VAR:type=value\n");
return false;
}
} else if (cmHasLiteralPrefix(arg, "-W")) {
@@ -393,7 +389,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
cmsys::RegularExpression regex(
- cmsys::Glob::PatternToRegex(entryPattern, true, true).c_str());
+ cmsys::Glob::PatternToRegex(entryPattern, true, true));
// go through all cache entries and collect the vars which will be
// removed
std::vector<std::string> entriesToDelete;
@@ -422,7 +418,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- std::cout << "loading initial cache file " << path << "\n";
+ cmSystemTools::Stdout("loading initial cache file " + path + "\n");
// Resolve script path specified on command line relative to $PWD.
path = cmSystemTools::CollapseFullPath(path);
this->ReadListFile(args, path);
@@ -462,12 +458,12 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
{
// if a generator was not yet created, temporarily create one
cmGlobalGenerator* gg = this->GetGlobalGenerator();
- bool created = false;
// if a generator was not specified use a generic one
+ std::unique_ptr<cmGlobalGenerator> gen;
if (!gg) {
- gg = new cmGlobalGenerator(this);
- created = true;
+ gen = cm::make_unique<cmGlobalGenerator>(this);
+ gg = gen.get();
}
// read in the list file to fill the cache
@@ -489,11 +485,6 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
cmSystemTools::Error("Error processing file: " + path);
}
}
-
- // free generic one if generated
- if (created) {
- delete gg;
- }
}
bool cmake::FindPackage(const std::vector<std::string>& args)
@@ -501,9 +492,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- // if a generator was not yet created, temporarily create one
- cmGlobalGenerator* gg = new cmGlobalGenerator(this);
- this->SetGlobalGenerator(gg);
+ this->SetGlobalGenerator(cm::make_unique<cmGlobalGenerator>(this));
cmStateSnapshot snapshot = this->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(
@@ -512,8 +501,9 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
cmSystemTools::GetCurrentWorkingDirectory());
// read in the list file to fill the cache
snapshot.SetDefaultDefinitions();
- cmMakefile* mf = new cmMakefile(gg, snapshot);
- gg->AddMakefile(mf);
+ auto mfu = cm::make_unique<cmMakefile>(this->GetGlobalGenerator(), snapshot);
+ cmMakefile* mf = mfu.get();
+ this->GlobalGenerator->AddMakefile(std::move(mfu));
mf->SetArgcArgv(args);
@@ -538,8 +528,8 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
std::vector<std::string> includeDirs = cmExpandedList(includes);
- gg->CreateGenerationObjects();
- cmLocalGenerator* lg = gg->LocalGenerators[0];
+ this->GlobalGenerator->CreateGenerationObjects();
+ const auto& lg = this->GlobalGenerator->LocalGenerators[0];
std::string includeFlags =
lg->GetIncludeFlags(includeDirs, nullptr, language);
@@ -549,7 +539,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
const char* targetName = "dummy";
std::vector<std::string> srcs;
cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
- tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
+ tgt->SetProperty("LINKER_LANGUAGE", language);
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
std::vector<std::string> libList = cmExpandedList(libs);
@@ -565,8 +555,9 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string linkPath;
std::string flags;
std::string linkFlags;
- gg->CreateGenerationObjects();
- cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
+ this->GlobalGenerator->CreateGenerationObjects();
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->FindGeneratorTarget(tgt->GetName());
cmLocalGenerator* lg = gtgt->GetLocalGenerator();
cmLinkLineComputer linkLineComputer(lg,
lg->GetStateSnapshot().GetDirectory());
@@ -586,10 +577,6 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}*/
}
- // free generic one if generated
- // this->SetGlobalGenerator(0); // setting 0-pointer is not possible
- // delete gg; // this crashes inside the cmake instance
-
return packageFound;
}
@@ -676,6 +663,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
} else if ((i < args.size() - 1) &&
(arg.find("--check-stamp-list", 0) == 0)) {
this->CheckStampList = args[++i];
+ } else if (arg == "--regenerate-during-build") {
+ this->RegenerateDuringBuild = true;
}
#if defined(CMAKE_HAVE_VS_GENERATORS)
else if ((i < args.size() - 1) &&
@@ -735,6 +724,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetLogLevel(logLevel);
+ this->LogLevelWasSetViaCLI = true;
} 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
@@ -746,10 +736,26 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetLogLevel(logLevel);
+ this->LogLevelWasSetViaCLI = true;
+ } else if (arg == "--log-context") {
+ this->SetShowLogContext(true);
+ } else if (arg.find("--debug-find", 0) == 0) {
+ std::cout << "Running with debug output on for the `find` commands.\n";
+ this->SetDebugFindOutputOn(true);
} else if (arg.find("--trace-expand", 0) == 0) {
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(true);
+ } else if (arg.find("--trace-format=", 0) == 0) {
+ this->SetTrace(true);
+ const auto traceFormat =
+ StringToTraceFormat(arg.substr(strlen("--trace-format=")));
+ if (traceFormat == TraceFormat::TRACE_UNDEFINED) {
+ cmSystemTools::Error("Invalid format specified for --trace-format. "
+ "Valid formats are human, json-v1.");
+ return;
+ }
+ this->SetTraceFormat(traceFormat);
} else if (arg.find("--trace-source=", 0) == 0) {
std::string file = arg.substr(strlen("--trace-source="));
cmSystemTools::ConvertToUnixSlashes(file);
@@ -821,7 +827,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
value = args[i];
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(value);
+ auto gen = this->CreateGlobalGenerator(value);
if (!gen) {
std::string kdevError;
if (value.find("KDevelop3", 0) != std::string::npos) {
@@ -833,7 +839,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
this->PrintGeneratorList();
return;
}
- this->SetGlobalGenerator(gen);
+ this->SetGlobalGenerator(std::move(gen));
}
// no option assume it is the path to the source or an existing build
else {
@@ -890,6 +896,23 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
}
+cmake::TraceFormat cmake::StringToTraceFormat(const std::string& traceStr)
+{
+ using TracePair = std::pair<std::string, TraceFormat>;
+ static const std::vector<TracePair> levels = {
+ { "human", TraceFormat::TRACE_HUMAN },
+ { "json-v1", TraceFormat::TRACE_JSON_V1 },
+ };
+
+ const auto traceStrLowCase = cmSystemTools::LowerCase(traceStr);
+
+ const auto it = std::find_if(levels.cbegin(), levels.cend(),
+ [&traceStrLowCase](const TracePair& p) {
+ return p.first == traceStrLowCase;
+ });
+ return (it != levels.cend()) ? it->second : TraceFormat::TRACE_UNDEFINED;
+}
+
void cmake::SetTraceFile(const std::string& file)
{
this->TraceFile.close();
@@ -904,6 +927,48 @@ void cmake::SetTraceFile(const std::string& file)
std::cout << "Trace will be written to " << file << "\n";
}
+void cmake::PrintTraceFormatVersion()
+{
+ if (!this->GetTrace()) {
+ return;
+ }
+
+ std::string msg;
+
+ switch (this->GetTraceFormat()) {
+ case TraceFormat::TRACE_JSON_V1: {
+#ifndef CMAKE_BOOTSTRAP
+ Json::Value val;
+ Json::Value version;
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = "";
+ version["major"] = 1;
+ version["minor"] = 0;
+ val["version"] = version;
+ msg = Json::writeString(builder, val);
+#endif
+ break;
+ }
+ case TraceFormat::TRACE_HUMAN:
+ msg = "";
+ break;
+ case TraceFormat::TRACE_UNDEFINED:
+ msg = "INTERNAL ERROR: Trace format is TRACE_UNDEFINED";
+ break;
+ }
+
+ if (msg.empty()) {
+ return;
+ }
+
+ auto& f = this->GetTraceFile();
+ if (f) {
+ f << msg << '\n';
+ } else {
+ cmSystemTools::Message(msg);
+ }
+}
+
void cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -1042,11 +1107,11 @@ void cmake::AddDefaultExtraGenerators()
void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
bool includeNamesWithPlatform) const
{
- for (cmGlobalGeneratorFactory* gen : this->Generators) {
+ for (const auto& gen : this->Generators) {
std::vector<std::string> names = gen->GetGeneratorNames();
if (includeNamesWithPlatform) {
- cmAppend(names, gen->GetGeneratorNamesWithPlatform());
+ cm::append(names, gen->GetGeneratorNamesWithPlatform());
}
for (std::string const& name : names) {
@@ -1091,7 +1156,8 @@ void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
}
}
-static std::pair<cmExternalMakefileProjectGenerator*, std::string>
+static std::pair<std::unique_ptr<cmExternalMakefileProjectGenerator>,
+ std::string>
createExtraGenerator(
const std::vector<cmExternalMakefileProjectGeneratorFactory*>& in,
const std::string& name)
@@ -1114,15 +1180,17 @@ createExtraGenerator(
return { nullptr, name };
}
-cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
+std::unique_ptr<cmGlobalGenerator> cmake::CreateGlobalGenerator(
+ const std::string& gname)
{
- std::pair<cmExternalMakefileProjectGenerator*, std::string> extra =
- createExtraGenerator(this->ExtraGenerators, gname);
- cmExternalMakefileProjectGenerator* extraGenerator = extra.first;
- const std::string name = extra.second;
+ std::pair<std::unique_ptr<cmExternalMakefileProjectGenerator>, std::string>
+ extra = createExtraGenerator(this->ExtraGenerators, gname);
+ std::unique_ptr<cmExternalMakefileProjectGenerator>& extraGenerator =
+ extra.first;
+ const std::string& name = extra.second;
- cmGlobalGenerator* generator = nullptr;
- for (cmGlobalGeneratorFactory* g : this->Generators) {
+ std::unique_ptr<cmGlobalGenerator> generator;
+ for (const auto& g : this->Generators) {
generator = g->CreateGlobalGenerator(name, this);
if (generator) {
break;
@@ -1130,9 +1198,7 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
}
if (generator) {
- generator->SetExternalMakefileProjectGenerator(extraGenerator);
- } else {
- delete extraGenerator;
+ generator->SetExternalMakefileProjectGenerator(std::move(extraGenerator));
}
return generator;
@@ -1184,15 +1250,13 @@ std::string cmake::FindCacheFile(const std::string& binaryDir)
return cachePath;
}
-void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
+void cmake::SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator> gg)
{
if (!gg) {
cmSystemTools::Error("Error SetGlobalGenerator called with null");
return;
}
- // delete the old generator
if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
// restore the original environment variables CXX and CC
// Restore CC
std::string env = "CC=";
@@ -1208,7 +1272,7 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
}
// set the new
- this->GlobalGenerator = gg;
+ this->GlobalGenerator = std::move(gg);
// set the global flag for unix style paths on cmSystemTools as soon as
// the generator is set. This allows gmake to be used on windows.
@@ -1571,7 +1635,7 @@ int cmake::ActualConfigure()
}
}
- cmMakefile* mf = this->GlobalGenerator->GetMakefiles()[0];
+ auto& mf = this->GlobalGenerator->GetMakefiles()[0];
if (mf->IsOn("CTEST_USE_LAUNCHERS") &&
!this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE")) {
cmSystemTools::Error(
@@ -1592,13 +1656,12 @@ int cmake::ActualConfigure()
std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
{
if (!this->EnvironmentGenerator.empty()) {
- cmGlobalGenerator* gen =
- this->CreateGlobalGenerator(this->EnvironmentGenerator);
+ auto gen = this->CreateGlobalGenerator(this->EnvironmentGenerator);
if (!gen) {
cmSystemTools::Error("CMAKE_GENERATOR was set but the specified "
"generator doesn't exist. Using CMake default.");
} else {
- return std::unique_ptr<cmGlobalGenerator>(gen);
+ return gen;
}
}
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
@@ -1648,13 +1711,14 @@ std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
}
}
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(found);
+ auto gen = this->CreateGlobalGenerator(found);
if (!gen) {
- gen = new cmGlobalNMakeMakefileGenerator(this);
+ gen = cm::make_unique<cmGlobalNMakeMakefileGenerator>(this);
}
- return std::unique_ptr<cmGlobalGenerator>(gen);
+ return std::unique_ptr<cmGlobalGenerator>(std::move(gen));
#else
- return cm::make_unique<cmGlobalUnixMakefileGenerator3>(this);
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalUnixMakefileGenerator3>(this));
#endif
}
@@ -1665,7 +1729,7 @@ void cmake::CreateDefaultGlobalGenerator()
// This print could be unified for all platforms
std::cout << "-- Building for: " << gen->GetName() << "\n";
#endif
- this->SetGlobalGenerator(gen.release());
+ this->SetGlobalGenerator(std::move(gen));
}
void cmake::PreLoadCMakeFiles()
@@ -1696,6 +1760,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return -1;
}
+ // Log the trace format version to the desired output
+ if (this->GetTrace()) {
+ this->PrintTraceFormatVersion();
+ }
+
// If we are given a stamp list file check if it is really out of date.
if (!this->CheckStampList.empty() &&
cmakeCheckStampList(this->CheckStampList)) {
@@ -1763,10 +1832,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
cmSystemTools::Message("CMake Configure step failed. "
"Build files cannot be regenerated correctly. "
"Attempting to stop IDE build.");
- cmGlobalVisualStudioGenerator* gg =
- static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
- gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
- this->VSSolutionFile);
+ cmGlobalVisualStudioGenerator& gg =
+ cm::static_reference_cast<cmGlobalVisualStudioGenerator>(
+ this->GlobalGenerator);
+ gg.CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
+ this->VSSolutionFile);
}
#endif
return ret;
@@ -1916,6 +1986,7 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
# endif
this->Generators.push_back(cmGlobalNinjaGenerator::NewFactory());
+ this->Generators.push_back(cmGlobalNinjaMultiGenerator::NewFactory());
#endif
#if defined(CMAKE_USE_WMAKE)
this->Generators.push_back(cmGlobalWatcomWMakeGenerator::NewFactory());
@@ -2021,7 +2092,7 @@ void cmake::AppendGlobalGeneratorsDocumentation(
const std::string defaultName = defaultGenerator->GetName();
bool foundDefaultOne = false;
- for (cmGlobalGeneratorFactory* g : this->Generators) {
+ for (const auto& g : this->Generators) {
cmDocumentationEntry e;
g->GetDocumentation(e);
if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
@@ -2161,12 +2232,12 @@ int cmake::CheckBuildSystem()
}
// Create the generator and use it to clear the dependencies.
- std::unique_ptr<cmGlobalGenerator> ggd(
- this->CreateGlobalGenerator(genName));
+ std::unique_ptr<cmGlobalGenerator> ggd =
+ this->CreateGlobalGenerator(genName);
if (ggd) {
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmMakefile mfd(ggd.get(), cm.GetCurrentSnapshot());
- std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mfd));
+ auto lgd = ggd->CreateLocalGenerator(&mfd);
lgd->ClearDependencies(&mfd, verbose);
}
}
@@ -2287,7 +2358,7 @@ void cmake::MarkCliAsUsed(const std::string& variable)
void cmake::GenerateGraphViz(const std::string& fileName) const
{
#ifndef CMAKE_BOOTSTRAP
- cmGraphVizWriter gvWriter(this->GetGlobalGenerator());
+ cmGraphVizWriter gvWriter(fileName, this->GetGlobalGenerator());
std::string settingsFile =
cmStrCat(this->GetHomeOutputDirectory(), "/CMakeGraphVizOptions.cmake");
@@ -2295,9 +2366,8 @@ void cmake::GenerateGraphViz(const std::string& fileName) const
cmStrCat(this->GetHomeDirectory(), "/CMakeGraphVizOptions.cmake");
gvWriter.ReadSettings(settingsFile, fallbackSettingsFile);
- gvWriter.WritePerTargetFiles(fileName);
- gvWriter.WriteTargetDependersFiles(fileName);
- gvWriter.WriteGlobalFile(fileName);
+
+ gvWriter.Write();
#endif
}
@@ -2307,7 +2377,7 @@ void cmake::SetProperty(const std::string& prop, const char* value)
this->State->SetGlobalProperty(prop, value);
}
-void cmake::AppendProperty(const std::string& prop, const char* value,
+void cmake::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
{
this->State->AppendGlobalProperty(prop, value, asString);
@@ -2376,12 +2446,12 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
}
value = args[i];
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(value);
+ auto gen = this->CreateGlobalGenerator(value);
if (!gen) {
cmSystemTools::Error("Could not create named generator " + value);
this->PrintGeneratorList();
} else {
- this->SetGlobalGenerator(gen);
+ this->SetGlobalGenerator(std::move(gen));
}
}
// no option assume it is the output file
@@ -2593,26 +2663,37 @@ int cmake::Build(int jobs, const std::string& dir,
std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return 1;
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(cachedGenerator);
+ auto gen = this->CreateGlobalGenerator(cachedGenerator);
if (!gen) {
std::cerr << "Error: could create CMAKE_GENERATOR \"" << cachedGenerator
<< "\"\n";
return 1;
}
- this->SetGlobalGenerator(gen);
+ this->SetGlobalGenerator(std::move(gen));
const char* cachedGeneratorInstance =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE");
if (cachedGeneratorInstance) {
- cmMakefile mf(gen, this->GetCurrentSnapshot());
- if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorInstance(cachedGeneratorInstance,
+ &mf)) {
return 1;
}
}
const char* cachedGeneratorPlatform =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
if (cachedGeneratorPlatform) {
- cmMakefile mf(gen, this->GetCurrentSnapshot());
- if (!gen->SetGeneratorPlatform(cachedGeneratorPlatform, &mf)) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorPlatform(cachedGeneratorPlatform,
+ &mf)) {
+ return 1;
+ }
+ }
+ const char* cachedGeneratorToolset =
+ this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ if (cachedGeneratorToolset) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorToolset(cachedGeneratorToolset,
+ true, &mf)) {
return 1;
}
}
@@ -2687,10 +2768,15 @@ int cmake::Build(int jobs, const std::string& dir,
}
#endif
- gen->PrintBuildCommandAdvice(std::cerr, jobs);
- return gen->Build(jobs, "", dir, projName, targets, output, "", config,
- clean, false, verbose, cmDuration::zero(),
- cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions);
+ if (!this->GlobalGenerator->ReadCacheEntriesForBuild(*this->State)) {
+ return 1;
+ }
+
+ this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
+ return this->GlobalGenerator->Build(
+ jobs, "", dir, projName, targets, output, "", config, clean, false,
+ verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
+ nativeOptions);
}
bool cmake::Open(const std::string& dir, bool dryRun)
@@ -2718,8 +2804,8 @@ bool cmake::Open(const std::string& dir, bool dryRun)
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
genName, extraGenName ? *extraGenName : "");
- std::unique_ptr<cmGlobalGenerator> gen(
- this->CreateGlobalGenerator(fullName));
+ std::unique_ptr<cmGlobalGenerator> gen =
+ this->CreateGlobalGenerator(fullName);
if (!gen) {
std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName
<< "\"\n";
diff --git a/Source/cmake.h b/Source/cmake.h
index 687c1056b1..35425ec523 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -5,12 +5,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <set>
+#include <stack>
#include <string>
#include <unordered_set>
+#include <utility>
#include <vector>
#include "cmGeneratedFileStream.h"
@@ -110,6 +113,14 @@ public:
LOG_TRACE
};
+ /** \brief Define supported trace formats **/
+ enum TraceFormat
+ {
+ TRACE_UNDEFINED,
+ TRACE_HUMAN,
+ TRACE_JSON_V1,
+ };
+
struct GeneratorInfo
{
std::string name;
@@ -202,21 +213,25 @@ public:
void PreLoadCMakeFiles();
//! Create a GlobalGenerator
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name);
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name);
//! Return the global generator assigned to this instance of cmake
- cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
+ cmGlobalGenerator* GetGlobalGenerator()
+ {
+ return this->GlobalGenerator.get();
+ }
//! Return the global generator assigned to this instance of cmake, const
const cmGlobalGenerator* GetGlobalGenerator() const
{
- return this->GlobalGenerator;
+ return this->GlobalGenerator.get();
}
//! Return the full path to where the CMakeCache.txt file should be.
static std::string FindCacheFile(const std::string& binaryDir);
//! Return the global generator assigned to this instance of cmake
- void SetGlobalGenerator(cmGlobalGenerator*);
+ void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);
//! Get the names of the current registered generators
void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
@@ -344,7 +359,7 @@ public:
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
const char* GetProperty(const std::string& prop);
bool GetPropertyAsBool(const std::string& prop);
@@ -380,20 +395,52 @@ public:
*/
cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
+ bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
+
//! 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);
+ static TraceFormat StringToTraceFormat(const std::string& levelStr);
+
+ bool HasCheckInProgress() const
+ {
+ return !this->CheckInProgressMessages.empty();
+ }
+ std::size_t GetCheckInProgressSize() const
+ {
+ return this->CheckInProgressMessages.size();
+ }
+ std::string GetTopCheckInProgressMessage()
+ {
+ auto message = this->CheckInProgressMessages.top();
+ this->CheckInProgressMessages.pop();
+ return message;
+ }
+ void PushCheckInProgressMessage(std::string message)
+ {
+ this->CheckInProgressMessages.emplace(std::move(message));
+ }
+
+ //! Should `message` command display context.
+ bool GetShowLogContext() const { return this->LogContext; }
+ void SetShowLogContext(bool b) { this->LogContext = b; }
//! Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
+ //! Do we want debug output from the find commands during the cmake run.
+ bool GetDebugFindOutput() { return this->DebugFindOutput; }
+ void SetDebugFindOutputOn(bool b) { this->DebugFindOutput = b; }
+
//! Do we want trace output during the cmake run.
- bool GetTrace() { return this->Trace; }
+ bool GetTrace() const { return this->Trace; }
void SetTrace(bool b) { this->Trace = b; }
- bool GetTraceExpand() { return this->TraceExpand; }
+ bool GetTraceExpand() const { return this->TraceExpand; }
void SetTraceExpand(bool b) { this->TraceExpand = b; }
+ TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
+ void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
void AddTraceSource(std::string const& file)
{
this->TraceOnlyThisSources.push_back(file);
@@ -404,6 +451,7 @@ public:
}
cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
void SetTraceFile(std::string const& file);
+ void PrintTraceFormatVersion();
bool GetWarnUninitialized() { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
@@ -499,11 +547,14 @@ public:
}
cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
+ bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
+
protected:
void RunCheckForUnusedVariables();
int HandleDeleteCacheVariables(const std::string& var);
- using RegisteredGeneratorsVector = std::vector<cmGlobalGeneratorFactory*>;
+ using RegisteredGeneratorsVector =
+ std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
RegisteredGeneratorsVector Generators;
using RegisteredExtraGeneratorsVector =
std::vector<cmExternalMakefileProjectGeneratorFactory*>;
@@ -513,7 +564,6 @@ protected:
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
- cmGlobalGenerator* GlobalGenerator = nullptr;
std::map<std::string, DiagLevel> DiagLevels;
std::string GeneratorInstance;
std::string GeneratorPlatform;
@@ -549,8 +599,10 @@ private:
ProgressCallbackType ProgressCallback;
WorkingMode CurrentWorkingMode = NORMAL_MODE;
bool DebugOutput = false;
+ bool DebugFindOutput = false;
bool Trace = false;
bool TraceExpand = false;
+ TraceFormat TraceFormatVar = TRACE_HUMAN;
cmGeneratedFileStream TraceFile;
bool WarnUninitialized = false;
bool WarnUnused = false;
@@ -571,6 +623,7 @@ private:
FileExtensions FortranFileExtensions;
bool ClearBuildSystem = false;
bool DebugTryCompile = false;
+ bool RegenerateDuringBuild = false;
std::unique_ptr<cmFileTimeCache> FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;
@@ -587,6 +640,12 @@ private:
std::vector<std::string> TraceOnlyThisSources;
LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
+ bool LogLevelWasSetViaCLI = false;
+ bool LogContext = false;
+
+ std::stack<std::string> CheckInProgressMessages;
+
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
void UpdateConversionPathTable();
@@ -714,4 +773,11 @@ private:
FOR_EACH_CXX11_FEATURE(F) \
FOR_EACH_CXX14_FEATURE(F)
+#define FOR_EACH_CUDA_FEATURE(F) \
+ F(cuda_std_03) \
+ F(cuda_std_11) \
+ F(cuda_std_14) \
+ F(cuda_std_17) \
+ F(cuda_std_20)
+
#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 6d3e6ee300..494d5d982d 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -1,7 +1,16 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmAlgorithms.h"
+#include <cassert>
+#include <cctype>
+#include <climits>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <cmext/algorithm>
+
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -24,14 +33,6 @@
# include "cmsys/ConsoleBuf.hxx"
#endif
-#include <cassert>
-#include <cctype>
-#include <climits>
-#include <cstring>
-#include <iostream>
-#include <string>
-#include <vector>
-
namespace {
#ifndef CMAKE_BOOTSTRAP
const char* cmDocumentationName[][2] = {
@@ -73,12 +74,15 @@ const char* cmDocumentationOptions[][2] = {
{ "--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." },
+ { "--log-context", "Prepend log messages with context, if given" },
{ "--debug-trycompile",
"Do not delete the try_compile build tree. Only "
"useful on one try_compile at a time." },
{ "--debug-output", "Put cmake in a debug mode." },
+ { "--debug-find", "Put cmake find in a debug mode." },
{ "--trace", "Put cmake in trace mode." },
{ "--trace-expand", "Put cmake in trace mode with variable expansion." },
+ { "--trace-format=<human|json-v1>", "Set the output format of the trace." },
{ "--trace-source=<file>",
"Trace only this CMake file/module. Multiple options allowed." },
{ "--trace-redirect=<file>",
@@ -99,7 +103,7 @@ int do_command(int ac, char const* const* av)
std::vector<std::string> args;
args.reserve(ac - 1);
args.emplace_back(av[0]);
- cmAppend(args, av + 2, av + ac);
+ cm::append(args, av + 2, av + ac);
return cmcmd::ExecuteCMakeCommand(args);
}
@@ -346,7 +350,7 @@ int do_build(int ac, char const* const* av)
#else
int jobs = cmake::NO_BUILD_PARALLEL_LEVEL;
std::vector<std::string> targets;
- std::string config = "Debug";
+ std::string config;
std::string dir;
std::vector<std::string> nativeOptions;
bool cleanFirst = false;
@@ -682,7 +686,6 @@ int main(int ac, char const* const* av)
ac = args.argc();
av = args.argv();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(av[0]);
if (ac > 1) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index d05e3c81ba..2bccbc7621 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2,6 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmcmd.h"
+#include <cmext/algorithm>
+
+#include <fcntl.h>
+
+#include "cm_uv.h"
+
#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
@@ -15,22 +21,22 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
+# include "cmFileTime.h"
# include "cmServer.h"
# include "cmServerConnection.h"
+
+# include "bindexplib.h"
#endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "cmsys/ConsoleBuf.hxx"
-
-# include "cmFileTime.h"
-
-# include "bindexplib.h"
#endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
@@ -107,10 +113,12 @@ void CMakeCommandUsage(const char* program)
<< " sha384sum <file>... - create SHA384 checksum of files\n"
<< " sha512sum <file>... - create SHA512 checksum of files\n"
<< " remove [-f] <file>... - remove the file(s), use -f to force "
- "it\n"
- << " remove_directory <dir>... - remove directories and their contents\n"
+ "it (deprecated: use rm instead)\n"
+ << " remove_directory <dir>... - remove directories and their contents (deprecated: use rm instead)\n"
<< " rename oldname newname - rename a file or directory "
"(on one volume)\n"
+ << " rm [-rRf] <file/dir>... - remove files or directories, use -f to "
+ "force it, r or R to remove directories and their contents recursively\n"
<< " server - start cmake in server mode\n"
<< " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
@@ -172,6 +180,24 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
+static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
+{
+ if (cmSystemTools::FileIsSymlink(dir)) {
+ if (!cmSystemTools::RemoveFile(dir)) {
+ std::cerr << "Error removing directory symlink \"" << dir << "\".\n";
+ return false;
+ }
+ } else if (!recursive) {
+ std::cerr << "Error removing directory \"" << dir
+ << "\" without recursive option.\n";
+ return false;
+ } else if (!cmSystemTools::RemoveADirectory(dir)) {
+ std::cerr << "Error removing directory \"" << dir << "\".\n";
+ return false;
+ }
+ return true;
+}
+
static int HandleIWYU(const std::string& runCmd,
const std::string& /* sourceFile */,
const std::vector<std::string>& orig_cmd)
@@ -179,7 +205,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 = cmExpandedList(runCmd, true);
- cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
+ cm::append(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.
std::string stdErr;
@@ -210,7 +236,7 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
tidy_cmd.push_back(sourceFile);
tidy_cmd.emplace_back("--");
- cmAppend(tidy_cmd, orig_cmd);
+ cm::append(tidy_cmd, orig_cmd);
// Run the tidy command line. Capture its stdout and hide its stderr.
std::string stdOut;
@@ -561,11 +587,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
- else if (args[1] == "__create_def") {
+#if !defined(CMAKE_BOOTSTRAP)
+ if (args[1] == "__create_def") {
if (args.size() < 4) {
std::cerr << "__create_def Usage: -E __create_def outfile.def "
- "objlistfile [-nm=nm-path]\n";
+ "objlistfile [--nm=nm-path]\n";
return 1;
}
cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
@@ -592,7 +618,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
}
- FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+ FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
if (!fout) {
std::cerr << "could not open output .def file: " << args[2].c_str()
<< "\n";
@@ -706,14 +732,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
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";
+ if (!cmRemoveDirectory(arg)) {
return_value = true;
}
}
@@ -739,6 +758,65 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
+ // Remove directories or files with rm
+ if (args[1] == "rm" && args.size() > 2) {
+ // If an error occurs, we want to continue removing the remaining
+ // files/directories.
+ int return_value = 0;
+ bool force = false;
+ bool recursive = false;
+ bool doing_options = true;
+ bool at_least_one_file = false;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (doing_options && cmHasLiteralPrefix(arg, "-")) {
+ if (arg == "--") {
+ doing_options = false;
+ }
+ if (arg.find('f') != std::string::npos) {
+ force = true;
+ }
+ if (arg.find_first_of("rR") != std::string::npos) {
+ recursive = true;
+ }
+ if (arg.find_first_not_of("-frR") != std::string::npos) {
+ cmSystemTools::Error("Unknown -E rm argument: " + arg);
+ return 1;
+ }
+ } else {
+ if (arg.empty()) {
+ continue;
+ }
+ at_least_one_file = true;
+ // Complain if the -f option was not given and
+ // either file does not exist or
+ // file could not be removed and still exists
+ bool file_exists_or_forced_remove = cmSystemTools::FileExists(arg) ||
+ cmSystemTools::FileIsSymlink(arg) || force;
+ if (cmSystemTools::FileIsDirectory(arg)) {
+ if (!cmRemoveDirectory(arg, recursive)) {
+ return_value = 1;
+ }
+ } else if ((!file_exists_or_forced_remove) ||
+ (!cmSystemTools::RemoveFile(arg) &&
+ cmSystemTools::FileExists(arg))) {
+ if (!file_exists_or_forced_remove) {
+ cmSystemTools::Error(
+ "File to remove does not exist and force is not set: " + arg);
+ } else {
+ cmSystemTools::Error("File can't be removed and still exist: " +
+ arg);
+ }
+ return_value = 1;
+ }
+ }
+ }
+ if (!at_least_one_file) {
+ cmSystemTools::Error("Missing file/directory to remove");
+ return 1;
+ }
+ return return_value;
+ }
+
// Touch file
if (args[1] == "touch" && args.size() > 2) {
for (auto const& arg : cmMakeRange(args).advance(2)) {
@@ -1007,13 +1085,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
- if (cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen)) {
- cm.SetGlobalGenerator(ggd);
+ if (auto ggd = cm.CreateGlobalGenerator(gen)) {
+ cm.SetGlobalGenerator(std::move(ggd));
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
- cmMakefile mf(ggd, snapshot);
- std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mf));
+ cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
+ auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
// Actually scan dependencies.
return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
@@ -1056,6 +1134,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return cmcmd::VisualStudioLink(args, 2);
}
+ if (args[1] == "cmake_llvm_rc") {
+ return cmcmd::RunLLVMRC(args);
+ }
+
// Internal CMake color makefile support.
if (args[1] == "cmake_echo_color") {
return cmcmd::ExecuteEchoColor(args);
@@ -1587,6 +1669,117 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
return -1;
}
+int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
+ const std::string& intermediate_file)
+{
+
+ cmUVProcessChainBuilder builder;
+
+ uv_fs_t fs_req;
+ int preprocessedFile =
+ uv_fs_open(nullptr, &fs_req, intermediate_file.c_str(), O_CREAT | O_RDWR,
+ 0644, nullptr);
+ uv_fs_req_cleanup(&fs_req);
+
+ builder
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ preprocessedFile)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
+ .AddCommand(command);
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::cerr << "Failed to start preprocessor.";
+ return 1;
+ }
+ if (!process.Wait()) {
+ std::cerr << "Failed to wait for preprocessor";
+ return 1;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ auto errorStream = process.ErrorStream();
+ if (errorStream) {
+ std::cerr << errorStream->rdbuf();
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
+{
+ // The arguments are
+ // args[0] == <cmake-executable>
+ // args[1] == cmake_llvm_rc
+ // args[2] == intermediate_file
+ // args[3..n] == preprocess+args
+ // args[n+1] == --
+ // args[n+2...] == llvm-rc+args
+ if (args.size() < 3) {
+ std::cerr << "Invalid cmake_llvm_rc arguments";
+ return 1;
+ }
+ const std::string& intermediate_file = args[2];
+ std::vector<std::string> preprocess;
+ std::vector<std::string> resource_compile;
+ std::vector<std::string>* pArgTgt = &preprocess;
+ for (std::string const& arg : cmMakeRange(args).advance(3)) {
+ if (arg == "--") {
+ pArgTgt = &resource_compile;
+ } else {
+ pArgTgt->push_back(arg);
+ }
+ }
+ if (preprocess.empty()) {
+ std::cerr << "Empty preprocessing command";
+ return 1;
+ }
+ if (resource_compile.empty()) {
+ std::cerr << "Empty resource compilation command";
+ return 1;
+ }
+
+ auto result = RunPreprocessor(preprocess, intermediate_file);
+ if (result != 0) {
+
+ cmSystemTools::RemoveFile(intermediate_file);
+ return result;
+ }
+ cmUVProcessChainBuilder builder;
+
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
+ .AddCommand(resource_compile);
+ auto process = builder.Start();
+ result = 0;
+ if (!process.Valid()) {
+ std::cerr << "Failed to start resource compiler.";
+ result = 1;
+ } else {
+ if (!process.Wait()) {
+ std::cerr << "Failed to wait for resource compiler";
+ result = 1;
+ }
+ }
+
+ cmSystemTools::RemoveFile(intermediate_file);
+ if (result != 0) {
+ return result;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ auto errorStream = process.ErrorStream();
+ if (errorStream) {
+ std::cerr << errorStream->rdbuf();
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
class cmVSLink
{
int Type;
@@ -1956,7 +2149,7 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
if (this->LinkGeneratesManifest) {
mtCommand.push_back(this->LinkerManifestFile);
}
- cmAppend(mtCommand, this->UserManifests);
+ cm::append(mtCommand, this->UserManifests);
mtCommand.push_back(out);
if (notify) {
// Add an undocumented option that enables a special return
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 17f2f9a529..5b6c81333c 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -31,6 +31,9 @@ protected:
static int ExecuteLinkScript(std::vector<std::string> const& args);
static int WindowsCEEnvironment(const char* version,
const std::string& name);
+ static int RunPreprocessor(const std::vector<std::string>& command,
+ const std::string& intermediate_file);
+ static int RunLLVMRC(std::vector<std::string> const& args);
static int VisualStudioLink(std::vector<std::string> const& args, int type);
};
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 0d65902ef0..fbdf75ada1 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -98,9 +98,12 @@ static const char* cmDocumentationOptions[][2] = {
"Run a specific number of tests by number." },
{ "-U, --union", "Take the Union of -I and -R" },
{ "--rerun-failed", "Run only the tests that failed previously" },
- { "--repeat-until-fail <n>",
- "Require each test to run <n> "
- "times without failing in order to pass" },
+ { "--repeat until-fail:<n>, --repeat-until-fail <n>",
+ "Require each test to run <n> times without failing in order to pass" },
+ { "--repeat until-pass:<n>",
+ "Allow each test to run up to <n> times in order to pass" },
+ { "--repeat after-timeout:<n>",
+ "Allow each test to run up to <n> times if it times out" },
{ "--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." },
@@ -141,6 +144,8 @@ static const char* cmDocumentationOptions[][2] = {
{ "--http1.0", "Submit using HTTP 1.0." },
{ "--no-compress-output", "Do not compress test output when submitting." },
{ "--print-labels", "Print all available test labels." },
+ { "--no-tests=<[error|ignore]>",
+ "Regard no tests found either as 'error' or 'ignore' it." },
{ nullptr, nullptr }
};
@@ -161,7 +166,6 @@ int main(int argc, char const* const* argv)
argv = encoding_args.argv();
cmSystemTools::DoNotInheritStdPipes();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(argv[0]);
diff --git a/Source/kwsys/CTestCustom.cmake.in b/Source/kwsys/CTestCustom.cmake.in
index 760221b124..c07f0f30f8 100644
--- a/Source/kwsys/CTestCustom.cmake.in
+++ b/Source/kwsys/CTestCustom.cmake.in
@@ -12,3 +12,7 @@
list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
kwsys.testProcess-10
)
+
+list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
+ "LICENSE WARNING"
+ )
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index b06752115c..75a2d4d0f9 100644
--- a/Source/kwsys/Encoding.hxx.in
+++ b/Source/kwsys/Encoding.hxx.in
@@ -68,6 +68,8 @@ public:
* absolute paths with Windows-style backslashes.
**/
static std::wstring ToWindowsExtendedPath(std::string const&);
+ static std::wstring ToWindowsExtendedPath(const char* source);
+ static std::wstring ToWindowsExtendedPath(std::wstring const& wsource);
# endif
#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 4593c9251c..5cad934ec3 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -221,8 +221,18 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
// Convert local paths to UNC style paths
std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
{
- std::wstring wsource = Encoding::ToWide(source);
+ return ToWindowsExtendedPath(ToWide(source));
+}
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(const char* source)
+{
+ return ToWindowsExtendedPath(ToWide(source));
+}
+
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource)
+{
// Resolve any relative paths
DWORD wfull_len;
@@ -269,7 +279,7 @@ std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
// If this case has been reached, then the path is invalid. Leave it
// unchanged
- return Encoding::ToWide(source);
+ return wsource;
}
# endif
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
index d79bbdf16b..b424488920 100644
--- a/Source/kwsys/FStream.hxx.in
+++ b/Source/kwsys/FStream.hxx.in
@@ -87,7 +87,7 @@ public:
bool _open(char const* file_name, std::ios_base::openmode mode)
{
- if (is_open() || file_) {
+ if (_is_open() || file_) {
return false;
}
# if defined(_MSC_VER)
@@ -108,7 +108,7 @@ public:
return success;
}
- bool is_open()
+ bool _is_open()
{
if (!buf_) {
return false;
@@ -116,7 +116,7 @@ public:
return buf_->is_open();
}
- bool is_open() const
+ bool _is_open() const
{
if (!buf_) {
return false;
@@ -198,9 +198,11 @@ public:
this->_set_state(this->_open(file_name, mode), this, this);
}
+ bool is_open() { return this->_is_open(); }
+
void close() { this->_set_state(this->_close(), this, this); }
- using basic_efilebuf<CharType, Traits>::is_open;
+ using basic_efilebuf<CharType, Traits>::_is_open;
internal_buffer_type* rdbuf() const { return this->buf_; }
@@ -212,7 +214,7 @@ class basic_ofstream
: public std::basic_ostream<CharType, Traits>
, public basic_efilebuf<CharType, Traits>
{
- using basic_efilebuf<CharType, Traits>::is_open;
+ using basic_efilebuf<CharType, Traits>::_is_open;
public:
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
@@ -242,6 +244,8 @@ public:
void close() { this->_set_state(this->_close(), this, this); }
+ bool is_open() { return this->_is_open(); }
+
internal_buffer_type* rdbuf() const { return this->buf_; }
~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index df7eb45589..d11db88280 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -66,16 +66,27 @@ private:
const char* searchstring;
};
+#ifdef _MSC_VER
+# pragma warning(push)
+# if _MSC_VER < 1900
+# pragma warning(disable : 4351) /* new behavior */
+# endif
+#endif
+
/**
* \brief Creates an invalid match object
*/
inline RegularExpressionMatch::RegularExpressionMatch()
+ : startp{}
+ , endp{}
+ , searchstring{}
{
- startp[0] = nullptr;
- endp[0] = nullptr;
- searchstring = nullptr;
}
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
/**
* \brief Returns true if the match pointers are valid
*/
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ce4d6ef950..d27081b8c6 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2186,12 +2186,15 @@ bool SystemTools::CopyFileIfDifferent(const std::string& source,
// FilesDiffer does not handle file to directory compare
if (SystemTools::FileIsDirectory(destination)) {
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
- if (SystemTools::FilesDiffer(source, destination)) {
- return SystemTools::CopyFileAlways(source, destination);
+ if (!SystemTools::ComparePath(new_destination, destination)) {
+ return SystemTools::CopyFileIfDifferent(source, new_destination);
+ }
+ } else {
+ // source and destination are files so do a copy if they
+ // are different
+ if (SystemTools::FilesDiffer(source, destination)) {
+ return SystemTools::CopyFileAlways(source, destination);
+ }
}
// at this point the files must be the same so return true
return true;
@@ -2326,14 +2329,8 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
static bool CopyFileContentBlockwise(const std::string& source,
const std::string& destination)
{
-// Open files
-#if defined(_WIN32)
- kwsys::ifstream fin(
- Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)).c_str(),
- std::ios::in | std::ios::binary);
-#else
+ // Open files
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
-#endif
if (!fin) {
return false;
}
@@ -2344,14 +2341,8 @@ static bool CopyFileContentBlockwise(const std::string& source,
// that do not allow file removal can be modified.
SystemTools::RemoveFile(destination);
-#if defined(_WIN32)
- kwsys::ofstream fout(
- Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(destination)).c_str(),
- std::ios::out | std::ios::trunc | std::ios::binary);
-#else
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
-#endif
if (!fout) {
return false;
}
@@ -4678,8 +4669,12 @@ void SystemTools::ClassFinalize()
# include <stdlib.h>
namespace KWSYS_NAMESPACE {
-static int SystemToolsDebugReport(int, char* message, int*)
+static int SystemToolsDebugReport(int, char* message, int* ret)
{
+ if (ret) {
+ // Pretend user clicked on Retry button in popup.
+ *ret = 1;
+ }
fprintf(stderr, "%s", message);
fflush(stderr);
return 1; // no further reporting required
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index 4dd246148c..4d1b46c871 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -146,6 +146,7 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm",
"screen-bce",
"screen-w",
"screen.linux",
+ "st-256color",
"tmux",
"tmux-256color",
"vt100",
@@ -172,6 +173,14 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
}
}
+ /* GNU make 4.1+ may tell us that its output is destined for a TTY. */
+ {
+ const char* termout = getenv("MAKE_TERMOUT");
+ if (termout && *termout != '\0') {
+ return 1;
+ }
+ }
+
/* If running inside emacs the terminal is not VT100. Some emacs
seem to claim the TERM is xterm even though they do not support
VT100 escapes. */
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 1f3a15b591..3f6eeb8c1d 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -1074,6 +1074,15 @@ static bool CheckCopyFileIfDifferent()
}
}
+ if (!kwsys::SystemTools::MakeDirectory("dir_a") ||
+ !kwsys::SystemTools::MakeDirectory("dir_b")) {
+ return false;
+ }
+
+ if (!kwsys::SystemTools::CopyFileIfDifferent("dir_a/", "dir_b")) {
+ ret = false;
+ }
+
return ret;
}