summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CTestCustom.cmake.in1
-rw-r--r--Help/command/foreach.rst2
-rw-r--r--Help/command/message.rst120
-rw-r--r--Help/command/project.rst7
-rw-r--r--Help/cpack_gen/nsis.rst21
-rw-r--r--Help/cpack_gen/packagemaker.rst53
-rw-r--r--Help/cpack_gen/productbuild.rst52
-rw-r--r--Help/dev/maint.rst18
-rw-r--r--Help/dev/review.rst21
-rw-r--r--Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst9
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst3
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst7
-rw-r--r--Help/manual/cmake.1.rst15
-rw-r--r--Help/manual/ctest.1.rst13
-rw-r--r--Help/prop_tgt/INSTALL_NAME_DIR.rst4
-rw-r--r--Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst6
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/ExternalProject-git-no-recurse.rst7
-rw-r--r--Help/release/dev/FindCURL-cmake-package.rst7
-rw-r--r--Help/release/dev/ccmake-colored-values.rst5
-rw-r--r--Help/release/dev/ccmake_progress_bar_and_log_display.rst6
-rw-r--r--Help/release/dev/cpack-nsis-uninstaller-name.rst6
-rw-r--r--Help/release/dev/cpack-nsis-welcome-finish-page-title.rst10
-rw-r--r--Help/release/dev/cpack-pkg-background.rst8
-rw-r--r--Help/release/dev/ctest-repeat-until-pass.rst6
-rw-r--r--Help/release/dev/deprecate-policy-old.rst8
-rw-r--r--Help/release/dev/export-compile-commands-environment-variable.rst6
-rw-r--r--Help/release/dev/feature-CMAKE_MESSAGE_CONTEXT.rst11
-rw-r--r--Help/release/dev/install-name-dir-genex.rst7
-rw-r--r--Help/release/dev/mingw_no_sh.rst5
-rw-r--r--Help/release/dev/new-message-types.rst5
-rw-r--r--Help/release/dev/vs-per-config-sources.rst5
-rw-r--r--Help/release/dev/vs-vctargetspath.rst10
-rw-r--r--Help/release/dev/vs_dotnet_documentation_file.rst6
-rw-r--r--Help/release/dev/xcode-scheme-env.rst5
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst3
-rw-r--r--Help/variable/CMAKE_GENERATOR_TOOLSET.rst5
-rw-r--r--Help/variable/CMAKE_MESSAGE_CONTEXT.rst62
-rw-r--r--Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst15
-rw-r--r--Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst15
-rw-r--r--Help/variable/CMAKE_PROJECT_INCLUDE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst11
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst15
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake12
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake12
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake9
-rw-r--r--Modules/CMakeDetermineSystem.cmake2
-rw-r--r--Modules/CMakeGenericSystem.cmake8
-rw-r--r--Modules/CMakeGraphVizOptions.cmake146
-rw-r--r--Modules/CMakeMinGWFindMake.cmake7
-rw-r--r--Modules/CMakeTestCCompiler.cmake6
-rw-r--r--Modules/CMakeTestCSharpCompiler.cmake8
-rw-r--r--Modules/CMakeTestCUDACompiler.cmake6
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake6
-rw-r--r--Modules/CMakeTestCompilerCommon.cmake11
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake12
-rw-r--r--Modules/CMakeTestOBJCCompiler.cmake6
-rw-r--r--Modules/CMakeTestOBJCXXCompiler.cmake6
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake6
-rw-r--r--Modules/CPack.cmake2
-rw-r--r--Modules/CheckCSourceCompiles.cmake6
-rw-r--r--Modules/CheckCSourceRuns.cmake6
-rw-r--r--Modules/CheckCXXSourceCompiles.cmake6
-rw-r--r--Modules/CheckCXXSourceRuns.cmake6
-rw-r--r--Modules/CheckFortranFunctionExists.cmake17
-rw-r--r--Modules/CheckFortranSourceCompiles.cmake6
-rw-r--r--Modules/CheckFortranSourceRuns.cmake6
-rw-r--r--Modules/CheckFunctionExists.cmake6
-rw-r--r--Modules/CheckIncludeFile.cmake6
-rw-r--r--Modules/CheckIncludeFileCXX.cmake6
-rw-r--r--Modules/CheckIncludeFiles.cmake6
-rw-r--r--Modules/CheckLanguage.cmake6
-rw-r--r--Modules/CheckLibraryExists.cmake6
-rw-r--r--Modules/CheckOBJCSourceCompiles.cmake6
-rw-r--r--Modules/CheckOBJCSourceRuns.cmake6
-rw-r--r--Modules/CheckOBJCXXSourceCompiles.cmake6
-rw-r--r--Modules/CheckOBJCXXSourceRuns.cmake6
-rw-r--r--Modules/CheckPrototypeDefinition.cmake7
-rw-r--r--Modules/CheckSymbolExists.cmake6
-rw-r--r--Modules/CheckTypeSize.cmake6
-rw-r--r--Modules/CheckVariableExists.cmake6
-rw-r--r--Modules/Compiler/NAG-Fortran.cmake6
-rw-r--r--Modules/CompilerId/VS-10.vcxproj.in2
-rw-r--r--Modules/ExternalProject.cmake27
-rw-r--r--Modules/FindCUDA.cmake11
-rw-r--r--Modules/FindCURL.cmake28
-rw-r--r--Modules/FindDCMTK.cmake6
-rw-r--r--Modules/FindMFC.cmake6
-rw-r--r--Modules/FindOpenSSL.cmake3
-rw-r--r--Modules/FindPython/Support.cmake50
-rw-r--r--Modules/FindThreads.cmake6
-rw-r--r--Modules/FortranCInterface.cmake6
-rw-r--r--Modules/FortranCInterface/Detect.cmake6
-rw-r--r--Modules/Internal/CPack/NSIS.template.in12
-rw-r--r--Modules/Platform/Android-Clang.cmake8
-rw-r--r--Modules/Platform/Android-Determine.cmake6
-rw-r--r--Modules/Platform/Android-Initialize.cmake6
-rw-r--r--Modules/Platform/Android.cmake5
-rw-r--r--Modules/Platform/Android/Determine-Compiler.cmake10
-rw-r--r--Modules/Platform/Apple-GNU.cmake12
-rw-r--r--Modules/TestBigEndian.cmake17
-rw-r--r--Modules/TestCXXAcceptsFlag.cmake6
-rw-r--r--Modules/TestForANSIForScope.cmake6
-rw-r--r--Modules/TestForSSTREAM.cmake6
-rw-r--r--Modules/TestForSTDNamespace.cmake6
-rw-r--r--Source/CMakeLists.txt7
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx37
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx66
-rw-r--r--Source/CPack/cmCPackPKGGenerator.h8
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx8
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx4
-rw-r--r--Source/CTest/cmCTestRunTest.cxx20
-rw-r--r--Source/CTest/cmCTestRunTest.h19
-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.cmake10
-rw-r--r--Source/Checks/cm_cxx17_check.cmake10
-rw-r--r--Source/Checks/cm_cxx_features.cmake10
-rw-r--r--Source/Checks/cm_message_checks_compat.cmake13
-rw-r--r--Source/CursesDialog/CMakeLists.txt25
-rw-r--r--Source/CursesDialog/ccmake.cxx2
-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.cxx24
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h4
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx132
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h19
-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/QtDialog/CMakeLists.txt4
-rw-r--r--Source/cmAlgorithms.h8
-rw-r--r--Source/cmCTest.cxx57
-rw-r--r--Source/cmCTest.h10
-rw-r--r--Source/cmComputeTargetDepends.cxx9
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx20
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx11
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx25
-rw-r--r--Source/cmExtraKateGenerator.cxx6
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx9
-rw-r--r--Source/cmForEachCommand.cxx145
-rw-r--r--Source/cmGeneratorExpression.cxx14
-rw-r--r--Source/cmGeneratorExpression.h3
-rw-r--r--Source/cmGeneratorTarget.cxx129
-rw-r--r--Source/cmGeneratorTarget.h33
-rw-r--r--Source/cmGlobalCommonGenerator.cxx5
-rw-r--r--Source/cmGlobalGenerator.cxx40
-rw-r--r--Source/cmGlobalGenerator.h3
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx5
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h3
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx44
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx36
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h8
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx12
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx25
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx43
-rw-r--r--Source/cmGlobalXCodeGenerator.h3
-rw-r--r--Source/cmGraphVizWriter.cxx723
-rw-r--r--Source/cmGraphVizWriter.h93
-rw-r--r--Source/cmInstallTargetGenerator.cxx6
-rw-r--r--Source/cmLinkItemGraphVisitor.cxx142
-rw-r--r--Source/cmLinkItemGraphVisitor.h75
-rw-r--r--Source/cmLocalGenerator.cxx69
-rw-r--r--Source/cmLocalGenerator.h13
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx6
-rw-r--r--Source/cmLocalNinjaGenerator.cxx4
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx35
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx18
-rw-r--r--Source/cmLocalVisualStudio7Generator.h2
-rw-r--r--Source/cmLocalXCodeGenerator.cxx4
-rw-r--r--Source/cmMakefile.cxx2
-rw-r--r--Source/cmMessageCommand.cxx135
-rw-r--r--Source/cmProjectCommand.cxx5
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx11
-rw-r--r--Source/cmQtAutoGenInitializer.cxx4
-rw-r--r--Source/cmSourceFile.h5
-rw-r--r--Source/cmStateSnapshot.cxx4
-rw-r--r--Source/cmTarget.cxx4
-rw-r--r--Source/cmVariableWatch.cxx14
-rw-r--r--Source/cmVariableWatch.h4
-rw-r--r--Source/cmVariableWatchCommand.cxx65
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx53
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h3
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx6
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h3
-rw-r--r--Source/cmake.cxx19
-rw-r--r--Source/cmake.h32
-rw-r--r--Source/cmakemain.cxx1
-rw-r--r--Source/ctest.cxx7
-rw-r--r--Source/kwsys/Encoding.hxx.in2
-rw-r--r--Source/kwsys/EncodingCXX.cxx14
-rw-r--r--Source/kwsys/RegularExpression.hxx.in6
-rw-r--r--Tests/CMakeLib/testUTF8.cxx2
-rw-r--r--Tests/CMakeLists.txt8
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt6
-rw-r--r--Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt5
-rw-r--r--Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake9
-rw-r--r--Tests/EnforceConfig.cmake.in1
-rw-r--r--Tests/ExternalProject/CMakeLists.txt60
-rw-r--r--Tests/ExternalProject/gitrepo-sub-rec.tgzbin0 -> 9008 bytes
-rw-r--r--Tests/FindPackageModeMakefileTest/CMakeLists.txt8
-rw-r--r--Tests/FindPackageModeMakefileTest/Makefile.in3
-rw-r--r--Tests/FindPython/CMakeLists.txt14
-rw-r--r--Tests/FindPython/CustomFailureMessage/CMakeLists.txt79
-rw-r--r--Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake57
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-good-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-good-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test1-pass.cmake13
-rw-r--r--Tests/RunCMake/CTestCommandLine/test1-timeout.cmake14
-rw-r--r--Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt13
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake2
-rw-r--r--Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in1
-rw-r--r--Tests/RunCMake/Graphviz/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Graphviz/GraphvizTestProject.cmake58
-rw-r--r--Tests/RunCMake/Graphviz/RunCMakeTest.cmake82
-rw-r--r--Tests/RunCMake/Graphviz/default_options-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot52
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot46
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot35
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot43
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot48
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot42
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot48
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot50
-rw-r--r--Tests/RunCMake/Graphviz/no_dependers_files-check.cmake4
-rw-r--r--Tests/RunCMake/Graphviz/no_executables-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_external_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_interface_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_module_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_object_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_per_target_files-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_shared_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_static_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_graph_header-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_graph_name-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_node_prefix-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/test_project/core_library.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/graphic_library.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/main.c4
-rw-r--r--Tests/RunCMake/Graphviz/test_project/module.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake15
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake69
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/none.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake6
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/test.c3
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt10
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt10
-rw-r--r--Tests/RunCMake/RunCMake.cmake29
-rw-r--r--Tests/RunCMake/TargetSources/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake26
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake8
-rw-r--r--Tests/RunCMake/VS10Project/VsGlobals-check.cmake93
-rw-r--r--Tests/RunCMake/VS10Project/VsGlobals.cmake7
-rw-r--r--Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake32
-rw-r--r--Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake3
-rw-r--r--Tests/RunCMake/foreach/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/foreach/foreach-all-test-stdout.txt44
-rw-r--r--Tests/RunCMake/foreach/foreach-all-test.cmake67
-rw-r--r--Tests/RunCMake/message/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/message/message-checks-stderr.txt3
-rw-r--r--Tests/RunCMake/message/message-checks-stdout.txt10
-rw-r--r--Tests/RunCMake/message/message-checks.cmake13
-rw-r--r--Tests/RunCMake/message/message-context-cache-stdout.txt8
-rw-r--r--Tests/RunCMake/message/message-context-cli-stdout.txt8
-rw-r--r--Tests/RunCMake/message/message-context-cli-wins-cache-stdout.txt5
-rw-r--r--Tests/RunCMake/message/message-context.cmake27
-rw-r--r--Tests/RunCMake/message/message-log-level-debug-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-default-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-override-stderr.txt12
-rw-r--r--Tests/RunCMake/message/message-log-level-override-stdout.txt3
-rw-r--r--Tests/RunCMake/message/message-log-level-status-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-trace-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-verbose-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-debug-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-default-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-status-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-trace-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-verbose-stdout.txt2
-rw-r--r--Utilities/IWYU/mapping.imp1
-rwxr-xr-xUtilities/Release/push.bash3
-rwxr-xr-xbootstrap1
348 files changed, 4811 insertions, 1360 deletions
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 823ee3c..af4bb2d 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -71,6 +71,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*isn.*t random" # we do not do crypto
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*srand.*seed choices are.*poor" # we do not do crypto
"IPA warning: function.*multiply defined in"
+ "LICENSE WARNING" # PGI license expiry. Not useful in nightly testing.
# Ignore compiler summary warning, assuming prior text has matched some
# other warning expression:
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index ae2afb2..ecbfed3 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -47,7 +47,7 @@ of undocumented behavior that may change in future releases.
.. code-block:: cmake
- foreach(loop_var IN [LISTS [<lists>]] [ITEMS [<items>]])
+ foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
In this variant, ``<lists>`` is a whitespace or semicolon
separated list of list-valued variables. The ``foreach``
diff --git a/Help/command/message.rst b/Help/command/message.rst
index c614286..6bc0e4c 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -1,13 +1,33 @@
message
-------
-Display a message to the user.
+Log a message.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+ `General messages`_
+ message([<mode>] "message text" ...)
+
+ `Reporting checks`_
+ message(<checkState> "message text" ...)
+
+
+General messages
+^^^^^^^^^^^^^^^^
.. code-block:: cmake
- message([<mode>] "message to display" ...)
+ message([<mode>] "message text" ...)
+
+Record the specified message text in the log. If more than one message
+string is given, they are concatenated into a single message with no
+separator between the strings.
-The optional ``<mode>`` keyword determines the type of message:
+The optional ``<mode>`` keyword determines the type of message, which
+influences the way the message is handled:
``FATAL_ERROR``
CMake Error, stop processing and generation.
@@ -59,12 +79,104 @@ The :manual:`curses interface <ccmake(1)>` shows ``STATUS`` to ``TRACE``
messages one at a time on a status line and other messages in an
interactive pop-up box. The ``--log-level`` command-line option to each of
these tools can be used to control which messages will be shown.
+To make a log level persist between CMake runs, the
+:variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can be set instead.
+Note that the command line option takes precedence over the cache variable.
-Messages of log levels ``NOTICE`` and below will also have each line preceded
+Messages of log levels ``NOTICE`` and below will have each line preceded
by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
a single string by concatenating its list items). For ``STATUS`` to ``TRACE``
messages, this indenting content will be inserted after the hyphens.
+Messages of log levels ``NOTICE`` and below can also have each line preceded
+with context of the form ``[some.context.example]``. The content between the
+square brackets is obtained by converting the :variable:`CMAKE_MESSAGE_CONTEXT`
+list variable to a dot-separated string. The message context will always
+appear before any indenting content but after any automatically added leading
+hyphens. By default, message context is not shown, it has to be explicitly
+enabled by giving the :manual:`cmake <cmake(1)>` ``--log-context``
+command-line option or by setting the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
+variable to true. See the :variable:`CMAKE_MESSAGE_CONTEXT` documentation for
+usage examples.
+
CMake Warning and Error message text displays using a simple markup
language. Non-indented text is formatted in line-wrapped paragraphs
delimited by newlines. Indented text is considered pre-formatted.
+
+
+Reporting checks
+^^^^^^^^^^^^^^^^
+
+A common pattern in CMake output is a message indicating the start of some
+sort of check, followed by another message reporting the result of that check.
+For example:
+
+.. code-block:: cmake
+
+ message(STATUS "Looking for someheader.h")
+ #... do the checks, set checkSuccess with the result
+ if(checkSuccess)
+ message(STATUS "Looking for someheader.h - found")
+ else()
+ message(STATUS "Looking for someheader.h - not found")
+ endif()
+
+This can be more robustly and conveniently expressed using the ``CHECK_...``
+keyword form of the ``message()`` command:
+
+.. code-block:: cmake
+
+ message(<checkState> "message" ...)
+
+where ``<checkState>`` must be one of the following:
+
+ ``CHECK_START``
+ Record a concise message about the check about to be performed.
+
+ ``CHECK_PASS``
+ Record a successful result for a check.
+
+ ``CHECK_FAIL``
+ Record an unsuccessful result for a check.
+
+When recording a check result, the command repeats the message from the most
+recently started check for which no result has yet been reported, then some
+separator characters and then the message text provided after the
+``CHECK_PASS`` or ``CHECK_FAIL`` keyword. Check messages are always reported
+at ``STATUS`` log level.
+
+Checks may be nested and every ``CHECK_START`` should have exactly one
+matching ``CHECK_PASS`` or ``CHECK_FAIL``.
+The :variable:`CMAKE_MESSAGE_INDENT` variable can also be used to add
+indenting to nested checks if desired. For example:
+
+.. code-block:: cmake
+
+ message(CHECK_START "Finding my things")
+ list(APPEND CMAKE_MESSAGE_INDENT " ")
+ unset(missingComponents)
+
+ message(CHECK_START "Finding partA")
+ # ... do check, assume we find A
+ message(CHECK_PASS "found")
+
+ message(CHECK_START "Finding partB")
+ # ... do check, assume we don't find B
+ list(APPEND missingComponents B)
+ message(CHECK_FAIL "not found")
+
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
+ if(missingComponents)
+ message(CHECK_FAIL "missing components: ${missingComponents}")
+ else()
+ message(CHECK_PASS "all components found")
+ endif()
+
+Output from the above would appear something like the following::
+
+ -- Finding my things
+ -- Finding partA
+ -- Finding partA - found
+ -- Finding partB
+ -- Finding partB - not found
+ -- Finding my things - missing components: B
diff --git a/Help/command/project.rst b/Help/command/project.rst
index 3951456..b6093d3 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -102,9 +102,12 @@ options are intended for use as default values in package metadata and documenta
Code Injection
^^^^^^^^^^^^^^
-If the :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variable is set, the file
-pointed to by that variable will be included as the first step of the
+If the :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` or
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables are set,
+the files they point to will be included as the first step of the
``project()`` command.
+If both are set, then :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` will be
+included before :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`.
If the :variable:`CMAKE_PROJECT_INCLUDE` or
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` variables are set, the files
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index cd2aea6..dc65249 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -128,3 +128,24 @@ on Windows Nullsoft Scriptable Install System.
set(CPACK_NSIS_MENU_LINKS
"doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
"CMake Help" "https://cmake.org" "CMake Web Site")
+
+.. variable:: CPACK_NSIS_UNINSTALL_NAME
+
+ Specify the name of the program to uninstall the version.
+ Default is ``Uninstall``.
+
+.. variable:: CPACK_NSIS_WELCOME_TITLE
+
+ The title to display on the top of the page for the welcome page.
+
+.. variable:: CPACK_NSIS_WELCOME_TITLE_3LINES
+
+ Display the title in the welcome page on 3 lines instead of 2.
+
+.. variable:: CPACK_NSIS_FINISH_TITLE
+
+ The title to display on the top of the page for the finish page.
+
+.. variable:: CPACK_NSIS_FINISH_TITLE_3LINES
+
+ Display the title in the finish page on 3 lines instead of 2.
diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst
index e9464b7..81acb9d 100644
--- a/Help/cpack_gen/packagemaker.rst
+++ b/Help/cpack_gen/packagemaker.rst
@@ -15,9 +15,60 @@ macOS using PackageMaker:
compatible with. Different versions of macOS support different
features. For example, CPack can only build component-based installers for
macOS 10.4 or newer, and can only build installers that download
- component son-the-fly for macOS 10.5 or newer. If left blank, this value
+ components on-the-fly for macOS 10.5 or newer. If left blank, this value
will be set to the minimum version of macOS that supports the requested
features. Set this variable to some value (e.g., 10.4) only if you want to
guarantee that your installer will work on that version of macOS, and
don't mind missing extra features available in the installer shipping with
later versions of macOS.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND
+
+ Adds a background to Distribtion XML if specified. The value contains the
+ path to image in ``Resources`` directory.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT
+
+ Adds an ``alignment`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_SCALING
+
+ Adds a ``scaling`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_MIME_TYPE
+
+ Adds a ``mime-type`` attribute to the background in Distribution XML.
+ The option contains MIME type of an image.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_UTI
+
+ Adds an ``uti`` attribute to the background in Distribution XML.
+ The option contains UTI type of an image.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA
+
+ Adds a background for the Dark Aqua theme to Distribution XML if
+ specified. The value contains the path to image in ``Resources``
+ directory.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_ALIGNMENT
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_SCALING
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_SCALING` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_MIME_TYPE
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_MIME_TYPE` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_UTI
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_UTI` option,
+ but for the dark theme.
diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst
index d22fcd4..82b79ae 100644
--- a/Help/cpack_gen/productbuild.rst
+++ b/Help/cpack_gen/productbuild.rst
@@ -58,7 +58,6 @@ macOS using ProductBuild:
component name. No ``postinstall`` script is added if this variable is not
defined for a given component.
-
.. variable:: CPACK_PRODUCTBUILD_RESOURCES_DIR
If specified the productbuild generator copies files from this directory
@@ -66,3 +65,54 @@ macOS using ProductBuild:
before the :variable:`CPACK_RESOURCE_FILE_WELCOME`,
:variable:`CPACK_RESOURCE_FILE_README`, and
:variable:`CPACK_RESOURCE_FILE_LICENSE` files are copied.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND
+
+ Adds a background to Distribtion XML if specified. The value contains the
+ path to image in ``Resources`` directory.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT
+
+ Adds an ``alignment`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_SCALING
+
+ Adds a ``scaling`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_MIME_TYPE
+
+ Adds a ``mime-type`` attribute to the background in Distribution XML.
+ The option contains MIME type of an image.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_UTI
+
+ Adds an ``uti`` attribute to the background in Distribution XML.
+ The option contains UTI type of an image.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA
+
+ Adds a background for the Dark Aqua theme to Distribution XML if
+ specified. The value contains the path to image in ``Resources``
+ directory.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_ALIGNMENT
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_SCALING
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_SCALING` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_MIME_TYPE
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_MIME_TYPE` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_UTI
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_UTI` option,
+ but for the dark theme.
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 44e2273..a1c1a6f 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -14,6 +14,11 @@ Review a Merge Request
The `CMake Review Process`_ requires a maintainer to issue the ``Do: merge``
command to integrate a merge request. Please check at least the following:
+* If the MR source branch (or part of it) should be backported
+ to the ``release`` branch (and is already based on a commit
+ contained in the ``release`` branch), add a ``Backport: release`` or
+ ``Backport: release:<commit-ish>`` trailing line to the MR description.
+
* If the MR source branch is not named well for the change it makes
(e.g. it is just ``master`` or the patch changed during review),
add a ``Topic-rename: <topic>`` trailing line to the MR description
@@ -38,9 +43,10 @@ command to integrate a merge request. Please check at least the following:
of various nightly builders.)
* Ensure that the MR targets the ``master`` branch. A MR intended for
- the ``release`` branch should be based on ``release`` but still merged
- to ``master`` first (via ``Do: merge``). A maintainer may then merge
- the MR topic to ``release`` manually.
+ the ``release`` branch should be based on ``release`` but still target
+ ``master``. Use the above-mentioned ``Backport: release`` line to tell
+ ``Do: merge`` to merge to both. If a MR is merged without the backport
+ line, a maintainer may still merge the MR topic to ``release`` manually.
Maintain Current Release
========================
@@ -51,6 +57,12 @@ using a local branch named ``release-$ver``, where ``$ver`` is the version
number of the current release in the form ``$major.$minor``. It is always
merged into ``master`` before publishing.
+To merge an open MR to the ``release`` branch, edit its description to
+use the ``Backport: release`` line mentioned above and then ``Do: merge``
+normally. To update the ``release`` branch manually (e.g. to merge a
+``$topic`` branch that was merged without the backport line), use the
+following procedure.
+
Before merging a ``$topic`` branch into ``release``, verify that the
``$topic`` branch has already been merged to ``master`` via the usual
``Do: merge`` process. Then, to merge the ``$topic`` branch into
diff --git a/Help/dev/review.rst b/Help/dev/review.rst
index cbde6fe..8ec41d2 100644
--- a/Help/dev/review.rst
+++ b/Help/dev/review.rst
@@ -53,6 +53,10 @@ in GitLab to track the state of a MR:
to a period of inactivity. See the `Expire`_ step. Use this label
after closing a MR for this reason.
+* ``workflow:external-discussion`` indicates that the MR has been closed
+ pending discussion elsewhere. See the `External Discussion`_ step.
+ Use this label after closing a MR for this reason.
+
The workflow status labels are intended to be mutually exclusive,
so please remove any existing workflow label when adding one.
@@ -429,6 +433,21 @@ Additionally, ``Do: merge`` extracts configuration from trailing lines
in the MR description (the following have no effect if used in a MR
comment instead):
+* ``Backport: release[:<commit-ish>]``: merge the topic branch into
+ the ``release`` branch to backport the change. This is allowed
+ only if the topic branch is based on a commit in ``release`` already.
+ If only part of the topic branch should be backported, specify it as
+ ``:<commit-ish>``. The ``<commit-ish>`` may use `git rev-parse`_
+ syntax to reference commits relative to the topic ``HEAD``.
+ See additional `backport instructions`_ for details.
+ For example:
+
+ ``Backport: release``
+ Merge the topic branch head into both ``release`` and ``master``.
+ ``Backport: release:HEAD~1^2``
+ Merge the topic branch head's parent's second parent commit into
+ the ``release`` branch. Merge the topic branch head to ``master``.
+
* ``Topic-rename: <topic>``: substitute ``<topic>`` for the name of
the MR topic branch in the constructed merge commit message.
It is also used in merge commits constructed by ``Do: stage``.
@@ -436,6 +455,8 @@ comment instead):
rename set in the MR description.
.. _`CMake GitLab Project Masters`: https://gitlab.kitware.com/cmake/cmake/settings/members
+.. _`backport instructions`: https://gitlab.kitware.com/utils/git-workflow/wikis/Backport-topics
+.. _`git rev-parse`: https://git-scm.com/docs/git-rev-parse
Close
-----
diff --git a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
new file mode 100644
index 0000000..e9e0810
--- /dev/null
+++ b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -0,0 +1,9 @@
+CMAKE_EXPORT_COMPILE_COMMANDS
+-----------------------------
+
+.. include:: ENV_VAR.txt
+
+The default value for :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` when there
+is no explicit configuration given on the first run while creating a new
+build tree. On later runs in an existing build tree the value persists in
+the cache as :variable:`CMAKE_EXPORT_COMPILE_COMMANDS`.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index 96ceb94..c98f18f 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -23,6 +23,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
/envvar/CMAKE_CONFIG_TYPE
+ /envvar/CMAKE_EXPORT_COMPILE_COMMANDS
/envvar/CMAKE_GENERATOR
/envvar/CMAKE_GENERATOR_INSTANCE
/envvar/CMAKE_GENERATOR_PLATFORM
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 75f4bd4..691481b 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -596,7 +596,8 @@ Target-Dependent Queries
requirement.
``$<INSTALL_PREFIX>``
Content of the install prefix when the target is exported via
- :command:`install(EXPORT)` and empty otherwise.
+ :command:`install(EXPORT)`, or when evaluated in
+ :prop_tgt:`INSTALL_NAME_DIR`, and empty otherwise.
Output-Related Expressions
--------------------------
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index e704371..94d08c6 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -348,6 +348,7 @@ Properties on Targets
/prop_tgt/VS_DOTNET_REFERENCES
/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL
/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION
+ /prop_tgt/VS_DOTNET_DOCUMENTATION_FILE
/prop_tgt/VS_DPI_AWARE
/prop_tgt/VS_GLOBAL_KEYWORD
/prop_tgt/VS_GLOBAL_PROJECT_TYPES
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 53b7f8d..01dd5fd 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -70,7 +70,6 @@ Variables that Provide Information
/variable/CMAKE_MAKE_PROGRAM
/variable/CMAKE_MATCH_COUNT
/variable/CMAKE_MATCH_n
- /variable/CMAKE_MESSAGE_INDENT
/variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION
/variable/CMAKE_NETRC
@@ -206,6 +205,10 @@ Variables that Change Behavior
/variable/CMAKE_LINK_DIRECTORIES_BEFORE
/variable/CMAKE_MFC_FLAG
/variable/CMAKE_MAXIMUM_RECURSION_DEPTH
+ /variable/CMAKE_MESSAGE_CONTEXT
+ /variable/CMAKE_MESSAGE_CONTEXT_SHOW
+ /variable/CMAKE_MESSAGE_INDENT
+ /variable/CMAKE_MESSAGE_LOG_LEVEL
/variable/CMAKE_MODULE_PATH
/variable/CMAKE_POLICY_DEFAULT_CMPNNNN
/variable/CMAKE_POLICY_WARNING_CMPNNNN
@@ -214,6 +217,7 @@ Variables that Change Behavior
/variable/CMAKE_PROJECT_INCLUDE
/variable/CMAKE_PROJECT_INCLUDE_BEFORE
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
+ /variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
/variable/CMAKE_STAGING_PREFIX
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
@@ -239,6 +243,7 @@ Variables that Change Behavior
/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
+ /variable/CMAKE_XCODE_SCHEME_ENVIRONMENT
/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC
/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 4ab55a0..71110d1 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -206,9 +206,24 @@ Options
The :command:`message` command will only output messages of the specified
log level or higher. The default log level is ``STATUS``.
+ To make a log level persist between CMake runs, set
+ :variable:`CMAKE_MESSAGE_LOG_LEVEL` as a cache variable instead.
+ If both the command line option and the variable are given, the command line
+ option takes precedence.
+
For backward compatibility reasons, ``--loglevel`` is also accepted as a
synonym for this option.
+``--log-context``
+ Enable the :command:`message` command outputting context attached to each
+ message.
+
+ This option turns on showing context for the current CMake run only.
+ To make showing the context persistent for all subsequent CMake runs, set
+ :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` as a cache variable instead.
+ When this command line option is given, :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
+ is ignored.
+
``--debug-trycompile``
Do not delete the :command:`try_compile` build tree.
Only useful on one :command:`try_compile` at a time.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index dbefb91..328f579 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -266,6 +266,19 @@ Options
This is useful in finding sporadic failures in test cases.
+``--repeat-until-pass <n>``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests if they fail for any reason.
+
+ This is useful in tolerating sporadic failures in test cases.
+
+``--repeat-after-timeout <n>``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests only if they timeout.
+
+ This is useful in tolerating sporadic timeouts in test cases
+ on busy machines.
+
``--max-width <width>``
Set the max width for a test name to output.
diff --git a/Help/prop_tgt/INSTALL_NAME_DIR.rst b/Help/prop_tgt/INSTALL_NAME_DIR.rst
index 2216072..747615a 100644
--- a/Help/prop_tgt/INSTALL_NAME_DIR.rst
+++ b/Help/prop_tgt/INSTALL_NAME_DIR.rst
@@ -10,3 +10,7 @@ installed targets.
This property is initialized by the value of the variable
:variable:`CMAKE_INSTALL_NAME_DIR` if it is set when a target is
created.
+
+This property supports :manual:`generator expressions <cmake-generator-expressions(7)>`.
+In particular, the ``$<INSTALL_PREFIX>`` generator expression can be used to set the
+directory relative to the install-time prefix.
diff --git a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
new file mode 100644
index 0000000..1bc361c
--- /dev/null
+++ b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
@@ -0,0 +1,6 @@
+VS_DOTNET_DOCUMENTATION_FILE
+----------------------------
+
+Visual Studio managed project .NET documentation output
+
+Sets the target XML documentation file output.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/ExternalProject-git-no-recurse.rst b/Help/release/dev/ExternalProject-git-no-recurse.rst
new file mode 100644
index 0000000..b9e09d3
--- /dev/null
+++ b/Help/release/dev/ExternalProject-git-no-recurse.rst
@@ -0,0 +1,7 @@
+ExternalProject-git-no-recurse
+------------------------------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ command gained a ``GIT_SUBMODULES_RECURSE`` option to specify whether
+ Git submodules should be updated recursively. The default is on to
+ preserve existing behavior.
diff --git a/Help/release/dev/FindCURL-cmake-package.rst b/Help/release/dev/FindCURL-cmake-package.rst
new file mode 100644
index 0000000..67c5bbc
--- /dev/null
+++ b/Help/release/dev/FindCURL-cmake-package.rst
@@ -0,0 +1,7 @@
+FindCURL-cmake-package
+----------------------
+
+* The :module:`FindCURL` module learned to find CURL using
+ the ``CURLConfig.cmake`` package configuration file generated by
+ CURL's cmake buildsystem. It also gained a new ``CURL_NO_CURL_CMAKE``
+ option to disable this behavior.
diff --git a/Help/release/dev/ccmake-colored-values.rst b/Help/release/dev/ccmake-colored-values.rst
new file mode 100644
index 0000000..b00885d
--- /dev/null
+++ b/Help/release/dev/ccmake-colored-values.rst
@@ -0,0 +1,5 @@
+ccmake-colored-values
+---------------------
+
+* :manual:`ccmake(1)` now displays cache values using colors
+ based on the entry type if the terminal supports color.
diff --git a/Help/release/dev/ccmake_progress_bar_and_log_display.rst b/Help/release/dev/ccmake_progress_bar_and_log_display.rst
new file mode 100644
index 0000000..5c67c7d
--- /dev/null
+++ b/Help/release/dev/ccmake_progress_bar_and_log_display.rst
@@ -0,0 +1,6 @@
+ccmake_progress_bar_and_log_display
+-----------------------------------
+
+* :manual:`ccmake(1)` now displays messages and a progress bar during
+ configure and generate. It will keep the output displayed if any
+ errors or warnings occurred.
diff --git a/Help/release/dev/cpack-nsis-uninstaller-name.rst b/Help/release/dev/cpack-nsis-uninstaller-name.rst
new file mode 100644
index 0000000..b7ceb4c
--- /dev/null
+++ b/Help/release/dev/cpack-nsis-uninstaller-name.rst
@@ -0,0 +1,6 @@
+cpack-nsis-uninstaller-name
+---------------------------
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_UNINSTALL_NAME`.
+ This can be used to specify the name of the Uninstall program.
diff --git a/Help/release/dev/cpack-nsis-welcome-finish-page-title.rst b/Help/release/dev/cpack-nsis-welcome-finish-page-title.rst
new file mode 100644
index 0000000..8091d31
--- /dev/null
+++ b/Help/release/dev/cpack-nsis-welcome-finish-page-title.rst
@@ -0,0 +1,10 @@
+cpack-nsis-welcome-finish-page-title
+------------------------------------
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_WELCOME_TITLE` and :variable:`CPACK_NSIS_WELCOME_TITLE_3LINES`.
+ These can be used to specify the welcome page title and display it in 3 lines.
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_FINISH_TITLE` and :variable:`CPACK_NSIS_FINISH_TITLE_3LINES`.
+ These can be used to specify the finish page title and display it in 3 lines.
diff --git a/Help/release/dev/cpack-pkg-background.rst b/Help/release/dev/cpack-pkg-background.rst
new file mode 100644
index 0000000..796f5d6
--- /dev/null
+++ b/Help/release/dev/cpack-pkg-background.rst
@@ -0,0 +1,8 @@
+cpack-pkg-background
+--------------------
+
+* The :cpack_gen:`CPack productbuild Generator` and
+ :cpack_gen:`CPack PackageMaker Generator` gained options
+ :variable:`CPACK_PRODUCTBUILD_BACKGROUND` and
+ :variable:`CPACK_PACKAGEMAKER_BACKGROUND`, respectively,
+ to specify a background image for the macOS installer.
diff --git a/Help/release/dev/ctest-repeat-until-pass.rst b/Help/release/dev/ctest-repeat-until-pass.rst
new file mode 100644
index 0000000..d177247
--- /dev/null
+++ b/Help/release/dev/ctest-repeat-until-pass.rst
@@ -0,0 +1,6 @@
+ctest-repeat-until-pass
+-----------------------
+
+* The :manual:`ctest(1)` tool learned new ``--repeat-until-pass <n>``
+ and ``--repeat-after-timeout <n>`` options to help tolerate sporadic
+ test failures.
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
new file mode 100644
index 0000000..401f4b2
--- /dev/null
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -0,0 +1,8 @@
+deprecate-policy-old
+--------------------
+
+* An explicit deprecation diagnostic was added for policy ``CMP0068``
+ and policy ``CMP0069`` (``CMP0067`` and below were already deprecated).
+ The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+ of all policies are deprecated and that projects should port to the
+ NEW behaviors.
diff --git a/Help/release/dev/export-compile-commands-environment-variable.rst b/Help/release/dev/export-compile-commands-environment-variable.rst
new file mode 100644
index 0000000..da9d66b
--- /dev/null
+++ b/Help/release/dev/export-compile-commands-environment-variable.rst
@@ -0,0 +1,6 @@
+export-compile-commands-environment-variable
+--------------------------------------------
+
+* The :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` variable now takes its
+ initial value from the :envvar:`CMAKE_EXPORT_COMPILE_COMMANDS` environment
+ variable if no explicit configuration is given.
diff --git a/Help/release/dev/feature-CMAKE_MESSAGE_CONTEXT.rst b/Help/release/dev/feature-CMAKE_MESSAGE_CONTEXT.rst
new file mode 100644
index 0000000..a6a5c71
--- /dev/null
+++ b/Help/release/dev/feature-CMAKE_MESSAGE_CONTEXT.rst
@@ -0,0 +1,11 @@
+feature-CMAKE_MESSAGE_CONTEXT
+-----------------------------
+
+* The :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can now be used
+ to persist a log level between CMake runs, unlike the ``--log-level``
+ command line option which only applies to that particular run.
+
+* The :command:`message` command learned to output context provided in
+ the :variable:`CMAKE_MESSAGE_CONTEXT` variable for log levels
+ ``NOTICE`` and below. Enable this output with the new ``--log-context``
+ command-line option or :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable.
diff --git a/Help/release/dev/install-name-dir-genex.rst b/Help/release/dev/install-name-dir-genex.rst
new file mode 100644
index 0000000..0cb41f0
--- /dev/null
+++ b/Help/release/dev/install-name-dir-genex.rst
@@ -0,0 +1,7 @@
+install-name-dir-genex
+----------------------
+
+* The :prop_tgt:`INSTALL_NAME_DIR` target property now supports
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ In particular, the ``$<INSTALL_PREFIX>`` generator expression can
+ be used to set the directory relative to the install-time prefix.
diff --git a/Help/release/dev/mingw_no_sh.rst b/Help/release/dev/mingw_no_sh.rst
new file mode 100644
index 0000000..7008865
--- /dev/null
+++ b/Help/release/dev/mingw_no_sh.rst
@@ -0,0 +1,5 @@
+mingw-no-sh
+-----------
+
+* The :generator:`MinGW Makefiles` generator no longer issues an error if
+ ``sh.exe`` is present in the environment's ``PATH``.
diff --git a/Help/release/dev/new-message-types.rst b/Help/release/dev/new-message-types.rst
new file mode 100644
index 0000000..8f164b9
--- /dev/null
+++ b/Help/release/dev/new-message-types.rst
@@ -0,0 +1,5 @@
+new-message-types
+-----------------
+
+* The :command:`message` command gained new keywords ``CHECK_START``,
+ ``CHECK_PASS`` and ``CHECK_FAIL``.
diff --git a/Help/release/dev/vs-per-config-sources.rst b/Help/release/dev/vs-per-config-sources.rst
new file mode 100644
index 0000000..bf7572b
--- /dev/null
+++ b/Help/release/dev/vs-per-config-sources.rst
@@ -0,0 +1,5 @@
+vs-per-config-sources
+---------------------
+
+* :ref:`Visual Studio Generators` learned to support per-config sources.
+ Previously only :ref:`Command-Line Build Tool Generators` supported them.
diff --git a/Help/release/dev/vs-vctargetspath.rst b/Help/release/dev/vs-vctargetspath.rst
new file mode 100644
index 0000000..d40af34
--- /dev/null
+++ b/Help/release/dev/vs-vctargetspath.rst
@@ -0,0 +1,10 @@
+vs-vctargetspath
+----------------
+
+* With :ref:`Visual Studio Generators` for VS 2010 and above,
+ the :variable:`CMAKE_GENERATOR_TOOLSET` setting gained an option
+ to specify the ``VCTargetsPath`` value for project files.
+
+* The :variable:`CMAKE_VS_GLOBALS` variable value now applies during
+ compiler identification and in targets created by the
+ :command:`add_custom_target` command.
diff --git a/Help/release/dev/vs_dotnet_documentation_file.rst b/Help/release/dev/vs_dotnet_documentation_file.rst
new file mode 100644
index 0000000..fdffb1c
--- /dev/null
+++ b/Help/release/dev/vs_dotnet_documentation_file.rst
@@ -0,0 +1,6 @@
+vs_dotnet_documentation_file
+----------------------------
+
+* The :prop_tgt:`VS_DOTNET_DOCUMENTATION_FILE` target property was added
+ to tell :ref:`Visual Studio Generators` to generate a ``DocumentationFile``
+ reference in ``.csproj`` files.
diff --git a/Help/release/dev/xcode-scheme-env.rst b/Help/release/dev/xcode-scheme-env.rst
new file mode 100644
index 0000000..238cb61
--- /dev/null
+++ b/Help/release/dev/xcode-scheme-env.rst
@@ -0,0 +1,5 @@
+xcode-scheme-env
+----------------
+
+* The :variable:`CMAKE_XCODE_SCHEME_ENVIRONMENT` variable was added
+ to initialize the :prop_tgt:`XCODE_SCHEME_ENVIRONMENT` target property.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 0cc3f97..a4585a5 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index 4548abc..6d2450b 100644
--- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -25,6 +25,9 @@ form. The format of the JSON file looks like:
}
]
+This is initialized by the :envvar:`CMAKE_EXPORT_COMPILE_COMMANDS` environment
+variable.
+
.. note::
This option is implemented only by :ref:`Makefile Generators`
and the :generator:`Ninja`. It is ignored on other generators.
diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
index 222824f..53ad2f3 100644
--- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
@@ -58,3 +58,8 @@ Supported pairs are:
Specify the toolset version to use. Supported by VS 2017
and above with the specified toolset installed.
See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` variable.
+
+``VCTargetsPath=<path>``
+ Specify an alternative ``VCTargetsPath`` value for Visual Studio
+ project files. This allows use of VS platform extension configuration
+ files (``.props`` and ``.targets``) that are not installed with VS.
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
new file mode 100644
index 0000000..6b4ca40
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
@@ -0,0 +1,62 @@
+CMAKE_MESSAGE_CONTEXT
+---------------------
+
+When enabled by the :manual:`cmake <cmake(1)>` ``--log-context`` command line
+option or the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable, the
+:command:`message` command converts the ``CMAKE_MESSAGE_CONTEXT`` list into a
+dot-separated string surrounded by square brackets and prepends it to each line
+for messages of log levels ``NOTICE`` and below.
+
+For logging contexts to work effectively, projects should generally
+``APPEND`` and ``POP_BACK`` an item to the current value of
+``CMAKE_MESSAGE_CONTEXT`` rather than replace it.
+Projects should not assume the message context at the top of the source tree
+is empty, as there are scenarios where the context might have already been set
+(e.g. hierarchical projects).
+
+.. warning::
+
+ Valid context names are restricted to anything that could be used
+ as a CMake variable name. All names that begin with an underscore
+ or the string ``cmake_`` are also reserved for use by CMake and
+ should not be used by projects.
+
+Example:
+
+.. code-block:: cmake
+
+ function(bar)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
+ message(VERBOSE "bar VERBOSE message")
+ endfunction()
+
+ function(baz)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
+ message(DEBUG "baz DEBUG message")
+ endfunction()
+
+ function(foo)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
+ bar()
+ message(TRACE "foo TRACE message")
+ baz()
+ endfunction()
+
+ list(APPEND CMAKE_MESSAGE_CONTEXT "top")
+
+ message(VERBOSE "Before `foo`")
+ foo()
+ message(VERBOSE "After `foo`")
+
+ list(POP_BACK CMAKE_MESSAGE_CONTEXT)
+
+
+Which results in the following output:
+
+.. code-block:: none
+
+ -- [top] Before `foo`
+ -- [top.foo.bar] bar VERBOSE message
+ -- [top.foo] foo TRACE message
+ -- [top.foo.baz] baz DEBUG message
+ -- [top] After `foo`
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
new file mode 100644
index 0000000..7ec218e
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
@@ -0,0 +1,15 @@
+CMAKE_MESSAGE_CONTEXT_SHOW
+--------------------------
+
+Setting this variable to true enables showing a context with each line
+logged by the :command:`message` command (see :variable:`CMAKE_MESSAGE_CONTEXT`
+for how the context itself is specified).
+
+This variable is an alternative to providing the ``--log-context`` option
+on the :manual:`cmake <cmake(1)>` command line. Whereas the command line
+option will apply only to that one CMake run, setting
+``CMAKE_MESSAGE_CONTEXT_SHOW`` to true as a cache variable will ensure that
+subsequent CMake runs will continue to show the message context.
+
+Projects should not set ``CMAKE_MESSAGE_CONTEXT_SHOW``. It is intended for
+users so that they may control whether or not to include context with messages.
diff --git a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
new file mode 100644
index 0000000..1d4cfe6
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
@@ -0,0 +1,15 @@
+CMAKE_MESSAGE_LOG_LEVEL
+-----------------------
+
+When set, this variable specifies the logging level used by the
+:command:`message` command. Valid values are the same as those for the
+``--log-level`` command line option of the :manual:`cmake(1)` program.
+If this variable is set and the ``--log-level`` command line option is
+given, the command line option takes precedence.
+
+The main advantage to using this variable is to make a log level persist
+between CMake runs. Setting it as a cache variable will ensure that
+subsequent CMake runs will continue to use the chosen log level.
+
+Projects should not set this variable, it is intended for users so that
+they may control the log level according to their own needs.
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
index 965c94e..5835264 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
@@ -5,5 +5,6 @@ A CMake language file or module to be included as the last step of all
:command:`project` command calls. This is intended for injecting custom code
into project builds without modifying their source.
-See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` and
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
index 70b15e6..280c14a 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
@@ -5,5 +5,6 @@ A CMake language file or module to be included as the first step of all
:command:`project` command calls. This is intended for injecting custom code
into project builds without modifying their source.
-See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` and
:variable:`CMAKE_PROJECT_INCLUDE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
index 3485c38..74247f1 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
@@ -6,5 +6,6 @@ A CMake language file or module to be included as the last step of any
name. This is intended for injecting custom code into project builds without
modifying their source.
-See also the :variable:`CMAKE_PROJECT_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
+:variable:`CMAKE_PROJECT_INCLUDE` and
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
new file mode 100644
index 0000000..db1432d
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
@@ -0,0 +1,11 @@
+CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
+-------------------------------------------
+
+A CMake language file or module to be included as the first step of any
+:command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
+name. This is intended for injecting custom code into project builds without
+modifying their source.
+
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_INCLUDE` and
+:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
new file mode 100644
index 0000000..4832659
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
@@ -0,0 +1,15 @@
+CMAKE_XCODE_SCHEME_ENVIRONMENT
+------------------------------
+
+Specify environment variables that should be added to the Arguments
+section of the generated Xcode scheme.
+
+If set to a list of environment variables and values of the form
+``MYVAR=value`` those environment variables will be added to the
+scheme.
+
+This variable initializes the :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
+property on all targets.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 01a81a1..6adebae 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -5,7 +5,7 @@
function(cmake_determine_compile_features lang)
if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features)
- message(STATUS "Detecting ${lang} compile features")
+ message(CHECK_START "Detecting ${lang} compile features")
set(CMAKE_C90_COMPILE_FEATURES)
set(CMAKE_C99_COMPILE_FEATURES)
@@ -16,7 +16,7 @@ function(cmake_determine_compile_features lang)
cmake_record_c_compile_features()
if(NOT _result EQUAL 0)
- message(STATUS "Detecting ${lang} compile features - failed")
+ message(CHECK_FAIL "failed")
return()
endif()
@@ -40,10 +40,10 @@ function(cmake_determine_compile_features lang)
set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE)
- message(STATUS "Detecting ${lang} compile features - done")
+ message(CHECK_PASS "done")
elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
- message(STATUS "Detecting ${lang} compile features")
+ message(CHECK_START "Detecting ${lang} compile features")
set(CMAKE_CXX98_COMPILE_FEATURES)
set(CMAKE_CXX11_COMPILE_FEATURES)
@@ -56,7 +56,7 @@ function(cmake_determine_compile_features lang)
cmake_record_cxx_compile_features()
if(NOT _result EQUAL 0)
- message(STATUS "Detecting ${lang} compile features - failed")
+ message(CHECK_FAIL "failed")
return()
endif()
@@ -90,7 +90,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
- message(STATUS "Detecting ${lang} compile features - done")
+ message(CHECK_PASS "done")
endif()
endfunction()
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 06f3ba2..c5611b5 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -12,7 +12,7 @@ include(CMakeTestCompilerCommon)
function(CMAKE_DETERMINE_COMPILER_ABI lang src)
if(NOT DEFINED CMAKE_${lang}_ABI_COMPILED)
- message(STATUS "Detecting ${lang} compiler ABI info")
+ message(CHECK_START "Detecting ${lang} compiler ABI info")
# Compile the ABI identification source.
set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
@@ -66,7 +66,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
# Load the resulting information strings.
if(CMAKE_${lang}_ABI_COMPILED AND NOT _copy_error)
- message(STATUS "Detecting ${lang} compiler ABI info - done")
+ message(CHECK_PASS "done")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
@@ -124,8 +124,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
# a try-compile
if("${lang}" MATCHES "Fortran"
AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
- set(_desc "Determine Intel Fortran Compiler Implicit Link Path")
- message(STATUS "${_desc}")
+ message(CHECK_START "Determine Intel Fortran Compiler Implicit Link Path")
# Build a sample project which reports symbols.
try_compile(IFORT_LIB_PATH_COMPILED
${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath
@@ -138,8 +137,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
"${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
"${_output}")
include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
- set(_desc "Determine Intel Fortran Compiler Implicit Link Path -- done")
- message(STATUS "${_desc}")
+ message(CHECK_PASS "done")
endif()
# Implicit link libraries cannot be used explicitly for multiple
@@ -166,7 +164,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
endif()
else()
- message(STATUS "Detecting ${lang} compiler ABI info - failed")
+ message(CHECK_FAIL "failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n")
endif()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 908e530..f7ef755 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -317,6 +317,15 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
endif()
+ if(CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR)
+ set(id_ToolsetVCTargetsDir "<VCTargetsPath>${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}</VCTargetsPath>")
+ endif()
+ set(id_CustomGlobals "")
+ foreach(pair IN LISTS CMAKE_VS_GLOBALS)
+ if("${pair}" MATCHES "([^=]+)=(.*)$")
+ string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n ")
+ endif()
+ endforeach()
if(id_platform STREQUAL ARM64)
set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
elseif(id_platform STREQUAL ARM)
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index dc208c6..f3ec4da 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -43,7 +43,7 @@ if(CMAKE_HOST_UNIX)
else()
exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
endif()
- if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$")
+ if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$|Android")
exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 77d8cfd..7efe5c4 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -51,16 +51,16 @@ if(CMAKE_GENERATOR MATCHES "Make")
set_property(GLOBAL PROPERTY TARGET_MESSAGES ${CMAKE_TARGET_MESSAGES})
endif()
if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
- set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
- "Enable/Disable output of compile commands during generation."
+ set(CMAKE_EXPORT_COMPILE_COMMANDS "$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}"
+ CACHE BOOL "Enable/Disable output of compile commands during generation."
)
mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
endif()
endif()
if(CMAKE_GENERATOR MATCHES "Ninja")
- set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
- "Enable/Disable output of compile commands during generation."
+ set(CMAKE_EXPORT_COMPILE_COMMANDS "$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}"
+ CACHE BOOL "Enable/Disable output of compile commands during generation."
)
mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
endif()
diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake
index 1911e73..be4a3be 100644
--- a/Modules/CMakeGraphVizOptions.cmake
+++ b/Modules/CMakeGraphVizOptions.cmake
@@ -5,119 +5,145 @@
CMakeGraphVizOptions
--------------------
-The builtin graphviz support of CMake.
+The builtin Graphviz support of CMake.
-Variables specific to the graphviz support
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Generating Graphviz files
+^^^^^^^^^^^^^^^^^^^^^^^^^
-CMake
-can generate `graphviz <http://www.graphviz.org/>`_ files, showing the dependencies between the
-targets in a project and also external libraries which are linked
-against. When CMake is run with the ``--graphviz=foo.dot`` option, it will
-produce:
+CMake can generate `Graphviz <https://www.graphviz.org/>`_ files showing the
+dependencies between the targets in a project, as well as external libraries
+which are linked against.
-* a ``foo.dot`` file showing all dependencies in the project
-* a ``foo.dot.<target>`` file for each target, file showing on which other targets the respective target depends
-* a ``foo.dot.<target>.dependers`` file, showing which other targets depend on the respective target
+When running CMake with the ``--graphviz=foo.dot`` option, it produces:
-The different dependency types ``PUBLIC``, ``PRIVATE`` and ``INTERFACE``
-are represented as solid, dashed and dotted edges.
+* a ``foo.dot`` file, showing all dependencies in the project
+* a ``foo.dot.<target>`` file for each target, showing on which other targets
+ it depends
+* a ``foo.dot.<target>.dependers`` file for each target, showing which other
+ targets depend on it
-This can result in huge graphs. Using the file
-``CMakeGraphVizOptions.cmake`` the look and content of the generated
-graphs can be influenced. This file is searched first in
-:variable:`CMAKE_BINARY_DIR` and then in :variable:`CMAKE_SOURCE_DIR`. If found, it is
-read and the variables set in it are used to adjust options for the
-generated graphviz files.
+Those .dot files can be converted to images using the *dot* command from the
+Graphviz package:
-.. variable:: GRAPHVIZ_GRAPH_TYPE
+.. code-block:: shell
- The graph type.
+ dot -Tpng -o foo.png foo.dot
- * Mandatory : NO
- * Default : "digraph"
+The different dependency types ``PUBLIC``, ``INTERFACE`` and ``PRIVATE``
+are represented as solid, dashed and dotted edges.
- Valid graph types are:
+Variables specific to the Graphviz support
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * "graph" : Nodes are joined with lines
- * "digraph" : Nodes are joined with arrows showing direction
- * "strict graph" : Like "graph" but max one line between each node
- * "strict digraph" : Like "graph" but max one line between each node in each direction
+The resulting graphs can be huge. The look and content of the generated graphs
+can be controlled using the file ``CMakeGraphVizOptions.cmake``. This file is
+first searched in :variable:`CMAKE_BINARY_DIR`, and then in
+:variable:`CMAKE_SOURCE_DIR`. If found, the variables set in it are used to
+adjust options for the generated Graphviz files.
.. variable:: GRAPHVIZ_GRAPH_NAME
The graph name.
- * Mandatory : NO
- * Default : "GG"
+ * Mandatory: NO
+ * Default: value of :variable:`CMAKE_PROJECT_NAME`
.. variable:: GRAPHVIZ_GRAPH_HEADER
- The header written at the top of the graphviz file.
+ The header written at the top of the Graphviz files.
- * Mandatory : NO
- * Default : "node [n fontsize = "12"];"
+ * Mandatory: NO
+ * Default: "node [ fontsize = "12" ];"
.. variable:: GRAPHVIZ_NODE_PREFIX
- The prefix for each node in the graphviz file.
+ The prefix for each node in the Graphviz files.
- * Mandatory : NO
- * Default : "node"
+ * Mandatory: NO
+ * Default: "node"
.. variable:: GRAPHVIZ_EXECUTABLES
- Set this to FALSE to exclude executables from the generated graphs.
+ Set to FALSE to exclude executables from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_STATIC_LIBS
- Set this to FALSE to exclude static libraries from the generated graphs.
+ Set to FALSE to exclude static libraries from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_SHARED_LIBS
- Set this to FALSE to exclude shared libraries from the generated graphs.
+ Set to FALSE to exclude shared libraries from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_MODULE_LIBS
- Set this to FALSE to exclude module libraries from the generated graphs.
+ Set to FALSE to exclude module libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_INTERFACE_LIBS
+
+ Set to FALSE to exclude interface libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
- * Mandatory : NO
- * Default : TRUE
+.. variable:: GRAPHVIZ_OBJECT_LIBS
+
+ Set to FALSE to exclude object libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_UNKNOWN_LIBS
+
+ Set to FALSE to exclude unknown libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_EXTERNAL_LIBS
- Set this to FALSE to exclude external libraries from the generated graphs.
+ Set to FALSE to exclude external libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_CUSTOM_TARGETS
+
+ Set to TRUE to include custom targets in the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: FALSE
.. variable:: GRAPHVIZ_IGNORE_TARGETS
- A list of regular expressions for ignoring targets.
+ A list of regular expressions for names of targets to exclude from the
+ generated graphs.
- * Mandatory : NO
- * Default : empty
+ * Mandatory: NO
+ * Default: empty
.. variable:: GRAPHVIZ_GENERATE_PER_TARGET
- Set this to FALSE to exclude per target graphs ``foo.dot.<target>``.
+ Set to FALSE to not generate per-target graphs ``foo.dot.<target>``.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_GENERATE_DEPENDERS
- Set this to FALSE to exclude depender graphs ``foo.dot.<target>.dependers``.
+ Set to FALSE to not generate depender graphs ``foo.dot.<target>.dependers``.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
#]=======================================================================]
diff --git a/Modules/CMakeMinGWFindMake.cmake b/Modules/CMakeMinGWFindMake.cmake
index 523f00c..f026e9a 100644
--- a/Modules/CMakeMinGWFindMake.cmake
+++ b/Modules/CMakeMinGWFindMake.cmake
@@ -7,10 +7,5 @@ find_program(CMAKE_MAKE_PROGRAM mingw32-make.exe PATHS
c:/MinGW/bin /MinGW/bin
"[HKEY_CURRENT_USER\\Software\\CodeBlocks;Path]/MinGW/bin"
)
-find_program(CMAKE_SH sh.exe )
-if(CMAKE_SH)
- message(FATAL_ERROR "sh.exe was found in your PATH, here:\n${CMAKE_SH}\nFor MinGW make to work correctly sh.exe must NOT be in your path.\nRun cmake from a shell that does not have sh.exe in your PATH.\nIf you want to use a UNIX shell, then use MSYS Makefiles.\n")
- set(CMAKE_MAKE_PROGRAM NOTFOUND)
-endif()
-mark_as_advanced(CMAKE_MAKE_PROGRAM CMAKE_SH)
+mark_as_advanced(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 7bf6fde..eadea89 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_C_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_C_COMPILER_WORKS)
- PrintTestCompilerStatus("C" "")
+ PrintTestCompilerStatus("C")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
"#ifdef __cplusplus\n"
@@ -52,7 +52,7 @@ if(NOT CMAKE_C_COMPILER_WORKS)
endif()
if(NOT CMAKE_C_COMPILER_WORKS)
- PrintTestCompilerStatus("C" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the C compiler works failed with "
"the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
@@ -63,7 +63,7 @@ if(NOT CMAKE_C_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(C_TEST_WAS_RUN)
- PrintTestCompilerStatus("C" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the C compiler works passed with "
"the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake
index 6715c30..1119a45 100644
--- a/Modules/CMakeTestCSharpCompiler.cmake
+++ b/Modules/CMakeTestCSharpCompiler.cmake
@@ -20,7 +20,9 @@ set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CSharp_COMPILER_WORKS)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER}")
+ # Don't call PrintTestCompilerStatus() because the "C#" we want to pass
+ # as the LANG doesn't match with the variable name "CMAKE_CSharp_COMPILER"
+ message(CHECK_START "Check for working C# compiler: ${CMAKE_CSharp_COMPILER}")
file(WRITE "${test_compile_file}"
"namespace Test {"
" public class CSharp {"
@@ -38,7 +40,7 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS)
endif()
if(NOT CMAKE_CSharp_COMPILER_WORKS)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the C# compiler works failed with "
"the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
@@ -49,7 +51,7 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CSharp_TEST_WAS_RUN)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the C# compiler works passed with "
"the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index f0454da..c145813 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -20,7 +20,7 @@ unset(CMAKE_CUDA_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CUDA_COMPILER_WORKS)
- PrintTestCompilerStatus("CUDA" "")
+ PrintTestCompilerStatus("CUDA")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.cu
"#ifndef __CUDACC__\n"
"# error \"The CMAKE_CUDA_COMPILER is set to an invalid CUDA compiler\"\n"
@@ -38,7 +38,7 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS)
endif()
if(NOT CMAKE_CUDA_COMPILER_WORKS)
- PrintTestCompilerStatus("CUDA" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CUDA compiler works failed with "
"the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
@@ -49,7 +49,7 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CUDA_TEST_WAS_RUN)
- PrintTestCompilerStatus("CUDA" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CUDA compiler works passed with "
"the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index 7e595b7..bd42153 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_CXX_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CXX_COMPILER_WORKS)
- PrintTestCompilerStatus("CXX" "")
+ PrintTestCompilerStatus("CXX")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx
"#ifndef __cplusplus\n"
@@ -45,7 +45,7 @@ if(NOT CMAKE_CXX_COMPILER_WORKS)
endif()
if(NOT CMAKE_CXX_COMPILER_WORKS)
- PrintTestCompilerStatus("CXX" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CXX compiler works failed with "
"the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
@@ -56,7 +56,7 @@ if(NOT CMAKE_CXX_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CXX_TEST_WAS_RUN)
- PrintTestCompilerStatus("CXX" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler works passed with "
"the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCompilerCommon.cmake b/Modules/CMakeTestCompilerCommon.cmake
index 6ee5175..da7c007 100644
--- a/Modules/CMakeTestCompilerCommon.cmake
+++ b/Modules/CMakeTestCompilerCommon.cmake
@@ -2,8 +2,15 @@
# file Copyright.txt or https://cmake.org/licensing for details.
-function(PrintTestCompilerStatus LANG MSG)
- message(STATUS "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${MSG}")
+function(PrintTestCompilerStatus LANG)
+ # ARGN shouldn't be needed now, but it is there to preserve backward
+ # compatibility in case this function is called from project code or
+ # custom toolchains (they shouldn't, but we can easily support it)
+ message(CHECK_START "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${ARGN}")
+endfunction()
+
+function(PrintTestCompilerResult TYPE MSG)
+ message(${TYPE} "${MSG}")
endfunction()
# if required set the target type if not already explicitly set
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index e9860e9..7461f9c 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -21,7 +21,7 @@ unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_Fortran_COMPILER_WORKS)
- PrintTestCompilerStatus("Fortran" "")
+ PrintTestCompilerStatus("Fortran")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f "
PROGRAM TESTFortran
PRINT *, 'Hello'
@@ -37,7 +37,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS)
endif()
if(NOT CMAKE_Fortran_COMPILER_WORKS)
- PrintTestCompilerStatus("Fortran" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran compiler works failed with "
"the following output:\n${OUTPUT}\n\n")
@@ -48,7 +48,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(FORTRAN_TEST_WAS_RUN)
- PrintTestCompilerStatus("Fortran" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler works passed with "
"the following output:\n${OUTPUT}\n\n")
@@ -60,7 +60,7 @@ else()
# Test for Fortran 90 support by using an f90-specific construct.
if(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
+ message(CHECK_START "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 "
PROGRAM TESTFortran90
integer stop ; stop = 1 ; do while ( stop .eq. 0 ) ; end do
@@ -70,13 +70,13 @@ else()
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90
OUTPUT_VARIABLE OUTPUT)
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- yes")
+ message(CHECK_PASS "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler supports Fortran 90 passed with "
"the following output:\n${OUTPUT}\n\n")
set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
else()
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- no")
+ message(CHECK_FAIL "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran compiler supports Fortran 90 failed with "
"the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/CMakeTestOBJCCompiler.cmake b/Modules/CMakeTestOBJCCompiler.cmake
index 0030683..bcc6fae 100644
--- a/Modules/CMakeTestOBJCCompiler.cmake
+++ b/Modules/CMakeTestOBJCCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_OBJC_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJC" "")
+ PrintTestCompilerStatus("OBJC")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m
"#ifdef __cplusplus\n"
@@ -49,7 +49,7 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS)
endif()
if(NOT CMAKE_OBJC_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJC" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Objective-C compiler works failed with "
"the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
@@ -60,7 +60,7 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(OBJC_TEST_WAS_RUN)
- PrintTestCompilerStatus("OBJC" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Objective-C compiler works passed with "
"the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestOBJCXXCompiler.cmake b/Modules/CMakeTestOBJCXXCompiler.cmake
index bcce2f1..83227d5 100644
--- a/Modules/CMakeTestOBJCXXCompiler.cmake
+++ b/Modules/CMakeTestOBJCXXCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJCXX" "")
+ PrintTestCompilerStatus("OBJCXX")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm
"#ifndef __cplusplus\n"
@@ -48,7 +48,7 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
endif()
if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJCXX" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Objective-C++ compiler works failed with "
"the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
@@ -59,7 +59,7 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(OBJCXX_TEST_WAS_RUN)
- PrintTestCompilerStatus("OBJCXX" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Objective-C++ compiler works passed with "
"the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
index 841aee6..3e4ff95 100644
--- a/Modules/CMakeTestSwiftCompiler.cmake
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -20,7 +20,7 @@ unset(CMAKE_Swift_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_Swift_COMPILER_WORKS)
- PrintTestCompilerStatus("Swift" "")
+ PrintTestCompilerStatus("Swift")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
"print(\"CMake\")\n")
try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
@@ -33,7 +33,7 @@ if(NOT CMAKE_Swift_COMPILER_WORKS)
endif()
if(NOT CMAKE_Swift_COMPILER_WORKS)
- PrintTestCompilerStatus("Swift" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Swift compiler works failed with "
"the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
@@ -44,7 +44,7 @@ if(NOT CMAKE_Swift_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(Swift_TEST_WAS_RUN)
- PrintTestCompilerStatus("Swift" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Swift compiler works passed with "
"the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 8a6a712..cbb5323 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -681,6 +681,8 @@ endif()
# value of CPACK_NSIS_PACKAGE_NAME instead
# of CPACK_PACKAGE_INSTALL_DIRECTORY
_cpack_set_default(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+# Specify the name of the Uninstall file in NSIS
+_cpack_set_default(CPACK_NSIS_UNINSTALL_NAME "Uninstall")
if(CPACK_NSIS_DISPLAY_NAME_SET)
_cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_NSIS_DISPLAY_NAME}")
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
index 77ba0cc..67fc993 100644
--- a/Modules/CheckCSourceCompiles.cmake
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -104,7 +104,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -125,7 +125,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -133,7 +133,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake
index eba70f2..7d116db 100644
--- a/Modules/CheckCSourceRuns.cmake
+++ b/Modules/CheckCSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -113,7 +113,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeeded with the following compile output:\n"
@@ -130,7 +130,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following compile output:\n"
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
index cc457a5..c693d32 100644
--- a/Modules/CheckCXXSourceCompiles.cmake
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -105,7 +105,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -126,7 +126,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -134,7 +134,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake
index 5e3f195..408e183 100644
--- a/Modules/CheckCXXSourceRuns.cmake
+++ b/Modules/CheckCXXSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -114,7 +114,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -131,7 +131,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake
index 7ca205a..d06203f 100644
--- a/Modules/CheckFortranFunctionExists.cmake
+++ b/Modules/CheckFortranFunctionExists.cmake
@@ -38,7 +38,7 @@ include_guard(GLOBAL)
macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
if(NOT DEFINED ${VARIABLE})
- message(STATUS "Looking for Fortran ${FUNCTION}")
+ message(CHECK_START "Looking for Fortran ${FUNCTION}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -61,21 +61,20 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
"
)
try_compile(${VARIABLE}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
- ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS}
- ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
- OUTPUT_VARIABLE OUTPUT
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
+ ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS}
+ ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
+ OUTPUT_VARIABLE OUTPUT
)
-# message(STATUS "${OUTPUT}")
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}")
- message(STATUS "Looking for Fortran ${FUNCTION} - found")
+ message(CHECK_PASS "found")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for Fortran ${FUNCTION} - not found")
+ message(CHECK_FAIL "not found")
set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran ${FUNCTION} exists failed with the following output:\n"
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index f94b254..f0fde8d 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -127,7 +127,7 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -148,7 +148,7 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -156,7 +156,7 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index a80c13d..a3e5d5d 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -122,7 +122,7 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -144,7 +144,7 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -161,7 +161,7 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake
index c39144f..136da89 100644
--- a/Modules/CheckFunctionExists.cmake
+++ b/Modules/CheckFunctionExists.cmake
@@ -57,7 +57,7 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION}")
+ message(CHECK_START "Looking for ${FUNCTION}")
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS
@@ -101,14 +101,14 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} - found")
+ message(CHECK_PASS "found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index d7b9481..3a10473 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -55,7 +55,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE}")
+ message(CHECK_START "Looking for ${INCLUDE}")
endif()
if(${ARGC} EQUAL 3)
set(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS})
@@ -109,7 +109,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -118,7 +118,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index de5a83b..496550f 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -54,7 +54,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE}")
+ message(CHECK_START "Looking for C++ include ${INCLUDE}")
endif()
if(${ARGC} EQUAL 3)
set(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
@@ -108,7 +108,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -117,7 +117,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index f52ab55..8e10cd6 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -131,7 +131,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description}")
+ message(CHECK_START "Looking for ${_description}")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
@@ -147,7 +147,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
unset(_CIF_LINK_LIBRARIES)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -156,7 +156,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index a1a3a7a..a337926 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -39,7 +39,7 @@ include_guard(GLOBAL)
macro(check_language lang)
if(NOT DEFINED CMAKE_${lang}_COMPILER)
set(_desc "Looking for a ${lang} compiler")
- message(STATUS ${_desc})
+ message(CHECK_START "${_desc}")
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang})
set(extra_compiler_variables)
@@ -78,13 +78,15 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${_desc} passed with the following output:\n"
"${output}\n")
+ set(_CHECK_COMPILER_STATUS CHECK_PASS)
else()
set(CMAKE_${lang}_COMPILER NOTFOUND)
+ set(_CHECK_COMPILER_STATUS CHECK_FAIL)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${_desc} failed with the following output:\n"
"${output}\n")
endif()
- message(STATUS "${_desc} - ${CMAKE_${lang}_COMPILER}")
+ message(${_CHECK_COMPILER_STATUS} "${CMAKE_${lang}_COMPILER}")
set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler")
mark_as_advanced(CMAKE_${lang}_COMPILER)
diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake
index 6504df5..6470dfd 100644
--- a/Modules/CheckLibraryExists.cmake
+++ b/Modules/CheckLibraryExists.cmake
@@ -42,7 +42,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
set(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
+ message(CHECK_START "Looking for ${FUNCTION} in ${LIBRARY}")
endif()
set(CHECK_LIBRARY_EXISTS_LINK_OPTIONS)
if(CMAKE_REQUIRED_LINK_OPTIONS)
@@ -78,7 +78,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -87,7 +87,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index a4676ad..601f1fa 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -104,7 +104,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -125,7 +125,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -133,7 +133,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCSourceRuns.cmake b/Modules/CheckOBJCSourceRuns.cmake
index 00a1ebd..6684693 100644
--- a/Modules/CheckOBJCSourceRuns.cmake
+++ b/Modules/CheckOBJCSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -113,7 +113,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following compile output:\n"
@@ -130,7 +130,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Objective-C SOURCE FILE Test ${VAR} failed with the following compile output:\n"
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 4c0fdd0..2ee79f4 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -105,7 +105,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -126,7 +126,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -134,7 +134,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCXXSourceRuns.cmake b/Modules/CheckOBJCXXSourceRuns.cmake
index a3d5923..7f7e04f 100644
--- a/Modules/CheckOBJCXXSourceRuns.cmake
+++ b/Modules/CheckOBJCXXSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -114,7 +114,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -131,7 +131,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake
index a7b020c..8b06403 100644
--- a/Modules/CheckPrototypeDefinition.cmake
+++ b/Modules/CheckPrototypeDefinition.cmake
@@ -54,6 +54,9 @@ include_guard(GLOBAL)
function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
if (NOT DEFINED ${_VARIABLE})
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(CHECK_START "Checking prototype ${_FUNCTION} for ${_VARIABLE}")
+ endif()
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
@@ -103,14 +106,14 @@ function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB
if (${_VARIABLE})
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
+ message(CHECK_PASS "True")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
"${OUTPUT}\n\n")
else ()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
+ message(CHECK_FAIL "False")
endif()
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 1053383..4f202c4 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -126,7 +126,7 @@ int main(int argc, char** argv)
"${SOURCEFILE}" @ONLY)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL}")
+ message(CHECK_START "Looking for ${SYMBOL}")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
@@ -140,7 +140,7 @@ int main(int argc, char** argv)
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -150,7 +150,7 @@ int main(int argc, char** argv)
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 3727373..2b07b7c 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -86,7 +86,7 @@ cmake_policy(SET CMP0054 NEW)
# Helper function. DO NOT CALL DIRECTLY.
function(__check_type_size_impl type var map builtin language)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type}")
+ message(CHECK_START "Check size of ${type}")
endif()
# Include header files.
@@ -173,7 +173,7 @@ function(__check_type_size_impl type var map builtin language)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type} - done")
+ message(CHECK_PASS "done")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining size of ${type} passed with the following output:\n${output}\n\n")
@@ -181,7 +181,7 @@ function(__check_type_size_impl type var map builtin language)
else()
# The check failed to compile.
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type} - failed")
+ message(CHECK_FAIL "failed")
endif()
file(READ ${src} content)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake
index f4953a3..8a93535 100644
--- a/Modules/CheckVariableExists.cmake
+++ b/Modules/CheckVariableExists.cmake
@@ -42,7 +42,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
set(MACRO_CHECK_VARIABLE_DEFINITIONS
"-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR}")
+ message(CHECK_START "Looking for ${VAR}")
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_VARIABLE_EXISTS_ADD_LINK_OPTIONS
@@ -67,7 +67,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR} - found")
+ message(CHECK_PASS "found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the variable ${VAR} exists passed with the following output:\n"
@@ -75,7 +75,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
else()
set(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR} - not found")
+ message(CHECK_FAIL "not found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the variable ${VAR} exists failed with the following output:\n"
diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake
index 9973feb..c54ab9d 100644
--- a/Modules/Compiler/NAG-Fortran.cmake
+++ b/Modules/Compiler/NAG-Fortran.cmake
@@ -1,6 +1,6 @@
# Help CMAKE_PARSE_IMPLICIT_LINK_INFO detect NAG Fortran object files.
if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED)
- message(STATUS "Detecting NAG Fortran directory")
+ message(CHECK_START "Detecting NAG Fortran directory")
# Run with -dryrun to see sample "link" line.
execute_process(
COMMAND ${CMAKE_Fortran_COMPILER} dummy.o -dryrun
@@ -20,11 +20,11 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED)
" directory: ${_nag_dir}\n"
" regex: ${CMAKE_Fortran_IMPLICIT_OBJECT_REGEX}\n"
"from output:\n${_dryrun}\n\n")
- message(STATUS "Detecting NAG Fortran directory - ${_nag_dir}")
+ message(CHECK_PASS "${_nag_dir}")
else()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting NAG Fortran directory with -dryrun failed:\n${_dryrun}\n\n")
- message(STATUS "Detecting NAG Fortran directory - failed")
+ message(CHECK_FAIL "failed")
endif()
endif()
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index d742274..b48a332 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -15,6 +15,8 @@
@id_WindowsTargetPlatformVersion@
@id_WindowsSDKDesktopARMSupport@
@id_CudaToolkitCustomDir@
+ @id_ToolsetVCTargetsDir@
+ @id_CustomGlobals@
</PropertyGroup>
@id_toolset_version_props@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 66061a1..cd4e22d 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -265,6 +265,11 @@ External Project Definition
is set to ``NEW`` if this value is set to an empty string then no submodules
are initialized or updated.
+ ``GIT_SUBMODULES_RECURSE <bool>``
+ Specify whether git submodules (if any) should update recursively by
+ passing the ``--recursive`` flag to ``git submodule update``.
+ If not specified, the default is on.
+
``GIT_SHALLOW <bool>``
When this option is enabled, the ``git clone`` operation will be given
the ``--depth 1`` option. This performs a shallow clone, which avoids
@@ -1065,7 +1070,7 @@ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
"ExternalProject module."
)
-function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
+function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
# Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
set(git_checkout_explicit-- "--")
@@ -1153,7 +1158,7 @@ endif()
set(init_submodules ${init_submodules})
if(init_submodules)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules}
+ COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update ${git_submodules_recurse} --init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -1394,7 +1399,7 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"
set(init_submodules ${init_submodules})
if(init_submodules)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules}
+ COMMAND \"${git_EXECUTABLE}\" submodule update ${git_submodules_recurse} --init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -2421,9 +2426,21 @@ function(_ep_add_download_command name)
message(FATAL_ERROR "error: could not find git for clone of ${name}")
endif()
+ get_property(git_submodules_recurse_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE SET)
+ if(NOT git_submodules_recurse_set)
+ set(git_submodules_recurse "--recursive")
+ else()
+ get_property(git_submodules_recurse_value TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE)
+ if(git_submodules_recurse_value)
+ set(git_submodules_recurse "--recursive")
+ else()
+ set(git_submodules_recurse "")
+ endif()
+ endif()
+
# The git submodule update '--recursive' flag requires git >= v1.6.5
#
- if(GIT_VERSION_STRING VERSION_LESS 1.6.5)
+ if(git_submodules_recurse AND GIT_VERSION_STRING VERSION_LESS 1.6.5)
message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
endif()
@@ -2477,7 +2494,7 @@ function(_ep_add_download_command name)
# The script will delete the source directory and then call git clone.
#
_ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
- ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
+ ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}"
)
set(comment "Performing download step (git clone) for '${name}'")
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index b6859aa..2a3e131 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -676,7 +676,7 @@ endif()
# Search for the cuda distribution.
if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
# Search in the CUDA_BIN_PATH first.
- find_path(CUDA_TOOLKIT_ROOT_DIR
+ find_program(CUDA_TOOLKIT_ROOT_DIR_NVCC
NAMES nvcc nvcc.exe
PATHS
ENV CUDA_TOOLKIT_ROOT
@@ -688,19 +688,22 @@ if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
)
# Now search default paths
- find_path(CUDA_TOOLKIT_ROOT_DIR
+ find_program(CUDA_TOOLKIT_ROOT_DIR_NVCC
NAMES nvcc nvcc.exe
PATHS /opt/cuda/bin
PATH_SUFFIXES cuda/bin
DOC "Toolkit location."
)
- if (CUDA_TOOLKIT_ROOT_DIR)
+ if (CUDA_TOOLKIT_ROOT_DIR_NVCC)
+ get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
+ get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR}" DIRECTORY CACHE)
string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR})
# We need to force this back into the cache.
set(CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR} CACHE PATH "Toolkit location." FORCE)
set(CUDA_TOOLKIT_TARGET_DIR ${CUDA_TOOLKIT_ROOT_DIR})
endif()
+ unset(CUDA_TOOLKIT_ROOT_DIR_NVCC CACHE)
if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
if(CUDA_FIND_REQUIRED)
@@ -921,7 +924,7 @@ set(CUDA_LIBRARIES)
if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY)
list(APPEND CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY})
elseif(CUDA_USE_STATIC_CUDA_RUNTIME AND CUDA_cudart_static_LIBRARY)
- list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
+ list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS})
if (CUDA_rt_LIBRARY)
list(APPEND CUDA_LIBRARIES ${CUDA_rt_LIBRARY})
endif()
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index aeebc84..919babc 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -37,8 +37,35 @@ This module defines the following variables:
``CURL_VERSION_STRING``
The version of ``curl`` found.
+
+CURL CMake
+^^^^^^^^^^
+
+If CURL was built using the CMake buildsystem then it provides its own
+``CURLConfig.cmake`` file for use with the :command:`find_package` command's
+config mode. This module looks for this file and, if found,
+returns its results with no further action.
+
+Set ``CURL_NO_CURL_CMAKE`` to ``ON`` to disable this search.
+
#]=======================================================================]
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+if(NOT CURL_NO_CURL_CMAKE)
+ # do a find package call to specifically look for the CMake version
+ # of curl
+ find_package(CURL QUIET NO_MODULE)
+ mark_as_advanced(CURL_DIR)
+
+ # if we found the CURL cmake package then we are done, and
+ # can print what we found and return.
+ if(CURL_FOUND)
+ find_package_handle_standard_args(CURL HANDLE_COMPONENTS CONFIG_MODE)
+ return()
+ endif()
+endif()
+
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_CURL QUIET libcurl)
@@ -139,7 +166,6 @@ if(CURL_FIND_COMPONENTS)
endforeach()
endif()
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(CURL
REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
VERSION_VAR CURL_VERSION_STRING
diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake
index d48de08..b2e00df 100644
--- a/Modules/FindDCMTK.cmake
+++ b/Modules/FindDCMTK.cmake
@@ -102,7 +102,7 @@ set(_SAVED_DCMTK_DIR ${DCMTK_DIR})
# Step1: Attempt to find a version of DCMTK providing a DCMTKConfig.cmake file.
#
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake")
+ message(CHECK_START "Trying to find DCMTK expecting DCMTKConfig.cmake")
endif()
find_package(DCMTK QUIET NO_MODULE)
if(DCMTK_FOUND
@@ -110,12 +110,12 @@ if(DCMTK_FOUND
AND NOT "x" STREQUAL "x${DCMTK_INCLUDE_DIRS}")
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - ok")
+ message(CHECK_PASS "ok")
endif()
return()
else()
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - failed")
+ message(CHECK_FAIL "failed")
endif()
endif()
diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake
index e366619..b8ca71b 100644
--- a/Modules/FindMFC.cmake
+++ b/Modules/FindMFC.cmake
@@ -31,7 +31,7 @@ if(MFC_ATTEMPT_TRY_COMPILE)
set(CHECK_INCLUDE_FILE_VAR "afxwin.h")
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
- message(STATUS "Looking for MFC")
+ message(CHECK_START "Looking for MFC")
# Try both shared and static as the root project may have set the /MT flag
try_compile(MFC_HAVE_MFC
${CMAKE_BINARY_DIR}
@@ -51,13 +51,13 @@ if(MFC_ATTEMPT_TRY_COMPILE)
OUTPUT_VARIABLE OUTPUT)
endif()
if(MFC_HAVE_MFC)
- message(STATUS "Looking for MFC - found")
+ message(CHECK_PASS "found")
set(MFC_HAVE_MFC 1 CACHE INTERNAL "Have MFC?")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if MFC exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for MFC - not found")
+ message(CHECK_FAIL "not found")
set(MFC_HAVE_MFC 0 CACHE INTERNAL "Have MFC?")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if MFC exists failed with the following output:\n"
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 33ceab7..3688ae9 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -131,6 +131,7 @@ find_path(OPENSSL_INCLUDE_DIR
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_INCLUDEDIR}
+ ${_OPENSSL_INCLUDE_DIRS}
PATH_SUFFIXES
include
)
@@ -319,6 +320,7 @@ else()
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
+ ${_OPENSSL_LIBRARY_DIRS}
PATH_SUFFIXES
lib
)
@@ -330,6 +332,7 @@ else()
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
+ ${_OPENSSL_LIBRARY_DIRS}
PATH_SUFFIXES
lib
)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index b67d563..0d6d2fc 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -409,6 +409,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}")
# interpreter does not exist anymore
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -427,6 +428,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
endif()
if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -444,6 +446,11 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (result OR (_PVI_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
# interpreter not usable or has wrong major version
+ if (result)
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ else()
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -459,6 +466,11 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# interpreter not usable or has wrong major version
+ if (result)
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ else()
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -476,6 +488,11 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P)
# interpreter not usable or has wrong architecture
+ if (result)
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ else()
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -500,6 +517,7 @@ function (_PYTHON_VALIDATE_COMPILER expected_version)
if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}")
# Compiler does not exist anymore
+ set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "_${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
@@ -526,6 +544,11 @@ function (_PYTHON_VALIDATE_COMPILER expected_version)
if (result OR (_PVC_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
# Compiler not usable or has wrong version
+ if (result)
+ set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
+ else()
+ set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "_${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
endif()
endfunction()
@@ -545,6 +568,7 @@ function (_PYTHON_VALIDATE_LIBRARY)
if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
# library does not exist anymore
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
if (WIN32)
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND")
@@ -558,16 +582,19 @@ function (_PYTHON_VALIDATE_LIBRARY)
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
else()
if (expected_version)
if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL expected_version) OR (lib_VERSION VERSION_LESS expected_version))
# library has wrong version
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
else()
if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# library has wrong major version
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
endif()
@@ -596,6 +623,7 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR)
if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
# include file does not exist anymore
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
return()
endif()
@@ -605,16 +633,19 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR)
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
else()
if (expected_version)
if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version))
# include dir has wrong version
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
else()
if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# include dir has wrong major version
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
endif()
@@ -836,6 +867,10 @@ endif()
unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
unset (_${_PYTHON_PREFIX}_CACHED_VARS)
+unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
# first step, search for the interpreter
@@ -1161,6 +1196,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# Interpreter is not usable
set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE)
unset (${_PYTHON_PREFIX}_VERSION)
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
endif()
endif()
@@ -1416,6 +1452,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
else()
# compiler not usable
set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE)
+ set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
endif()
file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
endif()
@@ -1914,6 +1951,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "Path to a library." FORCE)
if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
@@ -2046,6 +2084,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
+ set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
@@ -2169,6 +2208,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+ set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND")
endif()
@@ -2207,11 +2247,19 @@ if (${_PYTHON_PREFIX}_VERSION_MAJOR AND
_python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
endif()
+unset (_${_PYTHON_PREFIX}_REASON_FAILURE)
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
+ if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
+ string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}")
+ endif()
+endforeach()
+
include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args (${_PYTHON_PREFIX}
REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS}
VERSION_VAR ${_PYTHON_PREFIX}_VERSION
- HANDLE_COMPONENTS)
+ HANDLE_COMPONENTS
+ REASON_FAILURE_MESSAGE "${_${_PYTHON_PREFIX}_REASON_FAILURE}")
# Create imported targets and helper functions
if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index d39fe33..1780511 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -90,7 +90,7 @@ macro(_check_pthreads_flag)
if(NOT Threads_FOUND)
# If we did not find a thread library look for -pthread compiler option.
if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG)
- message(STATUS "Check if compiler accepts -pthread")
+ message(CHECK_START "Check if compiler accepts -pthread")
if(CMAKE_C_COMPILER_LOADED)
set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c)
elseif(CMAKE_CXX_COMPILER_LOADED)
@@ -106,9 +106,9 @@ macro(_check_pthreads_flag)
if(THREADS_HAVE_PTHREAD_ARG)
set(Threads_FOUND TRUE)
- message(STATUS "Check if compiler accepts -pthread - yes")
+ message(CHECK_PASS "yes")
else()
- message(STATUS "Check if compiler accepts -pthread - no")
+ message(CHECK_FAIL "no")
file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index 893a96f..547346b 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -341,7 +341,7 @@ function(FortranCInterface_VERIFY)
# Build the verification project if not yet built.
if(NOT DEFINED FortranCInterface_VERIFIED_${lang})
set(_desc "Verifying Fortran/${lang} Compiler Compatibility")
- message(STATUS "${_desc}")
+ message(CHECK_START "${_desc}")
# Build a sample project which reports symbols.
set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
@@ -363,12 +363,12 @@ function(FortranCInterface_VERIFY)
# Report results.
if(FortranCInterface_VERIFY_${lang}_COMPILED)
- message(STATUS "${_desc} - Success")
+ message(CHECK_PASS "Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${_desc} passed with the following output:\n${_output}\n\n")
set(FortranCInterface_VERIFIED_${lang} 1 CACHE INTERNAL "Fortran/${lang} compatibility")
else()
- message(STATUS "${_desc} - Failed")
+ message(CHECK_FAIL "Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${_desc} failed with the following output:\n${_output}\n\n")
set(FortranCInterface_VERIFIED_${lang} 0 CACHE INTERNAL "Fortran/${lang} compatibility")
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index 7789785..33de6c6 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -15,7 +15,7 @@ if(${FortranCInterface_BINARY_DIR}/Input.cmake
OR ${CMAKE_CURRENT_LIST_FILE}
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
)
- message(STATUS "Detecting Fortran/C Interface")
+ message(CHECK_START "Detecting Fortran/C Interface")
else()
return()
endif()
@@ -172,7 +172,9 @@ if(FortranCInterface_GLOBAL_FOUND)
else()
set(_result "Found GLOBAL but not MODULE mangling")
endif()
+ set(_result_type CHECK_PASS)
elseif(NOT _result)
set(_result "Failed to recognize symbols")
+ set(_result_type CHECK_FAIL)
endif()
-message(STATUS "Detecting Fortran/C Interface - ${_result}")
+message(${_result_type} "${_result}")
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index f75ae78..23bb0018 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -542,6 +542,8 @@ FunctionEnd
;--------------------------------
;Pages
+ @CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE@
+ @CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE@
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
@@ -557,6 +559,8 @@ FunctionEnd
@CPACK_NSIS_PAGE_COMPONENTS@
!insertmacro MUI_PAGE_INSTFILES
+ @CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE@
+ @CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE@
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
@@ -642,7 +646,7 @@ Section "-Core installation"
WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
;Create uninstaller
- WriteUninstaller "$INSTDIR\Uninstall.exe"
+ WriteUninstaller "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
Push "DisplayName"
Push "@CPACK_NSIS_DISPLAY_NAME@"
Call ConditionalAddToRegisty
@@ -653,7 +657,7 @@ Section "-Core installation"
Push "@CPACK_PACKAGE_VENDOR@"
Call ConditionalAddToRegisty
Push "UninstallString"
- Push "$INSTDIR\Uninstall.exe"
+ Push "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
Call ConditionalAddToRegisty
Push "NoRepair"
Push "1"
@@ -690,7 +694,7 @@ Section "-Core installation"
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
@CPACK_NSIS_CREATE_ICONS@
@CPACK_NSIS_CREATE_ICONS_EXTRA@
- CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
+ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
;Read a value from an InstallOptions INI file
!insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
@@ -829,7 +833,7 @@ Section "Uninstall"
!endif
;Remove the uninstaller itself.
- Delete "$INSTDIR\Uninstall.exe"
+ Delete "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
;Remove the installation directory if it is empty.
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 847178f..759448b 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -24,6 +24,14 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ macro(__android_compiler_clang lang)
+ endmacro()
+ return()
+endif()
+
include(Platform/Android-Common)
# The NDK toolchain configuration files at:
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index e7c1b48..2225897 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -18,6 +18,12 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index a5d2820..b90dd7a 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -24,6 +24,12 @@ if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
if(NOT CMAKE_SYSROOT)
if(CMAKE_ANDROID_NDK)
set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}")
diff --git a/Modules/Platform/Android.cmake b/Modules/Platform/Android.cmake
index f08f841..8ffa1b2 100644
--- a/Modules/Platform/Android.cmake
+++ b/Modules/Platform/Android.cmake
@@ -2,6 +2,11 @@ include(Platform/Linux)
set(ANDROID 1)
+# Natively compiling on an Android host doesn't need these flags to be reset.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
# Conventionally Android does not use versioned soname
# But in modern versions it is acceptable
if(NOT DEFINED CMAKE_PLATFORM_NO_VERSIONED_SONAME)
diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake
index 5c6b97b..f9c2d89 100644
--- a/Modules/Platform/Android/Determine-Compiler.cmake
+++ b/Modules/Platform/Android/Determine-Compiler.cmake
@@ -31,6 +31,16 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
set(_ANDROID_HOST_EXT "")
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(_ANDROID_HOST_EXT ".exe")
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ # Natively compiling on an Android host doesn't use the NDK cross-compilation
+ # tools.
+ macro(__android_determine_compiler lang)
+ # Do nothing
+ endmacro()
+ if(NOT CMAKE_CXX_COMPILER_NAMES)
+ set(CMAKE_CXX_COMPILER_NAMES c++)
+ endif()
+ return()
else()
message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
endif()
diff --git a/Modules/Platform/Apple-GNU.cmake b/Modules/Platform/Apple-GNU.cmake
index 0eb8168..9572736 100644
--- a/Modules/Platform/Apple-GNU.cmake
+++ b/Modules/Platform/Apple-GNU.cmake
@@ -19,17 +19,17 @@ endmacro()
macro(cmake_gnu_set_sysroot_flag lang)
if(NOT DEFINED CMAKE_${lang}_SYSROOT_FLAG)
set(_doc "${lang} compiler has -isysroot")
- message(STATUS "Checking whether ${_doc}")
+ message(CHECK_START "Checking whether ${_doc}")
execute_process(
COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
OUTPUT_VARIABLE _gcc_help
ERROR_VARIABLE _gcc_help
)
if("${_gcc_help}" MATCHES "isysroot")
- message(STATUS "Checking whether ${_doc} - yes")
+ message(CHECK_PASS "yes")
set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot")
else()
- message(STATUS "Checking whether ${_doc} - no")
+ message(CHECK_FAIL "no")
set(CMAKE_${lang}_SYSROOT_FLAG "")
endif()
set(CMAKE_${lang}_SYSROOT_FLAG_CODE "set(CMAKE_${lang}_SYSROOT_FLAG \"${CMAKE_${lang}_SYSROOT_FLAG}\")")
@@ -39,17 +39,17 @@ endmacro()
macro(cmake_gnu_set_osx_deployment_target_flag lang)
if(NOT DEFINED CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG)
set(_doc "${lang} compiler supports OSX deployment target flag")
- message(STATUS "Checking whether ${_doc}")
+ message(CHECK_START "Checking whether ${_doc}")
execute_process(
COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
OUTPUT_VARIABLE _gcc_help
ERROR_VARIABLE _gcc_help
)
if("${_gcc_help}" MATCHES "macosx-version-min")
- message(STATUS "Checking whether ${_doc} - yes")
+ message(CHECK_PASS "yes")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=")
else()
- message(STATUS "Checking whether ${_doc} - no")
+ message(CHECK_FAIL "no")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "")
endif()
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG_CODE "set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG \"${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}\")")
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
index 0c6e188..8a769b7 100644
--- a/Modules/TestBigEndian.cmake
+++ b/Modules/TestBigEndian.cmake
@@ -19,8 +19,8 @@ include(CheckTypeSize)
macro(TEST_BIG_ENDIAN VARIABLE)
if(NOT DEFINED HAVE_${VARIABLE})
- message(STATUS "Check if the system is big endian")
- message(STATUS "Searching 16 bit integer")
+ message(CHECK_START "Check if the system is big endian")
+ message(CHECK_START "Searching 16 bit integer")
if(CMAKE_C_COMPILER_LOADED)
set(_test_language "C")
@@ -32,19 +32,19 @@ macro(TEST_BIG_ENDIAN VARIABLE)
CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
- message(STATUS "Using unsigned short")
+ message(CHECK_PASS "Using unsigned short")
set(CMAKE_16BIT_TYPE "unsigned short")
else()
CHECK_TYPE_SIZE("unsigned int" CMAKE_SIZEOF_UNSIGNED_INT LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_INT)
- message(STATUS "Using unsigned int")
+ message(CHECK_PASS "Using unsigned int")
set(CMAKE_16BIT_TYPE "unsigned int")
else()
CHECK_TYPE_SIZE("unsigned long" CMAKE_SIZEOF_UNSIGNED_LONG LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_LONG)
- message(STATUS "Using unsigned long")
+ message(CHECK_PASS "Using unsigned long")
set(CMAKE_16BIT_TYPE "unsigned long")
else()
message(FATAL_ERROR "no suitable type found")
@@ -95,15 +95,16 @@ macro(TEST_BIG_ENDIAN VARIABLE)
if(CMAKE_TEST_ENDIANESS_STRINGS_LE)
set(${VARIABLE} 0 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
- message(STATUS "Check if the system is big endian - little endian")
+ message(CHECK_PASS "little endian")
endif()
if(CMAKE_TEST_ENDIANESS_STRINGS_BE)
set(${VARIABLE} 1 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
- message(STATUS "Check if the system is big endian - big endian")
+ message(CHECK_PASS "big endian")
endif()
if(NOT CMAKE_TEST_ENDIANESS_STRINGS_BE AND NOT CMAKE_TEST_ENDIANESS_STRINGS_LE)
+ message(CHECK_FAIL "TEST_BIG_ENDIAN found no result!")
message(SEND_ERROR "TEST_BIG_ENDIAN found no result!")
endif()
@@ -111,7 +112,7 @@ macro(TEST_BIG_ENDIAN VARIABLE)
"Determining if the system is big endian passed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
else()
- message(STATUS "Check if the system is big endian - failed")
+ message(CHECK_FAIL "failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the system is big endian failed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
set(${VARIABLE})
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake
index 92a362e..ce505f3 100644
--- a/Modules/TestCXXAcceptsFlag.cmake
+++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -23,19 +23,19 @@ Check if the CXX compiler accepts a flag.
macro(CHECK_CXX_ACCEPTS_FLAG FLAGS VARIABLE)
if(NOT DEFINED ${VARIABLE})
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS}")
+ message(CHECK_START "Checking to see if CXX compiler accepts flag ${FLAGS}")
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/DummyCXXFile.cxx
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${FLAGS}
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - yes")
+ message(CHECK_PASS "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler accepts the flag ${FLAGS} passed with "
"the following output:\n${OUTPUT}\n\n")
else()
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - no")
+ message(CHECK_FAIL "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CXX compiler accepts the flag ${FLAGS} failed with "
"the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake
index 272e4ec..0f2dc01 100644
--- a/Modules/TestForANSIForScope.cmake
+++ b/Modules/TestForANSIForScope.cmake
@@ -16,19 +16,19 @@ for-init-statement to the loop body.
#]=======================================================================]
if(NOT DEFINED CMAKE_ANSI_FOR_SCOPE)
- message(STATUS "Check for ANSI scope")
+ message(CHECK_START "Check for ANSI scope")
try_compile(CMAKE_ANSI_FOR_SCOPE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_ANSI_FOR_SCOPE)
- message(STATUS "Check for ANSI scope - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL
"Does the compiler support ansi for scope.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler understands ansi for scopes passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for ANSI scope - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL
"Does the compiler support ansi for scope.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake
index e70df00..545b7ec 100644
--- a/Modules/TestForSSTREAM.cmake
+++ b/Modules/TestForSSTREAM.cmake
@@ -15,19 +15,19 @@ check if the compiler supports the standard ANSI sstream header
#]=======================================================================]
if(NOT DEFINED CMAKE_HAS_ANSI_STRING_STREAM)
- message(STATUS "Check for sstream")
+ message(CHECK_START "Check for sstream")
try_compile(CMAKE_HAS_ANSI_STRING_STREAM ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSSTREAM.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_HAS_ANSI_STRING_STREAM)
- message(STATUS "Check for sstream - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_ANSI_STRING_STREAM 0 CACHE INTERNAL
"Does the compiler support sstream")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler has sstream passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for sstream - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_ANSI_STRING_STREAM 1 CACHE INTERNAL
"Does the compiler support sstream")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake
index 703e631..d101c83 100644
--- a/Modules/TestForSTDNamespace.cmake
+++ b/Modules/TestForSTDNamespace.cmake
@@ -15,19 +15,19 @@ check if the compiler supports std:: on stl classes
#]=======================================================================]
if(NOT DEFINED CMAKE_STD_NAMESPACE)
- message(STATUS "Check for STD namespace")
+ message(CHECK_START "Check for STD namespace")
try_compile(CMAKE_STD_NAMESPACE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_STD_NAMESPACE)
- message(STATUS "Check for STD namespace - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_STD_NAMESPACE 0 CACHE INTERNAL
"Does the compiler support std::.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler has std namespace passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for STD namespace - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_STD_NAMESPACE 1 CACHE INTERNAL
"Does the compiler support std::.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b1f7b29..d050fb7 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -289,6 +289,8 @@ set(SRCS
cmGeneratorExpression.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
+ cmLinkItemGraphVisitor.cxx
+ cmLinkItemGraphVisitor.h
cmGetPipes.cxx
cmGetPipes.h
cmGlobalCommonGenerator.cxx
@@ -1193,6 +1195,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 f72da64..f9e3d4a 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 16)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 3)
+set(CMake_VERSION_PATCH 20191115)
+#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
# Start with the full version number used in tags. It has no dev info.
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index adea8ec..f90a740 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -129,14 +129,13 @@ 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());
@@ -174,6 +173,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/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 3e1a51b..328aac3 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("Internal/CPack/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 69286ff..be730ab 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 c5ba726..12ea97b 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"),
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index dae268c..a3e55de 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 5895652..d7868f3 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -314,7 +314,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 +324,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/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 02d396e..9ab3c2e 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -171,8 +171,8 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->RunningCount += GetProcessorsUsed(test);
cmCTestRunTest* testRun = new cmCTestRunTest(*this);
- if (this->CTest->GetRepeatUntilFail()) {
- testRun->SetRunUntilFailOn();
+ if (this->CTest->GetRerunMode() != cmCTest::Rerun::Never) {
+ testRun->SetRerunMode(this->CTest->GetRerunMode());
testRun->SetNumberOfRuns(this->CTest->GetTestRepeat());
}
testRun->SetIndex(test);
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 3091050..317f0b4 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)
@@ -343,10 +340,14 @@ bool cmCTestRunTest::NeedsToRerun()
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->RerunMode == cmCTest::Rerun::UntilFail &&
+ this->TestResult.Status == cmCTestTestHandler::COMPLETED) ||
+ (this->RerunMode == cmCTest::Rerun::UntilPass &&
+ this->TestResult.Status != cmCTestTestHandler::COMPLETED) ||
+ (this->RerunMode == cmCTest::Rerun::AfterTimeout &&
+ this->TestResult.Status == cmCTestTestHandler::TIMEOUT)) {
this->RunAgain = true;
return true;
}
@@ -746,7 +747,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->RerunMode != cmCTest::Rerun::UntilPass &&
+ this->RerunMode != cmCTest::Rerun::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 f781c7a..d5e83d9 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 SetRerunMode(cmCTest::Rerun r) { this->RerunMode = r; }
void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties* prop)
{
this->TestProperties = prop;
@@ -132,9 +136,10 @@ private:
std::vector<std::map<
std::string, std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>
AllocatedResources;
- bool RunUntilFail;
- int NumberOfRunsLeft;
- bool RunAgain;
+ cmCTest::Rerun RerunMode = cmCTest::Rerun::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/Checks/Curses.cmake b/Source/Checks/Curses.cmake
index 2942b66..d35dd2a 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 6b8d10b..2263be3 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 38606b9..8e9c2c7 100644
--- a/Source/Checks/cm_cxx14_check.cmake
+++ b/Source/Checks/cm_cxx14_check.cmake
@@ -4,7 +4,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
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 4da2fd7..9e1d9c3 100644
--- a/Source/Checks/cm_cxx17_check.cmake
+++ b/Source/Checks/cm_cxx17_check.cmake
@@ -4,7 +4,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
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_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index fb68ed7..de8a77a 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()
@@ -31,14 +35,14 @@ function(cm_check_cxx_feature name)
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 0000000..024c397
--- /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 7009717..c24ee76 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 9e9dfbd..7732105 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);
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
index 97b0811..c4dbed8 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 0000000..641d48c
--- /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 0000000..78ca52c
--- /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 e2d8d06..a69fdee 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)
@@ -19,11 +20,7 @@ cmCursesLongMessageForm::cmCursesLongMessageForm(
std::vector<std::string> const& messages, const char* title)
{
// 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 +45,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 +86,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);
@@ -139,7 +136,6 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
form_driver(this->Form, REQ_BEG_FIELD);
this->UpdateStatusBar();
- this->PrintKeys();
touchwin(stdscr);
refresh();
}
@@ -153,6 +149,7 @@ void cmCursesLongMessageForm::HandleInput()
char debugMessage[128];
for (;;) {
+ this->PrintKeys();
int key = getch();
sprintf(debugMessage, "Message widget handling input, key: %d", key);
@@ -173,7 +170,16 @@ void cmCursesLongMessageForm::HandleInput()
}
this->UpdateStatusBar();
- this->PrintKeys();
+ touchwin(stdscr);
+ wrefresh(stdscr);
+ }
+}
+
+void cmCursesLongMessageForm::ScrollDown()
+{
+ if (this->Form) {
+ form_driver(this->Form, REQ_END_FIELD);
+ this->UpdateStatusBar();
touchwin(stdscr);
wrefresh(stdscr);
}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 42f9c71..dde5bff 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -26,6 +26,10 @@ public:
void HandleInput() override;
// Description:
+ // Scroll down to the end of the content
+ void ScrollDown();
+
+ // Description:
// Display form. Use a window of size width x height, starting
// at top, left.
void Render(int left, int top, int width, int height) override;
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 6b71e8a..ffc9528 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);
}
@@ -446,6 +447,15 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
bar[width] = '\0';
+ // Highlight the current label
+ // 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
+ using size_type = decltype(this->Fields)::size_type;
+ for (size_type index = 0; index < this->Fields.size() - 1; index += 3) {
+ bool currentLabel = index == static_cast<size_type>(findex - 2);
+ set_field_fore(this->Fields[index], currentLabel ? A_STANDOUT : A_NORMAL);
+ }
+
// Display CMake version info on the next line
// We want to display this on the right
char version[cmCursesMainForm::MAX_WIDTH];
@@ -469,18 +479,21 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
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)
@@ -489,15 +502,15 @@ int cmCursesMainForm::Configure(int noconfigure)
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 +518,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 +534,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,15 +542,17 @@ int cmCursesMainForm::Configure(int noconfigure)
int xx;
int yy;
getmaxyx(stdscr, yy, xx);
+ const char* title = "Configure produced the following output";
+ if (cmSystemTools::GetErrorOccuredFlag()) {
+ title = "Configure failed with the following output";
+ }
cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->Errors,
- cmSystemTools::GetErrorOccuredFlag()
- ? "Errors occurred during the last pass."
- : "CMake produced the following output.");
+ new cmCursesLongMessageForm(this->Outputs, title);
// reset error condition
cmSystemTools::ResetErrorOccuredFlag();
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
+ msgs->ScrollDown();
msgs->HandleInput();
// If they typed the wrong source directory, we report
// an error and exit
@@ -563,26 +575,21 @@ int cmCursesMainForm::Generate()
int yi;
getmaxyx(stdscr, yi, xi);
- curses_move(1, 1);
- this->UpdateStatusBar("Generating, please wait...");
- this->PrintKeys(1);
- touchwin(stdscr);
- refresh();
+ this->ResetOutputs();
+
+ 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,14 +599,15 @@ 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);
+ new cmCursesLongMessageForm(this->Outputs, title);
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
+ msgs->ScrollDown();
msgs->HandleInput();
// If they typed the wrong source directory, we report
// an error and exit
@@ -619,7 +627,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)
@@ -849,7 +859,7 @@ void cmCursesMainForm::HandleInput()
}
cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->HelpMessage, "Help.");
+ new cmCursesLongMessageForm(this->HelpMessage, "Help");
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -861,7 +871,7 @@ 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");
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -1024,6 +1034,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());
+ CurrentForm = newLogForm;
+ this->LogForm.reset(newLogForm);
+ this->LogForm->Render(1, 1, xi, yi);
+ this->LogForm->ScrollDown();
+}
+
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 +1112,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 b8769b7..598fbdf 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -16,6 +16,7 @@
#include "cmStateTypes.h"
class cmake;
+class cmCursesLongMessageForm;
/** \class cmCursesMainForm
* \brief The main page of ccmake
@@ -122,10 +123,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 eb773ad..a15241f 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 bb3808e..8ed42de 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 6296af2..c629478 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/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index cb89d19..98dd0e2 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/cmAlgorithms.h b/Source/cmAlgorithms.h
index e0d27ee..e83f160 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>
@@ -144,6 +145,13 @@ void cmDeleteAll(Range const& r)
ContainerAlgorithms::DefaultDeleter<Range>());
}
+template <typename T>
+void cmAppend(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r)
+{
+ std::transform(r.begin(), r.end(), std::back_inserter(v),
+ [](const std::unique_ptr<T>& item) { return item.get(); });
+}
+
template <typename T, typename Range>
void cmAppend(std::vector<T>& v, Range const& r)
{
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 6eae26e..34e9479 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -84,7 +84,7 @@ struct cmCTest::Private
};
int RepeatTests = 1; // default to run each test once
- bool RepeatUntilFail = false;
+ cmCTest::Rerun RerunMode = cmCTest::Rerun::Never;
std::string ConfigType;
std::string ScheduleType;
std::chrono::system_clock::time_point StopTime;
@@ -1839,11 +1839,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->RerunMode != cmCTest::Rerun::Never) {
+ errormsg = "At most one '--repeat-*' option may be used.";
+ return false;
+ }
i++;
long repeat = 1;
if (!cmStrToLong(args[i], &repeat)) {
@@ -1853,7 +1858,51 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
this->Impl->RepeatTests = static_cast<int>(repeat);
if (repeat > 1) {
- this->Impl->RepeatUntilFail = true;
+ this->Impl->RerunMode = cmCTest::Rerun::UntilFail;
+ }
+ }
+
+ if (this->CheckArgument(arg, "--repeat-until-pass")) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--repeat-until-pass' requires an argument";
+ return false;
+ }
+ if (this->Impl->RerunMode != cmCTest::Rerun::Never) {
+ errormsg = "At most one '--repeat-*' option may be used.";
+ return false;
+ }
+ i++;
+ long repeat = 1;
+ if (!cmStrToLong(args[i], &repeat)) {
+ errormsg =
+ "'--repeat-until-pass' given non-integer value '" + args[i] + "'";
+ return false;
+ }
+ this->Impl->RepeatTests = static_cast<int>(repeat);
+ if (repeat > 1) {
+ this->Impl->RerunMode = cmCTest::Rerun::UntilPass;
+ }
+ }
+
+ if (this->CheckArgument(arg, "--repeat-after-timeout")) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--repeat-after-timeout' requires an argument";
+ return false;
+ }
+ if (this->Impl->RerunMode != cmCTest::Rerun::Never) {
+ errormsg = "At most one '--repeat-*' option may be used.";
+ return false;
+ }
+ i++;
+ long repeat = 1;
+ if (!cmStrToLong(args[i], &repeat)) {
+ errormsg =
+ "'--repeat-after-timeout' given non-integer value '" + args[i] + "'";
+ return false;
+ }
+ this->Impl->RepeatTests = static_cast<int>(repeat);
+ if (repeat > 1) {
+ this->Impl->RerunMode = cmCTest::Rerun::AfterTimeout;
}
}
@@ -2852,9 +2901,9 @@ int cmCTest::GetTestRepeat() const
return this->Impl->RepeatTests;
}
-bool cmCTest::GetRepeatUntilFail() const
+cmCTest::Rerun cmCTest::GetRerunMode() const
{
- return this->Impl->RepeatUntilFail;
+ return this->Impl->RerunMode;
}
void cmCTest::SetBuildID(const std::string& id)
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 82a6f4c..bef0f8d 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -433,8 +433,14 @@ public:
/** Return the number of times a test should be run */
int GetTestRepeat() const;
- /** Return true if test should run until fail */
- bool GetRepeatUntilFail() const;
+ enum class Rerun
+ {
+ Never,
+ UntilFail,
+ UntilPass,
+ AfterTimeout,
+ };
+ Rerun GetRerunMode() const;
void GenerateSubprojectsOutput(cmXMLWriter& xml);
std::vector<std::string> GetLabelsForSubprojects();
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 162bab2..c22cf4a 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -4,6 +4,7 @@
#include <cassert>
#include <cstdio>
+#include <memory>
#include <sstream>
#include <utility>
@@ -160,12 +161,10 @@ void cmComputeTargetDepends::CollectTargets()
std::vector<cmLocalGenerator*> const& lgens =
this->GlobalGenerator->GetLocalGenerators();
for (cmLocalGenerator* lgen : lgens) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
- for (cmGeneratorTarget const* ti : targets) {
+ 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());
}
}
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 6d29c99..987ec9e 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/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 5a5d959..d1da2d7 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExtraCodeBlocksGenerator.h"
#include <map>
+#include <memory>
#include <ostream>
#include <set>
#include <utility>
@@ -283,8 +284,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 +316,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 +342,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 +353,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 +391,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
}
CbpUnit& cbpUnit = allFiles[fullPath];
- cbpUnit.Targets.push_back(target);
+ cbpUnit.Targets.push_back(target.get());
}
}
default: // intended fallthrough
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index c7b7457..269e8dd 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>
@@ -119,7 +120,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
const std::vector<cmLocalGenerator*>& lgs =
this->GlobalGenerator->GetLocalGenerators();
for (cmLocalGenerator* lg : lgs) {
- for (cmGeneratorTarget* lt : lg->GetGeneratorTargets()) {
+ for (const auto& lt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType type = lt->GetType();
std::string const& outputDir = lg->GetCurrentBinaryDirectory();
std::string targetName = lt->GetName();
@@ -142,7 +143,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 +270,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);
}
}
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index b286acf..cf79375 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>
@@ -496,9 +497,9 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
for (cmLocalGenerator* 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();
@@ -860,15 +860,14 @@ 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) {
+ 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);
}
}
@@ -916,15 +915,14 @@ 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();
+ 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/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index e8c9dd0..bbbc281 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>
@@ -111,12 +112,11 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
// and UTILITY targets
for (cmLocalGenerator* localGen :
this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- localGen->GetGeneratorTargets();
+ 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: {
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 495324c..603fea3 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;
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 44392ba..91cd4ef 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -2,7 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmForEachCommand.h"
-#include <cstdio>
+#include <algorithm>
+#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 <utility>
@@ -21,8 +26,6 @@
#include "cmSystemTools.h"
namespace {
-bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile);
-
class cmForEachFunctionBlocker : public cmFunctionBlocker
{
public:
@@ -60,7 +63,8 @@ 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(
@@ -70,13 +74,13 @@ bool cmForEachFunctionBlocker::Replay(
// 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());
}
for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
// set the variable to the loop value
- mf.AddDefinition(this->Args[0], arg);
+ mf.AddDefinition(this->Args.front(), arg);
// Invoke all the functions that were collected in the block.
for (cmListFileFunction const& func : functions) {
cmExecutionStatus status(mf);
@@ -84,12 +88,12 @@ bool cmForEachFunctionBlocker::Replay(
if (status.GetReturnInvoked()) {
inStatus.SetReturnInvoked();
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ mf.AddDefinition(this->Args.front(), oldDef);
return true;
}
if (status.GetBreakInvoked()) {
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ mf.AddDefinition(this->Args.front(), oldDef);
return true;
}
if (status.GetContinueInvoked()) {
@@ -102,11 +106,48 @@ bool cmForEachFunctionBlocker::Replay(
}
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ mf.AddDefinition(this->Args.front(), oldDef);
return true;
}
+
+bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile)
+{
+ auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
+ fb->Args.push_back(args.front());
+
+ enum Doing
+ {
+ DoingNone,
+ DoingLists,
+ DoingItems
+ };
+ Doing doing = DoingNone;
+ for (std::string const& arg : cmMakeRange(args).advance(2)) {
+ if (arg == "LISTS") {
+ doing = DoingLists;
+ } else if (arg == "ITEMS") {
+ doing = DoingItems;
+ } else if (doing == DoingLists) {
+ auto const& value = makefile.GetSafeDefinition(arg);
+ if (!value.empty()) {
+ cmExpandList(value, fb->Args, true);
+ }
+ } else if (doing == DoingItems) {
+ fb->Args.push_back(arg);
+ } else {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Unknown argument:\n", " ", arg, "\n"));
+ return true;
+ }
+ }
+
+ makefile.AddFunctionBlocker(std::move(fb));
+
+ return true;
}
+} // anonymous namespace
+
bool cmForEachCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -126,16 +167,16 @@ bool cmForEachCommand(std::vector<std::string> const& args,
int stop = 0;
int step = 0;
if (args.size() == 3) {
- stop = atoi(args[2].c_str());
+ stop = std::stoi(args[2]);
}
if (args.size() == 4) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
+ start = std::stoi(args[2]);
+ stop = std::stoi(args[3]);
}
if (args.size() == 5) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
- step = atoi(args[4].c_str());
+ start = std::stoi(args[2]);
+ stop = std::stoi(args[3]);
+ step = std::stoi(args[4]);
}
if (step == 0) {
if (start > stop) {
@@ -151,21 +192,24 @@ bool cmForEachCommand(std::vector<std::string> const& args,
", stop ", stop, ", step ", step));
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;
}
@@ -176,42 +220,3 @@ bool cmForEachCommand(std::vector<std::string> const& args,
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));
-
- return true;
-}
-}
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index b7f7d1d..de43d3e 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -385,6 +385,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 4bd1c9f..cd35e1e 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;
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index d38e9e1..573ad4d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -10,11 +10,11 @@
#include <cstdlib>
#include <cstring>
#include <iterator>
-#include <memory>
#include <sstream>
#include <unordered_set>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
#include <queue>
@@ -162,7 +162,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 +173,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 +223,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 +238,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,23 +309,12 @@ 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
{
std::vector<std::string> values;
- for (TargetPropertyEntry* se : this->SourceEntries) {
+ for (auto& se : this->SourceEntries) {
values.push_back(se->GetInput());
}
static std::string value;
@@ -1672,6 +1666,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 +2121,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 +2141,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 +2150,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) {
@@ -3277,10 +3293,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:
@@ -3778,10 +3794,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,
@@ -3932,10 +3948,10 @@ 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,
@@ -4719,9 +4735,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";
@@ -5066,10 +5082,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
@@ -5216,22 +5233,19 @@ 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
@@ -6378,8 +6392,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");
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 493eafc..336c91f 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>
@@ -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);
@@ -274,7 +279,8 @@ 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;
@@ -816,10 +822,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*>
@@ -882,14 +888,17 @@ private:
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;
+ 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;
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9fa4467..d6c0a87 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"
@@ -32,7 +33,7 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const
// 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 96656a5..d903289 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -10,6 +10,9 @@
#include <initializer_list>
#include <iterator>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -165,7 +168,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()) {
@@ -296,7 +299,7 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
{
bool failed = false;
for (cmLocalGenerator* localGen : this->LocalGenerators) {
- for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ for (const auto& target : localGen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::TargetType::UTILITY ||
@@ -336,7 +339,7 @@ bool cmGlobalGenerator::CheckTargetsForType() const
}
bool failed = false;
for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::EXECUTABLE &&
target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
std::vector<std::string> const& configs =
@@ -364,7 +367,7 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
}
bool failed = false;
for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ 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 +653,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;
}
@@ -1557,12 +1560,12 @@ bool cmGlobalGenerator::AddAutomaticSources()
{
for (cmLocalGenerator* lg : this->LocalGenerators) {
lg->CreateEvaluationFileOutputs();
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- lg->AddUnityBuild(gt);
- lg->AddPchDependencies(gt);
+ lg->AddUnityBuild(gt.get());
+ lg->AddPchDependencies(gt.get());
}
}
return true;
@@ -1650,8 +1653,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));
}
}
@@ -1667,9 +1669,9 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
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 gt = cm::make_unique<cmGeneratorTarget>(ownedImpTgt, lg);
+ importedMap[ownedImpTgt] = gt.get();
+ lg->AddOwnedImportedGeneratorTarget(std::move(gt));
}
}
@@ -2766,15 +2768,15 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
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);
}
}
}
@@ -2951,11 +2953,11 @@ void cmGlobalGenerator::WriteSummary()
cmGeneratedFileStream fout(fname);
for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
+ for (const auto& tgt : lg->GetGeneratorTargets()) {
if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->WriteSummary(tgt);
+ this->WriteSummary(tgt.get());
fout << tgt->GetSupportDirectory() << "\n";
}
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index f25ff7b..0e87357 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -128,7 +128,8 @@ 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);
/**
* Create LocalGenerators and process the CMakeLists files. This does not
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 5a708ab..7afcd49 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -64,8 +64,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 ccfe073..7cd8c79 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -58,7 +58,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/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4c2d69f..dfc495e 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -374,16 +374,15 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
for (cmLocalGenerator* lGenerator : lGenerators) {
lg = static_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";
}
@@ -549,7 +548,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
cmLocalUnixMakefileGenerator3* lg =
static_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();
@@ -580,7 +579,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
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();
@@ -595,8 +594,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
// Add a local name for the rule to relink the target before
// installation.
if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- makeTargetName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ makeTargetName = cmStrCat(
+ lg->GetRelativeTargetDirectory(gtarget.get()), "/preinstall");
localName = cmStrCat(name, "/preinstall");
depends.clear();
commands.clear();
@@ -625,7 +624,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,7 +636,7 @@ 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);
@@ -661,7 +660,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
{
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 = ",";
}
@@ -680,7 +679,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
}
- this->AppendGlobalTargetDepends(depends, gtarget);
+ this->AppendGlobalTargetDepends(depends, gtarget.get());
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName, depends, commands, true);
@@ -697,7 +696,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
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";
@@ -715,7 +715,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/rule");
+ localName =
+ cmStrCat(lg->GetRelativeTargetDirectory(gtarget.get()), "/rule");
lg->WriteMakeRule(ruleFileStream,
"Build rule for subdir invocation for target.",
localName, depends, commands, true);
@@ -729,8 +730,8 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
// Add rules to prepare the target for installation.
if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- localName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget.get()),
+ "/preinstall");
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall(makefileName, localName));
@@ -740,7 +741,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
// add the clean rule
- localName = lg->GetRelativeTargetDirectory(gtarget);
+ localName = lg->GetRelativeTargetDirectory(gtarget.get());
makeTargetName = cmStrCat(localName, "/clean");
depends.clear();
commands.clear();
@@ -760,7 +761,7 @@ 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& gt : lg->GetGeneratorTargets()) {
cmLocalGenerator* tlg = gt->GetLocalGenerator();
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -778,12 +779,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);
}
}
@@ -894,7 +896,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
// the targets
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) ||
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 09a49e1..5b83e2f 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -26,6 +26,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)
{
@@ -193,7 +203,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 +218,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return false;
}
- if (!this->FindVCTargetsPath(mf)) {
+ if (build) {
+ return true;
+ }
+
+ if (this->CustomVCTargetsPath.empty() && !this->FindVCTargetsPath(mf)) {
return false;
}
@@ -349,6 +363,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;
}
@@ -442,6 +461,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
this->GeneratorToolsetVersion = value;
return true;
}
+ if (key == "VCTargetsPath") {
+ this->CustomVCTargetsPath = value;
+ ConvertToWindowsSlashes(this->CustomVCTargetsPath);
+ return true;
+ }
return false;
}
@@ -603,6 +627,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();
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 9adcf08..8a76047 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -20,7 +20,8 @@ public:
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,
@@ -45,6 +46,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;
@@ -155,6 +159,7 @@ protected:
std::string GeneratorToolset;
std::string GeneratorToolsetVersion;
std::string GeneratorToolsetHostArchitecture;
+ std::string GeneratorToolsetCustomVCTargetsDir;
std::string GeneratorToolsetCuda;
std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
@@ -206,6 +211,7 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ std::string CustomVCTargetsPath;
std::string VCTargetsPath;
bool FindVCTargetsPath(cmMakefile* mf);
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 8e6125b..d39d42a 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio8Generator.h"
+#include <cm/memory>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
@@ -109,8 +111,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, false,
no_working_directory, no_byproducts, no_depends, no_commands);
- cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
- lg->AddGeneratorTarget(gt);
+ auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+ auto gt = ptr.get();
+ lg->AddGeneratorTarget(std::move(ptr));
// Organize in the "predefined targets" folder:
//
@@ -203,10 +206,9 @@ 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);
}
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index ed0cba7..2181994 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -7,6 +7,7 @@
#include <iostream>
#include <cm/iterator>
+#include <cm/memory>
#include <windows.h>
@@ -200,8 +201,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
"ALL_BUILD", cmCommandOrigin::Generator, true, no_working_dir,
no_byproducts, no_depends, no_commands, false, "Build all projects");
- cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
- gen[0]->AddGeneratorTarget(gt);
+ gen[0]->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(allBuild, gen[0]));
//
// Organize in the "predefined targets" folder:
@@ -212,12 +213,12 @@ 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)) {
+ if (!this->IsExcluded(gen[0], tgt.get())) {
allBuild->AddUtility(tgt->GetName());
}
}
@@ -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());
}
}
}
@@ -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
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 6cbd4f3..154bd8e 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>
@@ -267,7 +268,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 +284,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);
}
@@ -409,10 +413,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());
@@ -508,8 +512,7 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
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();
@@ -533,14 +536,13 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
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;
}
@@ -564,7 +566,7 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
cmObjectLibraryCommands::Accept);
}
- if (!this->IsExcluded(gens[0], target)) {
+ if (!this->IsExcluded(gens[0], target.get())) {
allbuild->AddUtility(target->GetName());
}
}
@@ -1089,8 +1091,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets)
{
this->SetCurrentLocalGenerator(gen);
- std::vector<cmGeneratorTarget*> gts =
- this->CurrentLocalGenerator->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> gts;
+ cmAppend(gts, this->CurrentLocalGenerator->GetGeneratorTargets());
std::sort(gts.begin(), gts.end(),
[this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) {
return this->TargetOrderIndex[l] < this->TargetOrderIndex[r];
@@ -1362,9 +1364,9 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguages()
{
for (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());
}
}
}
@@ -2830,7 +2832,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:
@@ -2845,11 +2847,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;
};
@@ -2875,7 +2878,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());
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index af905d0..f60ea72 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -103,7 +103,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/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index e0d545d..9c1a924 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 (cmLocalGenerator const* 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, 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 9c3051f..578660d 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/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index aa92fa7..69c9b7e 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -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/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
new file mode 100644
index 0000000..ab2cf9e
--- /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, 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 0000000..21dc659
--- /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/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 5f8b920..f2bf079 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2,6 +2,20 @@
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/string_view>
+
#include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
@@ -40,20 +54,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 +181,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 +259,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;
}
@@ -635,11 +631,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 +647,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 +673,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;
}
@@ -704,8 +704,8 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
}
// 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;
@@ -2482,8 +2482,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);
@@ -2872,8 +2871,8 @@ 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;
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 12359db..e5c89f9 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>
@@ -143,14 +144,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;
@@ -461,11 +464,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;
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 4b10798..29c169f 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -5,6 +5,7 @@
#include <algorithm>
#include <utility>
+#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGenerator.h"
@@ -50,10 +51,11 @@ void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
void cmLocalGhsMultiGenerator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cmAppend(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 134bbe1..ea500ac 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -82,11 +82,11 @@ 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();
}
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 4a70248..ce3be63 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -121,12 +121,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,7 +157,7 @@ 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;
}
@@ -165,7 +165,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
gt->GetObjectSources(objectSources, this->ConfigName);
// 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 +176,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 +352,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 +362,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 +384,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();
@@ -401,8 +402,8 @@ 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");
+ makeTargetName = cmStrCat(
+ this->GetRelativeTargetDirectory(target.get()), "/preinstall");
localName = cmStrCat(target->GetName(), "/preinstall");
depends.clear();
commands.clear();
@@ -1551,8 +1552,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();
@@ -1573,10 +1574,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);
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index f3d828b..d9c4ce0 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -4,6 +4,7 @@
#include "cm_expat.h"
+#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -101,10 +102,11 @@ void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
void cmLocalVisualStudio10Generator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cmAppend(remaining, this->GetGeneratorTargets());
for (auto& t : remaining) {
if (t) {
- GenerateTargetsDepthFirst(t, remaining);
+ this->GenerateTargetsDepthFirst(t, remaining);
}
}
this->WriteStampFiles();
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index ff1eaec..5354f14 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 =
@@ -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());
}
}
}
@@ -1329,7 +1329,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;
@@ -2053,7 +2053,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');
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 671783f..22a5f9a 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;
};
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 5a06d4a..ac0d35e 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/cmMakefile.cxx b/Source/cmMakefile.cxx
index f143ef7..bf488b1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4487,7 +4487,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
// Deprecate old policies, especially those that require a lot
// of code to maintain the old behavior.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0067 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0069 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 96a6386..bf8183b 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/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 7bb5209..a25fd42 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/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index ef6b886..4792860 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -73,7 +73,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
}
// 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 +104,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 +135,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));
}
}
}
@@ -160,7 +160,8 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
std::vector<std::string>() /*output*/,
std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
comment.c_str());
- localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen));
+ localGen->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(target, localGen));
// Set FOLDER property in the target
{
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index a20f106..68b7122 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1126,7 +1126,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
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) {
@@ -1206,7 +1206,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
// 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()) {
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 82a3625..19a0d29 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -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/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 645907c..832e74e 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/cmTarget.cxx b/Source/cmTarget.cxx
index 99c16f2..05c9e6e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -380,6 +380,7 @@ 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
}
@@ -511,8 +512,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
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
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 4995da9..35e1c8c 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 e4b3b7c..6c418ed 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 f2c8f3c..039f1ba 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,17 @@
#include "cmVariableWatch.h"
#include "cmake.h"
+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 +35,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 +73,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,7 +87,7 @@ 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)) }
{
}
@@ -101,8 +97,8 @@ private:
struct Impl
{
Impl(cmMakefile* makefile, std::string variable)
- : Makefile(makefile)
- , Variable(std::move(variable))
+ : Makefile{ makefile }
+ , Variable{ std::move(variable) }
{
}
@@ -112,12 +108,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 +133,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,
@@ -149,6 +146,6 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args,
}
status.GetMakefile().AddFinalAction(
- FinalAction(&status.GetMakefile(), variable));
+ FinalAction{ &status.GetMakefile(), variable });
return true;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 94b6495..5ffa576 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -52,7 +52,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 +60,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)
@@ -77,7 +77,7 @@ struct cmVisualStudio10TargetGenerator::Elem
}
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);
}
@@ -115,7 +115,7 @@ struct cmVisualStudio10TargetGenerator::Elem
}
}
- 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 +131,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 +274,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);
}
@@ -543,6 +543,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 +562,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 +681,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WritePlatformExtensions(e1);
}
+
+ this->WriteDotNetDocumentationFile(e0);
Elem(e0, "PropertyGroup").Attribute("Label", "UserMacros");
this->WriteWinRTPackageCertificateKeyFile(e0);
this->WritePathAndIncrementalLinkOptions(e0);
@@ -906,7 +913,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 +1019,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);
}
}
}
@@ -1732,7 +1751,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);
@@ -2619,9 +2638,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);
@@ -4022,8 +4041,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;
@@ -4842,7 +4861,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 a18a33d..30027c9 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 1139aa9..18c19b7 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -431,7 +431,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
if (this->Defines.empty()) {
return;
}
- const char* tag = "PreprocessorDefinitions";
+ std::string tag = "PreprocessorDefinitions";
if (lang == "CUDA") {
tag = "Defines";
}
@@ -473,7 +473,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 +528,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 560593e..d8dcfe2 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -86,7 +86,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/cmake.cxx b/Source/cmake.cxx
index f63a264..4a6108d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -735,6 +735,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,6 +747,9 @@ 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("--trace-expand", 0) == 0) {
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
@@ -2287,7 +2291,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 +2299,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
}
@@ -2616,6 +2619,14 @@ int cmake::Build(int jobs, const std::string& dir,
return 1;
}
}
+ const char* cachedGeneratorToolset =
+ this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ if (cachedGeneratorToolset) {
+ cmMakefile mf(gen, this->GetCurrentSnapshot());
+ if (!gen->SetGeneratorToolset(cachedGeneratorToolset, true, &mf)) {
+ return 1;
+ }
+ }
std::string output;
std::string projName;
const char* cachedProjectName =
diff --git a/Source/cmake.h b/Source/cmake.h
index 687c105..9e78436 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"
@@ -380,15 +383,40 @@ 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);
+ 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));
+ }
+
//! Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
+ //! Should `message` command display context.
+ bool GetShowLogContext() const { return this->LogContext; }
+ void SetShowLogContext(bool b) { this->LogContext = b; }
+
//! Do we want trace output during the cmake run.
bool GetTrace() { return this->Trace; }
void SetTrace(bool b) { this->Trace = b; }
@@ -587,6 +615,10 @@ private:
std::vector<std::string> TraceOnlyThisSources;
LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
+ bool LogLevelWasSetViaCLI = false;
+ bool LogContext = false;
+
+ std::stack<std::string> CheckInProgressMessages;
void UpdateConversionPathTable();
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 6d3e6ee..baf975e 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -73,6 +73,7 @@ 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." },
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 0d65902..a7b11cd 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -99,8 +99,11 @@ static const char* cmDocumentationOptions[][2] = {
{ "-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" },
+ "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." },
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index b067521..75a2d4d 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 4593c92..5cad934 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/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index df7eb45..0c2366b 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -70,10 +70,10 @@ private:
* \brief Creates an invalid match object
*/
inline RegularExpressionMatch::RegularExpressionMatch()
+ : startp{}
+ , endp{}
+ , searchstring{}
{
- startp[0] = nullptr;
- endp[0] = nullptr;
- searchstring = nullptr;
}
/**
diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx
index 986f595..1bf88cf 100644
--- a/Tests/CMakeLib/testUTF8.cxx
+++ b/Tests/CMakeLib/testUTF8.cxx
@@ -9,9 +9,11 @@ typedef char test_utf8_char[5];
static void test_utf8_char_print(test_utf8_char const c)
{
unsigned char const* d = reinterpret_cast<unsigned char const*>(c);
+#ifndef __clang_analyzer__ // somehow thinks arguments are not initialized
printf("[0x%02X,0x%02X,0x%02X,0x%02X]", static_cast<int>(d[0]),
static_cast<int>(d[1]), static_cast<int>(d[2]),
static_cast<int>(d[3]));
+#endif
}
static void byte_array_print(char const* s)
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 57fa7fc..b45782e 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -451,8 +451,12 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(StagingPrefix StagingPrefix)
ADD_TEST_MACRO(ImportedSameName ImportedSameName)
ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
- if(NOT _isMultiConfig)
- set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+ if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ if(_isMultiConfig)
+ set(ConfigSources_CTEST_OPTIONS --build-config $<CONFIGURATION>)
+ else()
+ set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+ endif()
ADD_TEST_MACRO(ConfigSources ConfigSources)
endif()
ADD_TEST_MACRO(SourcesProperty SourcesProperty)
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index 03babd2..85b9694 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -75,6 +75,12 @@ add_test(CMakeOnly.ProjectIncludeAny ${CMAKE_CMAKE_COMMAND}
add_test(CMakeOnly.ProjectIncludeBefore ${CMAKE_CMAKE_COMMAND}
-DTEST=ProjectIncludeBefore
+ -DCMAKE_ARGS=-DCMAKE_PROJECT_ProjectInclude_INCLUDE_BEFORE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectIncludeBefore/include.cmake
+ -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
+ )
+
+add_test(CMakeOnly.ProjectIncludeBeforeAny ${CMAKE_CMAKE_COMMAND}
+ -DTEST=ProjectIncludeBeforeAny
-DCMAKE_ARGS=-DCMAKE_PROJECT_INCLUDE_BEFORE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectIncludeBefore/include.cmake
-P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
)
diff --git a/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt b/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt
new file mode 100644
index 0000000..5cd9cba
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(FOO TRUE)
+project(ProjectInclude LANGUAGES NONE)
+if(NOT AUTO_INCLUDE)
+ message(FATAL_ERROR "include file not found")
+endif()
diff --git a/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake b/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake
new file mode 100644
index 0000000..0a4799d
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake
@@ -0,0 +1,9 @@
+if(NOT FOO)
+ message(FATAL_ERROR "FOO is not set")
+endif()
+
+if(NOT "${PROJECT_NAME}" STREQUAL "")
+ message(FATAL_ERROR "PROJECT_NAME should be empty")
+endif()
+
+set(AUTO_INCLUDE TRUE)
diff --git a/Tests/EnforceConfig.cmake.in b/Tests/EnforceConfig.cmake.in
index b7587aa..7781ded 100644
--- a/Tests/EnforceConfig.cmake.in
+++ b/Tests/EnforceConfig.cmake.in
@@ -33,5 +33,6 @@ unset(ENV{CMAKE_GENERATOR})
unset(ENV{CMAKE_GENERATOR_INSTANCE})
unset(ENV{CMAKE_GENERATOR_PLATFORM})
unset(ENV{CMAKE_GENERATOR_TOOLSET})
+unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
@TEST_HOME_ENV_CODE@
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 093391e..ef81169 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -482,6 +482,66 @@ if(do_git_tests)
)
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+ # Unzip/untar the git repository in our source folder so that other
+ # projects below may use it to test git args of ExternalProject_Add
+ #
+ set(proj SetupLocalGITRepositoryWithRecursiveSubmodules)
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT-with-recursive-submodules
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo-sub-rec.tgz
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ set(local_git_repo "../../LocalRepositories/GIT-with-recursive-submodules")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-default)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-exclusive)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES_RECURSE TRUE
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-off)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES_RECURSE FALSE
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=OFF
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
endif()
set(do_hg_tests 0)
diff --git a/Tests/ExternalProject/gitrepo-sub-rec.tgz b/Tests/ExternalProject/gitrepo-sub-rec.tgz
new file mode 100644
index 0000000..b0f3f18
--- /dev/null
+++ b/Tests/ExternalProject/gitrepo-sub-rec.tgz
Binary files differ
diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
index 23832da..8a87a8c 100644
--- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt
+++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
@@ -19,6 +19,14 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile" AND
# configure a FindFoo.cmake so it knows where the library can be found
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
+ # Need the -isysroot flag on recentish macOS after command line tools
+ # no longer provide headers in /usr/include
+ if(APPLE AND CMAKE_OSX_SYSROOT)
+ set(__EXTRA_OSX_SYSROOT_FLAGS "-isysroot ${CMAKE_OSX_SYSROOT}")
+ else()
+ set(__EXTRA_OSX_SYSROOT_FLAGS "")
+ endif()
+
# now set up the test:
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index 8e7ff72..5ef67d0 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -5,6 +5,7 @@ CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@
+__EXTRA_OSX_SYSROOT_FLAGS = @__EXTRA_OSX_SYSROOT_FLAGS@
CMAKE_FOO = $(CMAKE) --find-package -DCMAKE_MODULE_PATH=$(CMAKE_CURRENT_BINARY_DIR) -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=$(CMAKE_CXX_COMPILER_ID)
@@ -15,7 +16,7 @@ all: pngtest
main.o: clean main.cpp
@$(CMAKE_FOO) -DMODE=COMPILE >$(tmp)
@foo="`cat $(tmp)`"; \
- printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$$foo" >$(tmp)
+ printf '"%s" %s %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$$foo" >$(tmp)
@cat $(tmp)
@sh $(tmp)
@rm -f $(tmp)
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index 868cfe0..10c98c5 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -134,6 +134,20 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.CustomFailureMessage COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
endif()
if(CMake_TEST_FindPython_NumPy)
diff --git a/Tests/FindPython/CustomFailureMessage/CMakeLists.txt b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
new file mode 100644
index 0000000..a0d8eb2
--- /dev/null
+++ b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
@@ -0,0 +1,79 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestCustomFailureMessage LANGUAGES NONE)
+
+include(CTest)
+
+add_test(NAME FindPython.CustomFailureMessage.Interpreter COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Interpreter"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter"
+ "-DPython3_EXECUTABLE=/not/found/interpreter"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Interpreter PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Interpreter: Cannot run the interpreter")
+
+add_test(NAME FindPython.CustomFailureMessage.Library COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Library"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Development"
+ "-DPython3_LIBRARY=/not/found/library"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Library PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Development: Cannot find the library")
+
+add_test(NAME FindPython.CustomFailureMessage.Include COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Include"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Development"
+ "-DPython3_INCLUDE_DIR=/not/found/include"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Include PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Development: Cannot find the directory")
+
+add_test(NAME FindPython.CustomFailureMessage.Multiple COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Multiple"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter;Development"
+ "-DPython3_EXECUTABLE=/not/found/interpreter"
+ "-DPython3_LIBRARY=/not/found/library"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Multiple PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Interpreter: Cannot run the interpreter.+Development: Cannot find the library")
+
+
+if (CMake_TEST_FindPython_NumPy)
+ add_test(NAME FindPython.CustomFailureMessage.NumPy COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/NumPy"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter;Development;NumPy"
+ "-DPython3_NumPy_INCLUDE_DIR=/not/found/numpy/include"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ set_tests_properties(FindPython.CustomFailureMessage.NumPy PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+NumPy: Cannot find the directory")
+endif()
diff --git a/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt b/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt
new file mode 100644
index 0000000..fed963e
--- /dev/null
+++ b/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestCustomFailureMessage.Check LANGUAGES C)
+
+find_package (Python3 REQUIRED COMPONENTS ${CHECK_COMPONENTS})
diff --git a/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt b/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt
new file mode 100644
index 0000000..a736129
--- /dev/null
+++ b/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0068-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0068 will be removed from a future version
+ of CMake.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt
new file mode 100644
index 0000000..f51a6f4
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0069-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0069 will be removed from a future version
+ of CMake.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 6b2f117..1371295 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -189,6 +189,7 @@ add_RunCMake_test(GeneratorToolset)
add_RunCMake_test(GetPrerequisites)
add_RunCMake_test(GNUInstallDirs -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(GoogleTest) # Note: does not actually depend on Google Test
+add_RunCMake_test(Graphviz)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(LinkStatic)
@@ -289,6 +290,9 @@ add_RunCMake_test(set_property)
add_RunCMake_test(string)
add_RunCMake_test(test_include_dirs)
add_RunCMake_test(BundleUtilities)
+if(APPLE)
+ add_RunCMake_test(INSTALL_NAME_DIR)
+endif()
function(add_RunCMake_test_try_compile)
if(CMAKE_VERSION VERSION_LESS 3.9.20170907 AND "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index 6b23162..6a7fd3b 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -4,6 +4,16 @@ set(RunCMake_TEST_TIMEOUT 60)
unset(ENV{CTEST_PARALLEL_LEVEL})
unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+run_cmake_command(repeat-until-pass-bad1
+ ${CMAKE_CTEST_COMMAND} --repeat-until-pass
+ )
+run_cmake_command(repeat-until-pass-bad2
+ ${CMAKE_CTEST_COMMAND} --repeat-until-pass foo
+ )
+run_cmake_command(repeat-until-pass-good
+ ${CMAKE_CTEST_COMMAND} --repeat-until-pass 2
+ )
+
run_cmake_command(repeat-until-fail-bad1
${CMAKE_CTEST_COMMAND} --repeat-until-fail
)
@@ -14,14 +24,53 @@ run_cmake_command(repeat-until-fail-good
${CMAKE_CTEST_COMMAND} --repeat-until-fail 2
)
-function(run_repeat_until_fail_tests)
+run_cmake_command(repeat-after-timeout-bad1
+ ${CMAKE_CTEST_COMMAND} --repeat-after-timeout
+ )
+run_cmake_command(repeat-after-timeout-bad2
+ ${CMAKE_CTEST_COMMAND} --repeat-after-timeout foo
+ )
+run_cmake_command(repeat-after-timeout-good
+ ${CMAKE_CTEST_COMMAND} --repeat-after-timeout 2
+ )
+
+run_cmake_command(repeat-until-pass-and-fail
+ ${CMAKE_CTEST_COMMAND} --repeat-until-pass 2 --repeat-until-fail 2
+ )
+run_cmake_command(repeat-until-fail-and-pass
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail 2 --repeat-until-pass 2
+ )
+run_cmake_command(repeat-until-fail-and-timeout
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail 2 --repeat-after-timeout 2
+ )
+
+function(run_repeat_until_pass_tests)
# Use a single build tree for a few tests without cleaning.
- set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-pass-build)
+ run_cmake(repeat-until-pass-cmake)
set(RunCMake_TEST_NO_CLEAN 1)
- file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
- file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(repeat-until-pass-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug --repeat-until-pass 3
+ )
+endfunction()
+run_repeat_until_pass_tests()
+function(run_repeat_after_timeout_tests)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-after-timeout-build)
+ run_cmake(repeat-after-timeout-cmake)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(repeat-after-timeout-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug --repeat-after-timeout 3
+ )
+endfunction()
+run_repeat_after_timeout_tests()
+
+function(run_repeat_until_fail_tests)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build)
run_cmake(repeat-until-fail-cmake)
+ set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(repeat-until-fail-ctest
${CMAKE_CTEST_COMMAND} -C Debug --repeat-until-fail 3
)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-stderr.txt
new file mode 100644
index 0000000..aea92b8
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-after-timeout' requires an argument$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-stderr.txt
new file mode 100644
index 0000000..c5db55b
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-bad2-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-after-timeout' given non-integer value 'foo'$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake
new file mode 100644
index 0000000..873c0bd
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake
@@ -0,0 +1,15 @@
+enable_testing()
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+add_test(NAME initialization
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake")
+add_test(NAME test1
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test1-timeout.cmake")
+set_tests_properties(test1 PROPERTIES DEPENDS "initialization" TIMEOUT 5)
+
+add_test(hello ${CMAKE_COMMAND} -E echo hello)
+add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt
new file mode 100644
index 0000000..d0a5487
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt
@@ -0,0 +1,15 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-build
+ Start 1: initialization
+1/4 Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 2: test1
+2/4 Test #2: test1 ............................\*\*\*Timeout +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+3/4 Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 4: goodbye
+4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 4
+
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-good-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-good-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-good-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-stderr.txt
new file mode 100644
index 0000000..15ee3a9
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-pass-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: At most one '--repeat-\*' option may be used\.$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-stderr.txt
new file mode 100644
index 0000000..15ee3a9
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-and-timeout-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: At most one '--repeat-\*' option may be used\.$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-stderr.txt
new file mode 100644
index 0000000..15ee3a9
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-and-fail-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: At most one '--repeat-\*' option may be used\.$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-stderr.txt
new file mode 100644
index 0000000..c6afb1d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-until-pass' requires an argument$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-stderr.txt
new file mode 100644
index 0000000..cc3aed5
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-bad2-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-until-pass' given non-integer value 'foo'$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake
new file mode 100644
index 0000000..d109551
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake
@@ -0,0 +1,15 @@
+enable_testing()
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+add_test(NAME initialization
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake")
+add_test(NAME test1
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test1-pass.cmake")
+set_tests_properties(test1 PROPERTIES DEPENDS "initialization")
+
+add_test(hello ${CMAKE_COMMAND} -E echo hello)
+add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt
new file mode 100644
index 0000000..3745dc2
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt
@@ -0,0 +1,15 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-pass-build
+ Start 1: initialization
+1/4 Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 2: test1
+2/4 Test #2: test1 ............................\*\*\*Failed +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+3/4 Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 4: goodbye
+4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 4
+
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-good-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-good-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-good-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/test1-pass.cmake b/Tests/RunCMake/CTestCommandLine/test1-pass.cmake
new file mode 100644
index 0000000..dda8dea
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test1-pass.cmake
@@ -0,0 +1,13 @@
+# This is run by test test1 in repeat-until-pass-cmake.cmake with cmake -P.
+# It reads the file TEST_OUTPUT_FILE and increments the number
+# found in the file by 1. Unless the number is 2, then the
+# code sends out a cmake error causing the test to pass only on
+# the second time it is run.
+message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}")
+file(READ "${TEST_OUTPUT_FILE}" COUNT)
+message("COUNT= ${COUNT}")
+math(EXPR COUNT "${COUNT} + 1")
+file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}")
+if(NOT COUNT EQUAL 2)
+ message(FATAL_ERROR "this test passes only on the 2nd run")
+endif()
diff --git a/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake b/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake
new file mode 100644
index 0000000..fbf2ccc
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake
@@ -0,0 +1,14 @@
+# This is run by test test1 in repeat-after-timeout-cmake.cmake with cmake -P.
+# It reads the file TEST_OUTPUT_FILE and increments the number
+# found in the file by 1. Unless the number is 2, then the
+# code sends out a cmake error causing the test to not timeout only on
+# the second time it is run.
+message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}")
+file(READ "${TEST_OUTPUT_FILE}" COUNT)
+message("COUNT= ${COUNT}")
+math(EXPR COUNT "${COUNT} + 1")
+file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}")
+if(NOT COUNT EQUAL 2)
+ message("this test times out except on the 2nd run")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 10)
+endif()
diff --git a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
index f183594..1baa63a 100644
--- a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
+++ b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
+^CMake Deprecation Warning at cmp0069-is-old.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0069 will be removed from a future version
+ of CMake.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
Policy CMP0069 set to OLD
Call Stack \(most recent call first\):
cmp0069-is-old\.cmake:[0-9]+ \(check_ipo_supported\)
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index b608d33..f903c3d 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -254,6 +254,24 @@ function(run_EnvironmentGenerator)
endfunction()
run_EnvironmentGenerator()
+function(run_EnvironmentExportCompileCommands)
+ set(RunCMake_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/env-export-compile-commands)
+
+ run_cmake(env-export-compile-commands-unset)
+
+ set(ENV{CMAKE_EXPORT_COMPILE_COMMANDS} ON)
+ run_cmake(env-export-compile-commands-set)
+
+ set(RunCMake_TEST_OPTIONS -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF)
+ run_cmake(env-export-compile-commands-override)
+
+ unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
+endfunction(run_EnvironmentExportCompileCommands)
+
+if(RunCMake_GENERATOR MATCHES "Unix Makefiles" OR RunCMake_GENERATOR MATCHES "Ninja")
+ run_EnvironmentExportCompileCommands()
+endif()
+
if(RunCMake_GENERATOR STREQUAL "Ninja")
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake
new file mode 100644
index 0000000..032a1ae
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json generated with CMAKE_EXPORT_COMPILE_COMMANDS overridden")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake
new file mode 100644
index 0000000..a749a55
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json not generated with CMAKE_EXPORT_COMPILE_COMMANDS set")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake
new file mode 100644
index 0000000..c5878f0
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json generated with CMAKE_EXPORT_COMPILE_COMMANDS unset")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt b/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt
new file mode 100644
index 0000000..aa6fbfd
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.14)
+project(env-export-compile-commands C)
+
+# Add target with a source file to make sure compile_commands.json gets
+# generated.
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+add_executable(env-export-compile-commands ${CMAKE_CURRENT_BINARY_DIR}/main.c)
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index ae75561..bb22841 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -30,6 +30,8 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86")
run_cmake(BadToolsetHostArchTwice)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
+ set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=Test Path")
+ run_cmake(TestToolsetVCTargetsPathOnly)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")
run_cmake(TestToolsetVersionBoth)
set(RunCMake_GENERATOR_TOOLSET ",version=Test Toolset Version")
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt
new file mode 100644
index 0000000..c46373f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
+-- CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='Test Path'
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake
new file mode 100644
index 0000000..c20a303
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake
@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}'")
diff --git a/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in b/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in
new file mode 100644
index 0000000..8a1c3d0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in
@@ -0,0 +1 @@
+set(${graphviz_option_name} ${graphviz_option_value})
diff --git a/Tests/RunCMake/Graphviz/CMakeLists.txt b/Tests/RunCMake/Graphviz/CMakeLists.txt
new file mode 100644
index 0000000..d23d4cf
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
new file mode 100644
index 0000000..772f312
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
@@ -0,0 +1,58 @@
+# For the sake of clarity, we model a dummy but realistic application:
+#
+# - We have two executables, for a console and a GUI variant of that app
+# - Both executables depend on a CoreLibrary (STATIC)
+# - The GUI executable also depends on a GraphicLibrary (SHARED)
+# - We build two GraphicDrivers as MODULEs
+# - The CoreLibrary depends on a third-party header-only (INTERFACE)
+# GoofyLoggingLibrary, which we rename using an ALIAS for obvious reasons
+# - All library depend on a common INTERFACE library holding compiler flags
+# - We have a custom target to generate a man page
+# - Someone has added an UNKNOWN, IMPORTED crypto mining library!
+
+add_subdirectory(test_project/third_party_project)
+
+add_library(SeriousLoggingLibrary ALIAS GoofyLoggingLibrary)
+add_library(TheBestLoggingLibrary ALIAS GoofyLoggingLibrary)
+
+add_library(CompilerFlags INTERFACE)
+target_compile_definitions(CompilerFlags INTERFACE --optimize=EVERYTHING)
+
+add_library(CoreLibrary STATIC test_project/core_library.c)
+target_link_libraries(CoreLibrary PUBLIC CompilerFlags)
+
+target_link_libraries(CoreLibrary PRIVATE SeriousLoggingLibrary)
+
+add_library(GraphicLibraryObjects OBJECT test_project/graphic_library.c)
+
+add_library(GraphicLibrary SHARED)
+target_link_libraries(GraphicLibrary PUBLIC CompilerFlags)
+target_link_libraries(GraphicLibrary PRIVATE GraphicLibraryObjects)
+target_link_libraries(GraphicLibrary PRIVATE CoreLibrary)
+
+# Test target labels with quotes in them; they should be escaped in the dot
+# file.
+# See https://gitlab.kitware.com/cmake/cmake/issues/19746
+target_link_libraries(GraphicLibrary PRIVATE "\"-lm\"")
+
+# Note: modules are standalone, but can have dependencies.
+add_library(GraphicDriverOpenGL MODULE test_project/module.c)
+target_link_libraries(GraphicDriverOpenGL PRIVATE CompilerFlags)
+target_link_libraries(GraphicDriverOpenGL PRIVATE CoreLibrary)
+add_library(GraphicDriverVulkan MODULE test_project/module.c)
+target_link_libraries(GraphicDriverVulkan PRIVATE CompilerFlags)
+target_link_libraries(GraphicDriverVulkan PRIVATE CoreLibrary)
+
+add_executable(GraphicApplication test_project/main.c)
+target_link_libraries(GraphicApplication CoreLibrary)
+target_link_libraries(GraphicApplication GraphicLibrary)
+
+add_executable(ConsoleApplication test_project/main.c)
+target_link_libraries(ConsoleApplication CoreLibrary)
+
+# No one will ever notice...
+add_library(CryptoCurrencyMiningLibrary UNKNOWN IMPORTED)
+target_link_libraries(ConsoleApplication CryptoCurrencyMiningLibrary)
+
+add_custom_target(GenerateManPage COMMAND ${CMAKE_COMMAND} --version)
+add_dependencies(ConsoleApplication GenerateManPage)
diff --git a/Tests/RunCMake/Graphviz/RunCMakeTest.cmake b/Tests/RunCMake/Graphviz/RunCMakeTest.cmake
new file mode 100644
index 0000000..c0cea10
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/RunCMakeTest.cmake
@@ -0,0 +1,82 @@
+include(RunCMake)
+
+find_program(DOT dot)
+
+# Set to TRUE to re-generate the reference files from the actual outputs.
+# Make sure you verify them!
+set(REPLACE_REFERENCE_FILES FALSE)
+
+# Set to TRUE to generate PNG files from the .dot files, using Graphviz (dot).
+# Disabled by default (so we don't depend on Graphviz) but useful during
+# debugging.
+set(GENERATE_PNG_FILES FALSE)
+
+# 1. Generate the Graphviz (.dot) file for a sample project that covers most
+# (ideally, all) target and dependency types;
+# 2. Compare that generated file with a reference file.
+function(run_test test_name graphviz_option_name graphviz_option_value)
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test_name})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ # Set ${graphviz_option_name} to ${graphviz_option_value}.
+ if(graphviz_option_name)
+ configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeGraphVizOptions.cmake.in
+ ${RunCMake_TEST_BINARY_DIR}/CMakeGraphVizOptions.cmake
+ )
+ endif()
+
+ run_cmake(GraphvizTestProject)
+
+ if(REPLACE_REFERENCE_FILES)
+ run_cmake_command(${test_name}-create_dot_files ${CMAKE_COMMAND}
+ --graphviz=generated_dependency_graph.dot .
+ )
+
+ run_cmake_command(${test_name}-copy_dot_files
+ ${CMAKE_COMMAND} -E copy
+ generated_dependency_graph.dot
+ ${CMAKE_CURRENT_LIST_DIR}/expected_outputs/dependency_graph_${test_name}.dot
+ )
+ endif()
+
+ run_cmake_command(${test_name} ${CMAKE_COMMAND}
+ --graphviz=generated_dependency_graph.dot .
+ )
+
+ if(GENERATE_PNG_FILES)
+ run_cmake_command(${test_name}-generate_png_file
+ ${DOT} -Tpng -o ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.png
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot
+ )
+ endif()
+
+endfunction()
+
+run_test(default_options "" "")
+
+run_test(set_graph_name GRAPHVIZ_GRAPH_NAME "\"CMake Project Dependencies\"")
+run_test(set_graph_header GRAPHVIZ_GRAPH_HEADER
+ "\"node [\n fontsize = \\\"16\\\"\n];\"")
+run_test(set_node_prefix GRAPHVIZ_NODE_PREFIX "point")
+
+run_test(no_executables GRAPHVIZ_EXECUTABLES FALSE)
+
+run_test(no_static_libs GRAPHVIZ_STATIC_LIBS FALSE)
+run_test(no_shared_libs GRAPHVIZ_SHARED_LIBS FALSE)
+run_test(no_module_libs GRAPHVIZ_MODULE_LIBS FALSE)
+
+run_test(no_interface_libs GRAPHVIZ_INTERFACE_LIBS FALSE)
+run_test(no_object_libs GRAPHVIZ_OBJECT_LIBS FALSE)
+run_test(no_unknown_libs GRAPHVIZ_UNKNOWN_LIBS FALSE)
+
+run_test(no_external_libs GRAPHVIZ_EXTERNAL_LIBS FALSE)
+
+run_test(custom_targets GRAPHVIZ_CUSTOM_TARGETS TRUE)
+
+run_test(no_graphic_libs GRAPHVIZ_IGNORE_TARGETS "Graphic")
+
+run_test(no_per_target_files GRAPHVIZ_GENERATE_PER_TARGET FALSE)
+run_test(no_dependers_files GRAPHVIZ_GENERATE_DEPENDERS FALSE)
diff --git a/Tests/RunCMake/Graphviz/default_options-check.cmake b/Tests/RunCMake/Graphviz/default_options-check.cmake
new file mode 100644
index 0000000..c9a7562
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/default_options-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_default_options.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
new file mode 100644
index 0000000..8b0365a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
@@ -0,0 +1,52 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GenerateManPage", shape = box ];
+ "node1" -> "node5" // ConsoleApplication -> GenerateManPage
+ "node6" [ label = "GraphicApplication", shape = egg ];
+ "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node8" [ label = "\"-lm\"", shape = septagon ];
+ "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node7" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
new file mode 100644
index 0000000..558a470
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "CoreLibrary", shape = octagon ];
+ "node1" -> "node0" // CoreLibrary -> CompilerFlags
+ "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node1" -> "node2" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+ "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node4" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
new file mode 100644
index 0000000..660af37
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
@@ -0,0 +1,46 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node7" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
new file mode 100644
index 0000000..5af7fec
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
@@ -0,0 +1,35 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
new file mode 100644
index 0000000..94ec41c
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
@@ -0,0 +1,43 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "ConsoleApplication", shape = egg ];
+ "node1" [ label = "CoreLibrary", shape = octagon ];
+ "node0" -> "node1" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node2" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node0" -> "node2" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node3" [ label = "GraphicApplication", shape = egg ];
+ "node3" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+ "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node3" -> "node4" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
new file mode 100644
index 0000000..65b7a71
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
new file mode 100644
index 0000000..8116bc9
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
@@ -0,0 +1,48 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
new file mode 100644
index 0000000..439d1f7
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot
new file mode 100644
index 0000000..81199a2
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot
@@ -0,0 +1,42 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node3" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
new file mode 100644
index 0000000..1be6550
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
@@ -0,0 +1,48 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
new file mode 100644
index 0000000..1cfbe0f
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "16"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
new file mode 100644
index 0000000..9653c33
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
@@ -0,0 +1,50 @@
+digraph "CMake Project Dependencies" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
new file mode 100644
index 0000000..82d96d0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "point0" [ label = "CompilerFlags", shape = pentagon ];
+ "point1" [ label = "ConsoleApplication", shape = egg ];
+ "point2" [ label = "CoreLibrary", shape = octagon ];
+ "point2" -> "point0" // CoreLibrary -> CompilerFlags
+ "point3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "point2" -> "point3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "point1" -> "point2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "point4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "point1" -> "point4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "point5" [ label = "GraphicApplication", shape = egg ];
+ "point5" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "point6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "point7" [ label = "\"-lm\"", shape = septagon ];
+ "point6" -> "point7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "point6" -> "point0" // GraphicLibrary -> CompilerFlags
+ "point6" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "point8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "point6" -> "point8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "point5" -> "point6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "point9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "point9" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "point9" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "point10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "point10" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "point10" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake b/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake
new file mode 100644
index 0000000..f4a43b6
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake
@@ -0,0 +1,4 @@
+file(GLOB dependers_files ${RunCMake_TEST_BINARY_DIR}/*.dependers)
+if(${dependers_files})
+ set(RunCMake_TEST_FAILED "Found *.dependers files despite GRAPHVIZ_GENERATE_DEPENDERS set to FALSE.")
+endif()
diff --git a/Tests/RunCMake/Graphviz/no_executables-check.cmake b/Tests/RunCMake/Graphviz/no_executables-check.cmake
new file mode 100644
index 0000000..be29a4f
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_executables-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_executables.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_external_libs-check.cmake b/Tests/RunCMake/Graphviz/no_external_libs-check.cmake
new file mode 100644
index 0000000..518ef7b
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_external_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_external_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake b/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake
new file mode 100644
index 0000000..0f5aa47
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_graphic_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake b/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake
new file mode 100644
index 0000000..018fef0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_interface_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_module_libs-check.cmake b/Tests/RunCMake/Graphviz/no_module_libs-check.cmake
new file mode 100644
index 0000000..e185cb1
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_module_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_module_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_object_libs-check.cmake b/Tests/RunCMake/Graphviz/no_object_libs-check.cmake
new file mode 100644
index 0000000..90e7ecb
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_object_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_object_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake b/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake
new file mode 100644
index 0000000..95d05a1
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake
@@ -0,0 +1,5 @@
+file(GLOB per_target_files ${RunCMake_TEST_BINARY_DIR}/*.dot.*)
+list(FILTER per_target_files EXCLUDE REGEX ".*\\.dependers$")
+if(per_target_files)
+ set(RunCMake_TEST_FAILED "Found per-target .dot files despite GRAPHVIZ_GENERATE_PER_TARGET set to FALSE.")
+endif()
diff --git a/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake b/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake
new file mode 100644
index 0000000..b45da2e
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_shared_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_static_libs-check.cmake b/Tests/RunCMake/Graphviz/no_static_libs-check.cmake
new file mode 100644
index 0000000..befc11b
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_static_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_static_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake b/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake
new file mode 100644
index 0000000..95286bc
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_unknown_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_graph_header-check.cmake b/Tests/RunCMake/Graphviz/set_graph_header-check.cmake
new file mode 100644
index 0000000..1396484
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_graph_header-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_graph_header.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_graph_name-check.cmake b/Tests/RunCMake/Graphviz/set_graph_name-check.cmake
new file mode 100644
index 0000000..0c522e9
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_graph_name-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_graph_name.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake b/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake
new file mode 100644
index 0000000..61e9b24
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_node_prefix.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/test_project/core_library.c b/Tests/RunCMake/Graphviz/test_project/core_library.c
new file mode 100644
index 0000000..e8a8844
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/core_library.c
@@ -0,0 +1,3 @@
+void log_something()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/graphic_library.c b/Tests/RunCMake/Graphviz/test_project/graphic_library.c
new file mode 100644
index 0000000..958c8ab
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/graphic_library.c
@@ -0,0 +1,3 @@
+void initialize_graphics()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/main.c b/Tests/RunCMake/Graphviz/test_project/main.c
new file mode 100644
index 0000000..d123e09
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/main.c
@@ -0,0 +1,4 @@
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/module.c b/Tests/RunCMake/Graphviz/test_project/module.c
new file mode 100644
index 0000000..a508b09
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/module.c
@@ -0,0 +1,3 @@
+static void some_function()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt b/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt
new file mode 100644
index 0000000..e381750
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(ThirdPartyProject)
+
+add_library(GoofyLoggingLibrary INTERFACE)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt b/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt
new file mode 100644
index 0000000..5253d34
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${CMAKE_CURRENT_LIST_DIR}/INSTALL_NAME_DIR.cmake)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake
new file mode 100644
index 0000000..eaa0b45
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake
@@ -0,0 +1,15 @@
+function(add_install_name_dir_libraries install_name_dir)
+ add_library(build_dir SHARED test.c)
+ add_library(install_dir SHARED test.c)
+ if(NOT install_name_dir STREQUAL "NONE")
+ set_target_properties(build_dir install_dir PROPERTIES
+ INSTALL_NAME_DIR "${install_name_dir}"
+ )
+ endif()
+ set_target_properties(install_dir PROPERTIES
+ BUILD_WITH_INSTALL_NAME_DIR TRUE
+ )
+ install(TARGETS build_dir install_dir EXPORT InstallNameDirTest DESTINATION lib)
+ install(EXPORT InstallNameDirTest DESTINATION lib/cmake/InstallNameDirTest FILE InstallNameDirTest-targets.cmake)
+ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/targets.txt" CONTENT "$<TARGET_FILE:build_dir>\n$<TARGET_FILE:install_dir>\n" CONDITION $<CONFIG:Debug>)
+endfunction()
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake
new file mode 100644
index 0000000..2aa03dd
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake
@@ -0,0 +1,69 @@
+cmake_minimum_required(VERSION 3.16)
+
+include(RunCMake)
+
+function(run_install_test case)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/fake_install")
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${case})
+ run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${case}-install ${CMAKE_COMMAND} --install . --config Debug --prefix "${RunCMake_TEST_BINARY_DIR}/real_install")
+endfunction()
+
+find_program(OTOOL_COMMAND otool)
+
+function(check_install_name_dir file expected)
+ execute_process(COMMAND ${OTOOL_COMMAND} -l ${file} RESULT_VARIABLE _result OUTPUT_VARIABLE _output)
+ if(_result)
+ string(APPEND RunCMake_TEST_FAILED "Could not run otool on ${file}\n")
+ elseif(_output MATCHES "cmd LC_ID_DYLIB\n[^\n]*\n *name ([^\n]*) \\(offset [0-9]+\\)\n")
+ set(_install_name "${CMAKE_MATCH_1}")
+ if(NOT _install_name MATCHES "${expected}")
+ string(APPEND RunCMake_TEST_FAILED "Install name of ${file} did not match ${expected} (actual: ${_install_name})\n")
+ endif()
+ else()
+ string(APPEND RunCMake_TEST_FAILED "otool did not print install name for ${file}\n")
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_imported_soname contents target expected)
+ if(contents MATCHES "set_target_properties\\(${target} PROPERTIES\n[^\n]*\n *IMPORTED_SONAME_DEBUG \"([^\n]*)\"\n")
+ set(_soname "${CMAKE_MATCH_1}")
+ set(_regex "^${expected}lib${target}\\.dylib$")
+ if(NOT _soname MATCHES "${_regex}")
+ string(APPEND RunCMake_TEST_FAILED "Target ${target}'s IMPORTED_SONAME_DEBUG did not match ${_regex} (actual: ${_soname})\n")
+ endif()
+ else()
+ string(APPEND RunCMake_TEST_FAILED "Could not find IMPORTED_SONAME_DEBUG for target ${target} in package config file\n")
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_libraries fake_install real_install soname_prefix)
+ file(STRINGS "${RunCMake_TEST_BINARY_DIR}/targets.txt" _targets)
+ list(GET _targets 0 _build_dir)
+ list(GET _targets 1 _install_dir)
+ check_install_name_dir("${_build_dir}" "^@rpath/libbuild_dir\\.dylib$")
+ check_install_name_dir("${_install_dir}" "^${fake_install}libinstall_dir\\.dylib$")
+ check_install_name_dir("${RunCMake_TEST_BINARY_DIR}/real_install/lib/libbuild_dir.dylib" "^${real_install}libbuild_dir\\.dylib$")
+ check_install_name_dir("${RunCMake_TEST_BINARY_DIR}/real_install/lib/libinstall_dir.dylib" "^${real_install}libinstall_dir\\.dylib$")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/real_install/lib/cmake/InstallNameDirTest/InstallNameDirTest-targets-debug.cmake" _targets)
+ check_imported_soname("${_targets}" build_dir "${soname_prefix}")
+ check_imported_soname("${_targets}" install_dir "${soname_prefix}")
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+run_install_test(none)
+run_install_test(empty)
+run_install_test(simple)
+run_install_test(simple_genex)
+run_install_test(prefix_genex)
+run_install_test(empty_genex)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake
new file mode 100644
index 0000000..db87d2c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake
@@ -0,0 +1 @@
+check_libraries("" "" "")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake
new file mode 100644
index 0000000..0cde4d1
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries("")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake
new file mode 100644
index 0000000..db87d2c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake
@@ -0,0 +1 @@
+check_libraries("" "" "")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake
new file mode 100644
index 0000000..321c8d1
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<0:/usr/local/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake
new file mode 100644
index 0000000..c3e7ac4
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(@rpath/ @rpath/ @rpath/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake
new file mode 100644
index 0000000..79c5e7d
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries(NONE)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake
new file mode 100644
index 0000000..8cf7db8
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake
@@ -0,0 +1,6 @@
+check_libraries(
+ ".*/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-build/fake_install/lib/"
+ ".*/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-build/real_install/lib/"
+ # "$" has to be escaped twice because of its significance in regexes.
+ "\\\${_IMPORT_PREFIX}/lib/"
+ )
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake
new file mode 100644
index 0000000..7e26208
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<1:$<INSTALL_PREFIX>/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake
new file mode 100644
index 0000000..5f737cb
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(/usr/local/lib/ /usr/local/lib/ /usr/local/lib/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake
new file mode 100644
index 0000000..d019875
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries(/usr/local/lib)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake
new file mode 100644
index 0000000..5f737cb
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(/usr/local/lib/ /usr/local/lib/ /usr/local/lib/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake
new file mode 100644
index 0000000..1e729e8
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<1:/usr/local/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/test.c b/Tests/RunCMake/INSTALL_NAME_DIR/test.c
new file mode 100644
index 0000000..c2db61c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/test.c
@@ -0,0 +1,3 @@
+void test(void)
+{
+}
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
index 4dddc96..07deee2 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
index a8b4756..b2395b3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
index 4dddc96..07deee2 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
index a8b4756..b2395b3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
index 00b2b3c..52fedd3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
@@ -2,17 +2,17 @@
6
8
10
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of 10 exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:9 \(set\)
.*/CMakeLists\.txt:5 \(include\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
index 8f27bf1..1427f1d 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
@@ -2,17 +2,17 @@
6
8
10
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of 10 exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:9 \(set\)
CMakeLists\.txt:5 \(include\)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index da4d1e5..cb20fb1 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -146,6 +146,12 @@ function(run_cmake test)
"|clang[^:]*: warning: the object size sanitizer has no effect at -O0, but is explicitly enabled:"
"|Error kstat returned"
"|Hit xcodebuild bug"
+
+ "|LICENSE WARNING:"
+ "|Your license to use PGI[^\n]*expired"
+ "|Please obtain a new version at"
+ "|contact PGI Sales at"
+
"|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
"|[^\n]*is a member of multiple groups"
"|[^\n]*from Time Machine by path"
@@ -204,5 +210,28 @@ function(run_cmake_with_options test)
run_cmake(${test})
endfunction()
+function(ensure_files_match expected_file actual_file)
+ if(NOT EXISTS "${expected_file}")
+ message(FATAL_ERROR "Expected file does not exist:\n ${expected_file}")
+ endif()
+ if(NOT EXISTS "${actual_file}")
+ message(FATAL_ERROR "Actual file does not exist:\n ${actual_file}")
+ endif()
+ file(READ "${expected_file}" expected_file_content)
+ file(READ "${actual_file}" actual_file_content)
+ if(NOT "${expected_file_content}" STREQUAL "${actual_file_content}")
+ message(FATAL_ERROR "Actual file content does not match expected:\n
+ \n
+ expected file: ${expected_file}\n
+ expected content:\n
+ ${expected_file_content}\n
+ \n
+ actual file: ${actual_file}\n
+ actual content:\n
+ ${actual_file_content}\n
+ ")
+ endif()
+endfunction()
+
# Protect RunCMake tests from calling environment.
unset(ENV{MAKEFLAGS})
diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
index bee8c4e..0d462ba 100644
--- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
@@ -1,6 +1,6 @@
include(RunCMake)
-if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode")
+if(RunCMake_GENERATOR STREQUAL "Xcode")
run_cmake(ConfigNotAllowed)
endif()
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 44ccd6b..1487161 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -15,6 +15,7 @@ run_cmake(VsDebuggerCommand)
run_cmake(VsDebuggerCommandArguments)
run_cmake(VsDebuggerEnvironment)
run_cmake(VsCSharpCustomTags)
+run_cmake(VsCSharpDocumentationFile)
run_cmake(VsCSharpReferenceProps)
run_cmake(VsCSharpWithoutSources)
run_cmake(VsCSharpDeployFiles)
@@ -28,6 +29,10 @@ run_cmake(VsDpiAwareBadParam)
run_cmake(VsPrecompileHeaders)
run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
+set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)")
+run_cmake(VsVCTargetsPath)
+unset(RunCMake_GENERATOR_TOOLSET)
+
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
endif()
diff --git a/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake
new file mode 100644
index 0000000..0393362
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake
@@ -0,0 +1,26 @@
+#
+# Check C# VS project for required elements
+#
+set(csProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.csproj")
+if(NOT EXISTS "${csProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.")
+ return()
+endif()
+
+file(STRINGS "${csProjectFile}" lines)
+
+set(HAVE_DocumentationFile 0)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<DocumentationFile>([^<>]+)</DocumentationFile>")
+ if(HAVE_DocumentationFile)
+ set(RunCMake_TEST_FAILED "Documentation node has been generated more than once for\n ${csProjectFile}")
+ return()
+ endif()
+ set(HAVE_DocumentationFile 1)
+ endif()
+endforeach()
+
+if(NOT HAVE_DocumentationFile)
+ set(RunCMake_TEST_FAILED "Documentation node has not been generated for\n ${csProjectFile}")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake
new file mode 100644
index 0000000..83b6b97
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(CSharp)
+
+add_library(foo SHARED
+ foo.cs)
+
+set_target_properties(foo PROPERTIES
+ VS_DOTNET_DOCUMENTATION_FILE foo.xml)
diff --git a/Tests/RunCMake/VS10Project/VsGlobals-check.cmake b/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
index 0e7fd45..6a30099 100644
--- a/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
@@ -1,44 +1,65 @@
-set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
-if(NOT EXISTS "${vcProjectFile}")
- set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
- return()
-endif()
+macro(check_project_file projectFile)
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
-set(InsideGlobals FALSE)
-set(DefaultLanguageSet FALSE)
-set(MinimumVisualStudioVersionSet FALSE)
+ set(InsideGlobals FALSE)
+ set(DefaultLanguageSet FALSE)
+ set(MinimumVisualStudioVersionSet FALSE)
+ set(TestPropertySet FALSE)
-file(STRINGS "${vcProjectFile}" lines)
-foreach(line IN LISTS lines)
- if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
- set(InsideGlobals TRUE)
- elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
- if("${CMAKE_MATCH_1}" STREQUAL "en-US")
- if(InsideGlobals)
- message(STATUS "foo.vcxproj has correct DefaultLanguage global property")
- set(DefaultLanguageSet TRUE)
- else()
- message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
+ set(InsideGlobals TRUE)
+ elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "en-US")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct DefaultLanguage global property")
+ set(DefaultLanguageSet TRUE)
+ else()
+ message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
+ endif()
endif()
- endif()
- elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
- if("${CMAKE_MATCH_1}" STREQUAL "14.0")
- if(InsideGlobals)
- message(STATUS "foo.vcxproj has correct MinimumVisualStudioVersion global property")
- set(MinimumVisualStudioVersionSet TRUE)
- else()
- message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
+ elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "10.0")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct MinimumVisualStudioVersion global property")
+ set(MinimumVisualStudioVersionSet TRUE)
+ else()
+ message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
+ endif()
+ endif()
+ elseif(line MATCHES "^ *<TestProperty>(.+)</TestProperty> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "TestValue")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct TestProperty global property")
+ set(TestPropertySet TRUE)
+ else()
+ message(STATUS "TestProperty is set but not within \"Globals\" property group")
+ endif()
endif()
endif()
+ endforeach()
+
+ if(NOT DefaultLanguageSet)
+ set(RunCMake_TEST_FAILED "DefaultLanguage not found or not set correctly in ${projectName}.")
+ return()
+ endif()
+
+ if(NOT MinimumVisualStudioVersionSet)
+ set(RunCMake_TEST_FAILED "MinimumVisualStudioVersion not found or not set correctly in ${projectName}.")
+ return()
endif()
-endforeach()
-if(NOT DefaultLanguageSet)
- set(RunCMake_TEST_FAILED "DefaultLanguageSet not found or not set correctly.")
- return()
-endif()
+ if(NOT TestPropertySet)
+ set(RunCMake_TEST_FAILED "TestProperty not found or not set correctly in ${projectName}.")
+ return()
+ endif()
+endmacro()
-if(NOT MinimumVisualStudioVersionSet)
- set(RunCMake_TEST_FAILED "MinimumVisualStudioVersionSet not found or not set correctly.")
- return()
-endif()
+check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
+check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsGlobals.cmake b/Tests/RunCMake/VS10Project/VsGlobals.cmake
index a3ed5af..09d806d 100644
--- a/Tests/RunCMake/VS10Project/VsGlobals.cmake
+++ b/Tests/RunCMake/VS10Project/VsGlobals.cmake
@@ -1,8 +1,9 @@
-enable_language(CXX)
-
set(CMAKE_VS_GLOBALS
"DefaultLanguage=en-US"
- "MinimumVisualStudioVersion=14.0"
+ "MinimumVisualStudioVersion=10.0"
+ "TestProperty=TestValue"
)
+enable_language(CXX)
+
add_library(foo foo.cpp)
diff --git a/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake b/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake
new file mode 100644
index 0000000..5b1701c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake
@@ -0,0 +1,32 @@
+macro(check_project_file projectFile)
+ set(insideGlobals FALSE)
+ set(pathFound FALSE)
+
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
+
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<PropertyGroup Label=\"Globals\">.*$")
+ set(insideGlobals TRUE)
+ elseif(insideGlobals)
+ if(line MATCHES "^ *</PropertyGroup>.*$")
+ set(insideGlobals FALSE)
+ elseif(line MATCHES "^ *<VCTargetsPath>(.+)</VCTargetsPath>*$")
+ message(STATUS "Found VCTargetsPath = ${CMAKE_MATCH_1} in PropertyGroup 'Globals' in ${projectName}")
+ set(pathFound TRUE)
+ endif()
+ endif()
+ endforeach()
+ if(NOT pathFound)
+ set(RunCMake_TEST_FAILED "VCTargetsPath not found in \"Globals\" propertygroup in ${projectName}")
+ return() # This should intentionally return from the caller, not the macro
+ endif()
+endmacro()
+
+check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
+check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake b/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake
new file mode 100644
index 0000000..6a6088f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake
index 4b74cfe..0f1fdd4 100644
--- a/Tests/RunCMake/foreach/RunCMakeTest.cmake
+++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
include(RunCMake)
run_cmake(BadRangeInFunction)
+run_cmake(foreach-all-test)
diff --git a/Tests/RunCMake/foreach/foreach-all-test-stdout.txt b/Tests/RunCMake/foreach/foreach-all-test-stdout.txt
new file mode 100644
index 0000000..e8f622d
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-all-test-stdout.txt
@@ -0,0 +1,44 @@
+-- foreach\(RANGE\):
+-- \[0\.\.1\]/1
+-- < 0
+-- < 1
+-- \[1\.\.1\]/1
+-- < 1
+-- \[0\.\.10\]/2
+-- < 0
+-- < 2
+-- < 4
+-- < 6
+-- < 8
+-- < 10
+-- \[-10\.\.0\]/3
+-- < -10
+-- < -7
+-- < -4
+-- < -1
+-- \[0\.\.-10\]/-5
+-- < 0
+-- < -5
+-- < -10
+-- foreach\(IN ITEMS\):
+-- < one
+-- < two
+-- < three
+-- foreach\(IN LISTS\):
+-- < satu
+-- < dua
+-- < tiga
+-- foreach\(IN LISTS and ITEMS\):
+-- < satu
+-- < dua
+-- < tiga
+-- < one
+-- < two
+-- < three
+-- foreach\(IN ITEMS and LISTS\):
+-- < one
+-- < two
+-- < three
+-- < satu
+-- < dua
+-- < tiga
diff --git a/Tests/RunCMake/foreach/foreach-all-test.cmake b/Tests/RunCMake/foreach/foreach-all-test.cmake
new file mode 100644
index 0000000..2e377c8
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-all-test.cmake
@@ -0,0 +1,67 @@
+message(STATUS "foreach(RANGE):")
+list(APPEND CMAKE_MESSAGE_INDENT " ")
+
+message(STATUS "[0..1]/1")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i RANGE 1)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "[1..1]/1")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i RANGE 1 1)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "[0..10]/2")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i RANGE 0 10 2)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "[-10..0]/3")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i RANGE -10 0 3)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "[0..-10]/-5")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i RANGE 0 -10 -5)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "foreach(IN ITEMS):")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i IN ITEMS one two three)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "foreach(IN LISTS):")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+list(APPEND count satu dua tiga)
+foreach(i IN LISTS count)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "foreach(IN LISTS and ITEMS):")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i IN LISTS count ITEMS one two three)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
+
+message(STATUS "foreach(IN ITEMS and LISTS):")
+list(APPEND CMAKE_MESSAGE_INDENT " < ")
+foreach(i IN ITEMS one two three LISTS count)
+ message(STATUS ${i})
+endforeach()
+list(POP_BACK CMAKE_MESSAGE_INDENT)
diff --git a/Tests/RunCMake/message/RunCMakeTest.cmake b/Tests/RunCMake/message/RunCMakeTest.cmake
index 681839d..0313ed1 100644
--- a/Tests/RunCMake/message/RunCMakeTest.cmake
+++ b/Tests/RunCMake/message/RunCMakeTest.cmake
@@ -65,6 +65,11 @@ foreach(opt IN ITEMS loglevel log-level)
endforeach()
run_cmake_command(
+ message-log-level-override
+ ${CMAKE_COMMAND} --log-level=debug -DCMAKE_MESSAGE_LOG_LEVEL=TRACE -P ${RunCMake_SOURCE_DIR}/message-all-loglevels.cmake
+ )
+
+run_cmake_command(
message-indent
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent.cmake
)
@@ -72,3 +77,23 @@ run_cmake_command(
message-indent-multiline
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent-multiline.cmake
)
+
+run_cmake_command(
+ message-context-cli
+ ${CMAKE_COMMAND} --log-level=trace --log-context -P ${RunCMake_SOURCE_DIR}/message-context.cmake
+ )
+
+run_cmake_command(
+ message-context-cache
+ ${CMAKE_COMMAND} -DCMAKE_MESSAGE_LOG_LEVEL=TRACE -DCMAKE_MESSAGE_CONTEXT_SHOW=ON -P ${RunCMake_SOURCE_DIR}/message-context.cmake
+ )
+
+run_cmake_command(
+ message-context-cli-wins-cache
+ ${CMAKE_COMMAND} --log-level=verbose --log-context -DCMAKE_MESSAGE_CONTEXT_SHOW=OFF -P ${RunCMake_SOURCE_DIR}/message-context.cmake
+ )
+
+run_cmake_command(
+ message-checks
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-checks.cmake
+ )
diff --git a/Tests/RunCMake/message/message-checks-stderr.txt b/Tests/RunCMake/message/message-checks-stderr.txt
new file mode 100644
index 0000000..fdacdb2
--- /dev/null
+++ b/Tests/RunCMake/message/message-checks-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Warning \(dev\) at.*/Tests/RunCMake/message/message-checks.cmake:13 \(message\):
+ Ignored CHECK_FAIL without CHECK_START
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/message/message-checks-stdout.txt b/Tests/RunCMake/message/message-checks-stdout.txt
new file mode 100644
index 0000000..4f5f2ef
--- /dev/null
+++ b/Tests/RunCMake/message/message-checks-stdout.txt
@@ -0,0 +1,10 @@
+-- Find `libfoo`
+-- Looking for `libfoo\.h`
+-- Looking for `libfoo\.h` - found \[/usr/include\]
+-- Looking for `libfoo\.so`
+-- Looking for `libfoo\.so` - found \[/usr/lib/libfoo\.so\]
+-- Getting `libfoo` version
+-- Looking for `libfoo/version\.h`
+-- Looking for `libfoo/version\.h` - found
+-- Getting `libfoo` version - 1\.2\.3
+-- Find `libfoo` - required version 4\.5\.6 but found 1\.2\.3
diff --git a/Tests/RunCMake/message/message-checks.cmake b/Tests/RunCMake/message/message-checks.cmake
new file mode 100644
index 0000000..605846e
--- /dev/null
+++ b/Tests/RunCMake/message/message-checks.cmake
@@ -0,0 +1,13 @@
+message(CHECK_START "Find `libfoo`")
+message(CHECK_START "Looking for `libfoo.h`")
+message(CHECK_PASS "found [/usr/include]")
+message(CHECK_START "Looking for `libfoo.so`")
+message(CHECK_PASS "found [/usr/lib/libfoo.so]")
+message(CHECK_START "Getting `libfoo` version")
+message(CHECK_START "Looking for `libfoo/version.h`")
+message(CHECK_PASS "found")
+message(CHECK_PASS "1.2.3")
+message(CHECK_FAIL "required version 4.5.6 but found 1.2.3")
+
+# Should generate an error, no associated CHECK_START
+message(CHECK_FAIL "unmatched check fail case")
diff --git a/Tests/RunCMake/message/message-context-cache-stdout.txt b/Tests/RunCMake/message/message-context-cache-stdout.txt
new file mode 100644
index 0000000..af18c15
--- /dev/null
+++ b/Tests/RunCMake/message/message-context-cache-stdout.txt
@@ -0,0 +1,8 @@
+-- Begin context output test
+-- \[top\] Top: before
+-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
+-- \[top\.foo\] foo TRACE message
+-- \[top\.foo\.baz\] This is the multi-line
+\[top\.foo\.baz\] baz DEBUG message
+-- \[top\] Top: after
+-- End of context output test
diff --git a/Tests/RunCMake/message/message-context-cli-stdout.txt b/Tests/RunCMake/message/message-context-cli-stdout.txt
new file mode 100644
index 0000000..af18c15
--- /dev/null
+++ b/Tests/RunCMake/message/message-context-cli-stdout.txt
@@ -0,0 +1,8 @@
+-- Begin context output test
+-- \[top\] Top: before
+-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
+-- \[top\.foo\] foo TRACE message
+-- \[top\.foo\.baz\] This is the multi-line
+\[top\.foo\.baz\] baz DEBUG message
+-- \[top\] Top: after
+-- End of context output test
diff --git a/Tests/RunCMake/message/message-context-cli-wins-cache-stdout.txt b/Tests/RunCMake/message/message-context-cli-wins-cache-stdout.txt
new file mode 100644
index 0000000..157db97
--- /dev/null
+++ b/Tests/RunCMake/message/message-context-cli-wins-cache-stdout.txt
@@ -0,0 +1,5 @@
+-- Begin context output test
+-- \[top\] Top: before
+-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
+-- \[top\] Top: after
+-- End of context output test
diff --git a/Tests/RunCMake/message/message-context.cmake b/Tests/RunCMake/message/message-context.cmake
new file mode 100644
index 0000000..93d4cd9
--- /dev/null
+++ b/Tests/RunCMake/message/message-context.cmake
@@ -0,0 +1,27 @@
+function(bar)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
+ list(APPEND CMAKE_MESSAGE_INDENT "<-- indent -->")
+ message(VERBOSE "bar VERBOSE message")
+endfunction()
+
+function(baz)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
+ message(DEBUG "This is the multi-line\nbaz DEBUG message")
+endfunction()
+
+function(foo)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
+ bar()
+ message(TRACE "foo TRACE message")
+ baz()
+endfunction()
+
+message(STATUS "Begin context output test")
+list(APPEND CMAKE_MESSAGE_CONTEXT "top")
+
+message(STATUS "Top: before")
+foo()
+message(STATUS "Top: after")
+
+list(POP_BACK CMAKE_MESSAGE_CONTEXT)
+message(STATUS "End of context output test")
diff --git a/Tests/RunCMake/message/message-log-level-debug-stdout.txt b/Tests/RunCMake/message/message-log-level-debug-stdout.txt
index 1452137..feee110 100644
--- a/Tests/RunCMake/message/message-log-level-debug-stdout.txt
+++ b/Tests/RunCMake/message/message-log-level-debug-stdout.txt
@@ -1,3 +1,3 @@
-- STATUS message
-- VERBOSE message
--- DEBUG message
+-- DEBUG message$
diff --git a/Tests/RunCMake/message/message-log-level-default-stdout.txt b/Tests/RunCMake/message/message-log-level-default-stdout.txt
index 809f4cc..b5d6acb 100644
--- a/Tests/RunCMake/message/message-log-level-default-stdout.txt
+++ b/Tests/RunCMake/message/message-log-level-default-stdout.txt
@@ -1 +1 @@
--- STATUS message
+-- STATUS message$
diff --git a/Tests/RunCMake/message/message-log-level-override-stderr.txt b/Tests/RunCMake/message/message-log-level-override-stderr.txt
new file mode 100644
index 0000000..efec736
--- /dev/null
+++ b/Tests/RunCMake/message/message-log-level-override-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Deprecation Warning at.*/Tests/RunCMake/message/message-all-loglevels\.cmake:2 \(message\):
+ Deprecation warning
++
+CMake Warning \(dev\) at.*/Tests/RunCMake/message/message-all-loglevels\.cmake:3 \(message\):
+ Author warning message
+This warning is for project developers\. Use -Wno-dev to suppress it\.
++
+CMake Warning at.*/Tests/RunCMake/message/message-all-loglevels\.cmake:4 \(message\):
+ Warning message
++
+Default NOTICE message
+NOTICE message$
diff --git a/Tests/RunCMake/message/message-log-level-override-stdout.txt b/Tests/RunCMake/message/message-log-level-override-stdout.txt
new file mode 100644
index 0000000..feee110
--- /dev/null
+++ b/Tests/RunCMake/message/message-log-level-override-stdout.txt
@@ -0,0 +1,3 @@
+-- STATUS message
+-- VERBOSE message
+-- DEBUG message$
diff --git a/Tests/RunCMake/message/message-log-level-status-stdout.txt b/Tests/RunCMake/message/message-log-level-status-stdout.txt
index 809f4cc..b5d6acb 100644
--- a/Tests/RunCMake/message/message-log-level-status-stdout.txt
+++ b/Tests/RunCMake/message/message-log-level-status-stdout.txt
@@ -1 +1 @@
--- STATUS message
+-- STATUS message$
diff --git a/Tests/RunCMake/message/message-log-level-trace-stdout.txt b/Tests/RunCMake/message/message-log-level-trace-stdout.txt
index 1cfce6f..3d36a7f 100644
--- a/Tests/RunCMake/message/message-log-level-trace-stdout.txt
+++ b/Tests/RunCMake/message/message-log-level-trace-stdout.txt
@@ -1,4 +1,4 @@
-- STATUS message
-- VERBOSE message
-- DEBUG message
--- TRACE message
+-- TRACE message$
diff --git a/Tests/RunCMake/message/message-log-level-verbose-stdout.txt b/Tests/RunCMake/message/message-log-level-verbose-stdout.txt
index c15d43f..47c0846 100644
--- a/Tests/RunCMake/message/message-log-level-verbose-stdout.txt
+++ b/Tests/RunCMake/message/message-log-level-verbose-stdout.txt
@@ -1,2 +1,2 @@
-- STATUS message
--- VERBOSE message
+-- VERBOSE message$
diff --git a/Tests/RunCMake/message/message-loglevel-debug-stdout.txt b/Tests/RunCMake/message/message-loglevel-debug-stdout.txt
index 1452137..feee110 100644
--- a/Tests/RunCMake/message/message-loglevel-debug-stdout.txt
+++ b/Tests/RunCMake/message/message-loglevel-debug-stdout.txt
@@ -1,3 +1,3 @@
-- STATUS message
-- VERBOSE message
--- DEBUG message
+-- DEBUG message$
diff --git a/Tests/RunCMake/message/message-loglevel-default-stdout.txt b/Tests/RunCMake/message/message-loglevel-default-stdout.txt
index 809f4cc..b5d6acb 100644
--- a/Tests/RunCMake/message/message-loglevel-default-stdout.txt
+++ b/Tests/RunCMake/message/message-loglevel-default-stdout.txt
@@ -1 +1 @@
--- STATUS message
+-- STATUS message$
diff --git a/Tests/RunCMake/message/message-loglevel-status-stdout.txt b/Tests/RunCMake/message/message-loglevel-status-stdout.txt
index 809f4cc..b5d6acb 100644
--- a/Tests/RunCMake/message/message-loglevel-status-stdout.txt
+++ b/Tests/RunCMake/message/message-loglevel-status-stdout.txt
@@ -1 +1 @@
--- STATUS message
+-- STATUS message$
diff --git a/Tests/RunCMake/message/message-loglevel-trace-stdout.txt b/Tests/RunCMake/message/message-loglevel-trace-stdout.txt
index 1cfce6f..3d36a7f 100644
--- a/Tests/RunCMake/message/message-loglevel-trace-stdout.txt
+++ b/Tests/RunCMake/message/message-loglevel-trace-stdout.txt
@@ -1,4 +1,4 @@
-- STATUS message
-- VERBOSE message
-- DEBUG message
--- TRACE message
+-- TRACE message$
diff --git a/Tests/RunCMake/message/message-loglevel-verbose-stdout.txt b/Tests/RunCMake/message/message-loglevel-verbose-stdout.txt
index c15d43f..47c0846 100644
--- a/Tests/RunCMake/message/message-loglevel-verbose-stdout.txt
+++ b/Tests/RunCMake/message/message-loglevel-verbose-stdout.txt
@@ -1,2 +1,2 @@
-- STATUS message
--- VERBOSE message
+-- VERBOSE message$
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index ef31e8b..5e4c7ba 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -24,6 +24,7 @@
{ include: [ "<bits/shared_ptr.h>", private, "<memory>", public ] },
{ include: [ "<bits/std_function.h>", private, "<functional>", public ] },
{ include: [ "<bits/refwrap.h>", private, "<functional>", public ] },
+ { include: [ "<bits/std_abs.h>", private, "<stdlib.h>", public ] },
{ include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] },
{ include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] },
{ include: [ "<bits/time.h>", private, "<time.h>", public ] },
diff --git a/Utilities/Release/push.bash b/Utilities/Release/push.bash
index 1c8efe9..a1c6651 100755
--- a/Utilities/Release/push.bash
+++ b/Utilities/Release/push.bash
@@ -50,6 +50,9 @@ if test -z "$dir"; then
dir="v${version}"
fi
readonly dir
+if ! test -d "${dest}/${dir}"; then
+ mkdir "${dest}/${dir}"
+fi
for f in cmake-${version}*; do
if ! test -f "${f}"; then
diff --git a/bootstrap b/bootstrap
index 883b165..4432d49 100755
--- a/bootstrap
+++ b/bootstrap
@@ -372,6 +372,7 @@ CMAKE_CXX_SOURCES="\
cmLDConfigTool \
cmLinkDirectoriesCommand \
cmLinkItem \
+ cmLinkItemGraphVisitor \
cmLinkLineComputer \
cmLinkLineDeviceComputer \
cmListCommand \