Merge topic 'windows-kernel-mode-driver' 54bbd00448 WindowsKernelModeDriver: Switch to appending to variables Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !9941
diff --git a/.clang-tidy b/.clang-tidy index 6d2edd4..68d0a8f 100644 --- a/.clang-tidy +++ b/.clang-tidy
@@ -7,7 +7,6 @@ -bugprone-implicit-widening-of-multiplication-result,\ -bugprone-inc-dec-in-conditions,\ -bugprone-macro-parentheses,\ --bugprone-misplaced-widening-cast,\ -bugprone-multi-level-implicit-pointer-conversion,\ -bugprone-narrowing-conversions,\ -bugprone-switch-missing-default-case,\ @@ -36,11 +35,8 @@ performance-*,\ -performance-avoid-endl,\ -performance-enum-size,\ --performance-inefficient-vector-operation,\ --performance-noexcept-swap,\ readability-*,\ -readability-avoid-nested-conditional-operator,\ --readability-avoid-return-with-void-value,\ -readability-avoid-unconditional-preprocessor-if,\ -readability-convert-member-functions-to-static,\ -readability-function-cognitive-complexity,\ @@ -52,11 +48,6 @@ -readability-magic-numbers,\ -readability-make-member-function-const,\ -readability-named-parameter,\ --readability-redundant-casting,\ --readability-redundant-declaration,\ --readability-redundant-inline-specifier,\ --readability-redundant-member-init,\ --readability-reference-to-constructed-temporary,\ -readability-simplify-boolean-expr,\ -readability-static-accessed-through-instance,\ -readability-suspicious-call-argument,\
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b352b06..43bb7cc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml
@@ -747,6 +747,13 @@ CMAKE_CI_BUILD_NAME: oneapi2024.1.0_makefiles CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2024.1.0-el8 +t:oneapi2024.2.0-makefiles: + extends: + - .cmake_test_linux_inteloneapi_makefiles + variables: + CMAKE_CI_BUILD_NAME: oneapi2024.2.0_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2024.2.0-rocky9 + b:linux-x86_64-package: extends: - .linux_package
diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a562c..ae1359e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -1,7 +1,7 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR) set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
diff --git a/Help/command/LINK_LIBRARIES_LINKER.txt b/Help/command/LINK_LIBRARIES_LINKER.txt new file mode 100644 index 0000000..7dc6b84 --- /dev/null +++ b/Help/command/LINK_LIBRARIES_LINKER.txt
@@ -0,0 +1,24 @@ +Handling Compiler Driver Differences +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.32 + +To pass options to the linker tool, each compiler driver has its own syntax. +The ``LINKER:`` prefix and ``,`` separator can be used to specify, in a portable +way, options to pass to the linker tool. ``LINKER:`` is replaced by the +appropriate driver option and ``,`` by the appropriate driver separator. +The driver prefix and driver separator are given by the values of the +:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG` and +:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP` variables. + +For example, ``"LINKER:-z,defs"`` becomes ``-Xlinker -z -Xlinker defs`` for +``Clang`` and ``-Wl,-z,defs`` for ``GNU GCC``. + +The ``LINKER:`` prefix supports, as an alternative syntax, specification of +arguments using the ``SHELL:`` prefix and space as separator. The previous +example then becomes ``"LINKER:SHELL:-z defs"``. + +.. note:: + + Specifying the ``SHELL:`` prefix anywhere other than at the beginning of the + ``LINKER:`` prefix is not supported.
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst index 145bd90..0d94eb0 100644 --- a/Help/command/ctest_run_script.rst +++ b/Help/command/ctest_run_script.rst
@@ -9,7 +9,6 @@ script_file_name2 ... [RETURN_VALUE var]) Runs a script or scripts much like if it was run from :option:`ctest -S`. -If no argument is provided then the current script is run using the current -settings of the variables. If ``NEW_PROCESS`` is specified then each -script will be run in a separate process.If ``RETURN_VALUE`` is specified -the return value of the last script run will be put into ``var``. +If ``NEW_PROCESS`` is specified then each script will be run in a separate +process. If ``RETURN_VALUE`` is specified the return value of the last script +run will be put into ``var``.
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index 94a2429..caa6441 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst
@@ -148,6 +148,8 @@ See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. +.. include:: ../command/LINK_LIBRARIES_LINKER.txt + Libraries for a Target and/or its Dependents ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst index 10b3f7d..8098bb0 100644 --- a/Help/dev/maint.rst +++ b/Help/dev/maint.rst
@@ -350,7 +350,7 @@ away from setting policies to OLD. Update the ``cmake_policy`` version range generated by ``install(EXPORT)`` -in ``cmExportFileGenerator::GeneratePolicyHeaderCode`` and +in ``cmExportCMakeConfigGenerator::GeneratePolicyHeaderCode`` and ``install_jar_exports`` in ``javaTargets.cmake.in`` to end at the previous release. We use one release back since we now know all the policies added for that version. Commit with a message such as::
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 10dbe10..b310e89 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst
@@ -415,6 +415,7 @@ /prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE /prop_tgt/UNITY_BUILD_MODE + /prop_tgt/UNITY_BUILD_RELOCATABLE /prop_tgt/UNITY_BUILD_UNIQUE_ID /prop_tgt/VERIFY_INTERFACE_HEADER_SETS /prop_tgt/VERSION
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 9281339..683ac2f 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst
@@ -421,11 +421,8 @@ .. option:: --force-new-ctest-process - Run child CTest instances as new processes. - - By default CTest will run child CTest instances within the same - process. If this behavior is not desired, this argument will - enforce new processes for child CTest processes. + Ignored. This option once disabled a now-removed optimization + for tests running ``ctest`` itself. .. option:: --schedule-random
diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index 53f5838..73d273b 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
@@ -32,6 +32,8 @@ :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties. +.. include:: ../command/LINK_LIBRARIES_LINKER.txt + Creating Relocatable Packages ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst index 785b17c..886adf2 100644 --- a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst +++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -8,3 +8,9 @@ .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS`` .. |PROPERTY_LINK| replace:: :prop_tgt:`LINK_OPTIONS` .. include:: INTERFACE_BUILD_PROPERTY.txt + +.. include:: ../command/DEVICE_LINK_OPTIONS.txt + +.. include:: ../command/OPTIONS_SHELL.txt + +.. include:: ../command/LINK_OPTIONS_LINKER.txt
diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index b449aa1..8814980 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst
@@ -33,3 +33,5 @@ corresponding :prop_tgt:`LINK_LIBRARIES_STRATEGY` target property for details on how CMake orders direct link dependencies on linker command lines. + +.. include:: ../command/LINK_LIBRARIES_LINKER.txt
diff --git a/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst b/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst new file mode 100644 index 0000000..daac7fd --- /dev/null +++ b/Help/prop_tgt/UNITY_BUILD_RELOCATABLE.rst
@@ -0,0 +1,40 @@ +UNITY_BUILD_RELOCATABLE +----------------------- + +.. versionadded:: 3.32 + +By default, the unity file generated when :prop_tgt:`UNITY_BUILD` is enabled +uses absolute paths to reference the original source files. This causes the +unity file to result in a different output depending on the location of the +source files. + +When this property is set to true, the ``#include`` lines inside the generated +unity source files will attempt to use relative paths to the original source +files if possible in order to standardize the output of the unity file. + +The unity file's path to the original source file will use the following +priority: + +* relative path to the generated unity file if the source file exists + directly or in subfolder under the :variable:`CMAKE_BINARY_DIR` + +* relative path to :variable:`CMAKE_SOURCE_DIR` if the source file exists + directly or in subfolder under the :variable:`CMAKE_SOURCE_DIR` + +* absolute path to the source file. + +This target property *does not* guarantee a consistent unity file across +different environments as the final priority is an absolute path. + +Example usage: + +.. code-block:: cmake + + add_library(example_library + source1.cxx + source2.cxx + source3.cxx) + + set_target_properties(example_library PROPERTIES + UNITY_BUILD True + UNITY_BUILD_RELOCATABLE TRUE)
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/FindProtobuf-protoc-exe-option.rst b/Help/release/dev/FindProtobuf-protoc-exe-option.rst new file mode 100644 index 0000000..93d60cb --- /dev/null +++ b/Help/release/dev/FindProtobuf-protoc-exe-option.rst
@@ -0,0 +1,5 @@ +FindProtobuf-protoc-exe-option +------------------------------ + +* The :module:`FindProtobuf` module :command:`protobuf_generate` command + gained a ``PROTOC_EXE`` option to specify a custom ``protoc`` executable.
diff --git a/Help/release/dev/ctest-remove-declarative-script-mode.rst b/Help/release/dev/ctest-remove-declarative-script-mode.rst new file mode 100644 index 0000000..c346abe --- /dev/null +++ b/Help/release/dev/ctest-remove-declarative-script-mode.rst
@@ -0,0 +1,14 @@ +ctest-remove-declarative-script-mode +------------------------------------ + +* CTest's declarative scripting mode has been removed. This mode used to be + triggered by a :option:`ctest -S` script which did not call any + :ref:`CTest Commands` unless :variable:`CTEST_RUN_CURRENT_SCRIPT` was + explicitly set to ``OFF``. This feature was undocumented and was not covered + by any unit tests. + +* The :variable:`CTEST_RUN_CURRENT_SCRIPT` variable no longer has any special + meaning. + +* The :command:`ctest_run_script` command may no longer be called without any + arguments.
diff --git a/Help/release/dev/target_link_libraries-LINKER-prefix.rst b/Help/release/dev/target_link_libraries-LINKER-prefix.rst new file mode 100644 index 0000000..08f36af --- /dev/null +++ b/Help/release/dev/target_link_libraries-LINKER-prefix.rst
@@ -0,0 +1,5 @@ +target_link_libraries-LINKER-prefix +----------------------------------- + +* The :command:`target_link_libraries` command gains the support of the + ``LINKER:`` prefix.
diff --git a/Help/release/index.rst b/Help/release/index.rst index 40767b7..101dd68 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ 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_LINK_DEPENDS_USE_LINKER.rst b/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst index 1867ad8..1c07a23 100644 --- a/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst +++ b/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst
@@ -13,8 +13,9 @@ .. note:: - CMake version |release| defaults this variable to ``FALSE`` because - GNU binutils linkers (``ld``, ``ld.bfd``, ``ld.gold``) generate spurious + CMake version |release| defaults this variable to ``FALSE`` if the linker is + one from the GNU binutils linkers (``ld`` and ``ld.bfd`` for version less + than 2.41 or ``ld.gold`` for any version) because it generate spurious dependencies on temporary files when LTO is enabled. See `GNU bug 30568`_. .. _`GNU bug 30568`: https://sourceware.org/bugzilla/show_bug.cgi?id=30568
diff --git a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst index 8cb6eaa..616324e 100644 --- a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst +++ b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
@@ -1,7 +1,5 @@ CTEST_RUN_CURRENT_SCRIPT ------------------------ -.. versionadded:: 3.11 - -Setting this to 0 prevents :manual:`ctest(1)` from being run again when it -reaches the end of a script run by calling :option:`ctest -S`. +Removed. This variable once supported an undocumented feature that has since +been removed.
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake index 2dc1585..7030034 100644 --- a/Modules/CMakeASMInformation.cmake +++ b/Modules/CMakeASMInformation.cmake
@@ -96,5 +96,6 @@ set(CMAKE_EXECUTABLE_RPATH_LINK_ASM${ASM_DIALECT}_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_ASM${ASM_DIALECT}_FLAG}) endif() +set(CMAKE_ASM${ASM_DIALECT}_USE_LINKER_INFORMATION TRUE) set(CMAKE_ASM${ASM_DIALECT}_INFOMATION_LOADED 1)
diff --git a/Modules/CMakeAddNewLanguage.txt b/Modules/CMakeAddNewLanguage.txt index b0be590..011195c 100644 --- a/Modules/CMakeAddNewLanguage.txt +++ b/Modules/CMakeAddNewLanguage.txt
@@ -20,12 +20,20 @@ This file is used to store compiler information and is copied down into try compile directories so that try compiles do not need to re-determine and test the LANG -CMakeTest(LANG)Compiler.cmake -> test the compiler and set: - SET(CMAKE_(LANG)_COMPILER_WORKS 1 CACHE INTERNAL "") - -CMake(LANG)Information.cmake -> set up rule variables for LANG : +CMake(LANG)Information.cmake => set compiler configuration: CMAKE_(LANG)_CREATE_SHARED_LIBRARY CMAKE_(LANG)_CREATE_SHARED_MODULE CMAKE_(LANG)_CREATE_STATIC_LIBRARY CMAKE_(LANG)_COMPILE_OBJECT CMAKE_(LANG)_LINK_EXECUTABLE + + CMAKE_(LANG)_USE_LINKER_INFORMATION + +CMakeTest(LANG)Compiler.cmake -> test the compiler and set: + SET(CMAKE_(LANG)_COMPILER_WORKS 1 CACHE INTERNAL "") + + +If the variable CMAKE_(LANG)_USE_LINKER_INFORMATION has value TRUE, the file CMake(LANG)LinkerInformation.cmake +should be defined. + +CMake(LANG)LinkerInformation.cmake -> set up linker configuration for LANG.
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake index 72fb801..977e51a 100644 --- a/Modules/CMakeCInformation.cmake +++ b/Modules/CMakeCInformation.cmake
@@ -175,4 +175,6 @@ "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") endif() +set(CMAKE_C_USE_LINKER_INFORMATION TRUE) + set(CMAKE_C_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeCSharpInformation.cmake b/Modules/CMakeCSharpInformation.cmake index 41cd449..f698bdf 100644 --- a/Modules/CMakeCSharpInformation.cmake +++ b/Modules/CMakeCSharpInformation.cmake
@@ -64,4 +64,7 @@ set(CMAKE_CSharp_LINK_EXECUTABLE "CSharp_NO_LINK_EXECUTABLE") set(CMAKE_CSharp_USE_RESPONSE_FILE_FOR_OBJECTS 1) + +set(CMAKE_CSharp_USE_LINKER_INFORMATION FALSE) + set(CMAKE_CSharp_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 66a5faa..fa197b2 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake
@@ -150,4 +150,6 @@ unset(__IMPLICIT_DLINK_FLAGS) +set(CMAKE_CUDA_USE_LINKER_INFORMATION TRUE) + set(CMAKE_CUDA_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake index e521fb8..cc130ae 100644 --- a/Modules/CMakeCXXInformation.cmake +++ b/Modules/CMakeCXXInformation.cmake
@@ -183,4 +183,6 @@ CMAKE_VERBOSE_MAKEFILE ) +set(CMAKE_CXX_USE_LINKER_INFORMATION TRUE) + set(CMAKE_CXX_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index 984a39d..a376e10 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake
@@ -129,5 +129,7 @@ mark_as_advanced(CMAKE_Fortran_STANDARD_LIBRARIES) endif() +set(CMAKE_Fortran_USE_LINKER_INFORMATION TRUE) + # set this variable so we can avoid loading this more than once. set(CMAKE_Fortran_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeHIPInformation.cmake b/Modules/CMakeHIPInformation.cmake index dc76c63..c013df8 100644 --- a/Modules/CMakeHIPInformation.cmake +++ b/Modules/CMakeHIPInformation.cmake
@@ -98,6 +98,8 @@ "<CMAKE_HIP_COMPILER> <FLAGS> <CMAKE_HIP_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") endif() +set(CMAKE_HIP_USE_LINKER_INFORMATION TRUE) + set(CMAKE_HIP_INFORMATION_LOADED 1) # Load the file and find the relevant HIP runtime.
diff --git a/Modules/CMakeISPCInformation.cmake b/Modules/CMakeISPCInformation.cmake index 5acb682..4a4b72a 100644 --- a/Modules/CMakeISPCInformation.cmake +++ b/Modules/CMakeISPCInformation.cmake
@@ -62,4 +62,6 @@ "<CMAKE_ISPC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> --emit-obj <SOURCE> -h <ISPC_HEADER>") endif() +set(CMAKE_ISPC_USE_LINKER_INFORMATION FALSE) + set(CMAKE_ISPC_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeJavaInformation.cmake b/Modules/CMakeJavaInformation.cmake index 989afc1..0ca8395 100644 --- a/Modules/CMakeJavaInformation.cmake +++ b/Modules/CMakeJavaInformation.cmake
@@ -47,3 +47,5 @@ else() set(CMAKE_INCLUDE_FLAG_SEP_Java ":") endif() + +set(CMAKE_Java_USE_LINKER_INFORMATION FALSE)
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake index bcb8b11..56e8239 100644 --- a/Modules/CMakeOBJCInformation.cmake +++ b/Modules/CMakeOBJCInformation.cmake
@@ -187,4 +187,6 @@ set(CMAKE_EXECUTABLE_RPATH_LINK_OBJC_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJC_FLAG}) endif() +set(CMAKE_OBJC_USE_LINKER_INFORMATION TRUE) + set(CMAKE_OBJC_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake index 4fcd469..a242dab 100644 --- a/Modules/CMakeOBJCXXInformation.cmake +++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -179,4 +179,6 @@ CMAKE_VERBOSE_MAKEFILE ) +set(CMAKE_OBJCXX_USE_LINKER_INFORMATION TRUE) + set(CMAKE_OBJCXX_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 87c9e8a..d9ecbd8 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -49,20 +49,21 @@ set(multiValueArgs ) cmake_parse_arguments(EXTRA_PARSE "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(is_lfortran 0) + set(is_lfortran_less_0_40 0) set(is_msvc 0) if(EXTRA_PARSE_LANGUAGE) if("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" OR "x${CMAKE_${EXTRA_PARSE_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC") set(is_msvc 1) - elseif("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_ID}" STREQUAL "xLFortran") - set(is_lfortran 1) + elseif("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_ID}" STREQUAL "xLFortran" + AND CMAKE_${EXTRA_PARSE_LANGUAGE}_COMPILER_VERSION VERSION_LESS "0.40") + set(is_lfortran_less_0_40 1) endif() endif() # Parse implicit linker arguments. set(linker "ld[0-9]*(\\.[a-z]+)?") - if(is_lfortran) - # FIXME(lfortran): No way to pass -v to clang/gcc driver. + if(is_lfortran_less_0_40) + # lfortran < 0.40 has no way to pass -v to clang/gcc driver. string(APPEND linker "|clang|gcc") endif() if(is_msvc) @@ -85,8 +86,8 @@ set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=|/ldfe ") set(linker_tool_regex "^[ \t]*(->|\")?[ \t]*(([^\"]*[/\\])?(${linker}))(\"|,| |$)") set(linker_tool_exclude_regex "cuda-fake-ld|-fuse-ld=|^ExecuteExternalTool ") - if(is_lfortran) - # FIXME(lfortran): No way to pass -v to clang/gcc driver. + if(is_lfortran_less_0_40) + # lfortran < 0.40 has no way to pass -v to clang/gcc driver. string(APPEND linker_tool_exclude_regex "|^clang |^gcc ") endif() set(linker_tool "NOTFOUND")
diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake index b634796..d716469 100644 --- a/Modules/CMakeRCInformation.cmake +++ b/Modules/CMakeRCInformation.cmake
@@ -46,5 +46,7 @@ "<CMAKE_RC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /fo <OBJECT> <SOURCE>") endif() +set(CMAKE_RC_USE_LINKER_INFORMATION FALSE) + # set this variable so we can avoid loading this more than once. set(CMAKE_RC_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index a46d298..904a528 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake
@@ -172,4 +172,6 @@ endif() endif() +set(CMAKE_Swift_USE_LINKER_INFORMATION TRUE) + set(CMAKE_Swift_INFORMATION_LOADED 1)
diff --git a/Modules/Compiler/LFortran-Fortran.cmake b/Modules/Compiler/LFortran-Fortran.cmake index 4180730..9090e1d 100644 --- a/Modules/Compiler/LFortran-Fortran.cmake +++ b/Modules/Compiler/LFortran-Fortran.cmake
@@ -3,7 +3,7 @@ string(APPEND CMAKE_Fortran_FLAGS_RELEASE_INIT " -O3") string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT " -O2 -g") set(CMAKE_Fortran_MODDIR_FLAG "-J") -set(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_VERBOSE_FLAG "-v -Wl,-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "--fixed-form") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "--cpp")
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake index 3515bf0..6d0ace7 100644 --- a/Modules/FindBISON.cmake +++ b/Modules/FindBISON.cmake
@@ -281,7 +281,8 @@ VERBATIM DEPENDS ${_BisonInput} COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}" - WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY}) + WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY} + COMMAND_EXPAND_LISTS) unset(_BISON_WORKING_DIRECTORY)
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake index 5ce8a90..f736130 100644 --- a/Modules/FindCURL.cmake +++ b/Modules/FindCURL.cmake
@@ -239,9 +239,24 @@ IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}") endif() - if(CURL_USE_STATIC_LIBS AND MSVC) - set_target_properties(CURL::libcurl PROPERTIES - INTERFACE_LINK_LIBRARIES "normaliz.lib;ws2_32.lib;wldap32.lib") + if(PC_CURL_FOUND) + if(PC_CURL_LINK_LIBRARIES) + set_property(TARGET CURL::libcurl PROPERTY + INTERFACE_LINK_LIBRARIES "${PC_CURL_LINK_LIBRARIES}") + endif() + if(PC_CURL_LDFLAGS_OTHER) + set_property(TARGET CURL::libcurl PROPERTY + INTERFACE_LINK_OPTIONS "${PC_CURL_LDFLAGS_OTHER}") + endif() + if(PC_CURL_CFLAGS_OTHER) + set_property(TARGET CURL::libcurl PROPERTY + INTERFACE_COMPILE_OPTIONS "${PC_CURL_CFLAGS_OTHER}") + endif() + else() + if(CURL_USE_STATIC_LIBS AND MSVC) + set_target_properties(CURL::libcurl PROPERTIES + INTERFACE_LINK_LIBRARIES "normaliz.lib;ws2_32.lib;wldap32.lib") + endif() endif() endif()
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 197e71f..1d69c57 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake
@@ -108,20 +108,27 @@ Add custom commands to process ``.proto`` files to C++:: - protobuf_generate_cpp (<SRCS> <HDRS> - [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...]) + protobuf_generate_cpp ( + <srcs-var> <hdrs-var> + [DESCRIPTORS <var>] + [EXPORT_MACRO <macro>] + [<proto-file>...]) - ``SRCS`` + ``<srcs-var>`` Variable to define with autogenerated source files - ``HDRS`` + + ``<hdrs-var>`` Variable to define with autogenerated header files - ``DESCRIPTORS`` + + ``DESCRIPTORS <var>`` .. versionadded:: 3.10 Variable to define with autogenerated descriptor files, if requested. - ``EXPORT_MACRO`` + + ``EXPORT_MACRO <macro>`` is a macro which should expand to ``__declspec(dllexport)`` or ``__declspec(dllimport)`` depending on what is being compiled. - ``ARGN`` + + ``<proto-file>...`` ``.proto`` files .. command:: protobuf_generate_python @@ -130,11 +137,12 @@ Add custom commands to process ``.proto`` files to Python:: - protobuf_generate_python (<PY> [<ARGN>...]) + protobuf_generate_python (<py-srcs-var> [<proto-file>...]) - ``PY`` + ``<py-srcs-var>`` Variable to define with autogenerated Python files - ``ARGN`` + + ``<proto-file>...`` ``.proto`` files .. command:: protobuf_generate @@ -146,63 +154,82 @@ protobuf_generate ( TARGET <target> [LANGUAGE <lang>] - [OUT_VAR <out_var>] + [OUT_VAR <var>] [EXPORT_MACRO <macro>] [PROTOC_OUT_DIR <dir>] [PLUGIN <plugin>] - [PLUGIN_OPTIONS <plugin_options>] - [DEPENDENCIES <depends] - [PROTOS <protobuf_files>] - [IMPORT_DIRS <dirs>] - [GENERATE_EXTENSIONS <extensions>] - [PROTOC_OPTIONS <protoc_options>] + [PLUGIN_OPTIONS <plugin-options>] + [DEPENDENCIES <dependencies>] + [PROTOS <proto-file>...] + [IMPORT_DIRS <dir>...] + [GENERATE_EXTENSIONS <extension>...] + [PROTOC_OPTIONS <option>...] + [PROTOC_EXE <executable>] [APPEND_PATH]) ``APPEND_PATH`` A flag that causes the base path of all proto schema files to be added to ``IMPORT_DIRS``. - ``LANGUAGE`` + + ``LANGUAGE <lang>`` A single value: cpp or python. Determines what kind of source files are being generated. Defaults to cpp. - ``OUT_VAR`` + + ``OUT_VAR <var>`` Name of a CMake variable that will be filled with the paths to the generated source files. - ``EXPORT_MACRO`` + + ``EXPORT_MACRO <macro>`` Name of a macro that is applied to all generated Protobuf message classes and extern variables. It can, for example, be used to declare DLL exports. - ``PROTOC_OUT_DIR`` + + ``PROTOC_OUT_DIR <dir>`` Output directory of generated source files. Defaults to ``CMAKE_CURRENT_BINARY_DIR``. - ``PLUGIN`` + + ``PLUGIN <plugin>`` .. versionadded:: 3.21 An optional plugin executable. This could, for example, be the path to ``grpc_cpp_plugin``. - ``PLUGIN_OPTIONS`` + + ``PLUGIN_OPTIONS <plugin-options>`` .. versionadded:: 3.28 Additional options provided to the plugin, such as ``generate_mock_code=true`` for the gRPC cpp plugin. - ``DEPENDENCIES`` + + ``DEPENDENCIES <dependencies>`` .. versionadded:: 3.28 Arguments forwarded to the ``DEPENDS`` of the underlying ``add_custom_command`` invocation. - ``TARGET`` + + ``TARGET <target>`` CMake target that will have the generated files added as sources. - ``PROTOS`` + + ``PROTOS <proto-file>...`` List of proto schema files. If omitted, then every source file ending in *proto* of ``TARGET`` will be used. - ``IMPORT_DIRS`` + + ``IMPORT_DIRS <dir>...`` A common parent directory for the schema files. For example, if the schema file is ``proto/helloworld/helloworld.proto`` and the import directory ``proto/`` then the generated files are ``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.h`` and ``${PROTOC_OUT_DIR}/helloworld/helloworld.pb.cc``. - ``GENERATE_EXTENSIONS`` + + ``GENERATE_EXTENSIONS <extension>...`` If LANGUAGE is omitted then this must be set to the extensions that protoc generates. - ``PROTOC_OPTIONS`` + + ``PROTOC_OPTIONS <option>...`` .. versionadded:: 3.28 Additional arguments that are forwarded to protoc. + ``PROTOC_EXE <executable>`` + .. versionadded:: 3.32 + + Command name, path, or CMake executable used to generate protobuf bindings. + If omitted, ``protobuf::protoc`` is used. + Example:: find_package(gRPC CONFIG REQUIRED) @@ -223,7 +250,7 @@ function(protobuf_generate) set(_options APPEND_PATH DESCRIPTORS) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES PROTOC_EXE) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -292,10 +319,14 @@ return() endif() - if(NOT TARGET protobuf::protoc) - message(SEND_ERROR "protoc executable not found. " - "Please define the Protobuf_PROTOC_EXECUTABLE variable or ensure that protoc is in CMake's search path.") - return() + if(NOT protobuf_generate_PROTOC_EXE) + if(NOT TARGET protobuf::protoc) + message(SEND_ERROR "protoc executable not found. " + "Please define the Protobuf_PROTOC_EXECUTABLE variable, or pass PROTOC_EXE to protobuf_generate, or ensure that protoc is in CMake's search path.") + return() + endif() + # Default to using the CMake executable + set(protobuf_generate_PROTOC_EXE protobuf::protoc) endif() if(protobuf_generate_APPEND_PATH) @@ -368,7 +399,7 @@ add_custom_command( OUTPUT ${_generated_srcs} - COMMAND protobuf::protoc + COMMAND ${protobuf_generate_PROTOC_EXE} ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES} COMMENT ${_comment}
diff --git a/Modules/Internal/CMakeCSharpLinkerInformation.cmake b/Modules/Internal/CMakeCSharpLinkerInformation.cmake deleted file mode 100644 index ff73a37..0000000 --- a/Modules/Internal/CMakeCSharpLinkerInformation.cmake +++ /dev/null
@@ -1,8 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - - -# This file sets the basic flags for the linker used by the CSharp compiler in CMake. -# For now, nothing to define - -set(CMAKE_CSharp_LINKER_INFORMATION_LOADED 1)
diff --git a/Modules/Internal/CMakeISPCLinkerInformation.cmake b/Modules/Internal/CMakeISPCLinkerInformation.cmake deleted file mode 100644 index 47950aa..0000000 --- a/Modules/Internal/CMakeISPCLinkerInformation.cmake +++ /dev/null
@@ -1,8 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - - -# This file sets the basic flags for the linker used by the ISPC compiler in CMake. -# For now, ISPC is not able to handle the link step - -set(CMAKE_ISPC_LINKER_INFORMATION_LOADED 1)
diff --git a/Modules/Internal/CMakeJavaLinkerInformation.cmake b/Modules/Internal/CMakeJavaLinkerInformation.cmake deleted file mode 100644 index c0edadd..0000000 --- a/Modules/Internal/CMakeJavaLinkerInformation.cmake +++ /dev/null
@@ -1,5 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - - -# Java language does not have a concept of linker, so nothing to configure.
diff --git a/Modules/Internal/CMakeRCLinkerInformation.cmake b/Modules/Internal/CMakeRCLinkerInformation.cmake deleted file mode 100644 index 1b0563e..0000000 --- a/Modules/Internal/CMakeRCLinkerInformation.cmake +++ /dev/null
@@ -1,17 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - - -# This file sets the basic flags for the linker used by the C compiler in CMake. -# It also loads the available platform file for the system-linker -# if it exists. -# It also loads a system - linker - processor (or target hardware) -# specific file, which is mainly useful for crosscompiling and embedded systems. - -include(Internal/CMakeCommonLinkerInformation) - -set(_INCLUDED_FILE 0) - -# Foe now, no linker associated with RC language - -set(CMAKE_RC_LINKER_INFORMATION_LOADED 1)
diff --git a/Modules/UseJava/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in index 6002d4e..11f1f06 100644 --- a/Modules/UseJava/javaTargets.cmake.in +++ b/Modules/UseJava/javaTargets.cmake.in
@@ -1,5 +1,5 @@ cmake_policy(PUSH) -cmake_policy(VERSION 2.8.12...3.29) +cmake_policy(VERSION 2.8.12...3.30) #---------------------------------------------------------------- # Generated CMake Java target import file.
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c4cd101..6c896c1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt
@@ -1071,7 +1071,7 @@ cmCTest.cxx CTest/cmProcess.cxx CTest/cmCTestBinPacker.cxx - CTest/cmCTestBuildAndTestHandler.cxx + CTest/cmCTestBuildAndTest.cxx CTest/cmCTestBuildCommand.cxx CTest/cmCTestBuildHandler.cxx CTest/cmCTestConfigureCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ce004af..b1279bc 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 31) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 2) +set(CMake_VERSION_PATCH 20241025) +#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/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index c70a2f1..e5b9297 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackArchiveGenerator.h" -#include <cstring> #include <map> #include <ostream> #include <unordered_map> @@ -238,10 +237,7 @@ // Change to local toplevel cmWorkingDirectory workdir(localToplevel); if (workdir.Failed()) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Failed to change working directory to " - << localToplevel << " : " - << std::strerror(workdir.GetLastResult()) << std::endl); + cmCPackLogger(cmCPackLog::LOG_ERROR, workdir.GetError() << std::endl); return 0; } std::string filePrefix; @@ -448,10 +444,7 @@ DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive); cmWorkingDirectory workdir(this->toplevel); if (workdir.Failed()) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Failed to change working directory to " - << this->toplevel << " : " - << std::strerror(workdir.GetLastResult()) << std::endl); + cmCPackLogger(cmCPackLog::LOG_ERROR, workdir.GetError() << std::endl); return 0; } for (std::string const& file : this->files) {
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 44d0ece..d5c8cc8 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx
@@ -3,7 +3,6 @@ #include "cmCPackGenerator.h" #include <algorithm> -#include <cstring> #include <memory> #include <utility> @@ -52,10 +51,9 @@ } void cmCPackGenerator::DisplayVerboseOutput(const std::string& msg, - float progress) + float /*unused*/) { - (void)progress; - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, msg << std::endl); } int cmCPackGenerator::PrepareNames() @@ -434,10 +432,7 @@ cmWorkingDirectory workdir(goToDir); if (workdir.Failed()) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Failed to change working directory to " - << goToDir << " : " - << std::strerror(workdir.GetLastResult()) - << std::endl); + workdir.GetError() << std::endl); return 0; } for (auto const& symlinked : symlinkedFiles) {
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 305ac56..68e759d 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx
@@ -208,6 +208,7 @@ CommandArgument{ "--list-presets", CommandArgument::Values::Zero, CommandArgument::setToTrue(listPresets) }, CommandArgument{ "-D", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&log, &definitions](const std::string& arg, cmake*, cmMakefile*) -> bool { std::string value = arg; @@ -405,7 +406,7 @@ bool cpackConfigFileSpecified = true; if (!cpackConfigFile.empty()) { - cpackConfigFile = cmSystemTools::CollapseFullPath(cpackConfigFile); + cpackConfigFile = cmSystemTools::ToNormalizedPathOnDisk(cpackConfigFile); } else { cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/CPackConfig.cmake"); @@ -479,7 +480,7 @@ if (!cpackProjectDirectory.empty()) { // The value has been set on the command line. Ensure it is absolute. cpackProjectDirectory = - cmSystemTools::CollapseFullPath(cpackProjectDirectory); + cmSystemTools::ToNormalizedPathOnDisk(cpackProjectDirectory); } else { // The value has not been set on the command line. Check config file. if (cmValue pd = globalMF.GetDefinition("CPACK_PACKAGE_DIRECTORY")) {
diff --git a/Source/CTest/cmCTestBuildAndTest.cxx b/Source/CTest/cmCTestBuildAndTest.cxx new file mode 100644 index 0000000..a142445 --- /dev/null +++ b/Source/CTest/cmCTestBuildAndTest.cxx
@@ -0,0 +1,341 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCTestBuildAndTest.h" + +#include <chrono> +#include <cstdint> +#include <iostream> +#include <ratio> +#include <utility> + +#include <cm3p/uv.h> + +#include "cmBuildOptions.h" +#include "cmCTest.h" +#include "cmCTestTestHandler.h" +#include "cmGlobalGenerator.h" +#include "cmMakefile.h" +#include "cmProcessOutput.h" +#include "cmState.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmUVHandlePtr.h" +#include "cmUVProcessChain.h" +#include "cmUVStream.h" +#include "cmWorkingDirectory.h" +#include "cmake.h" + +struct cmMessageMetadata; + +cmCTestBuildAndTest::cmCTestBuildAndTest(cmCTest* ctest) + : CTest(ctest) +{ +} + +bool cmCTestBuildAndTest::RunCMake(cmake* cm) +{ + std::vector<std::string> args; + args.push_back(cmSystemTools::GetCMakeCommand()); + args.push_back(this->SourceDir); + if (!this->BuildGenerator.empty()) { + args.push_back("-G" + this->BuildGenerator); + } + if (!this->BuildGeneratorPlatform.empty()) { + args.push_back("-A" + this->BuildGeneratorPlatform); + } + if (!this->BuildGeneratorToolset.empty()) { + args.push_back("-T" + this->BuildGeneratorToolset); + } + + const char* config = nullptr; + if (!this->CTest->GetConfigType().empty()) { + config = this->CTest->GetConfigType().c_str(); + } + + if (config) { + args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config)); + } + if (!this->BuildMakeProgram.empty() && + (this->BuildGenerator.find("Make") != std::string::npos || + this->BuildGenerator.find("Ninja") != std::string::npos)) { + args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram); + } + + for (std::string const& opt : this->BuildOptions) { + args.push_back(opt); + } + std::cout << "======== CMake output ======\n"; + if (cm->Run(args) != 0) { + std::cout << "======== End CMake output ======\n" + "Error: cmake execution failed\n"; + return false; + } + // do another config? + if (this->BuildTwoConfig) { + if (cm->Run(args) != 0) { + std::cout << "======== End CMake output ======\n" + "Error: cmake execution failed\n"; + return false; + } + } + std::cout << "======== End CMake output ======\n"; + return true; +} + +bool cmCTestBuildAndTest::RunTest(std::vector<std::string> const& argv, + int* retVal, cmDuration timeout) +{ + cmUVProcessChainBuilder builder; + builder.AddCommand(argv).SetMergedBuiltinStreams(); + auto chain = builder.Start(); + + cmProcessOutput processOutput(cmProcessOutput::Auto); + cm::uv_pipe_ptr outputStream; + outputStream.init(chain.GetLoop(), 0); + uv_pipe_open(outputStream, chain.OutputStream()); + auto outputHandle = cmUVStreamRead( + outputStream, + [&processOutput](std::vector<char> data) { + std::string decoded; + processOutput.DecodeText(data.data(), data.size(), decoded); + std::cout << decoded << std::flush; + }, + []() {}); + + bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0)); + + bool result = false; + + if (complete) { + auto const& status = chain.GetStatus(0); + auto exception = status.GetException(); + switch (exception.first) { + case cmUVProcessChain::ExceptionCode::None: + *retVal = static_cast<int>(status.ExitStatus); + result = true; + break; + case cmUVProcessChain::ExceptionCode::Spawn: { + std::cout << "\n*** ERROR executing: " << exception.second; + } break; + default: { + *retVal = status.TermSignal; + std::cout << "\n*** Exception executing: " << exception.second; + } break; + } + } + + return result; +} + +class cmCTestBuildAndTestCaptureRAII +{ + cmake& CM; + +public: + cmCTestBuildAndTestCaptureRAII(cmake& cm) + : CM(cm) + { + cmSystemTools::SetMessageCallback( + [](const std::string& msg, const cmMessageMetadata& /* unused */) { + std::cout << msg << std::endl; + }); + + cmSystemTools::SetStdoutCallback( + [](std::string const& m) { std::cout << m << std::flush; }); + cmSystemTools::SetStderrCallback( + [](std::string const& m) { std::cout << m << std::flush; }); + + this->CM.SetProgressCallback([](const std::string& msg, float prog) { + if (prog < 0) { + std::cout << msg << std::endl; + } + }); + } + + ~cmCTestBuildAndTestCaptureRAII() + { + this->CM.SetProgressCallback(nullptr); + cmSystemTools::SetStderrCallback(nullptr); + cmSystemTools::SetStdoutCallback(nullptr); + cmSystemTools::SetMessageCallback(nullptr); + } + + cmCTestBuildAndTestCaptureRAII(const cmCTestBuildAndTestCaptureRAII&) = + delete; + cmCTestBuildAndTestCaptureRAII& operator=( + const cmCTestBuildAndTestCaptureRAII&) = delete; +}; + +int cmCTestBuildAndTest::Run() +{ + // if the generator and make program are not specified then it is an error + if (this->BuildGenerator.empty()) { + std::cout << "--build-and-test requires that the generator " + "be provided using the --build-generator " + "command line option.\n"; + return 1; + } + + cmake cm(cmake::RoleProject, cmState::Project); + cm.SetHomeDirectory(""); + cm.SetHomeOutputDirectory(""); + cmCTestBuildAndTestCaptureRAII captureRAII(cm); + static_cast<void>(captureRAII); + + if (this->CTest->GetConfigType().empty() && !this->ConfigSample.empty()) { + // use the config sample to set the ConfigType + std::string fullPath; + std::string resultingConfig; + std::vector<std::string> extraPaths; + std::vector<std::string> failed; + fullPath = cmCTestTestHandler::FindExecutable( + this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed); + if (!fullPath.empty() && !resultingConfig.empty()) { + this->CTest->SetConfigType(resultingConfig); + } + std::cout << "Using config sample with results: " << fullPath << " and " + << resultingConfig << std::endl; + } + + // we need to honor the timeout specified, the timeout include cmake, build + // and test time + auto clock_start = std::chrono::steady_clock::now(); + + // make sure the binary dir is there + std::cout << "Internal cmake changing into directory: " << this->BinaryDir + << std::endl; + if (!cmSystemTools::FileIsDirectory(this->BinaryDir)) { + cmSystemTools::MakeDirectory(this->BinaryDir); + } + cmWorkingDirectory workdir(this->BinaryDir); + if (workdir.Failed()) { + std::cout << workdir.GetError() << '\n'; + return 1; + } + + if (this->BuildNoCMake) { + // Make the generator available for the Build call below. + cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator)); + if (!this->BuildGeneratorPlatform.empty()) { + cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot()); + if (!cm.GetGlobalGenerator()->SetGeneratorPlatform( + this->BuildGeneratorPlatform, &mf)) { + return 1; + } + } + + // Load the cache to make CMAKE_MAKE_PROGRAM available. + cm.LoadCache(this->BinaryDir); + } else { + // do the cmake step, no timeout here since it is not a sub process + if (!this->RunCMake(&cm)) { + return 1; + } + } + + // do the build + if (this->BuildTargets.empty()) { + this->BuildTargets.emplace_back(); + } + for (std::string const& tar : this->BuildTargets) { + cmDuration remainingTime = std::chrono::seconds(0); + if (this->Timeout > cmDuration::zero()) { + remainingTime = + this->Timeout - (std::chrono::steady_clock::now() - clock_start); + if (remainingTime <= std::chrono::seconds(0)) { + std::cout << "--build-and-test timeout exceeded. "; + return 1; + } + } + const char* config = nullptr; + if (!this->CTest->GetConfigType().empty()) { + config = this->CTest->GetConfigType().c_str(); + } + if (!config) { + config = "Debug"; + } + + cmBuildOptions buildOptions(!this->BuildNoClean, false, + PackageResolveMode::Disable); + int retVal = cm.GetGlobalGenerator()->Build( + cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, + this->BuildProject, { tar }, std::cout, this->BuildMakeProgram, config, + buildOptions, false, remainingTime, cmSystemTools::OUTPUT_PASSTHROUGH); + // if the build failed then return + if (retVal) { + return 1; + } + } + + // if no test was specified then we are done + if (this->TestCommand.empty()) { + return 0; + } + + // now run the compiled test if we can find it + // store the final location in fullPath + std::string fullPath; + std::string resultingConfig; + std::vector<std::string> extraPaths; + // if this->ExecutableDirectory is set try that as well + if (!this->ExecutableDirectory.empty()) { + std::string tempPath = + cmStrCat(this->ExecutableDirectory, '/', this->TestCommand); + extraPaths.push_back(tempPath); + } + std::vector<std::string> failed; + fullPath = cmCTestTestHandler::FindExecutable( + this->CTest, this->TestCommand, resultingConfig, extraPaths, failed); + + if (!cmSystemTools::FileExists(fullPath)) { + std::cout + << "Could not find path to executable, perhaps it was not built: " + << this->TestCommand << "\n" + << "tried to find it in these places:\n" + << fullPath << '\n'; + for (std::string const& fail : failed) { + std::cout << fail << '\n'; + } + return 1; + } + + std::vector<std::string> testCommand; + testCommand.push_back(fullPath); + for (std::string const& testCommandArg : this->TestCommandArgs) { + testCommand.push_back(testCommandArg); + } + int retval = 0; + // run the test from the this->BuildRunDir if set + if (!this->BuildRunDir.empty()) { + std::cout << "Run test in directory: " << this->BuildRunDir << '\n'; + if (!workdir.SetDirectory(this->BuildRunDir)) { + std::cout << workdir.GetError() << '\n'; + return 1; + } + } + std::cout << "Running test command: \"" << fullPath << '"'; + for (std::string const& testCommandArg : this->TestCommandArgs) { + std::cout << " \"" << testCommandArg << '"'; + } + std::cout << '\n'; + + // how much time is remaining + cmDuration remainingTime = std::chrono::seconds(0); + if (this->Timeout > cmDuration::zero()) { + remainingTime = + this->Timeout - (std::chrono::steady_clock::now() - clock_start); + if (remainingTime <= std::chrono::seconds(0)) { + std::cout << "--build-and-test timeout exceeded. "; + return 1; + } + } + + bool runTestRes = this->RunTest(testCommand, &retval, remainingTime); + + if (!runTestRes || retval != 0) { + std::cout << "\nTest command failed: " << testCommand[0] << '\n'; + retval = 1; + } + + return retval; +}
diff --git a/Source/CTest/cmCTestBuildAndTest.h b/Source/CTest/cmCTestBuildAndTest.h new file mode 100644 index 0000000..f680bc2 --- /dev/null +++ b/Source/CTest/cmCTestBuildAndTest.h
@@ -0,0 +1,56 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> +#include <vector> + +#include "cmDuration.h" + +class cmake; +class cmCTest; + +/** \class cmCTestBuildAndTest + * \brief A class that handles ctest -S invocations + * + */ +class cmCTestBuildAndTest +{ +public: + /* + * The main entry point for this class + */ + int Run(); + + cmCTestBuildAndTest(cmCTest* ctest); + +private: + cmCTest* CTest; + + bool RunCMake(cmake* cm); + bool RunTest(std::vector<std::string> const& args, int* retVal, + cmDuration timeout); + + std::string BuildGenerator; + std::string BuildGeneratorPlatform; + std::string BuildGeneratorToolset; + std::vector<std::string> BuildOptions; + bool BuildTwoConfig = false; + std::string BuildMakeProgram; + std::string ConfigSample; + std::string SourceDir; + std::string BinaryDir; + std::string BuildProject; + std::string TestCommand; + bool BuildNoClean = false; + std::string BuildRunDir; + std::string ExecutableDirectory; + std::vector<std::string> TestCommandArgs; + std::vector<std::string> BuildTargets; + bool BuildNoCMake = false; + cmDuration Timeout = cmDuration::zero(); + + friend class cmCTest; +};
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx deleted file mode 100644 index 9faabf7..0000000 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ /dev/null
@@ -1,453 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCTestBuildAndTestHandler.h" - -#include <chrono> -#include <cstdlib> -#include <cstring> -#include <ratio> - -#include "cmBuildOptions.h" -#include "cmCTest.h" -#include "cmCTestTestHandler.h" -#include "cmGlobalGenerator.h" -#include "cmMakefile.h" -#include "cmState.h" -#include "cmStringAlgorithms.h" -#include "cmSystemTools.h" -#include "cmWorkingDirectory.h" -#include "cmake.h" - -struct cmMessageMetadata; - -cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() -{ - this->BuildTwoConfig = false; - this->BuildNoClean = false; - this->BuildNoCMake = false; - this->Timeout = cmDuration::zero(); -} - -void cmCTestBuildAndTestHandler::Initialize() -{ - this->BuildTargets.clear(); - this->Superclass::Initialize(); -} - -const char* cmCTestBuildAndTestHandler::GetOutput() -{ - return this->Output.c_str(); -} -int cmCTestBuildAndTestHandler::ProcessHandler() -{ - this->Output.clear(); - std::string output; - cmSystemTools::ResetErrorOccurredFlag(); - int retv = this->RunCMakeAndTest(&this->Output); - cmSystemTools::ResetErrorOccurredFlag(); - return retv; -} - -int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, - std::ostringstream& out, - std::string& cmakeOutString, - cmake* cm) -{ - std::vector<std::string> args; - args.push_back(cmSystemTools::GetCMakeCommand()); - args.push_back(this->SourceDir); - if (!this->BuildGenerator.empty()) { - args.push_back("-G" + this->BuildGenerator); - } - if (!this->BuildGeneratorPlatform.empty()) { - args.push_back("-A" + this->BuildGeneratorPlatform); - } - if (!this->BuildGeneratorToolset.empty()) { - args.push_back("-T" + this->BuildGeneratorToolset); - } - - const char* config = nullptr; - if (!this->CTest->GetConfigType().empty()) { - config = this->CTest->GetConfigType().c_str(); - } - - if (config) { - args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config)); - } - if (!this->BuildMakeProgram.empty() && - (this->BuildGenerator.find("Make") != std::string::npos || - this->BuildGenerator.find("Ninja") != std::string::npos)) { - args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram); - } - - for (std::string const& opt : this->BuildOptions) { - args.push_back(opt); - } - if (cm->Run(args) != 0) { - out << "Error: cmake execution failed\n"; - out << cmakeOutString << "\n"; - if (outstring) { - *outstring = out.str(); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl); - } - return 1; - } - // do another config? - if (this->BuildTwoConfig) { - if (cm->Run(args) != 0) { - out << "Error: cmake execution failed\n"; - out << cmakeOutString << "\n"; - if (outstring) { - *outstring = out.str(); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl); - } - return 1; - } - } - out << "======== CMake output ======\n"; - out << cmakeOutString; - out << "======== End CMake output ======\n"; - return 0; -} - -class cmCTestBuildAndTestCaptureRAII -{ - cmake& CM; - -public: - cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s) - : CM(cm) - { - cmSystemTools::SetMessageCallback( - [&s](const std::string& msg, const cmMessageMetadata& /* unused */) { - s += msg; - s += "\n"; - }); - - cmSystemTools::SetStdoutCallback([&s](std::string const& m) { s += m; }); - cmSystemTools::SetStderrCallback([&s](std::string const& m) { s += m; }); - - this->CM.SetProgressCallback([&s](const std::string& msg, float prog) { - if (prog < 0) { - s += msg; - s += "\n"; - } - }); - } - - ~cmCTestBuildAndTestCaptureRAII() - { - this->CM.SetProgressCallback(nullptr); - cmSystemTools::SetStderrCallback(nullptr); - cmSystemTools::SetStdoutCallback(nullptr); - cmSystemTools::SetMessageCallback(nullptr); - } - - cmCTestBuildAndTestCaptureRAII(const cmCTestBuildAndTestCaptureRAII&) = - delete; - cmCTestBuildAndTestCaptureRAII& operator=( - const cmCTestBuildAndTestCaptureRAII&) = delete; -}; - -int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) -{ - // if the generator and make program are not specified then it is an error - if (this->BuildGenerator.empty()) { - if (outstring) { - *outstring = "--build-and-test requires that the generator " - "be provided using the --build-generator " - "command line option.\n"; - } - return 1; - } - - cmake cm(cmake::RoleProject, cmState::Project); - cm.SetHomeDirectory(""); - cm.SetHomeOutputDirectory(""); - std::string cmakeOutString; - cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString); - static_cast<void>(captureRAII); - std::ostringstream out; - - if (this->CTest->GetConfigType().empty() && !this->ConfigSample.empty()) { - // use the config sample to set the ConfigType - std::string fullPath; - std::string resultingConfig; - std::vector<std::string> extraPaths; - std::vector<std::string> failed; - fullPath = cmCTestTestHandler::FindExecutable( - this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed); - if (!fullPath.empty() && !resultingConfig.empty()) { - this->CTest->SetConfigType(resultingConfig); - } - out << "Using config sample with results: " << fullPath << " and " - << resultingConfig << std::endl; - } - - // we need to honor the timeout specified, the timeout include cmake, build - // and test time - auto clock_start = std::chrono::steady_clock::now(); - - // make sure the binary dir is there - out << "Internal cmake changing into directory: " << this->BinaryDir - << std::endl; - if (!cmSystemTools::FileIsDirectory(this->BinaryDir)) { - cmSystemTools::MakeDirectory(this->BinaryDir); - } - cmWorkingDirectory workdir(this->BinaryDir); - if (workdir.Failed()) { - auto msg = "Failed to change working directory to " + this->BinaryDir + - " : " + std::strerror(workdir.GetLastResult()) + "\n"; - if (outstring) { - *outstring = msg; - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, msg); - } - return 1; - } - - if (this->BuildNoCMake) { - // Make the generator available for the Build call below. - cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator)); - if (!this->BuildGeneratorPlatform.empty()) { - cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot()); - if (!cm.GetGlobalGenerator()->SetGeneratorPlatform( - this->BuildGeneratorPlatform, &mf)) { - return 1; - } - } - - // Load the cache to make CMAKE_MAKE_PROGRAM available. - cm.LoadCache(this->BinaryDir); - } else { - // do the cmake step, no timeout here since it is not a sub process - if (this->RunCMake(outstring, out, cmakeOutString, &cm)) { - return 1; - } - } - - // do the build - if (this->BuildTargets.empty()) { - this->BuildTargets.emplace_back(); - } - for (std::string const& tar : this->BuildTargets) { - cmDuration remainingTime = std::chrono::seconds(0); - if (this->Timeout > cmDuration::zero()) { - remainingTime = - this->Timeout - (std::chrono::steady_clock::now() - clock_start); - if (remainingTime <= std::chrono::seconds(0)) { - if (outstring) { - *outstring = "--build-and-test timeout exceeded. "; - } - return 1; - } - } - const char* config = nullptr; - if (!this->CTest->GetConfigType().empty()) { - config = this->CTest->GetConfigType().c_str(); - } - if (!config) { - config = "Debug"; - } - - cmBuildOptions buildOptions(!this->BuildNoClean, false, - PackageResolveMode::Disable); - int retVal = cm.GetGlobalGenerator()->Build( - cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, - this->BuildProject, { tar }, out, this->BuildMakeProgram, config, - buildOptions, false, remainingTime); - // if the build failed then return - if (retVal) { - if (outstring) { - *outstring = out.str(); - } - return 1; - } - } - if (outstring) { - *outstring = out.str(); - } - - // if no test was specified then we are done - if (this->TestCommand.empty()) { - return 0; - } - - // now run the compiled test if we can find it - // store the final location in fullPath - std::string fullPath; - std::string resultingConfig; - std::vector<std::string> extraPaths; - // if this->ExecutableDirectory is set try that as well - if (!this->ExecutableDirectory.empty()) { - std::string tempPath = - cmStrCat(this->ExecutableDirectory, '/', this->TestCommand); - extraPaths.push_back(tempPath); - } - std::vector<std::string> failed; - fullPath = cmCTestTestHandler::FindExecutable( - this->CTest, this->TestCommand, resultingConfig, extraPaths, failed); - - if (!cmSystemTools::FileExists(fullPath)) { - out << "Could not find path to executable, perhaps it was not built: " - << this->TestCommand << "\n"; - out << "tried to find it in these places:\n"; - out << fullPath << "\n"; - for (std::string const& fail : failed) { - out << fail << "\n"; - } - if (outstring) { - *outstring = out.str(); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, out.str()); - } - return 1; - } - - std::vector<std::string> testCommand; - testCommand.push_back(fullPath); - for (std::string const& testCommandArg : this->TestCommandArgs) { - testCommand.push_back(testCommandArg); - } - std::string outs; - int retval = 0; - // run the test from the this->BuildRunDir if set - if (!this->BuildRunDir.empty()) { - out << "Run test in directory: " << this->BuildRunDir << "\n"; - if (!workdir.SetDirectory(this->BuildRunDir)) { - out << "Failed to change working directory : " - << std::strerror(workdir.GetLastResult()) << "\n"; - if (outstring) { - *outstring = out.str(); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, out.str()); - } - return 1; - } - } - out << "Running test command: \"" << fullPath << "\""; - for (std::string const& testCommandArg : this->TestCommandArgs) { - out << " \"" << testCommandArg << "\""; - } - out << "\n"; - - // how much time is remaining - cmDuration remainingTime = std::chrono::seconds(0); - if (this->Timeout > cmDuration::zero()) { - remainingTime = - this->Timeout - (std::chrono::steady_clock::now() - clock_start); - if (remainingTime <= std::chrono::seconds(0)) { - if (outstring) { - *outstring = "--build-and-test timeout exceeded. "; - } - return 1; - } - } - - bool runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, nullptr, - remainingTime, nullptr); - - if (!runTestRes || retval != 0) { - out << "Test command failed: " << testCommand[0] << "\n"; - retval = 1; - } - - out << outs << "\n"; - if (outstring) { - *outstring = out.str(); - } else { - cmCTestLog(this->CTest, OUTPUT, out.str() << std::endl); - } - return retval; -} - -int cmCTestBuildAndTestHandler::ProcessCommandLineArguments( - const std::string& currentArg, size_t& idx, - const std::vector<std::string>& allArgs, bool& validArg) -{ - bool buildAndTestArg = true; - // --build-and-test options - if (cmHasLiteralPrefix(currentArg, "--build-and-test") && - idx < allArgs.size() - 1) { - if (idx + 2 < allArgs.size()) { - idx++; - this->SourceDir = allArgs[idx]; - idx++; - this->BinaryDir = allArgs[idx]; - // dir must exist before CollapseFullPath is called - cmSystemTools::MakeDirectory(this->BinaryDir); - this->BinaryDir = cmSystemTools::CollapseFullPath(this->BinaryDir); - this->SourceDir = cmSystemTools::CollapseFullPath(this->SourceDir); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "--build-and-test must have source and binary dir" - << std::endl); - return 0; - } - } else if (cmHasLiteralPrefix(currentArg, "--build-target") && - idx < allArgs.size() - 1) { - idx++; - this->BuildTargets.push_back(allArgs[idx]); - } else if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) { - this->BuildNoCMake = true; - } else if (cmHasLiteralPrefix(currentArg, "--build-run-dir") && - idx < allArgs.size() - 1) { - idx++; - this->BuildRunDir = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--build-two-config")) { - this->BuildTwoConfig = true; - } else if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") && - idx < allArgs.size() - 1) { - idx++; - this->ExecutableDirectory = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--test-timeout") && - idx < allArgs.size() - 1) { - idx++; - this->Timeout = cmDuration(atof(allArgs[idx].c_str())); - } else if (currentArg == "--build-generator" && idx < allArgs.size() - 1) { - idx++; - this->BuildGenerator = allArgs[idx]; - } else if (currentArg == "--build-generator-platform" && - idx < allArgs.size() - 1) { - idx++; - this->BuildGeneratorPlatform = allArgs[idx]; - } else if (currentArg == "--build-generator-toolset" && - idx < allArgs.size() - 1) { - idx++; - this->BuildGeneratorToolset = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--build-project") && - idx < allArgs.size() - 1) { - idx++; - this->BuildProject = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") && - idx < allArgs.size() - 1) { - idx++; - this->BuildMakeProgram = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--build-config-sample") && - idx < allArgs.size() - 1) { - idx++; - this->ConfigSample = allArgs[idx]; - } else if (cmHasLiteralPrefix(currentArg, "--build-noclean")) { - this->BuildNoClean = true; - } else if (cmHasLiteralPrefix(currentArg, "--build-options")) { - while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" && - allArgs[idx + 1] != "--test-command") { - ++idx; - this->BuildOptions.push_back(allArgs[idx]); - } - } else if (cmHasLiteralPrefix(currentArg, "--test-command") && - idx < allArgs.size() - 1) { - ++idx; - this->TestCommand = allArgs[idx]; - while (idx + 1 < allArgs.size()) { - ++idx; - this->TestCommandArgs.push_back(allArgs[idx]); - } - } else { - buildAndTestArg = false; - } - validArg = validArg || buildAndTestArg; - return 1; -}
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h deleted file mode 100644 index 60b3a11..0000000 --- a/Source/CTest/cmCTestBuildAndTestHandler.h +++ /dev/null
@@ -1,71 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#pragma once - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <cstddef> -#include <sstream> -#include <string> -#include <vector> - -#include "cmCTestGenericHandler.h" -#include "cmDuration.h" - -class cmake; - -/** \class cmCTestBuildAndTestHandler - * \brief A class that handles ctest -S invocations - * - */ -class cmCTestBuildAndTestHandler : public cmCTestGenericHandler -{ -public: - using Superclass = cmCTestGenericHandler; - - /* - * The main entry point for this class - */ - int ProcessHandler() override; - - //! Set all the build and test arguments - int ProcessCommandLineArguments(const std::string& currentArg, size_t& idx, - const std::vector<std::string>& allArgs, - bool& validArg) override; - - /* - * Get the output variable - */ - const char* GetOutput(); - - cmCTestBuildAndTestHandler(); - - void Initialize() override; - -protected: - //! Run CMake and build a test and then run it as a single test. - int RunCMakeAndTest(std::string* output); - int RunCMake(std::string* outstring, std::ostringstream& out, - std::string& cmakeOutString, cmake* cm); - - std::string Output; - - std::string BuildGenerator; - std::string BuildGeneratorPlatform; - std::string BuildGeneratorToolset; - std::vector<std::string> BuildOptions; - bool BuildTwoConfig; - std::string BuildMakeProgram; - std::string ConfigSample; - std::string SourceDir; - std::string BinaryDir; - std::string BuildProject; - std::string TestCommand; - bool BuildNoClean; - std::string BuildRunDir; - std::string ExecutableDirectory; - std::vector<std::string> TestCommandArgs; - std::vector<std::string> BuildTargets; - bool BuildNoCMake; - cmDuration Timeout; -};
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index d8ef195..410a35e 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -24,7 +24,6 @@ { auto ni = cm::make_unique<cmCTestBuildCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index e962cc7..a665993 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -580,9 +580,6 @@ int numErrorsAllowed = this->MaxErrors; int numWarningsAllowed = this->MaxWarnings; std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory"); - // make sure the source dir is in the correct case on windows - // via a call to collapse full path. - srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/'); for (it = ew.begin(); it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) { cmCTestBuildErrorWarning* cm = &(*it); @@ -613,8 +610,9 @@ } } else { // make sure it is a full path with the correct case - cm->SourceFile = cmSystemTools::CollapseFullPath(cm->SourceFile); - cmSystemTools::ReplaceString(cm->SourceFile, srcdir.c_str(), ""); + cm->SourceFile = + cmSystemTools::ToNormalizedPathOnDisk(cm->SourceFile); + cmSystemTools::ReplaceString(cm->SourceFile, srcdir, ""); } cm->LineNumber = atoi(re->match(rit.LineIndex).c_str()); break;
diff --git a/Source/CTest/cmCTestCommand.h b/Source/CTest/cmCTestCommand.h index 007378d..ccdef7c 100644 --- a/Source/CTest/cmCTestCommand.h +++ b/Source/CTest/cmCTestCommand.h
@@ -5,7 +5,6 @@ #include "cmCommand.h" class cmCTest; -class cmCTestScriptHandler; /** \class cmCTestCommand * \brief A superclass for all commands added to the CTestScriptHandler @@ -17,12 +16,5 @@ class cmCTestCommand : public cmCommand { public: - cmCTestCommand() - { - this->CTest = nullptr; - this->CTestScriptHandler = nullptr; - } - - cmCTest* CTest; - cmCTestScriptHandler* CTestScriptHandler; + cmCTest* CTest = nullptr; };
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index f338637..59699df 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -29,7 +29,6 @@ { auto ni = cm::make_unique<cmCTestConfigureCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h index 55c68b2..6eb5868 100644 --- a/Source/CTest/cmCTestCoverageCommand.h +++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -32,7 +32,6 @@ { auto ni = cm::make_unique<cmCTestCoverageCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index cec4a7e..edc9280 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -6,7 +6,6 @@ #include <chrono> #include <cstdio> #include <cstdlib> -#include <cstring> #include <iomanip> #include <iterator> #include <memory> @@ -1325,10 +1324,7 @@ std::string fileDir = cmSystemTools::GetFilenamePath(f); cmWorkingDirectory workdir(fileDir); if (workdir.Failed()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Unable to change working directory to " - << fileDir << " : " - << std::strerror(workdir.GetLastResult()) << std::endl); + cmCTestLog(this->CTest, ERROR_MESSAGE, workdir.GetError() << std::endl); cont->Error++; continue; } @@ -1550,9 +1546,7 @@ std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory"); cmWorkingDirectory workdir(buildDir); if (workdir.Failed()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Unable to change working directory to " << buildDir - << std::endl); + cmCTestLog(this->CTest, ERROR_MESSAGE, workdir.GetError() << std::endl); return false; }
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx index 2c92d77..5ae89a1 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -2,22 +2,98 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestEmptyBinaryDirectoryCommand.h" -#include "cmCTestScriptHandler.h" +#include "cmsys/Directory.hxx" + #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStringAlgorithms.h" +#include "cmSystemTools.h" -bool cmCTestEmptyBinaryDirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus& status) +namespace { + +// Try to remove the binary directory once +cmsys::Status TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath) +{ + cmsys::Directory directory; + directory.Load(directoryPath); + + // Make sure that CMakeCache.txt is deleted last. + for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) { + std::string path = directory.GetFile(i); + + if (path == "." || path == ".." || path == "CMakeCache.txt") { + continue; + } + + std::string fullPath = cmStrCat(directoryPath, "/", path); + + bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && + !cmSystemTools::FileIsSymlink(fullPath); + + cmsys::Status status; + if (isDirectory) { + status = cmSystemTools::RemoveADirectory(fullPath); + } else { + status = cmSystemTools::RemoveFile(fullPath); + } + if (!status) { + return status; + } + } + + return cmSystemTools::RemoveADirectory(directoryPath); +} + +/* + * Empty Binary Directory + */ +bool EmptyBinaryDirectory(const std::string& sname, std::string& err) +{ + // try to avoid deleting root + if (sname.size() < 2) { + err = "path too short"; + return false; + } + + // consider non existing target directory a success + if (!cmSystemTools::FileExists(sname)) { + return true; + } + + // try to avoid deleting directories that we shouldn't + std::string check = cmStrCat(sname, "/CMakeCache.txt"); + + if (!cmSystemTools::FileExists(check)) { + err = "path does not contain an existing CMakeCache.txt file"; + return false; + } + + cmsys::Status status; + for (int i = 0; i < 5; ++i) { + status = TryToRemoveBinaryDirectoryOnce(sname); + if (status) { + return true; + } + cmSystemTools::Delay(100); + } + + err = status.GetString(); + return false; +} + +} // namespace + +bool cmCTestEmptyBinaryDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 1) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } std::string err; - if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0], err)) { + if (!EmptyBinaryDirectory(args[0], err)) { status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Did not remove the binary directory:\n ", args[0],
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index ba2b0eb..d19ae98 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -5,42 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> -#include <utility> #include <vector> -#include <cm/memory> - -#include "cmCTestCommand.h" -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCTestEmptyBinaryDirectory - * \brief Run a ctest script - * - * cmLibrarysCommand defines a list of executable (i.e., test) - * programs to create. - */ -class cmCTestEmptyBinaryDirectoryCommand : public cmCTestCommand -{ -public: - cmCTestEmptyBinaryDirectoryCommand() {} - - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>(); - ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; - return std::unique_ptr<cmCommand>(std::move(ni)); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmCTestEmptyBinaryDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status);
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 99c5a2b..3a5ec04 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx
@@ -146,7 +146,7 @@ !cdup.empty()) { top_dir += "/"; top_dir += cdup; - top_dir = cmSystemTools::CollapseFullPath(top_dir); + top_dir = cmSystemTools::ToNormalizedPathOnDisk(top_dir); } return top_dir; }
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index a189d60..39fa6eb 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h
@@ -4,7 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cstddef> #include <map> #include <string> #include <vector> @@ -44,16 +43,6 @@ virtual int ProcessHandler() = 0; /** - * Process command line arguments that are applicable for the handler - */ - virtual int ProcessCommandLineArguments( - const std::string& /*currentArg*/, size_t& /*idx*/, - const std::vector<std::string>& /*allArgs*/, bool& /*valid*/) - { - return 1; - } - - /** * Initialize handler */ virtual void Initialize();
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index c377d68..753ec0f 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -4,7 +4,6 @@ #include <algorithm> #include <cstdlib> -#include <cstring> #include <sstream> #include <cm/string_view> @@ -190,9 +189,7 @@ cmWorkingDirectory workdir( this->CTest->GetCTestConfiguration("BuildDirectory")); if (workdir.Failed()) { - this->SetError("failed to change directory to " + - this->CTest->GetCTestConfiguration("BuildDirectory") + - " : " + std::strerror(workdir.GetLastResult())); + this->SetError(workdir.GetError()); if (captureCMakeError) { this->Makefile->AddDefinition(this->CaptureCMakeError, "-1"); cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index ee39e49..fcb4836 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -30,7 +30,6 @@ { auto ni = cm::make_unique<cmCTestMemCheckCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 84ea32b..ac74697 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -8,7 +8,6 @@ #include <cmath> #include <cstddef> // IWYU pragma: keep #include <cstdlib> -#include <cstring> #include <iomanip> #include <iostream> #include <list> @@ -279,9 +278,7 @@ cmWorkingDirectory workdir(this->Properties[test]->Directory); if (workdir.Failed()) { cmCTestRunTest::StartFailure(std::move(testRun), this->Total, - "Failed to change working directory to " + - this->Properties[test]->Directory + " : " + - std::strerror(workdir.GetLastResult()), + workdir.GetError(), "Failed to change working directory"); return; } @@ -501,7 +498,7 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test) { - size_t processors = static_cast<int>(this->Properties[test]->Processors); + size_t processors = this->Properties[test]->Processors; size_t const parallelLevel = this->GetParallelLevel(); // If processors setting is set higher than the -j // setting, we default to using all of the process slots.
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index 7661d4d..38953ea 100644 --- a/Source/CTest/cmCTestRunScriptCommand.cxx +++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -3,16 +3,16 @@ #include "cmCTestRunScriptCommand.h" #include "cmCTestScriptHandler.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" - -class cmExecutionStatus; +#include "cmSystemTools.h" bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) + cmExecutionStatus& status) { if (args.empty()) { - this->CTestScriptHandler->RunCurrentScript(); - return true; + status.SetError("called with incorrect number of arguments"); + return false; } bool np = false; @@ -37,7 +37,8 @@ ++i; } else { int ret; - cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i], + cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, + cmSystemTools::CollapseFullPath(args[i]), !np, &ret); this->Makefile->AddDefinition(returnVariable, std::to_string(ret)); }
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 510b748..c7b1c5a 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -33,7 +33,6 @@ { auto ni = cm::make_unique<cmCTestRunScriptCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 483b3b4..326846e 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx
@@ -7,7 +7,6 @@ #include <cstddef> // IWYU pragma: keep #include <cstdint> #include <cstdio> -#include <cstring> #include <iomanip> #include <ratio> #include <sstream> @@ -398,10 +397,7 @@ // change to tests directory cmWorkingDirectory workdir(testRun->TestProperties->Directory); if (workdir.Failed()) { - testRun->StartFailure(testRun->TotalNumberOfTests, - "Failed to change working directory to " + - testRun->TestProperties->Directory + " : " + - std::strerror(workdir.GetLastResult()), + testRun->StartFailure(testRun->TotalNumberOfTests, workdir.GetError(), "Failed to change working directory"); return true; }
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index ed567d4..be298fa 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestScriptHandler.h" -#include <cstdio> #include <cstdlib> #include <map> #include <ratio> @@ -13,8 +12,6 @@ #include <cm3p/uv.h> -#include "cmsys/Directory.hxx" - #include "cmCTest.h" #include "cmCTestBuildCommand.h" #include "cmCTestCommand.h" @@ -32,51 +29,22 @@ #include "cmCTestUploadCommand.h" #include "cmCommand.h" #include "cmDuration.h" -#include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" -#include "cmList.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" -#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUVHandlePtr.h" #include "cmUVProcessChain.h" #include "cmValue.h" #include "cmake.h" -#ifdef _WIN32 -# include <windows.h> -#else -# include <unistd.h> -#endif - cmCTestScriptHandler::cmCTestScriptHandler() = default; void cmCTestScriptHandler::Initialize() { this->Superclass::Initialize(); - this->Backup = false; - this->EmptyBinDir = false; - this->EmptyBinDirOnce = false; - - this->SourceDir.clear(); - this->BinaryDir.clear(); - this->BackupSourceDir.clear(); - this->BackupBinaryDir.clear(); - this->CTestRoot.clear(); - this->CVSCheckOut.clear(); - this->CTestCmd.clear(); - this->UpdateCmd.clear(); - this->CTestEnv.clear(); - this->InitialCache.clear(); - this->CMakeCmd.clear(); - this->CMOutFile.clear(); - this->ExtraUpdates.clear(); - - this->MinimumInterval = 20 * 60; - this->ContinuousDuration = -1; // what time in seconds did this script start running this->ScriptStartTime = std::chrono::steady_clock::time_point(); @@ -106,9 +74,8 @@ int res = 0; for (size_t i = 0; i < this->ConfigurationScripts.size(); ++i) { // for each script run it - res |= this->RunConfigurationScript( - cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i]), - this->ScriptProcessScope[i]); + res |= this->RunConfigurationScript(this->ConfigurationScripts[i], + this->ScriptProcessScope[i]); } if (res) { return -1; @@ -131,7 +98,6 @@ std::string const& name, std::unique_ptr<cmCTestCommand> command) { command->CTest = this->CTest; - command->CTestScriptHandler = this; this->CMake->GetState()->AddBuiltinCommand(name, std::move(command)); } @@ -252,20 +218,21 @@ } }); + cmState* state = this->CMake->GetState(); this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>()); this->AddCTestCommand("ctest_configure", cm::make_unique<cmCTestConfigureCommand>()); this->AddCTestCommand("ctest_coverage", cm::make_unique<cmCTestCoverageCommand>()); - this->AddCTestCommand("ctest_empty_binary_directory", - cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>()); + state->AddBuiltinCommand("ctest_empty_binary_directory", + cmCTestEmptyBinaryDirectoryCommand); this->AddCTestCommand("ctest_memcheck", cm::make_unique<cmCTestMemCheckCommand>()); this->AddCTestCommand("ctest_read_custom_files", cm::make_unique<cmCTestReadCustomFilesCommand>()); this->AddCTestCommand("ctest_run_script", cm::make_unique<cmCTestRunScriptCommand>()); - this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>()); + state->AddBuiltinCommand("ctest_sleep", cmCTestSleepCommand); this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>()); this->AddCTestCommand("ctest_submit", cm::make_unique<cmCTestSubmitCommand>()); @@ -314,8 +281,6 @@ cmSystemTools::GetCTestCommand()); this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME", cmSystemTools::GetCMakeCommand()); - this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true); - this->SetRunCurrentScript(true); this->UpdateElapsedTime(); // set the CTEST_CONFIGURATION_TYPE variable to the current value of the @@ -366,113 +331,6 @@ return 0; } -// extract variables from the script to set ivars -int cmCTestScriptHandler::ExtractVariables() -{ - // Temporary variables - cmValue minInterval; - cmValue contDuration; - - this->SourceDir = - this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"); - this->BinaryDir = - this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY"); - - // add in translations for src and bin - cmSystemTools::AddKeepPath(this->SourceDir); - cmSystemTools::AddKeepPath(this->BinaryDir); - - this->CTestCmd = this->Makefile->GetSafeDefinition("CTEST_COMMAND"); - this->CVSCheckOut = this->Makefile->GetSafeDefinition("CTEST_CVS_CHECKOUT"); - this->CTestRoot = this->Makefile->GetSafeDefinition("CTEST_DASHBOARD_ROOT"); - this->UpdateCmd = this->Makefile->GetSafeDefinition("CTEST_UPDATE_COMMAND"); - if (this->UpdateCmd.empty()) { - this->UpdateCmd = this->Makefile->GetSafeDefinition("CTEST_CVS_COMMAND"); - } - this->CTestEnv = this->Makefile->GetSafeDefinition("CTEST_ENVIRONMENT"); - this->InitialCache = - this->Makefile->GetSafeDefinition("CTEST_INITIAL_CACHE"); - this->CMakeCmd = this->Makefile->GetSafeDefinition("CTEST_CMAKE_COMMAND"); - this->CMOutFile = - this->Makefile->GetSafeDefinition("CTEST_CMAKE_OUTPUT_FILE_NAME"); - - this->Backup = this->Makefile->IsOn("CTEST_BACKUP_AND_RESTORE"); - this->EmptyBinDir = - this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY"); - this->EmptyBinDirOnce = - this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE"); - - minInterval = - this->Makefile->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL"); - contDuration = this->Makefile->GetDefinition("CTEST_CONTINUOUS_DURATION"); - - char updateVar[40]; - int i; - for (i = 1; i < 10; ++i) { - snprintf(updateVar, sizeof(updateVar), "CTEST_EXTRA_UPDATES_%i", i); - cmValue updateVal = this->Makefile->GetDefinition(updateVar); - if (updateVal) { - if (this->UpdateCmd.empty()) { - cmSystemTools::Error( - std::string(updateVar) + - " specified without specifying CTEST_CVS_COMMAND."); - return 12; - } - this->ExtraUpdates.emplace_back(*updateVal); - } - } - - // in order to backup and restore we also must have the cvs root - if (this->Backup && this->CVSCheckOut.empty()) { - cmSystemTools::Error( - "Backup was requested without specifying CTEST_CVS_CHECKOUT."); - return 3; - } - - // make sure the required info is here - if (this->SourceDir.empty() || this->BinaryDir.empty() || - this->CTestCmd.empty()) { - std::string msg = - cmStrCat("CTEST_SOURCE_DIRECTORY = ", - (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)", - "\nCTEST_BINARY_DIRECTORY = ", - (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)", - "\nCTEST_COMMAND = ", - (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)"); - cmSystemTools::Error( - "Some required settings in the configuration file were missing:\n" + - msg); - return 4; - } - - // if the dashboard root isn't specified then we can compute it from the - // this->SourceDir - if (this->CTestRoot.empty()) { - this->CTestRoot = cmSystemTools::GetFilenamePath(this->SourceDir); - } - - // the script may override the minimum continuous interval - if (minInterval) { - this->MinimumInterval = 60 * atof(minInterval->c_str()); - } - if (contDuration) { - this->ContinuousDuration = 60.0 * atof(contDuration->c_str()); - } - - this->UpdateElapsedTime(); - - return 0; -} - -void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait) -{ -#if defined(_WIN32) - Sleep(1000 * secondsToWait); -#else - sleep(secondsToWait); -#endif -} - // run a specific script int cmCTestScriptHandler::RunConfigurationScript( const std::string& total_script_arg, bool pscope) @@ -495,355 +353,10 @@ "Executing Script: " << total_script_arg << std::endl); result = this->ExecuteScript(total_script_arg); } - if (result) { - return result; - } - - // only run the current script if we should - if (this->Makefile && this->Makefile->IsOn("CTEST_RUN_CURRENT_SCRIPT") && - this->ShouldRunCurrentScript) { - return this->RunCurrentScript(); - } - return result; -} - -int cmCTestScriptHandler::RunCurrentScript() -{ - int result; - - // do not run twice - this->SetRunCurrentScript(false); - - // no popup widows - cmSystemTools::SetRunCommandHideConsole(true); - - // extract the vars from the cache and store in ivars - result = this->ExtractVariables(); - if (result) { - return result; - } - - // set any environment variables - if (!this->CTestEnv.empty()) { - cmList envArgs{ this->CTestEnv }; - cmSystemTools::AppendEnv(envArgs); - } - - // now that we have done most of the error checking finally run the - // dashboard, we may be asked to repeatedly run this dashboard, such as - // for a continuous, do we need to run it more than once? - if (this->ContinuousDuration >= 0) { - this->UpdateElapsedTime(); - auto ending_time = - std::chrono::steady_clock::now() + cmDuration(this->ContinuousDuration); - if (this->EmptyBinDirOnce) { - this->EmptyBinDir = true; - } - do { - auto startOfInterval = std::chrono::steady_clock::now(); - result = this->RunConfigurationDashboard(); - auto interval = std::chrono::steady_clock::now() - startOfInterval; - auto minimumInterval = cmDuration(this->MinimumInterval); - if (interval < minimumInterval) { - auto sleepTime = - cmDurationTo<unsigned int>(minimumInterval - interval); - this->SleepInSeconds(sleepTime); - } - if (this->EmptyBinDirOnce) { - this->EmptyBinDir = false; - } - } while (std::chrono::steady_clock::now() < ending_time); - } - // otherwise just run it once - else { - result = this->RunConfigurationDashboard(); - } return result; } -int cmCTestScriptHandler::CheckOutSourceDir() -{ - std::string output; - int retVal; - - if (!cmSystemTools::FileExists(this->SourceDir) && - !this->CVSCheckOut.empty()) { - // we must now checkout the src dir - output.clear(); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run cvs: " << this->CVSCheckOut << std::endl); - bool res = cmSystemTools::RunSingleCommand( - this->CVSCheckOut, &output, &output, &retVal, this->CTestRoot.c_str(), - this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); - if (!res || retVal != 0) { - cmSystemTools::Error("Unable to perform cvs checkout:\n" + output); - return 6; - } - } - return 0; -} - -int cmCTestScriptHandler::BackupDirectories() -{ - // compute the backup names - this->BackupSourceDir = cmStrCat(this->SourceDir, "_CMakeBackup"); - this->BackupBinaryDir = cmStrCat(this->BinaryDir, "_CMakeBackup"); - - // backup the binary and src directories if requested - if (this->Backup) { - // if for some reason those directories exist then first delete them - if (cmSystemTools::FileExists(this->BackupSourceDir)) { - cmSystemTools::RemoveADirectory(this->BackupSourceDir); - } - if (cmSystemTools::FileExists(this->BackupBinaryDir)) { - cmSystemTools::RemoveADirectory(this->BackupBinaryDir); - } - - // first rename the src and binary directories - rename(this->SourceDir.c_str(), this->BackupSourceDir.c_str()); - rename(this->BinaryDir.c_str(), this->BackupBinaryDir.c_str()); - - // we must now checkout the src dir - int retVal = this->CheckOutSourceDir(); - if (retVal) { - this->RestoreBackupDirectories(); - return retVal; - } - } - - return 0; -} - -int cmCTestScriptHandler::PerformExtraUpdates() -{ - std::string command; - std::string output; - int retVal; - bool res; - - // do an initial cvs update as required - command = this->UpdateCmd; - for (std::string const& eu : this->ExtraUpdates) { - cmList cvsArgs{ eu }; - if (cvsArgs.size() == 2) { - std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]); - output.clear(); - retVal = 0; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run Update: " << fullCommand << std::endl); - res = cmSystemTools::RunSingleCommand( - fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(), - this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); - if (!res || retVal != 0) { - cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu, - "\nWith output:\n", output)); - return 0; - } - } - } - return 0; -} - -// run a single dashboard entry -int cmCTestScriptHandler::RunConfigurationDashboard() -{ - // local variables - std::string command; - std::string output; - int retVal; - bool res; - - // make sure the src directory is there, if it isn't then we might be able - // to check it out from cvs - retVal = this->CheckOutSourceDir(); - if (retVal) { - return retVal; - } - - // backup the dirs if requested - retVal = this->BackupDirectories(); - if (retVal) { - return retVal; - } - - // clear the binary directory? - if (this->EmptyBinDir) { - std::string err; - if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir, err)) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Problem removing the binary directory (" - << err << "): " << this->BinaryDir << std::endl); - } - } - - // make sure the binary directory exists if it isn't the srcdir - if (!cmSystemTools::FileExists(this->BinaryDir) && - this->SourceDir != this->BinaryDir) { - if (!cmSystemTools::MakeDirectory(this->BinaryDir)) { - cmSystemTools::Error("Unable to create the binary directory:\n" + - this->BinaryDir); - this->RestoreBackupDirectories(); - return 7; - } - } - - // if the binary directory and the source directory are the same, - // and we are starting with an empty binary directory, then that means - // we must check out the source tree - if (this->EmptyBinDir && this->SourceDir == this->BinaryDir) { - // make sure we have the required info - if (this->CVSCheckOut.empty()) { - cmSystemTools::Error( - "You have specified the source and binary " - "directories to be the same (an in source build). You have also " - "specified that the binary directory is to be erased. This means " - "that the source will have to be checked out from CVS. But you have " - "not specified CTEST_CVS_CHECKOUT"); - return 8; - } - - // we must now checkout the src dir - retVal = this->CheckOutSourceDir(); - if (retVal) { - this->RestoreBackupDirectories(); - return retVal; - } - } - - // backup the dirs if requested - retVal = this->PerformExtraUpdates(); - if (retVal) { - return retVal; - } - - // put the initial cache into the bin dir - if (!this->InitialCache.empty()) { - if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir, - this->InitialCache)) { - this->RestoreBackupDirectories(); - return 9; - } - } - - // do an initial cmake to setup the DartConfig file - int cmakeFailed = 0; - std::string cmakeFailedOuput; - if (!this->CMakeCmd.empty()) { - command = cmStrCat(this->CMakeCmd, " \"", this->SourceDir); - output.clear(); - command += "\""; - retVal = 0; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run cmake command: " << command << std::endl); - res = cmSystemTools::RunSingleCommand( - command, &output, &output, &retVal, this->BinaryDir.c_str(), - this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); - - if (!this->CMOutFile.empty()) { - std::string cmakeOutputFile = this->CMOutFile; - if (!cmSystemTools::FileIsFullPath(cmakeOutputFile)) { - cmakeOutputFile = this->BinaryDir + "/" + cmakeOutputFile; - } - - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Write CMake output to file: " << cmakeOutputFile - << std::endl); - cmGeneratedFileStream fout(cmakeOutputFile); - if (fout) { - fout << output.c_str(); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot open CMake output file: " - << cmakeOutputFile << " for writing" << std::endl); - } - } - if (!res || retVal != 0) { - // even if this fails continue to the next step - cmakeFailed = 1; - cmakeFailedOuput = output; - } - } - - // run ctest, it may be more than one command in here - cmList ctestCommands{ this->CTestCmd }; - // for each variable/argument do a putenv - for (std::string const& ctestCommand : ctestCommands) { - command = ctestCommand; - output.clear(); - retVal = 0; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run ctest command: " << command << std::endl); - res = cmSystemTools::RunSingleCommand( - command, &output, &output, &retVal, this->BinaryDir.c_str(), - this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); - - // did something critical fail in ctest - if (!res || cmakeFailed || retVal & cmCTest::BUILD_ERRORS) { - this->RestoreBackupDirectories(); - if (cmakeFailed) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Unable to run cmake:" << std::endl - << cmakeFailedOuput << std::endl); - return 10; - } - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Unable to run ctest:" << std::endl - << "command: " << command << std::endl - << "output: " << output << std::endl); - if (!res) { - return 11; - } - return retVal * 100; - } - } - - // if all was successful, delete the backup dirs to free up disk space - if (this->Backup) { - cmSystemTools::RemoveADirectory(this->BackupSourceDir); - cmSystemTools::RemoveADirectory(this->BackupBinaryDir); - } - - return 0; -} - -bool cmCTestScriptHandler::WriteInitialCache(const std::string& directory, - const std::string& text) -{ - std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt"); - cmGeneratedFileStream fout(cacheFile); - if (!fout) { - return false; - } - - fout.write(text.data(), text.size()); - - // Make sure the operating system has finished writing the file - // before closing it. This will ensure the file is finished before - // the check below. - fout.flush(); - fout.close(); - return true; -} - -void cmCTestScriptHandler::RestoreBackupDirectories() -{ - // if we backed up the dirs and the build failed, then restore - // the backed up dirs - if (this->Backup) { - // if for some reason those directories exist then first delete them - if (cmSystemTools::FileExists(this->SourceDir)) { - cmSystemTools::RemoveADirectory(this->SourceDir); - } - if (cmSystemTools::FileExists(this->BinaryDir)) { - cmSystemTools::RemoveADirectory(this->BinaryDir); - } - // rename the src and binary directories - rename(this->BackupSourceDir.c_str(), this->SourceDir.c_str()); - rename(this->BackupBinaryDir.c_str(), this->BinaryDir.c_str()); - } -} - bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf, const std::string& sname, bool InProcess, int* returnValue) @@ -859,73 +372,6 @@ return true; } -bool cmCTestScriptHandler::EmptyBinaryDirectory(const std::string& sname, - std::string& err) -{ - // try to avoid deleting root - if (sname.size() < 2) { - err = "path too short"; - return false; - } - - // consider non existing target directory a success - if (!cmSystemTools::FileExists(sname)) { - return true; - } - - // try to avoid deleting directories that we shouldn't - std::string check = cmStrCat(sname, "/CMakeCache.txt"); - - if (!cmSystemTools::FileExists(check)) { - err = "path does not contain an existing CMakeCache.txt file"; - return false; - } - - cmsys::Status status; - for (int i = 0; i < 5; ++i) { - status = TryToRemoveBinaryDirectoryOnce(sname); - if (status) { - return true; - } - cmSystemTools::Delay(100); - } - - err = status.GetString(); - return false; -} - -cmsys::Status cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( - const std::string& directoryPath) -{ - cmsys::Directory directory; - directory.Load(directoryPath); - - for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) { - std::string path = directory.GetFile(i); - - if (path == "." || path == ".." || path == "CMakeCache.txt") { - continue; - } - - std::string fullPath = cmStrCat(directoryPath, "/", path); - - bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && - !cmSystemTools::FileIsSymlink(fullPath); - - cmsys::Status status; - if (isDirectory) { - status = cmSystemTools::RemoveADirectory(fullPath); - } else { - status = cmSystemTools::RemoveFile(fullPath); - } - if (!status) { - return status; - } - } - - return cmSystemTools::RemoveADirectory(directoryPath); -} - cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed() { if (!this->Makefile) { @@ -944,8 +390,3 @@ std::chrono::steady_clock::now() - this->ScriptStartTime); return (timelimit - duration); } - -void cmCTestScriptHandler::SetRunCurrentScript(bool value) -{ - this->ShouldRunCurrentScript = value; -}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index 8aa07e7..2096ab7 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h
@@ -9,8 +9,6 @@ #include <string> #include <vector> -#include "cmsys/Status.hxx" - #include "cmCTestGenericHandler.h" #include "cmDuration.h" @@ -22,39 +20,6 @@ /** \class cmCTestScriptHandler * \brief A class that handles ctest -S invocations - * - * CTest script is controlled using several variables that script has to - * specify and some optional ones. Required ones are: - * CTEST_SOURCE_DIRECTORY - Source directory of the project - * CTEST_BINARY_DIRECTORY - Binary directory of the project - * CTEST_COMMAND - Testing commands - * - * Optional variables are: - * CTEST_BACKUP_AND_RESTORE - * CTEST_CMAKE_COMMAND - * CTEST_CMAKE_OUTPUT_FILE_NAME - * CTEST_CONTINUOUS_DURATION - * CTEST_CONTINUOUS_MINIMUM_INTERVAL - * CTEST_CVS_CHECKOUT - * CTEST_CVS_COMMAND - * CTEST_UPDATE_COMMAND - * CTEST_DASHBOARD_ROOT - * CTEST_ENVIRONMENT - * CTEST_INITIAL_CACHE - * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY - * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE - * - * In addition the following variables can be used. The number can be 1-10. - * CTEST_EXTRA_UPDATES_1 - * CTEST_EXTRA_UPDATES_2 - * ... - * CTEST_EXTRA_UPDATES_10 - * - * CTest script can use the following arguments CTest provides: - * CTEST_SCRIPT_ARG - * CTEST_SCRIPT_DIRECTORY - * CTEST_SCRIPT_NAME - * */ class cmCTestScriptHandler : public cmCTestGenericHandler { @@ -77,23 +42,10 @@ static bool RunScript(cmCTest* ctest, cmMakefile* mf, const std::string& script, bool InProcess, int* returnValue); - int RunCurrentScript(); - - /* - * Empty Binary Directory - */ - static bool EmptyBinaryDirectory(const std::string& dir, std::string& err); - - /* - * Write an initial CMakeCache.txt from the given contents. - */ - static bool WriteInitialCache(const std::string& directory, - const std::string& text); /* * Some elapsed time handling functions */ - static void SleepInSeconds(unsigned int secondsToWait); void UpdateElapsedTime(); /** @@ -112,65 +64,22 @@ void CreateCMake(); cmake* GetCMake() { return this->CMake.get(); } - - void SetRunCurrentScript(bool value); + cmMakefile* GetMakefile() { return this->Makefile.get(); } private: // reads in a script int ReadInScript(const std::string& total_script_arg); int ExecuteScript(const std::string& total_script_arg); - // extract vars from the script to set ivars - int ExtractVariables(); - - // perform a CVS checkout of the source dir - int CheckOutSourceDir(); - - // perform any extra cvs updates that were requested - int PerformExtraUpdates(); - - // backup and restore dirs - int BackupDirectories(); - void RestoreBackupDirectories(); - int RunConfigurationScript(const std::string& script, bool pscope); - int RunConfigurationDashboard(); // Add ctest command void AddCTestCommand(std::string const& name, std::unique_ptr<cmCTestCommand> command); - // Try to remove the binary directory once - static cmsys::Status TryToRemoveBinaryDirectoryOnce( - const std::string& directoryPath); - std::vector<std::string> ConfigurationScripts; std::vector<bool> ScriptProcessScope; - bool ShouldRunCurrentScript; - - bool Backup = false; - bool EmptyBinDir = false; - bool EmptyBinDirOnce = false; - - std::string SourceDir; - std::string BinaryDir; - std::string BackupSourceDir; - std::string BackupBinaryDir; - std::string CTestRoot; - std::string CVSCheckOut; - std::string CTestCmd; - std::string UpdateCmd; - std::string CTestEnv; - std::string InitialCache; - std::string CMakeCmd; - std::string CMOutFile; - std::vector<std::string> ExtraUpdates; - - // the *60 is because the settings are in minutes but GetTime is seconds - double MinimumInterval = 30 * 60; - double ContinuousDuration = -1; - // what time in seconds did this script start running std::chrono::steady_clock::time_point ScriptStartTime = std::chrono::steady_clock::time_point();
diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx index 623d3b6..f57d856 100644 --- a/Source/CTest/cmCTestSleepCommand.cxx +++ b/Source/CTest/cmCTestSleepCommand.cxx
@@ -2,42 +2,34 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestSleepCommand.h" +#include <chrono> #include <cstdlib> +#include <thread> -#include "cmCTestScriptHandler.h" +#include "cmExecutionStatus.h" -class cmExecutionStatus; - -bool cmCTestSleepCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) +bool cmCTestSleepCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (args.empty()) { - this->SetError("called with incorrect number of arguments"); - return false; - } - // sleep for specified seconds - unsigned int time1 = atoi(args[0].c_str()); if (args.size() == 1) { - cmCTestScriptHandler::SleepInSeconds(time1); - // update the elapsed time since it could have slept for a while - this->CTestScriptHandler->UpdateElapsedTime(); + unsigned int duration = atoi(args[0].c_str()); + std::this_thread::sleep_for(std::chrono::seconds(duration)); return true; } // sleep up to a duration if (args.size() == 3) { + unsigned int time1 = atoi(args[0].c_str()); unsigned int duration = atoi(args[1].c_str()); unsigned int time2 = atoi(args[2].c_str()); if (time1 + duration > time2) { duration = (time1 + duration - time2); - cmCTestScriptHandler::SleepInSeconds(duration); - // update the elapsed time since it could have slept for a while - this->CTestScriptHandler->UpdateElapsedTime(); + std::this_thread::sleep_for(std::chrono::seconds(duration)); } return true; } - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; }
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 9425576..3d4eb1e 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h
@@ -5,42 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> -#include <utility> #include <vector> -#include <cm/memory> - -#include "cmCTestCommand.h" -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmCTestSleep - * \brief Run a ctest script - * - * cmLibrarysCommand defines a list of executable (i.e., test) - * programs to create. - */ -class cmCTestSleepCommand : public cmCTestCommand -{ -public: - cmCTestSleepCommand() {} - - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - auto ni = cm::make_unique<cmCTestSleepCommand>(); - ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; - return std::unique_ptr<cmCommand>(std::move(ni)); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; -}; +bool cmCTestSleepCommand(std::vector<std::string> const& args, + cmExecutionStatus& status);
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 84d12d7..14ff9df 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -9,17 +9,12 @@ #include "cmCTestVC.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmValue.h" class cmExecutionStatus; -cmCTestStartCommand::cmCTestStartCommand() -{ - this->CreateNewTag = true; - this->Quiet = false; -} - bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus& /*unused*/) { @@ -29,6 +24,8 @@ } size_t cnt = 0; + bool append = false; + bool quiet = false; const char* smodel = nullptr; cmValue src_dir; cmValue bld_dir; @@ -47,10 +44,10 @@ cnt++; } else if (args[cnt] == "APPEND") { cnt++; - this->CreateNewTag = false; + append = true; } else if (args[cnt] == "QUIET") { cnt++; - this->Quiet = true; + quiet = true; } else if (!smodel) { smodel = args[cnt].c_str(); cnt++; @@ -82,7 +79,7 @@ "as an argument or set CTEST_BINARY_DIRECTORY"); return false; } - if (!smodel && this->CreateNewTag) { + if (!smodel && !append) { this->SetError("no test model specified and APPEND not specified. Specify " "either a test model or the APPEND argument"); return false; @@ -95,9 +92,8 @@ std::string sourceDir = cmSystemTools::CollapseFullPath(*src_dir); std::string binaryDir = cmSystemTools::CollapseFullPath(*bld_dir); - this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir, - this->Quiet); - this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, this->Quiet); + this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir, quiet); + this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, quiet); if (smodel) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, @@ -105,7 +101,7 @@ << smodel << std::endl << " Source directory: " << *src_dir << std::endl << " Build directory: " << *bld_dir << std::endl, - this->Quiet); + quiet); } else { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with " @@ -113,12 +109,12 @@ << std::endl << " Source directory: " << *src_dir << std::endl << " Build directory: " << *bld_dir << std::endl, - this->Quiet); + quiet); } const char* group = this->CTest->GetSpecificGroup(); if (group) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Group: " << group << std::endl, this->Quiet); + " Group: " << group << std::endl, quiet); } // Log startup actions. @@ -144,7 +140,6 @@ return false; } - this->CTest->SetRunCurrentScript(false); this->CTest->SetSuppressUpdatingCTestConfiguration(true); int model; if (smodel) { @@ -155,7 +150,79 @@ this->CTest->SetTestModel(model); this->CTest->SetProduceXML(true); - return this->CTest->InitializeFromCommand(this); + std::string fname; + + std::string src_dir_fname = cmStrCat(sourceDir, "/CTestConfig.cmake"); + cmSystemTools::ConvertToUnixSlashes(src_dir_fname); + + std::string bld_dir_fname = cmStrCat(binaryDir, "/CTestConfig.cmake"); + cmSystemTools::ConvertToUnixSlashes(bld_dir_fname); + + if (cmSystemTools::FileExists(bld_dir_fname)) { + fname = bld_dir_fname; + } else if (cmSystemTools::FileExists(src_dir_fname)) { + fname = src_dir_fname; + } + + if (!fname.empty()) { + cmCTestOptionalLog( + this->CTest, OUTPUT, + " Reading ctest configuration file: " << fname << std::endl, quiet); + bool readit = this->Makefile->ReadDependentFile(fname); + if (!readit) { + std::string m = cmStrCat("Could not find include file: ", fname); + this->SetError(m); + return false; + } + } + + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "NightlyStartTime", "CTEST_NIGHTLY_START_TIME", quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "Site", + "CTEST_SITE", quiet); + this->CTest->SetCTestConfigurationFromCMakeVariable( + this->Makefile, "BuildName", "CTEST_BUILD_NAME", quiet); + + this->CTest->Initialize(bld_dir); + this->CTest->UpdateCTestConfiguration(); + + cmCTestOptionalLog( + this->CTest, OUTPUT, + " Site: " << this->CTest->GetCTestConfiguration("Site") << std::endl + << " Build name: " + << cmCTest::SafeBuildIdField( + this->CTest->GetCTestConfiguration("BuildName")) + << std::endl, + quiet); + + if (this->CTest->GetTestModel() == cmCTest::NIGHTLY && + this->CTest->GetCTestConfiguration("NightlyStartTime").empty()) { + cmCTestOptionalLog( + this->CTest, WARNING, + "WARNING: No nightly start time found please set in CTestConfig.cmake" + " or DartConfig.cmake" + << std::endl, + quiet); + return false; + } + + this->CTest->ReadCustomConfigurationFileTree(bld_dir, this->Makefile); + + if (append) { + if (!this->CTest->ReadExistingTag(quiet)) { + return false; + } + } else { + if (!this->CTest->CreateNewTag(quiet)) { + return false; + } + } + + cmCTestOptionalLog(this->CTest, OUTPUT, + " Use " << this->CTest->GetTestGroupString() << " tag: " + << this->CTest->GetCurrentTag() << std::endl, + quiet); + return true; } bool cmCTestStartCommand::InitialCheckout(std::ostream& ofs,
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index b3d06a7..22ae9bc 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h
@@ -24,8 +24,6 @@ class cmCTestStartCommand : public cmCTestCommand { public: - cmCTestStartCommand(); - /** * This is a virtual constructor for the command. */ @@ -33,9 +31,6 @@ { auto ni = cm::make_unique<cmCTestStartCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; - ni->CreateNewTag = this->CreateNewTag; - ni->Quiet = this->Quiet; return std::unique_ptr<cmCommand>(std::move(ni)); } @@ -46,18 +41,6 @@ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - /** - * Will this invocation of ctest_start create a new TAG file? - */ - bool ShouldCreateNewTag() { return this->CreateNewTag; } - - /** - * Should this invocation of ctest_start output non-error messages? - */ - bool ShouldBeQuiet() { return this->Quiet; } - private: bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir); - bool CreateNewTag; - bool Quiet; };
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 029f81f..0d2501d 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -29,7 +29,6 @@ { auto ni = cm::make_unique<cmCTestSubmitCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 91dea55..cf95168 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -139,20 +139,6 @@ this->Files.clear(); } -int cmCTestSubmitHandler::ProcessCommandLineArguments( - const std::string& currentArg, size_t& idx, - const std::vector<std::string>& allArgs, bool& validArg) -{ - if (cmHasLiteralPrefix(currentArg, "--http-header") && - idx < allArgs.size() - 1) { - ++idx; - this->HttpHeaders.push_back(allArgs[idx]); - this->CommandLineHttpHeaders.push_back(allArgs[idx]); - validArg = true; - } - return 1; -} - bool cmCTestSubmitHandler::SubmitUsingHTTP( const std::string& localprefix, const std::vector<std::string>& files, const std::string& remoteprefix, const std::string& url) @@ -275,7 +261,7 @@ upload_as += "&stamp="; upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); upload_as += "-"; - upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); + upload_as += ctest_curl.Escape(this->CTest->GetTestGroupString()); cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); if (cm) { @@ -584,18 +570,18 @@ auto timeNow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); str << "stamp=" << curl.Escape(this->CTest->GetCurrentTag()) << "-" - << curl.Escape(this->CTest->GetTestModelString()) << "&" - << "model=" << curl.Escape(this->CTest->GetTestModelString()) << "&" + << curl.Escape(this->CTest->GetTestGroupString()) << "&" + << "model=" << curl.Escape(this->CTest->GetTestGroupString()) << "&" << "build=" << curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&" << "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site")) << "&" - << "group=" << curl.Escape(this->CTest->GetTestModelString()) + << "group=" << curl.Escape(this->CTest->GetTestGroupString()) << "&" // For now, we send both "track" and "group" to CDash in case we're // submitting to an older instance that still expects the prior // terminology. - << "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&" + << "track=" << curl.Escape(this->CTest->GetTestGroupString()) << "&" << "starttime=" << timeNow << "&" << "endtime=" << timeNow << "&" << "datafilesmd5[0]=" << md5sum << "&" @@ -906,7 +892,7 @@ cmCTest::SafeBuildIdField(this->CTest->GetCTestConfiguration("BuildName")); std::string name = this->CTest->GetCTestConfiguration("Site") + "___" + buildname + "___" + this->CTest->GetCurrentTag() + "-" + - this->CTest->GetTestModelString() + "___XML___"; + this->CTest->GetTestGroupString() + "___XML___"; return name; }
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index d152b71..9993e29 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -4,7 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cstddef> #include <iosfwd> #include <set> #include <string> @@ -34,11 +33,6 @@ void Initialize() override; - //! Set all the submit arguments - int ProcessCommandLineArguments(const std::string& currentArg, size_t& idx, - const std::vector<std::string>& allArgs, - bool& validArg) override; - /** Specify a set of parts (by name) to submit. */ void SelectParts(std::set<cmCTest::Part> const& parts); @@ -48,6 +42,12 @@ // handle the cdash file upload protocol int HandleCDashUploadFile(std::string const& file, std::string const& type); + void AddCommandLineHttpHeader(std::string const& h) + { + this->HttpHeaders.push_back(h); + this->CommandLineHttpHeaders.push_back(h); + } + void SetHttpHeaders(std::vector<std::string> const& v) { if (this->CommandLineHttpHeaders.empty()) {
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 23661c5..bcaa571 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h
@@ -32,7 +32,6 @@ { auto ni = cm::make_unique<cmCTestTestCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index c7875cd..b213e97 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -8,7 +8,6 @@ #include <cstddef> // IWYU pragma: keep #include <cstdio> #include <cstdlib> -#include <cstring> #include <ctime> #include <functional> #include <iomanip> @@ -97,8 +96,7 @@ { cmWorkingDirectory workdir(fname); if (workdir.Failed()) { - status.SetError("Failed to change directory to " + fname + " : " + - std::strerror(workdir.GetLastResult())); + status.SetError(workdir.GetError()); return false; } const char* testFilename; @@ -380,6 +378,33 @@ } } +void cmCTestTestHandler::SetCMakeVariables(cmMakefile& mf) +{ + mf.AddDefinition("CTEST_CUSTOM_PRE_TEST", + cmList(this->CustomPreTest).to_string()); + mf.AddDefinition("CTEST_CUSTOM_POST_TEST", + cmList(this->CustomPostTest).to_string()); + mf.AddDefinition("CTEST_CUSTOM_TESTS_IGNORE", + cmList(this->CustomTestsIgnore).to_string()); + mf.AddDefinition("CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE", + std::to_string(this->CustomMaximumPassedTestOutputSize)); + mf.AddDefinition("CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE", + std::to_string(this->CustomMaximumFailedTestOutputSize)); + mf.AddDefinition("CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION", + [this]() -> cm::string_view { + switch (this->TestOutputTruncation) { + case cmCTestTypes::TruncationMode::Tail: + return "tail"_s; + case cmCTestTypes::TruncationMode::Middle: + return "middle"_s; + case cmCTestTypes::TruncationMode::Head: + return "head"_s; + default: + return ""_s; + } + }()); +} + int cmCTestTestHandler::PreProcessHandler() { if (!this->ExecuteCommands(this->CustomPreTest)) { @@ -1761,7 +1786,7 @@ for (unsigned int ai = 0; ai < attempted.size() && fullPath.empty(); ++ai) { // first check without exe extension if (cmSystemTools::FileExists(attempted[ai], true)) { - fullPath = cmSystemTools::CollapseFullPath(attempted[ai]); + fullPath = cmSystemTools::ToNormalizedPathOnDisk(attempted[ai]); resultingConfig = attemptedConfigs[ai]; } // then try with the exe extension @@ -1770,7 +1795,7 @@ tempPath = cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension()); if (cmSystemTools::FileExists(tempPath, true)) { - fullPath = cmSystemTools::CollapseFullPath(tempPath); + fullPath = cmSystemTools::ToNormalizedPathOnDisk(tempPath); resultingConfig = attemptedConfigs[ai]; } else { failed.push_back(tempPath);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index dd1bc59..024b544 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h
@@ -228,6 +228,11 @@ // Support for writing test results in JUnit XML format. void SetJUnitXMLFileName(const std::string& id); + /** + * Set CMake variables from CTest Options + */ + void SetCMakeVariables(cmMakefile& mf); + protected: using SetOfTests = std::set<cmCTestTestHandler::cmCTestTestResult, cmCTestTestResultLess>;
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h index e4c3453..fecc482 100644 --- a/Source/CTest/cmCTestUpdateCommand.h +++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -29,7 +29,6 @@ { auto ni = cm::make_unique<cmCTestUpdateCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 045eb84..565f383 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -195,7 +195,7 @@ xml.Element("BuildName", buildname); xml.Element("BuildStamp", this->CTest->GetCurrentTag() + "-" + - this->CTest->GetTestModelString()); + this->CTest->GetTestGroupString()); xml.Element("StartDateTime", start_time); xml.Element("StartTime", start_time_time); xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index a9d1dd2..ade88b0 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h
@@ -32,7 +32,6 @@ { auto ni = cm::make_unique<cmCTestUploadCommand>(); ni->CTest = this->CTest; - ni->CTestScriptHandler = this->CTestScriptHandler; return std::unique_ptr<cmCommand>(std::move(ni)); }
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx index 59e2b88..8fb10b6 100644 --- a/Source/CTest/cmCTestUploadHandler.cxx +++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -49,7 +49,7 @@ xml.Attribute("BuildName", buildname); xml.Attribute("BuildStamp", this->CTest->GetCurrentTag() + "-" + - this->CTest->GetTestModelString()); + this->CTest->GetTestGroupString()); xml.Attribute("Name", this->CTest->GetCTestConfiguration("Site")); xml.Attribute("Generator", std::string("ctest-") + cmVersion::GetCMakeVersion());
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt index bd7c415..1f04bd2 100644 --- a/Source/Checks/Curses/CMakeLists.txt +++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR) project(CheckCurses C) set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 21ed8c8..7847a4b 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx
@@ -172,8 +172,8 @@ } } - sourceDirectory = cmSystemTools::CollapseFullPath(path.toStdString()); - cmSystemTools::ConvertToUnixSlashes(sourceDirectory); + sourceDirectory = + cmSystemTools::ToNormalizedPathOnDisk(path.toStdString()); } else if (arg.startsWith("-B")) { QString path = arg.mid(2); if (path.isEmpty()) { @@ -189,8 +189,8 @@ } } - binaryDirectory = cmSystemTools::CollapseFullPath(path.toStdString()); - cmSystemTools::ConvertToUnixSlashes(binaryDirectory); + binaryDirectory = + cmSystemTools::ToNormalizedPathOnDisk(path.toStdString()); } else if (arg.startsWith("--preset=")) { QString preset = arg.mid(cmStrLen("--preset=")); if (preset.isEmpty()) { @@ -223,7 +223,7 @@ } else { if (args.count() == 2) { std::string filePath = - cmSystemTools::CollapseFullPath(args[1].toStdString()); + cmSystemTools::ToNormalizedPathOnDisk(args[1].toStdString()); // check if argument is a directory containing CMakeCache.txt std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt"); @@ -243,7 +243,7 @@ } else if (cmSystemTools::FileExists(srcFilePath.c_str())) { dialog.setSourceDirectory(QString::fromStdString(filePath)); dialog.setBinaryDirectory( - QString::fromStdString(cmSystemTools::CollapseFullPath("."))); + QString::fromStdString(cmSystemTools::GetCurrentWorkingDirectory())); } } }
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 45c4717..7c94ea2 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx
@@ -258,9 +258,7 @@ #endif // Apply the same transformations that the command-line invocation does auto sanitizePath = [](QString const& value) -> std::string { - std::string path = cmSystemTools::CollapseFullPath(value.toStdString()); - cmSystemTools::ConvertToUnixSlashes(path); - return path; + return cmSystemTools::ToNormalizedPathOnDisk(value.toStdString()); }; this->CMakeInstance->SetHomeDirectory(sanitizePath(this->SourceDirectory));
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index e67e0c2..94dfa3e 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -189,7 +189,7 @@ static uint qHash(const QCMakeProperty& p) { - return static_cast<uint>(qHash(p.Key)); + return qHash(p.Key); } void QCMakeCacheModel::setShowNewProperties(bool f) @@ -242,7 +242,7 @@ bool b = this->blockSignals(true); this->clear(); - this->NewPropertyCount = static_cast<int>(newProps.size()); + this->NewPropertyCount = newProps.size(); if (View == FlatView) { QCMakePropertyList newP = newProps.values();
diff --git a/Source/QtDialog/QCMakePresetItemModel.cxx b/Source/QtDialog/QCMakePresetItemModel.cxx index 31a6000..cb96b6b 100644 --- a/Source/QtDialog/QCMakePresetItemModel.cxx +++ b/Source/QtDialog/QCMakePresetItemModel.cxx
@@ -83,7 +83,7 @@ if (this->m_presets.empty()) { return 1; } - return static_cast<int>(this->m_presets.size() + 2); + return this->m_presets.size() + 2; } int QCMakePresetItemModel::columnCount(const QModelIndex& parent) const @@ -144,5 +144,5 @@ index++; } - return static_cast<int>(this->m_presets.size() + 1); + return this->m_presets.size() + 1; }
diff --git a/Source/cmCMakePath.h b/Source/cmCMakePath.h index fd71c1f..52fd6aa 100644 --- a/Source/cmCMakePath.h +++ b/Source/cmCMakePath.h
@@ -617,19 +617,18 @@ // Non-members // =========== - friend inline bool operator==(const cmCMakePath& lhs, - const cmCMakePath& rhs) noexcept + friend bool operator==(const cmCMakePath& lhs, + const cmCMakePath& rhs) noexcept { return lhs.Compare(rhs) == 0; } - friend inline bool operator!=(const cmCMakePath& lhs, - const cmCMakePath& rhs) noexcept + friend bool operator!=(const cmCMakePath& lhs, + const cmCMakePath& rhs) noexcept { return lhs.Compare(rhs) != 0; } - friend inline cmCMakePath operator/(const cmCMakePath& lhs, - const cmCMakePath& rhs) + friend cmCMakePath operator/(const cmCMakePath& lhs, const cmCMakePath& rhs) { cmCMakePath result(lhs); result /= rhs;
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 2e6cd40..6f101cb 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx
@@ -168,7 +168,7 @@ static int CCONV cmCommandExists(void* arg, const char* name) { cmMakefile* mf = static_cast<cmMakefile*>(arg); - return static_cast<int>(mf->GetState()->GetCommand(name) ? 1 : 0); + return mf->GetState()->GetCommand(name) ? 1 : 0; } static void CCONV cmAddDefineFlag(void* arg, const char* definition)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 829fbf9..c15075c 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx
@@ -41,23 +41,25 @@ #endif #include "cmCMakePresetsGraph.h" -#include "cmCTestBuildAndTestHandler.h" +#include "cmCTestBuildAndTest.h" #include "cmCTestBuildHandler.h" #include "cmCTestConfigureHandler.h" #include "cmCTestCoverageHandler.h" #include "cmCTestGenericHandler.h" #include "cmCTestMemCheckHandler.h" #include "cmCTestScriptHandler.h" -#include "cmCTestStartCommand.h" #include "cmCTestSubmitHandler.h" #include "cmCTestTestHandler.h" #include "cmCTestUpdateHandler.h" #include "cmCTestUploadHandler.h" +#include "cmCommandLineArgument.h" #include "cmDynamicLoader.h" +#include "cmExecutionStatus.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmJSONState.h" #include "cmList.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmProcessOutput.h" #include "cmState.h" @@ -71,6 +73,7 @@ #include "cmValue.h" #include "cmVersion.h" #include "cmVersionConfig.h" +#include "cmWorkingDirectory.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -80,6 +83,11 @@ struct cmCTest::Private { + Private(cmCTest* ctest) + : BuildAndTest(ctest) + { + } + /** Representation of one part. */ struct PartInfo { @@ -114,13 +122,9 @@ bool FlushTestProgressLine = false; - bool ForceNewCTestProcess = false; - - bool RunConfigurationScript = false; - // these are helper classes cmCTestBuildHandler BuildHandler; - cmCTestBuildAndTestHandler BuildAndTestHandler; + cmCTestBuildAndTest BuildAndTest; cmCTestCoverageHandler CoverageHandler; cmCTestScriptHandler ScriptHandler; cmCTestTestHandler TestHandler; @@ -132,17 +136,16 @@ std::vector<cmCTestGenericHandler*> GetTestingHandlers() { - return { &this->BuildHandler, &this->BuildAndTestHandler, - &this->CoverageHandler, &this->ScriptHandler, - &this->TestHandler, &this->UpdateHandler, - &this->ConfigureHandler, &this->MemCheckHandler, - &this->SubmitHandler, &this->UploadHandler }; + return { &this->BuildHandler, &this->CoverageHandler, + &this->ScriptHandler, &this->TestHandler, + &this->UpdateHandler, &this->ConfigureHandler, + &this->MemCheckHandler, &this->SubmitHandler, + &this->UploadHandler }; } std::map<std::string, cmCTestGenericHandler*> GetNamedTestingHandlers() { return { { "build", &this->BuildHandler }, - { "buildtest", &this->BuildAndTestHandler }, { "coverage", &this->CoverageHandler }, { "script", &this->ScriptHandler }, { "test", &this->TestHandler }, @@ -199,14 +202,9 @@ bool CompressXMLFiles = false; bool CompressTestOutput = true; - // By default we write output to the process output streams. - std::ostream* StreamOut = &std::cout; - std::ostream* StreamErr = &std::cerr; - bool SuppressUpdatingCTestConfiguration = false; bool Debug = false; - bool ShowLineNumbers = false; bool Quiet = false; std::string BuildID; @@ -216,7 +214,7 @@ int SubmitIndex = 0; std::unique_ptr<cmGeneratedFileStream> OutputLogFile; - int OutputLogFileLastTag = -1; + cm::optional<cmCTest::LogType> OutputLogFileLastTag; bool OutputTestOutputOnTestFailure = false; bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole(); @@ -340,7 +338,7 @@ } cmCTest::cmCTest() - : Impl(new Private) + : Impl(cm::make_unique<Private>(this)) { std::string envValue; if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) { @@ -418,15 +416,143 @@ return PartCount; } -int cmCTest::Initialize(const std::string& binary_dir, - cmCTestStartCommand* command) +void cmCTest::Initialize(std::string const& binary_dir) { - bool quiet = false; - if (command && command->ShouldBeQuiet()) { - quiet = true; + this->Impl->BuildID = ""; + for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) { + this->Impl->Parts[p].SubmitFiles.clear(); } - cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); + if (!this->Impl->InteractiveDebugMode) { + this->BlockTestErrorDiagnostics(); + } else { + cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1"); + } + + this->Impl->BinaryDir = binary_dir; + cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir); +} + +bool cmCTest::CreateNewTag(bool quiet) +{ + std::string const testingDir = this->Impl->BinaryDir + "/Testing"; + std::string const tagfile = testingDir + "/TAG"; + + auto const result = cmSystemTools::MakeDirectory(testingDir); + if (!result.IsSuccess()) { + cmCTestLog(this, ERROR_MESSAGE, + "Cannot create directory \"" + << testingDir << "\": " << result.GetString() << std::endl); + return false; + } + + cmCTestOptionalLog(this, DEBUG, + "TestModel: " << this->GetTestGroupString() << std::endl, + quiet); + cmCTestOptionalLog( + this, DEBUG, "TestModel: " << this->Impl->TestModel << std::endl, quiet); + + struct tm* lctime = [this]() -> tm* { + if (this->Impl->TestModel == cmCTest::NIGHTLY) { + return this->GetNightlyTime( + this->GetCTestConfiguration("NightlyStartTime"), + this->Impl->TomorrowTag); + } + time_t tctime = time(nullptr); + if (this->Impl->TomorrowTag) { + tctime += (24 * 60 * 60); + } + return gmtime(&tctime); + }(); + + char datestring[100]; + snprintf(datestring, sizeof(datestring), "%04d%02d%02d-%02d%02d", + lctime->tm_year + 1900, lctime->tm_mon + 1, lctime->tm_mday, + lctime->tm_hour, lctime->tm_min); + this->Impl->CurrentTag = datestring; + + cmsys::ofstream ofs(tagfile.c_str()); + ofs << this->Impl->CurrentTag << std::endl; + ofs << this->GetTestGroupString() << std::endl; + ofs << this->GetTestModelString() << std::endl; + + return true; +} + +bool cmCTest::ReadExistingTag(bool quiet) +{ + std::string const testingDir = this->Impl->BinaryDir + "/Testing"; + std::string const tagfile = testingDir + "/TAG"; + + std::string tag; + std::string group; + std::string modelStr; + int model = cmCTest::UNKNOWN; + + cmsys::ifstream tfin(tagfile.c_str()); + if (tfin) { + cmSystemTools::GetLineFromStream(tfin, tag); + cmSystemTools::GetLineFromStream(tfin, group); + if (cmSystemTools::GetLineFromStream(tfin, modelStr)) { + model = GetTestModelFromString(modelStr); + } + tfin.close(); + } + + if (tag.empty()) { + if (!quiet) { + cmCTestLog(this, ERROR_MESSAGE, + "Cannot read existing TAG file in " << testingDir + << std::endl); + } + return false; + } + + if (this->Impl->TestModel == cmCTest::UNKNOWN) { + if (model == cmCTest::UNKNOWN) { + cmCTestLog(this, ERROR_MESSAGE, + "TAG file does not contain model and " + "no model specified in start command" + << std::endl); + return false; + } + + this->SetTestModel(model); + } + + if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN && + this->Impl->TestModel != cmCTest::UNKNOWN) { + cmCTestOptionalLog(this, WARNING, + "Model given in TAG does not match " + "model given in ctest_start()" + << std::endl, + quiet); + } + + if (!this->Impl->SpecificGroup.empty() && + group != this->Impl->SpecificGroup) { + cmCTestOptionalLog(this, WARNING, + "Group given in TAG does not match " + "group given in ctest_start()" + << std::endl, + quiet); + } else { + this->Impl->SpecificGroup = group; + } + + cmCTestOptionalLog(this, OUTPUT, + " Use existing tag: " << tag << " - " + << this->GetTestGroupString() + << std::endl, + quiet); + + this->Impl->CurrentTag = tag; + return true; +} + +void cmCTest::InitializeTesting(const std::string& binary_dir) +{ + cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); if (!this->Impl->InteractiveDebugMode) { this->BlockTestErrorDiagnostics(); } else { @@ -438,31 +564,7 @@ this->UpdateCTestConfiguration(); - cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); - if (this->Impl->ProduceXML) { - cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); - cmCTestOptionalLog(this, OUTPUT, - " Site: " - << this->GetCTestConfiguration("Site") << std::endl - << " Build name: " - << cmCTest::SafeBuildIdField( - this->GetCTestConfiguration("BuildName")) - << std::endl, - quiet); - cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet); - if (this->Impl->TestModel == cmCTest::NIGHTLY && - this->GetCTestConfiguration("NightlyStartTime").empty()) { - cmCTestOptionalLog( - this, WARNING, - "WARNING: No nightly start time found please set in CTestConfig.cmake" - " or DartConfig.cmake" - << std::endl, - quiet); - cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, - quiet); - return 0; - } - } + cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); cmake cm(cmake::RoleScript, cmState::CTest); cm.SetHomeDirectory(""); @@ -470,235 +572,7 @@ cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf)) { - cmCTestOptionalLog( - this, DEBUG, "Cannot find custom configuration file tree" << std::endl, - quiet); - return 0; - } - - if (this->Impl->ProduceXML) { - // Verify "Testing" directory exists: - // - std::string testingDir = this->Impl->BinaryDir + "/Testing"; - if (cmSystemTools::FileExists(testingDir)) { - if (!cmSystemTools::FileIsDirectory(testingDir)) { - cmCTestLog(this, ERROR_MESSAGE, - "File " << testingDir - << " is in the place of the testing directory" - << std::endl); - return 0; - } - } else { - if (!cmSystemTools::MakeDirectory(testingDir)) { - cmCTestLog(this, ERROR_MESSAGE, - "Cannot create directory " << testingDir << std::endl); - return 0; - } - } - - // Create new "TAG" file or read existing one: - // - bool createNewTag = true; - if (command) { - createNewTag = command->ShouldCreateNewTag(); - } - - std::string tagfile = testingDir + "/TAG"; - cmsys::ifstream tfin(tagfile.c_str()); - std::string tag; - - if (createNewTag) { - time_t tctime = time(nullptr); - if (this->Impl->TomorrowTag) { - tctime += (24 * 60 * 60); - } - struct tm* lctime = gmtime(&tctime); - if (tfin && cmSystemTools::GetLineFromStream(tfin, tag)) { - int year = 0; - int mon = 0; - int day = 0; - int hour = 0; - int min = 0; - sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d", &year, &mon, &day, &hour, - &min); - if (year != lctime->tm_year + 1900 || mon != lctime->tm_mon + 1 || - day != lctime->tm_mday) { - tag.clear(); - } - std::string group; - if (cmSystemTools::GetLineFromStream(tfin, group) && - !this->Impl->Parts[PartStart] && !command) { - this->Impl->SpecificGroup = group; - } - std::string model; - if (cmSystemTools::GetLineFromStream(tfin, model) && - !this->Impl->Parts[PartStart] && !command) { - this->Impl->TestModel = GetTestModelFromString(model); - } - tfin.close(); - } - if (tag.empty() || command || this->Impl->Parts[PartStart]) { - cmCTestOptionalLog( - this, DEBUG, - "TestModel: " << this->GetTestModelString() << std::endl, quiet); - cmCTestOptionalLog(this, DEBUG, - "TestModel: " << this->Impl->TestModel << std::endl, - quiet); - if (this->Impl->TestModel == cmCTest::NIGHTLY) { - lctime = this->GetNightlyTime( - this->GetCTestConfiguration("NightlyStartTime"), - this->Impl->TomorrowTag); - } - char datestring[100]; - snprintf(datestring, sizeof(datestring), "%04d%02d%02d-%02d%02d", - lctime->tm_year + 1900, lctime->tm_mon + 1, lctime->tm_mday, - lctime->tm_hour, lctime->tm_min); - tag = datestring; - cmsys::ofstream ofs(tagfile.c_str()); - if (ofs) { - ofs << tag << std::endl; - ofs << this->GetTestModelString() << std::endl; - switch (this->Impl->TestModel) { - case cmCTest::EXPERIMENTAL: - ofs << "Experimental" << std::endl; - break; - case cmCTest::NIGHTLY: - ofs << "Nightly" << std::endl; - break; - case cmCTest::CONTINUOUS: - ofs << "Continuous" << std::endl; - break; - } - } - ofs.close(); - if (!command) { - cmCTestOptionalLog(this, OUTPUT, - "Create new tag: " << tag << " - " - << this->GetTestModelString() - << std::endl, - quiet); - } - } - } else { - std::string group; - std::string modelStr; - int model = cmCTest::UNKNOWN; - - if (tfin) { - cmSystemTools::GetLineFromStream(tfin, tag); - cmSystemTools::GetLineFromStream(tfin, group); - if (cmSystemTools::GetLineFromStream(tfin, modelStr)) { - model = GetTestModelFromString(modelStr); - } - tfin.close(); - } - - if (tag.empty()) { - cmCTestLog(this, ERROR_MESSAGE, - "Cannot read existing TAG file in " << testingDir - << std::endl); - return 0; - } - - if (this->Impl->TestModel == cmCTest::UNKNOWN) { - if (model == cmCTest::UNKNOWN) { - cmCTestLog(this, ERROR_MESSAGE, - "TAG file does not contain model and " - "no model specified in start command" - << std::endl); - return 0; - } - - this->SetTestModel(model); - } - - if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN && - this->Impl->TestModel != cmCTest::UNKNOWN) { - cmCTestOptionalLog(this, WARNING, - "Model given in TAG does not match " - "model given in ctest_start()" - << std::endl, - quiet); - } - - if (!this->Impl->SpecificGroup.empty() && - group != this->Impl->SpecificGroup) { - cmCTestOptionalLog(this, WARNING, - "Group given in TAG does not match " - "group given in ctest_start()" - << std::endl, - quiet); - } else { - this->Impl->SpecificGroup = group; - } - - cmCTestOptionalLog(this, OUTPUT, - " Use existing tag: " << tag << " - " - << this->GetTestModelString() - << std::endl, - quiet); - } - - this->Impl->CurrentTag = tag; - } - - return 1; -} - -bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) -{ - std::string src_dir = this->GetCTestConfiguration("SourceDirectory"); - std::string bld_dir = this->GetCTestConfiguration("BuildDirectory"); - this->Impl->BuildID = ""; - for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) { - this->Impl->Parts[p].SubmitFiles.clear(); - } - - cmMakefile* mf = command->GetMakefile(); - std::string fname; - - std::string src_dir_fname = cmStrCat(src_dir, "/CTestConfig.cmake"); - cmSystemTools::ConvertToUnixSlashes(src_dir_fname); - - std::string bld_dir_fname = cmStrCat(bld_dir, "/CTestConfig.cmake"); - cmSystemTools::ConvertToUnixSlashes(bld_dir_fname); - - if (cmSystemTools::FileExists(bld_dir_fname)) { - fname = bld_dir_fname; - } else if (cmSystemTools::FileExists(src_dir_fname)) { - fname = src_dir_fname; - } - - if (!fname.empty()) { - cmCTestOptionalLog(this, OUTPUT, - " Reading ctest configuration file: " << fname - << std::endl, - command->ShouldBeQuiet()); - bool readit = mf->ReadDependentFile(fname); - if (!readit) { - std::string m = cmStrCat("Could not find include file: ", fname); - command->SetError(m); - return false; - } - } - - this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime", - "CTEST_NIGHTLY_START_TIME", - command->ShouldBeQuiet()); - this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE", - command->ShouldBeQuiet()); - this->SetCTestConfigurationFromCMakeVariable( - mf, "BuildName", "CTEST_BUILD_NAME", command->ShouldBeQuiet()); - - if (!this->Initialize(bld_dir, command)) { - return false; - } - cmCTestOptionalLog(this, OUTPUT, - " Use " << this->GetTestModelString() << " tag: " - << this->GetCurrentTag() << std::endl, - command->ShouldBeQuiet()); - return true; + this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf); } bool cmCTest::UpdateCTestConfiguration() @@ -825,10 +699,6 @@ return false; } -void cmCTest::Finalize() -{ -} - bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name, cmGeneratedFileStream& stream, bool compress) { @@ -894,11 +764,6 @@ return &this->Impl->BuildHandler; } -cmCTestBuildAndTestHandler* cmCTest::GetBuildAndTestHandler() -{ - return &this->Impl->BuildAndTestHandler; -} - cmCTestCoverageHandler* cmCTest::GetCoverageHandler() { return &this->Impl->CoverageHandler; @@ -941,77 +806,141 @@ int cmCTest::ProcessSteps() { - int res = 0; - bool notest = true; - int update_count = 0; + this->Impl->ExtraVerbose = this->Impl->Verbose; + this->Impl->Verbose = true; + this->Impl->ProduceXML = true; - for (Part p = PartStart; notest && p != PartCount; - p = static_cast<Part>(p + 1)) { - notest = !this->Impl->Parts[p]; + for (auto& handler : this->Impl->GetTestingHandlers()) { + handler->SetVerbose(this->Impl->Verbose); + handler->SetSubmitIndex(this->Impl->SubmitIndex); } + + const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory(); + std::string workDir = currDir; + if (!this->Impl->TestDir.empty()) { + workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir); + } + + cmWorkingDirectory changeDir(workDir); + if (changeDir.Failed()) { + cmCTestLog(this, ERROR_MESSAGE, changeDir.GetError() << std::endl); + return 1; + } + + this->Impl->BinaryDir = workDir; + cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir); + this->UpdateCTestConfiguration(); + this->BlockTestErrorDiagnostics(); + + int res = 0; + cmCTestScriptHandler script; + script.SetCTestInstance(this); + script.CreateCMake(); + cmMakefile& mf = *script.GetMakefile(); + this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf); + this->SetCMakeVariables(mf); + std::vector<cmListFileArgument> args{ + cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0), + cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0), + }; + + if (this->Impl->Parts[PartStart]) { + auto const func = cmListFileFunction( + "ctest_start", 0, 0, + { + { this->GetTestModelString(), cmListFileArgument::Unquoted, 0 }, + { "GROUP", cmListFileArgument::Unquoted, 0 }, + { this->GetTestGroupString(), cmListFileArgument::Unquoted, 0 }, + }); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status)) { + return 12; + } + } else if (!this->ReadExistingTag(true) && !this->CreateNewTag(false)) { + cmCTestLog(this, ERROR_MESSAGE, + "Problem initializing the dashboard." << std::endl); + return 12; + } + if (this->Impl->Parts[PartUpdate] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { - cmCTestUpdateHandler* uphandler = this->GetUpdateHandler(); - uphandler->SetPersistentOption( - "SourceDirectory", this->GetCTestConfiguration("SourceDirectory")); - update_count = uphandler->ProcessHandler(); - if (update_count < 0) { + auto const func = cmListFileFunction("ctest_update", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status)) { res |= cmCTest::UPDATE_ERRORS; } } - if (this->Impl->TestModel == cmCTest::CONTINUOUS && !update_count) { + if (this->Impl->TestModel == cmCTest::CONTINUOUS && + mf.GetDefinition("return_value").IsOff()) { return 0; } if (this->Impl->Parts[PartConfigure] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { - if (this->GetConfigureHandler()->ProcessHandler() < 0) { + auto const func = cmListFileFunction("ctest_configure", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::CONFIGURE_ERRORS; } } if (this->Impl->Parts[PartBuild] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetBuildHandler()->ProcessHandler() < 0) { + this->SetCMakeVariables(mf); + auto const func = cmListFileFunction("ctest_build", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::BUILD_ERRORS; } } - if ((this->Impl->Parts[PartTest] || notest) && + if (this->Impl->Parts[PartTest] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetTestHandler()->ProcessHandler() < 0) { + this->SetCMakeVariables(mf); + auto const func = cmListFileFunction("ctest_test", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::TEST_ERRORS; } } if (this->Impl->Parts[PartCoverage] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetCoverageHandler()->ProcessHandler() < 0) { + this->SetCMakeVariables(mf); + auto const func = cmListFileFunction("ctest_coverage", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::COVERAGE_ERRORS; } } if (this->Impl->Parts[PartMemCheck] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetMemCheckHandler()->ProcessHandler() < 0) { + this->SetCMakeVariables(mf); + auto const func = cmListFileFunction("ctest_memcheck", 0, 0, args); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::MEMORY_ERRORS; } } - if (!notest) { - std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes"; - if (cmSystemTools::FileIsDirectory(notes_dir)) { - cmsys::Directory d; - d.Load(notes_dir); - unsigned long kk; - for (kk = 0; kk < d.GetNumberOfFiles(); kk++) { - const char* file = d.GetFile(kk); - std::string fullname = notes_dir + "/" + file; - if (cmSystemTools::FileExists(fullname, true)) { - if (!this->Impl->NotesFiles.empty()) { - this->Impl->NotesFiles += ";"; - } - this->Impl->NotesFiles += fullname; - this->Impl->Parts[PartNotes].Enable(); + std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes"; + if (cmSystemTools::FileIsDirectory(notes_dir)) { + cmsys::Directory d; + d.Load(notes_dir); + unsigned long kk; + for (kk = 0; kk < d.GetNumberOfFiles(); kk++) { + const char* file = d.GetFile(kk); + std::string fullname = notes_dir + "/" + file; + if (cmSystemTools::FileExists(fullname, true)) { + if (!this->Impl->NotesFiles.empty()) { + this->Impl->NotesFiles += ";"; } + this->Impl->NotesFiles += fullname; + this->Impl->Parts[PartNotes].Enable(); } } } @@ -1023,32 +952,31 @@ } if (this->Impl->Parts[PartSubmit]) { this->UpdateCTestConfiguration(); - if (this->GetSubmitHandler()->ProcessHandler() < 0) { + this->SetCMakeVariables(mf); + + std::string count = this->GetCTestConfiguration("CTestSubmitRetryCount"); + std::string delay = this->GetCTestConfiguration("CTestSubmitRetryDelay"); + auto const func = cmListFileFunction( + "ctest_submit", 0, 0, + { + cmListFileArgument("RETRY_COUNT", cmListFileArgument::Unquoted, 0), + cmListFileArgument(count, cmListFileArgument::Quoted, 0), + cmListFileArgument("RETRY_DELAY", cmListFileArgument::Unquoted, 0), + cmListFileArgument(delay, cmListFileArgument::Quoted, 0), + cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0), + cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0), + }); + auto status = cmExecutionStatus(mf); + if (!mf.ExecuteCommand(func, status) || + std::stoi(mf.GetDefinition("return_value")) < 0) { res |= cmCTest::SUBMIT_ERRORS; } } - if (res != 0) { - cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest" << std::endl); - if (!this->Impl->OutputTestOutputOnTestFailure) { - const std::string lastTestLog = - this->GetBinaryDir() + "/Testing/Temporary/LastTest.log"; - cmCTestLog(this, ERROR_MESSAGE, - "Output from these tests are in: " << lastTestLog - << std::endl); - cmCTestLog(this, ERROR_MESSAGE, - "Use \"--rerun-failed --output-on-failure\" to re-run the " - "failed cases verbosely." - << std::endl); - } - } return res; } -std::string cmCTest::GetTestModelString() +std::string cmCTest::GetTestModelString() const { - if (!this->Impl->SpecificGroup.empty()) { - return this->Impl->SpecificGroup; - } switch (this->Impl->TestModel) { case cmCTest::NIGHTLY: return "Nightly"; @@ -1058,6 +986,14 @@ return "Experimental"; } +std::string cmCTest::GetTestGroupString() const +{ + if (!this->Impl->SpecificGroup.empty()) { + return this->Impl->SpecificGroup; + } + return this->GetTestModelString(); +} + int cmCTest::GetTestModelFromString(const std::string& str) { if (str.empty()) { @@ -1185,177 +1121,6 @@ return true; } -bool cmCTest::RunTest(const std::vector<std::string>& argv, - std::string* output, int* retVal, std::ostream* log, - cmDuration testTimeOut, - std::vector<std::string>* environment, Encoding encoding) -{ - bool modifyEnv = (environment && !environment->empty()); - - // determine how much time we have - cmDuration timeout = this->GetRemainingTimeAllowed(); - if (timeout != cmCTest::MaxDuration()) { - timeout -= std::chrono::minutes(2); - } - if (this->Impl->TimeOut > cmDuration::zero() && - this->Impl->TimeOut < timeout) { - timeout = this->Impl->TimeOut; - } - if (testTimeOut > cmDuration::zero() && - testTimeOut < this->GetRemainingTimeAllowed()) { - timeout = testTimeOut; - } - - // always have at least 1 second if we got to here - if (timeout <= cmDuration::zero()) { - timeout = std::chrono::seconds(1); - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "Test timeout computed to be: " - << (timeout == cmCTest::MaxDuration() - ? std::string("infinite") - : std::to_string(cmDurationTo<unsigned int>(timeout))) - << "\n"); - if (cmSystemTools::SameFile(argv[0], cmSystemTools::GetCTestCommand()) && - !this->Impl->ForceNewCTestProcess) { - cmCTest inst; - inst.Impl->ConfigType = this->Impl->ConfigType; - inst.Impl->TimeOut = timeout; - - // Capture output of the child ctest. - std::ostringstream oss; - inst.SetStreams(&oss, &oss); - - std::vector<std::string> args; - for (auto const& i : argv) { - // make sure we pass the timeout in for any build and test - // invocations. Since --build-generator is required this is a - // good place to check for it, and to add the arguments in - if (i == "--build-generator" && timeout != cmCTest::MaxDuration() && - timeout > cmDuration::zero()) { - args.emplace_back("--test-timeout"); - args.push_back(std::to_string(cmDurationTo<unsigned int>(timeout))); - } - args.emplace_back(i); - } - if (log) { - *log << "* Run internal CTest" << std::endl; - } - - std::unique_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv; - if (modifyEnv) { - saveEnv = cm::make_unique<cmSystemTools::SaveRestoreEnvironment>(); - cmSystemTools::AppendEnv(*environment); - } - - *retVal = inst.Run(args, output); - if (output) { - *output += oss.str(); - } - if (log && output) { - *log << *output; - } - if (output) { - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "Internal cmCTest object used to run test." << std::endl - << *output - << std::endl); - } - - return true; - } - std::vector<char> tempOutput; - if (output) { - output->clear(); - } - - std::unique_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv; - if (modifyEnv) { - saveEnv = cm::make_unique<cmSystemTools::SaveRestoreEnvironment>(); - cmSystemTools::AppendEnv(*environment); - } - - cmUVProcessChainBuilder builder; - builder.AddCommand(argv).SetMergedBuiltinStreams(); - cmCTestLog(this, DEBUG, "Command is: " << argv[0] << std::endl); - auto chain = builder.Start(); - - cmProcessOutput processOutput(encoding); - cm::uv_pipe_ptr outputStream; - outputStream.init(chain.GetLoop(), 0); - uv_pipe_open(outputStream, chain.OutputStream()); - auto outputHandle = cmUVStreamRead( - outputStream, - [this, &processOutput, &output, &tempOutput, - &log](std::vector<char> data) { - std::string strdata; - processOutput.DecodeText(data.data(), data.size(), strdata); - if (output) { - cm::append(tempOutput, data.data(), data.data() + data.size()); - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, strdata); - if (log) { - log->write(strdata.c_str(), strdata.size()); - } - }, - [this, &processOutput, &log]() { - std::string strdata; - processOutput.DecodeText(std::string(), strdata); - if (!strdata.empty()) { - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, strdata); - if (log) { - log->write(strdata.c_str(), strdata.size()); - } - } - }); - - bool complete = chain.Wait(static_cast<uint64_t>(timeout.count() * 1000.0)); - processOutput.DecodeText(tempOutput, tempOutput); - if (output && tempOutput.begin() != tempOutput.end()) { - output->append(tempOutput.data(), tempOutput.size()); - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "-- Process completed" << std::endl); - - bool result = false; - - if (complete) { - auto const& status = chain.GetStatus(0); - auto exception = status.GetException(); - switch (exception.first) { - case cmUVProcessChain::ExceptionCode::None: - *retVal = static_cast<int>(status.ExitStatus); - if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) { - this->OutputTestErrors(tempOutput); - } - result = true; - break; - case cmUVProcessChain::ExceptionCode::Spawn: { - std::string outerr = - cmStrCat("\n*** ERROR executing: ", exception.second); - if (output) { - *output += outerr; - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); - } break; - default: { - if (this->Impl->OutputTestOutputOnTestFailure) { - this->OutputTestErrors(tempOutput); - } - *retVal = status.TermSignal; - std::string outerr = - cmStrCat("\n*** Exception executing: ", exception.second); - if (output) { - *output += outerr; - } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); - } break; - } - } - - return result; -} - std::string cmCTest::SafeBuildIdField(const std::string& value) { std::string safevalue(value); @@ -1405,7 +1170,7 @@ std::string buildname = cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName")); std::string stamp = cmCTest::SafeBuildIdField(this->Impl->CurrentTag + "-" + - this->GetTestModelString()); + this->GetTestGroupString()); std::string site = cmCTest::SafeBuildIdField(this->GetCTestConfiguration("Site")); @@ -1531,7 +1296,7 @@ xml.StartElement("Site"); xml.Attribute("BuildName", buildname); xml.Attribute("BuildStamp", - this->Impl->CurrentTag + "-" + this->GetTestModelString()); + this->Impl->CurrentTag + "-" + this->GetTestGroupString()); xml.Attribute("Name", this->GetCTestConfiguration("Site")); xml.Attribute("Generator", std::string("ctest-") + cmVersion::GetCMakeVersion()); @@ -1616,31 +1381,14 @@ return 0; } -bool cmCTest::TryToChangeDirectory(std::string const& dir) -{ - cmCTestLog(this, OUTPUT, - "Internal ctest changing into directory: " << dir << std::endl); - cmsys::Status status = cmSystemTools::ChangeDirectory(dir); - if (!status) { - auto msg = "Failed to change working directory to \"" + dir + - "\" : " + status.GetString() + "\n"; - cmCTestLog(this, ERROR_MESSAGE, msg); - return false; - } - return true; -} - std::string cmCTest::Base64GzipEncodeFile(std::string const& file) { - const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory(); - std::string parentDir = cmSystemTools::GetParentDirectory(file); - // Temporarily change to the file's directory so the tar gets created // with a flat directory structure. - if (currDir != parentDir) { - if (!this->TryToChangeDirectory(parentDir)) { - return ""; - } + cmWorkingDirectory workdir(cmSystemTools::GetParentDirectory(file)); + if (workdir.Failed()) { + cmCTestLog(this, ERROR_MESSAGE, workdir.GetError() << std::endl); + return ""; } std::string tarFile = file + "_temp.tar.gz"; @@ -1657,12 +1405,6 @@ } std::string base64 = this->Base64EncodeFile(tarFile); cmSystemTools::RemoveFile(tarFile); - - // Change back to the directory we started in. - if (currDir != parentDir) { - cmSystemTools::ChangeDirectory(currDir); - } - return base64; } @@ -1721,7 +1463,7 @@ // for a -D argument convert the next argument into // the proper list of dashboard steps via SetTest -bool cmCTest::AddTestsForDashboardType(std::string& targ) +bool cmCTest::AddTestsForDashboardType(std::string const& targ) { if (targ == "Experimental") { this->SetTestModel(cmCTest::EXPERIMENTAL); @@ -1844,7 +1586,7 @@ return true; } -void cmCTest::ErrorMessageUnknownDashDValue(std::string& val) +void cmCTest::ErrorMessageUnknownDashDValue(std::string const& val) { cmCTestLog(this, ERROR_MESSAGE, "CTest -D called with incorrect option: " << val << '\n'); @@ -1869,389 +1611,6 @@ return (arg == varg1) || (varg2 && arg == varg2); } -// Processes one command line argument (and its arguments if any) -// for many simple options and then returns -bool cmCTest::HandleCommandLineArguments(size_t& i, - std::vector<std::string>& args, - std::string& errormsg) -{ - std::string arg = args[i]; - cm::string_view noTestsPrefix = "--no-tests="; - if (this->CheckArgument(arg, "-F"_s)) { - this->Impl->Failover = true; - } else if (this->CheckArgument(arg, "-j"_s, "--parallel")) { - cm::optional<size_t> parallelLevel; - // No value or an empty value tells ctest to choose a default. - if (i + 1 < args.size() && !cmHasLiteralPrefix(args[i + 1], "-")) { - ++i; - if (!args[i].empty()) { - // A non-empty value must be a non-negative integer. - unsigned long plevel = 0; - if (!cmStrToULong(args[i], &plevel)) { - errormsg = - cmStrCat("'", arg, "' given invalid value '", args[i], "'"); - return false; - } - parallelLevel = plevel; - } - } - this->SetParallelLevel(parallelLevel); - this->Impl->ParallelLevelSetInCli = true; - } else if (cmHasPrefix(arg, "-j")) { - // The value must be a non-negative integer. - unsigned long plevel = 0; - if (!cmStrToULong(arg.substr(2), &plevel)) { - errormsg = cmStrCat("'", arg, "' given invalid value '", args[i], "'"); - return false; - } - this->SetParallelLevel(plevel); - this->Impl->ParallelLevelSetInCli = true; - } - - else if (this->CheckArgument(arg, "--repeat-until-fail"_s)) { - if (i >= args.size() - 1) { - errormsg = "'--repeat-until-fail' requires an argument"; - return false; - } - if (this->Impl->RepeatMode != cmCTest::Repeat::Never) { - errormsg = "At most one '--repeat' option may be used."; - return false; - } - i++; - long repeat = 1; - if (!cmStrToLong(args[i], &repeat)) { - errormsg = cmStrCat("'--repeat-until-fail' given non-integer value '", - args[i], "'"); - return false; - } - this->Impl->RepeatCount = static_cast<int>(repeat); - if (repeat > 1) { - this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; - } - } - - else if (this->CheckArgument(arg, "--repeat"_s)) { - if (i >= args.size() - 1) { - errormsg = "'--repeat' requires an argument"; - return false; - } - if (this->Impl->RepeatMode != cmCTest::Repeat::Never) { - errormsg = "At most one '--repeat' option may be used."; - return false; - } - i++; - cmsys::RegularExpression repeatRegex( - "^(until-fail|until-pass|after-timeout):([0-9]+)$"); - if (repeatRegex.find(args[i])) { - std::string const& count = repeatRegex.match(2); - unsigned long n = 1; - cmStrToULong(count, &n); // regex guarantees success - this->Impl->RepeatCount = static_cast<int>(n); - if (this->Impl->RepeatCount > 1) { - std::string const& mode = repeatRegex.match(1); - if (mode == "until-fail") { - this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; - } else if (mode == "until-pass") { - this->Impl->RepeatMode = cmCTest::Repeat::UntilPass; - } else if (mode == "after-timeout") { - this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout; - } - } - } else { - errormsg = cmStrCat("'--repeat' given invalid value '", args[i], "'"); - return false; - } - } - - else if (this->CheckArgument(arg, "--test-load"_s) && i < args.size() - 1) { - i++; - unsigned long load; - if (cmStrToULong(args[i], &load)) { - this->SetTestLoad(load); - } else { - cmCTestLog(this, WARNING, - "Invalid value for 'Test Load' : " << args[i] << '\n'); - } - } - - else if (this->CheckArgument(arg, "--no-compress-output"_s)) { - this->Impl->CompressTestOutput = false; - } - - else if (this->CheckArgument(arg, "--print-labels"_s)) { - this->Impl->PrintLabels = true; - } - - else if (this->CheckArgument(arg, "--http1.0"_s)) { - this->Impl->UseHTTP10 = true; - } - - else if (this->CheckArgument(arg, "--timeout"_s) && i < args.size() - 1) { - i++; - auto timeout = cmDuration(atof(args[i].c_str())); - this->Impl->GlobalTimeout = timeout; - } - - else if (this->CheckArgument(arg, "--stop-time"_s) && i < args.size() - 1) { - i++; - this->SetStopTime(args[i]); - } - - else if (this->CheckArgument(arg, "--stop-on-failure"_s)) { - this->Impl->StopOnFailure = true; - } - - else if (this->CheckArgument(arg, "-C"_s, "--build-config") && - i < args.size() - 1) { - i++; - this->SetConfigType(args[i]); - } - - else if (this->CheckArgument(arg, "--debug"_s)) { - this->Impl->Debug = true; - this->Impl->ShowLineNumbers = true; - } else if ((this->CheckArgument(arg, "--group"_s) || - // This is an undocumented / deprecated option. - // "Track" has been renamed to "Group". - this->CheckArgument(arg, "--track"_s)) && - i < args.size() - 1) { - i++; - this->Impl->SpecificGroup = args[i]; - } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) { - this->Impl->ShowLineNumbers = true; - } else if (this->CheckArgument(arg, "--no-label-summary"_s)) { - this->Impl->LabelSummary = false; - } else if (this->CheckArgument(arg, "--no-subproject-summary"_s)) { - this->Impl->SubprojectSummary = false; - } else if (this->CheckArgument(arg, "-Q"_s, "--quiet")) { - this->Impl->Quiet = true; - } else if (this->CheckArgument(arg, "--progress"_s)) { - this->Impl->TestProgressOutput = true; - } else if (this->CheckArgument(arg, "-V"_s, "--verbose")) { - this->Impl->Verbose = true; - } else if (this->CheckArgument(arg, "-VV"_s, "--extra-verbose")) { - this->Impl->ExtraVerbose = true; - this->Impl->Verbose = true; - } else if (this->CheckArgument(arg, "--output-on-failure"_s)) { - this->Impl->OutputTestOutputOnTestFailure = true; - } else if (this->CheckArgument(arg, "--test-output-size-passed"_s) && - i < args.size() - 1) { - i++; - long outputSize; - if (cmStrToLong(args[i], &outputSize)) { - this->Impl->TestHandler.SetTestOutputSizePassed( - static_cast<int>(outputSize)); - } else { - cmCTestLog(this, WARNING, - "Invalid value for '--test-output-size-passed': " << args[i] - << "\n"); - } - } else if (this->CheckArgument(arg, "--test-output-size-failed"_s) && - i < args.size() - 1) { - i++; - long outputSize; - if (cmStrToLong(args[i], &outputSize)) { - this->Impl->TestHandler.SetTestOutputSizeFailed( - static_cast<int>(outputSize)); - } else { - cmCTestLog(this, WARNING, - "Invalid value for '--test-output-size-failed': " << args[i] - << "\n"); - } - } else if (this->CheckArgument(arg, "--test-output-truncation"_s) && - i < args.size() - 1) { - i++; - if (!this->Impl->TestHandler.SetTestOutputTruncation(args[i])) { - errormsg = "Invalid value for '--test-output-truncation': " + args[i]; - return false; - } - } else if (this->CheckArgument(arg, "-N"_s, "--show-only")) { - this->Impl->ShowOnly = true; - } else if (cmHasLiteralPrefix(arg, "--show-only=")) { - this->Impl->ShowOnly = true; - - // Check if a specific format is requested. Defaults to human readable - // text. - std::string argWithFormat = "--show-only="; - std::string format = arg.substr(argWithFormat.length()); - if (format == "json-v1") { - // Force quiet mode so the only output is the json object model. - this->Impl->Quiet = true; - this->Impl->OutputAsJson = true; - this->Impl->OutputAsJsonVersion = 1; - } else if (format != "human") { - errormsg = "'--show-only=' given unknown value '" + format + "'"; - return false; - } - } - - else if (this->CheckArgument(arg, "-O"_s, "--output-log") && - i < args.size() - 1) { - i++; - this->SetOutputLogFileName(args[i]); - } - - else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) { - this->Impl->TomorrowTag = true; - } else if (this->CheckArgument(arg, "--force-new-ctest-process"_s)) { - this->Impl->ForceNewCTestProcess = true; - } else if (this->CheckArgument(arg, "-W"_s, "--max-width") && - i < args.size() - 1) { - i++; - this->Impl->MaxTestNameWidth = atoi(args[i].c_str()); - } else if (this->CheckArgument(arg, "--interactive-debug-mode"_s) && - i < args.size() - 1) { - i++; - this->Impl->InteractiveDebugMode = cmIsOn(args[i]); - } else if (this->CheckArgument(arg, "--submit-index"_s) && - i < args.size() - 1) { - i++; - this->Impl->SubmitIndex = atoi(args[i].c_str()); - if (this->Impl->SubmitIndex < 0) { - this->Impl->SubmitIndex = 0; - } - } - - else if (this->CheckArgument(arg, "--overwrite"_s) && i < args.size() - 1) { - i++; - this->AddCTestConfigurationOverwrite(args[i]); - } else if (this->CheckArgument(arg, "-A"_s, "--add-notes") && - i < args.size() - 1) { - this->Impl->ProduceXML = true; - this->SetTest("Notes"); - i++; - this->SetNotesFiles(args[i]); - return true; - } else if (this->CheckArgument(arg, "--test-dir"_s)) { - if (i >= args.size() - 1) { - errormsg = "'--test-dir' requires an argument"; - return false; - } - i++; - this->Impl->TestDir = std::string(args[i]); - } else if (this->CheckArgument(arg, "--output-junit"_s)) { - if (i >= args.size() - 1) { - errormsg = "'--output-junit' requires an argument"; - return false; - } - i++; - this->SetOutputJUnitFileName(std::string(args[i])); - } - - else if (cmHasPrefix(arg, noTestsPrefix)) { - cm::string_view noTestsMode = - cm::string_view(arg).substr(noTestsPrefix.length()); - if (noTestsMode == "error") { - this->Impl->NoTestsMode = cmCTest::NoTests::Error; - } else if (noTestsMode != "ignore") { - errormsg = - cmStrCat("'--no-tests=' given unknown value '", noTestsMode, '\''); - return false; - } else { - this->Impl->NoTestsMode = cmCTest::NoTests::Ignore; - } - this->Impl->NoTestsModeSetInCli = true; - } - - // options that control what tests are run - else if (this->CheckArgument(arg, "-I"_s, "--tests-information") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("TestsToRunInformation", - args[i]); - this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation", - args[i]); - } else if (this->CheckArgument(arg, "-U"_s, "--union")) { - this->GetTestHandler()->SetPersistentOption("UseUnion", "true"); - this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true"); - } else if (this->CheckArgument(arg, "-R"_s, "--tests-regex") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression", - args[i]); - this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression", - args[i]); - } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->AddPersistentMultiOption("LabelRegularExpression", - args[i]); - this->GetMemCheckHandler()->AddPersistentMultiOption( - "LabelRegularExpression", args[i]); - } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->AddPersistentMultiOption( - "ExcludeLabelRegularExpression", args[i]); - this->GetMemCheckHandler()->AddPersistentMultiOption( - "ExcludeLabelRegularExpression", args[i]); - } - - else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression", - args[i]); - this->GetMemCheckHandler()->SetPersistentOption("ExcludeRegularExpression", - args[i]); - } - - else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption( - "ExcludeFixtureRegularExpression", args[i]); - this->GetMemCheckHandler()->SetPersistentOption( - "ExcludeFixtureRegularExpression", args[i]); - } else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption( - "ExcludeFixtureSetupRegularExpression", args[i]); - this->GetMemCheckHandler()->SetPersistentOption( - "ExcludeFixtureSetupRegularExpression", args[i]); - } else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption( - "ExcludeFixtureCleanupRegularExpression", args[i]); - this->GetMemCheckHandler()->SetPersistentOption( - "ExcludeFixtureCleanupRegularExpression", args[i]); - } - - else if (this->CheckArgument(arg, "--resource-spec-file"_s) && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("ResourceSpecFile", args[i]); - this->GetMemCheckHandler()->SetPersistentOption("ResourceSpecFile", - args[i]); - } - - else if (this->CheckArgument(arg, "--tests-from-file"_s) && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("TestListFile", args[i]); - this->GetMemCheckHandler()->SetPersistentOption("TestListFile", args[i]); - } - - else if (this->CheckArgument(arg, "--exclude-from-file"_s) && - i < args.size() - 1) { - i++; - this->GetTestHandler()->SetPersistentOption("ExcludeTestListFile", - args[i]); - this->GetMemCheckHandler()->SetPersistentOption("ExcludeTestListFile", - args[i]); - } - - else if (this->CheckArgument(arg, "--rerun-failed"_s)) { - this->GetTestHandler()->SetPersistentOption("RerunFailed", "true"); - this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true"); - } else { - return false; - } - return true; -} - #if !defined(_WIN32) bool cmCTest::ConsoleIsNotDumb() { @@ -2296,46 +1655,6 @@ #endif } -// handle the -S -SR and -SP arguments -bool cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, - bool& SRArgumentSpecified) -{ - std::string arg = args[i]; - if (this->CheckArgument(arg, "-SP"_s, "--script-new-process") && - i < args.size() - 1) { - this->Impl->RunConfigurationScript = true; - i++; - cmCTestScriptHandler* ch = this->GetScriptHandler(); - // -SR is an internal argument, -SP should be ignored when it is passed - if (!SRArgumentSpecified) { - ch->AddConfigurationScript(args[i], false); - } - } - - else if (this->CheckArgument(arg, "-SR"_s, "--script-run") && - i < args.size() - 1) { - SRArgumentSpecified = true; - this->Impl->RunConfigurationScript = true; - i++; - cmCTestScriptHandler* ch = this->GetScriptHandler(); - ch->AddConfigurationScript(args[i], true); - } - - else if (this->CheckArgument(arg, "-S"_s, "--script") && - i < args.size() - 1) { - this->Impl->RunConfigurationScript = true; - i++; - cmCTestScriptHandler* ch = this->GetScriptHandler(); - // -SR is an internal argument, -S should be ignored when it is passed - if (!SRArgumentSpecified) { - ch->AddConfigurationScript(args[i], true); - } - } else { - return false; - } - return true; -} - bool cmCTest::AddVariableDefinition(const std::string& arg) { std::string name; @@ -2485,8 +1804,6 @@ } this->Impl->Debug = expandedPreset->Output->Debug.value_or(false); - this->Impl->ShowLineNumbers = - expandedPreset->Output->Debug.value_or(false); this->Impl->OutputTestOutputOnTestFailure = expandedPreset->Output->OutputOnFailure.value_or(false); this->Impl->Quiet = expandedPreset->Output->Quiet.value_or(false); @@ -2675,12 +1992,13 @@ } // the main entry point of ctest, called from main -int cmCTest::Run(std::vector<std::string>& args, std::string* output) +int cmCTest::Run(std::vector<std::string> const& args) { const char* ctestExec = "ctest"; bool cmakeAndTest = false; - bool executeTests = true; + bool processSteps = false; bool SRArgumentSpecified = false; + std::vector<std::pair<std::string, bool>> runScripts; // copy the command line cm::append(this->Impl->InitialCommandLineArguments, args); @@ -2702,10 +2020,10 @@ success = this->SetArgsFromPreset("", listPresets); } else { if (cmHasLiteralPrefix(*it, "--preset=")) { - auto presetName = it->substr(9); + auto const& presetName = it->substr(9); success = this->SetArgsFromPreset(presetName, listPresets); } else if (++it != args.end()) { - auto presetName = *it; + auto const& presetName = *it; success = this->SetArgsFromPreset(presetName, listPresets); } else { cmSystemTools::Error("'--preset' requires an argument"); @@ -2722,103 +2040,712 @@ } } + auto const dashD = [this, &processSteps](std::string const& targ) -> bool { + // AddTestsForDashboard parses the dashboard type and converts it + // into the separate stages + if (this->AddTestsForDashboardType(targ)) { + processSteps = true; + return true; + } + if (this->AddVariableDefinition(targ)) { + return true; + } + this->ErrorMessageUnknownDashDValue(targ); + return false; + }; + auto const dashT = [this, &processSteps, + ctestExec](std::string const& action) -> bool { + if (!this->SetTest(action, false)) { + cmCTestLog(this, ERROR_MESSAGE, + "CTest -T called with incorrect option: " << action << '\n'); + /* clang-format off */ + cmCTestLog(this, ERROR_MESSAGE, + "Available options are:\n" + " " << ctestExec << " -T all\n" + " " << ctestExec << " -T start\n" + " " << ctestExec << " -T update\n" + " " << ctestExec << " -T configure\n" + " " << ctestExec << " -T build\n" + " " << ctestExec << " -T test\n" + " " << ctestExec << " -T coverage\n" + " " << ctestExec << " -T memcheck\n" + " " << ctestExec << " -T notes\n" + " " << ctestExec << " -T submit\n"); + /* clang-format on */ + return false; + } + processSteps = true; + return true; + }; + auto const dashM = [this, &processSteps, + ctestExec](std::string const& model) -> bool { + if (cmSystemTools::LowerCase(model) == "nightly"_s) { + this->SetTestModel(cmCTest::NIGHTLY); + } else if (cmSystemTools::LowerCase(model) == "continuous"_s) { + this->SetTestModel(cmCTest::CONTINUOUS); + } else if (cmSystemTools::LowerCase(model) == "experimental"_s) { + this->SetTestModel(cmCTest::EXPERIMENTAL); + } else { + cmCTestLog(this, ERROR_MESSAGE, + "CTest -M called with incorrect option: " << model << '\n'); + /* clang-format off */ + cmCTestLog(this, ERROR_MESSAGE, + "Available options are:\n" + " " << ctestExec << " -M Continuous\n" + " " << ctestExec << " -M Experimental\n" + " " << ctestExec << " -M Nightly\n"); + /* clang-format on */ + return false; + } + processSteps = true; + return true; + }; + auto const dashSP = + [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool { + // -SR is an internal argument, -SP should be ignored when it is passed + if (!SRArgumentSpecified) { + runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script), + false); + } + return true; + }; + auto const dashSR = + [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool { + SRArgumentSpecified = true; + runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script), + true); + return true; + }; + auto const dash_S = + [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool { + // -SR is an internal argument, -S should be ignored when it is passed + if (!SRArgumentSpecified) { + runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script), + true); + } + return true; + }; + auto const dashJ = [this](cm::string_view arg, + std::string const& j) -> bool { + cm::optional<size_t> parallelLevel; + // No value or an empty value tells ctest to choose a default. + if (!j.empty()) { + // A non-empty value must be a non-negative integer. + unsigned long plevel = 0; + if (!cmStrToULong(j, &plevel)) { + cmSystemTools::Error( + cmStrCat('\'', arg, "' given invalid value '", j, '\'')); + return false; + } + parallelLevel = plevel; + } + this->SetParallelLevel(parallelLevel); + this->Impl->ParallelLevelSetInCli = true; + return true; + }; + auto const dashC = [this](std::string const& config) -> bool { + this->SetConfigType(config); + return true; + }; + auto const dashGroup = [this](std::string const& group) -> bool { + this->Impl->SpecificGroup = group; + return true; + }; + auto const dashQ = [this](std::string const&) -> bool { + this->Impl->Quiet = true; + return true; + }; + auto const dashV = [this](std::string const&) -> bool { + this->Impl->Verbose = true; + return true; + }; + auto const dashVV = [this](std::string const&) -> bool { + this->Impl->ExtraVerbose = true; + this->Impl->Verbose = true; + return true; + }; + auto const dashO = [this](std::string const& log) -> bool { + this->SetOutputLogFileName(log); + return true; + }; + auto const dashW = [this](std::string const& width) -> bool { + this->Impl->MaxTestNameWidth = atoi(width.c_str()); + return true; + }; + auto const dashA = [this, &processSteps](std::string const& notes) -> bool { + processSteps = true; + this->SetTest("Notes"); + this->SetNotesFiles(notes); + return true; + }; + auto const dashI = [this](std::string const& tests) -> bool { + this->Impl->TestHandler.SetPersistentOption("TestsToRunInformation", + tests); + this->Impl->MemCheckHandler.SetPersistentOption("TestsToRunInformation", + tests); + return true; + }; + auto const dashU = [this](std::string const&) -> bool { + this->Impl->TestHandler.SetPersistentOption("UseUnion", "true"); + this->Impl->MemCheckHandler.SetPersistentOption("UseUnion", "true"); + return true; + }; + auto const dashR = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.SetPersistentOption("IncludeRegularExpression", + expr); + this->Impl->MemCheckHandler.SetPersistentOption("IncludeRegularExpression", + expr); + return true; + }; + auto const dashE = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.SetPersistentOption("ExcludeRegularExpression", + expr); + this->Impl->MemCheckHandler.SetPersistentOption("ExcludeRegularExpression", + expr); + return true; + }; + auto const dashL = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.AddPersistentMultiOption("LabelRegularExpression", + expr); + this->Impl->MemCheckHandler.AddPersistentMultiOption( + "LabelRegularExpression", expr); + return true; + }; + auto const dashLE = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.AddPersistentMultiOption( + "ExcludeLabelRegularExpression", expr); + this->Impl->MemCheckHandler.AddPersistentMultiOption( + "ExcludeLabelRegularExpression", expr); + return true; + }; + auto const dashFA = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.SetPersistentOption( + "ExcludeFixtureRegularExpression", expr); + this->Impl->MemCheckHandler.SetPersistentOption( + "ExcludeFixtureRegularExpression", expr); + return true; + }; + auto const dashFS = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.SetPersistentOption( + "ExcludeFixtureSetupRegularExpression", expr); + this->Impl->MemCheckHandler.SetPersistentOption( + "ExcludeFixtureSetupRegularExpression", expr); + return true; + }; + auto const dashFC = [this](std::string const& expr) -> bool { + this->Impl->TestHandler.SetPersistentOption( + "ExcludeFixtureCleanupRegularExpression", expr); + this->Impl->MemCheckHandler.SetPersistentOption( + "ExcludeFixtureCleanupRegularExpression", expr); + return true; + }; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + + auto const arguments = std::vector<CommandArgument>{ + CommandArgument{ "--dashboard", CommandArgument::Values::One, dashD }, + CommandArgument{ "-D", + "-D must be followed by dashboard mode or VAR=VALUE.", + CommandArgument::Values::One, dashD }, + CommandArgument{ + "-D", "-D must be followed by dashboard mode or VAR=VALUE.", + CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, + [this](std::string const& def) -> bool { + // Unsuccessful parsing of VAR=VALUE has historically + // been ignored. + this->AddVariableDefinition(def); + return true; + } }, + CommandArgument{ "-T", CommandArgument::Values::One, dashT }, + CommandArgument{ "--test-action", CommandArgument::Values::One, dashT }, + CommandArgument{ "-M", CommandArgument::Values::One, dashM }, + CommandArgument{ "--test-model", CommandArgument::Values::One, dashM }, + CommandArgument{ "--extra-submit", CommandArgument::Values::One, + [this, &processSteps](std::string const& extra) -> bool { + processSteps = true; + this->SetTest("Submit"); + return this->SubmitExtraFiles(extra); + } }, + CommandArgument{ + "--build-and-test", "--build-and-test must have source and binary dir", + CommandArgument::Values::Two, + [this, &cmakeAndTest](std::string const& dirs) -> bool { + cmakeAndTest = true; + cmList dirList{ dirs }; + if (dirList.size() != 2) { + return false; + } + this->Impl->BuildAndTest.SourceDir = + cmSystemTools::ToNormalizedPathOnDisk(dirList[0]); + this->Impl->BuildAndTest.BinaryDir = + cmSystemTools::ToNormalizedPathOnDisk(dirList[1]); + cmSystemTools::MakeDirectory(this->Impl->BuildAndTest.BinaryDir); + return true; + } }, + CommandArgument{ "--build-target", CommandArgument::Values::One, + [this](std::string const& t) -> bool { + this->Impl->BuildAndTest.BuildTargets.emplace_back(t); + return true; + } }, + CommandArgument{ "--build-noclean", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->BuildAndTest.BuildNoClean = true; + return true; + } }, + CommandArgument{ "--build-nocmake", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->BuildAndTest.BuildNoCMake = true; + return true; + } }, + CommandArgument{ "--build-two-config", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->BuildAndTest.BuildTwoConfig = true; + return true; + } }, + CommandArgument{ "--build-run-dir", CommandArgument::Values::One, + [this](std::string const& dir) -> bool { + this->Impl->BuildAndTest.BuildRunDir = dir; + return true; + } }, + CommandArgument{ "--build-exe-dir", CommandArgument::Values::One, + [this](std::string const& dir) -> bool { + this->Impl->BuildAndTest.ExecutableDirectory = dir; + return true; + } }, + CommandArgument{ "--test-timeout", CommandArgument::Values::One, + [this](std::string const& t) -> bool { + this->Impl->BuildAndTest.Timeout = + cmDuration(atof(t.c_str())); + return true; + } }, + CommandArgument{ "--build-generator", CommandArgument::Values::One, + [this](std::string const& g) -> bool { + this->Impl->BuildAndTest.BuildGenerator = g; + return true; + } }, + CommandArgument{ "--build-generator-platform", + CommandArgument::Values::One, + [this](std::string const& p) -> bool { + this->Impl->BuildAndTest.BuildGeneratorPlatform = p; + return true; + } }, + CommandArgument{ "--build-generator-toolset", CommandArgument::Values::One, + [this](std::string const& t) -> bool { + this->Impl->BuildAndTest.BuildGeneratorToolset = t; + return true; + } }, + CommandArgument{ "--build-project", CommandArgument::Values::One, + [this](std::string const& p) -> bool { + this->Impl->BuildAndTest.BuildProject = p; + return true; + } }, + CommandArgument{ "--build-makeprogram", CommandArgument::Values::One, + [this](std::string const& p) -> bool { + this->Impl->BuildAndTest.BuildMakeProgram = p; + return true; + } }, + CommandArgument{ "--build-config-sample", CommandArgument::Values::One, + [this](std::string const& s) -> bool { + this->Impl->BuildAndTest.ConfigSample = s; + return true; + } }, + CommandArgument{ "-SP", CommandArgument::Values::One, dashSP }, + CommandArgument{ "--script-new-process", CommandArgument::Values::One, + dashSP }, + CommandArgument{ "-SR", CommandArgument::Values::One, dashSR }, + CommandArgument{ "--script-run", CommandArgument::Values::One, dashSR }, + CommandArgument{ "-S", CommandArgument::Values::One, dash_S }, + CommandArgument{ "--script", CommandArgument::Values::One, dash_S }, + CommandArgument{ "-F", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->Failover = true; + return true; + } }, + CommandArgument{ + "-j", CommandArgument::Values::ZeroOrOne, + [&dashJ](std::string const& j) -> bool { return dashJ("-j"_s, j); } }, + CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, + [&dashJ](std::string const& j) -> bool { + return dashJ("--parallel"_s, j); + } }, + CommandArgument{ "-j", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + [this](std::string const& j) -> bool { + // The value must be a non-negative integer. + unsigned long plevel = 0; + if (!cmStrToULong(j, &plevel)) { + cmSystemTools::Error( + cmStrCat("'-j' given invalid value '", j, '\'')); + return false; + } + this->SetParallelLevel(plevel); + this->Impl->ParallelLevelSetInCli = true; + return true; + } }, + CommandArgument{ + "--repeat-until-fail", "'--repeat-until-fail' requires an argument", + CommandArgument::Values::One, + [this](std::string const& r) -> bool { + if (this->Impl->RepeatMode != cmCTest::Repeat::Never) { + cmSystemTools::Error("At most one '--repeat' option may be used."); + return false; + } + long repeat = 1; + if (!cmStrToLong(r, &repeat)) { + cmSystemTools::Error(cmStrCat( + "'--repeat-until-fail' given non-integer value '", r, '\'')); + return false; + } + this->Impl->RepeatCount = static_cast<int>(repeat); + if (repeat > 1) { + this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; + } + return true; + } }, + CommandArgument{ + "--repeat", CommandArgument::Values::One, + [this](std::string const& r) -> bool { + if (this->Impl->RepeatMode != cmCTest::Repeat::Never) { + cmSystemTools::Error("At most one '--repeat' option may be used."); + return false; + } + cmsys::RegularExpression repeatRegex( + "^(until-fail|until-pass|after-timeout):([0-9]+)$"); + if (repeatRegex.find(r)) { + std::string const& count = repeatRegex.match(2); + unsigned long n = 1; + cmStrToULong(count, &n); // regex guarantees success + this->Impl->RepeatCount = static_cast<int>(n); + if (this->Impl->RepeatCount > 1) { + std::string const& mode = repeatRegex.match(1); + if (mode == "until-fail") { + this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; + } else if (mode == "until-pass") { + this->Impl->RepeatMode = cmCTest::Repeat::UntilPass; + } else if (mode == "after-timeout") { + this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout; + } + } + } else { + cmSystemTools::Error( + cmStrCat("'--repeat' given invalid value '", r, '\'')); + return false; + } + return true; + } }, + CommandArgument{ "--test-load", CommandArgument::Values::One, + [this](std::string const& l) -> bool { + unsigned long load; + if (cmStrToULong(l, &load)) { + this->SetTestLoad(load); + } else { + cmCTestLog( + this, WARNING, + "Invalid value for 'Test Load' : " << l << '\n'); + } + return true; + } }, + CommandArgument{ "--no-compress-output", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->CompressTestOutput = false; + return true; + } }, + CommandArgument{ "--print-labels", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->PrintLabels = true; + return true; + } }, + CommandArgument{ "--http1.0", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->UseHTTP10 = true; + return true; + } }, + CommandArgument{ "--timeout", CommandArgument::Values::One, + [this](std::string const& t) -> bool { + auto timeout = cmDuration(atof(t.c_str())); + this->Impl->GlobalTimeout = timeout; + return true; + } }, + CommandArgument{ "--stop-time", CommandArgument::Values::One, + [this](std::string const& t) -> bool { + this->SetStopTime(t); + return true; + } }, + CommandArgument{ "--stop-on-failure", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->StopOnFailure = true; + return true; + } }, + CommandArgument{ "-C", CommandArgument::Values::One, dashC }, + CommandArgument{ "--build-config", CommandArgument::Values::One, dashC }, + CommandArgument{ "--debug", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->Debug = true; + return true; + } }, + CommandArgument{ "--group", CommandArgument::Values::One, dashGroup }, + // This is an undocumented / deprecated option. + // "Track" has been renamed to "Group". + CommandArgument{ "--track", CommandArgument::Values::One, dashGroup }, + CommandArgument{ "--show-line-numbers", CommandArgument::Values::Zero, + [](std::string const&) -> bool { + // Silently ignore this never-documented and now-removed + // option. + return true; + } }, + CommandArgument{ "--no-label-summary", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->LabelSummary = false; + return true; + } }, + CommandArgument{ "--no-subproject-summary", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->SubprojectSummary = false; + return true; + } }, + CommandArgument{ "--progress", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->TestProgressOutput = true; + return true; + } }, + CommandArgument{ "-Q", CommandArgument::Values::Zero, dashQ }, + CommandArgument{ "--quiet", CommandArgument::Values::Zero, dashQ }, + CommandArgument{ "-V", CommandArgument::Values::Zero, dashV }, + CommandArgument{ "--verbose", CommandArgument::Values::Zero, dashV }, + CommandArgument{ "-VV", CommandArgument::Values::Zero, dashVV }, + CommandArgument{ "--extra-verbose", CommandArgument::Values::Zero, + dashVV }, + CommandArgument{ "--output-on-failure", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->OutputTestOutputOnTestFailure = true; + return true; + } }, + CommandArgument{ "--test-output-size-passed", CommandArgument::Values::One, + [this](std::string const& sz) -> bool { + long outputSize; + if (cmStrToLong(sz, &outputSize)) { + this->Impl->TestHandler.SetTestOutputSizePassed( + static_cast<int>(outputSize)); + } else { + cmCTestLog( + this, WARNING, + "Invalid value for '--test-output-size-passed': " + << sz << "\n"); + } + return true; + } }, + CommandArgument{ "--test-output-size-failed", CommandArgument::Values::One, + [this](std::string const& sz) -> bool { + long outputSize; + if (cmStrToLong(sz, &outputSize)) { + this->Impl->TestHandler.SetTestOutputSizeFailed( + static_cast<int>(outputSize)); + } else { + cmCTestLog( + this, WARNING, + "Invalid value for '--test-output-size-failed': " + << sz << "\n"); + } + return true; + } }, + CommandArgument{ + "--test-output-truncation", CommandArgument::Values::One, + [this](std::string const& mode) -> bool { + if (!this->Impl->TestHandler.SetTestOutputTruncation(mode)) { + cmSystemTools::Error( + cmStrCat("Invalid value for '--test-output-truncation': ", mode)); + return false; + } + return true; + } }, + CommandArgument{ "--show-only", CommandArgument::Values::ZeroOrOne, + [this](std::string const& format) -> bool { + this->Impl->ShowOnly = true; + // Check if a specific format is requested. + // Defaults to human readable text. + if (format == "json-v1") { + // Force quiet mode so the only output + // is the json object model. + this->Impl->Quiet = true; + this->Impl->OutputAsJson = true; + this->Impl->OutputAsJsonVersion = 1; + } else if (format == "human") { + } else if (!format.empty()) { + cmSystemTools::Error( + cmStrCat("'--show-only=' given unknown value '", + format, '\'')); + return false; + } + return true; + } }, + CommandArgument{ "-N", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->ShowOnly = true; + return true; + } }, + CommandArgument{ "-O", CommandArgument::Values::One, dashO }, + CommandArgument{ "--output-log", CommandArgument::Values::One, dashO }, + CommandArgument{ "--tomorrow-tag", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->TomorrowTag = true; + return true; + } }, + CommandArgument{ "--force-new-ctest-process", + CommandArgument::Values::Zero, + [](std::string const&) -> bool { + // Silently ignore now-removed option. + return true; + } }, + CommandArgument{ "-W", CommandArgument::Values::One, dashW }, + CommandArgument{ "--max-width", CommandArgument::Values::One, dashW }, + CommandArgument{ "--interactive-debug-mode", CommandArgument::Values::One, + [this](std::string const& idm) -> bool { + this->Impl->InteractiveDebugMode = cmIsOn(idm); + return true; + } }, + CommandArgument{ "--http-header", CommandArgument::Values::One, + [this](std::string const& h) -> bool { + this->Impl->SubmitHandler.AddCommandLineHttpHeader(h); + return true; + } }, + CommandArgument{ "--submit-index", CommandArgument::Values::One, + [this](std::string const& index) -> bool { + this->Impl->SubmitIndex = atoi(index.c_str()); + if (this->Impl->SubmitIndex < 0) { + this->Impl->SubmitIndex = 0; + } + return true; + } }, + CommandArgument{ "--overwrite", CommandArgument::Values::One, + [this](std::string const& opt) -> bool { + this->AddCTestConfigurationOverwrite(opt); + return true; + } }, + CommandArgument{ "-A", CommandArgument::Values::One, dashA }, + CommandArgument{ "--add-notes", CommandArgument::Values::One, dashA }, + CommandArgument{ "--test-dir", "'--test-dir' requires an argument", + CommandArgument::Values::One, + [this](std::string const& dir) -> bool { + this->Impl->TestDir = dir; + return true; + } }, + CommandArgument{ "--output-junit", CommandArgument::Values::One, + [this](std::string const& file) -> bool { + this->SetOutputJUnitFileName(file); + return true; + } }, + CommandArgument{ "--no-tests", CommandArgument::Values::One, + [this](std::string const& action) -> bool { + if (action == "error"_s) { + this->Impl->NoTestsMode = cmCTest::NoTests::Error; + } else if (action == "ignore"_s) { + this->Impl->NoTestsMode = cmCTest::NoTests::Ignore; + } else { + cmSystemTools::Error( + cmStrCat("'--no-tests=' given unknown value '", + action, '\'')); + return false; + } + this->Impl->NoTestsModeSetInCli = true; + return true; + } }, + CommandArgument{ "-I", CommandArgument::Values::One, dashI }, + CommandArgument{ "--tests-information", CommandArgument::Values::One, + dashI }, + CommandArgument{ "-U", CommandArgument::Values::One, dashU }, + CommandArgument{ "--union", CommandArgument::Values::One, dashU }, + CommandArgument{ "-R", CommandArgument::Values::One, dashR }, + CommandArgument{ "--tests-regex", CommandArgument::Values::One, dashR }, + CommandArgument{ "-E", CommandArgument::Values::One, dashE }, + CommandArgument{ "--exclude-regex", CommandArgument::Values::One, dashE }, + CommandArgument{ "-L", CommandArgument::Values::One, dashL }, + CommandArgument{ "--label-regex", CommandArgument::Values::One, dashL }, + CommandArgument{ "-LE", CommandArgument::Values::One, dashLE }, + CommandArgument{ "--label-exclude", CommandArgument::Values::One, dashLE }, + CommandArgument{ "-FA", CommandArgument::Values::One, dashFA }, + CommandArgument{ "--fixture-exclude-any", CommandArgument::Values::One, + dashFA }, + CommandArgument{ "-FS", CommandArgument::Values::One, dashFS }, + CommandArgument{ "--fixture-exclude-setup", CommandArgument::Values::One, + dashFS }, + CommandArgument{ "-FC", CommandArgument::Values::One, dashFC }, + CommandArgument{ "--fixture-exclude-cleanup", CommandArgument::Values::One, + dashFC }, + CommandArgument{ "--resource-spec-file", CommandArgument::Values::One, + [this](std::string const& file) -> bool { + this->Impl->TestHandler.SetPersistentOption( + "ResourceSpecFile", file); + this->Impl->MemCheckHandler.SetPersistentOption( + "ResourceSpecFile", file); + return true; + } }, + CommandArgument{ + "--tests-from-file", CommandArgument::Values::One, + [this](std::string const& file) -> bool { + this->Impl->TestHandler.SetPersistentOption("TestListFile", file); + this->Impl->MemCheckHandler.SetPersistentOption("TestListFile", file); + return true; + } }, + CommandArgument{ "--exclude-from-file", CommandArgument::Values::One, + [this](std::string const& file) -> bool { + this->Impl->TestHandler.SetPersistentOption( + "ExcludeTestListFile", file); + this->Impl->MemCheckHandler.SetPersistentOption( + "ExcludeTestListFile", file); + return true; + } }, + CommandArgument{ "--schedule-random", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->ScheduleType = "Random"; + return true; + } }, + CommandArgument{ + "--rerun-failed", CommandArgument::Values::Zero, + [this](std::string const&) -> bool { + this->Impl->TestHandler.SetPersistentOption("RerunFailed", "true"); + this->Impl->MemCheckHandler.SetPersistentOption("RerunFailed", "true"); + return true; + } }, + }; + // process the command line arguments for (size_t i = 1; i < args.size(); ++i) { - // handle the simple commandline arguments - std::string errormsg; - bool validArg = this->HandleCommandLineArguments(i, args, errormsg); - if (!validArg && !errormsg.empty()) { - cmSystemTools::Error(errormsg); - return 1; - } - std::string arg = args[i]; - - // handle the script arguments -S -SR -SP - validArg = - validArg || this->HandleScriptArguments(i, args, SRArgumentSpecified); - - // --dashboard: handle a request for a dashboard - if (this->CheckArgument(arg, "-D"_s, "--dashboard") && - i < args.size() - 1) { - this->Impl->ProduceXML = true; - i++; - std::string targ = args[i]; - // AddTestsForDashboard parses the dashboard type and converts it - // into the separate stages - if (!this->AddTestsForDashboardType(targ)) { - if (!this->AddVariableDefinition(targ)) { - this->ErrorMessageUnknownDashDValue(targ); - executeTests = false; + std::string const& arg = args[i]; + bool matched = false; + for (auto const& m : arguments) { + if (m.matches(arg)) { + matched = true; + if (!m.parse(arg, i, args)) { + return 1; } - } - validArg = true; - } - - // If it's not exactly -D, but it starts with -D, then try to parse out - // a variable definition from it, same as CMake does. Unsuccessful - // attempts are simply ignored since previous ctest versions ignore - // this too. (As well as many other unknown command line args.) - // - if (arg != "-D" && cmHasLiteralPrefix(arg, "-D")) { - std::string input = arg.substr(2); - this->AddVariableDefinition(input); - validArg = true; - } - - // --test-action: calls SetTest(<stage>, /*report=*/ false) to enable - // the corresponding stage - if (!this->HandleTestActionArgument(ctestExec, i, args, validArg)) { - executeTests = false; - } - - // --test-model: what type of test model - if (!this->HandleTestModelArgument(ctestExec, i, args, validArg)) { - executeTests = false; - } - - // --extra-submit - if (this->CheckArgument(arg, "--extra-submit"_s) && i < args.size() - 1) { - this->Impl->ProduceXML = true; - this->SetTest("Submit"); - i++; - if (!this->SubmitExtraFiles(args[i])) { - return 0; - } - validArg = true; - } - - // --build-and-test options - if (this->CheckArgument(arg, "--build-and-test"_s) && - i < args.size() - 1) { - cmakeAndTest = true; - validArg = true; - } - - // --schedule-random - if (this->CheckArgument(arg, "--schedule-random"_s)) { - this->Impl->ScheduleType = "Random"; - validArg = true; - } - - // pass the argument to all the handlers as well, but it may no longer be - // set to what it was originally so I'm not sure this is working as - // intended - for (auto& handler : this->Impl->GetTestingHandlers()) { - if (!handler->ProcessCommandLineArguments(arg, i, args, validArg)) { - cmCTestLog( - this, ERROR_MESSAGE, - "Problem parsing command line arguments within a handler\n"); - return 0; + break; } } - - if (!validArg && cmHasLiteralPrefix(arg, "-") && + if (!matched && arg == "--build-options"_s) { + matched = true; + while (i + 1 < args.size() && args[i + 1] != "--build-target"_s && + args[i + 1] != "--test-command"_s) { + ++i; + this->Impl->BuildAndTest.BuildOptions.emplace_back(args[i]); + } + } + if (!matched && arg == "--test-command"_s && i + 1 < args.size()) { + matched = true; + ++i; + this->Impl->BuildAndTest.TestCommand = args[i]; + while (i + 1 < args.size()) { + ++i; + this->Impl->BuildAndTest.TestCommandArgs.emplace_back(args[i]); + } + } + if (!matched && cmHasLiteralPrefix(arg, "-") && !cmHasLiteralPrefix(arg, "--preset")) { cmSystemTools::Error(cmStrCat("Unknown argument: ", arg)); cmSystemTools::Error("Run 'ctest --help' for all supported options."); return 1; } - } // the close of the for argument loop + } // handle CTEST_PARALLEL_LEVEL environment variable if (!this->Impl->ParallelLevelSetInCli) { @@ -2872,157 +2799,91 @@ // now what should cmake do? if --build-and-test was specified then // we run the build and test handler and return if (cmakeAndTest) { - return this->RunCMakeAndTest(output); + return this->RunCMakeAndTest(); } - if (executeTests) { - return this->ExecuteTests(); + // -S, -SP, and/or -SP was specified + if (!runScripts.empty()) { + return this->RunScripts(runScripts); } - return 1; + // -D, -T, and/or -M was specified + if (processSteps) { + return this->ProcessSteps(); + } + + return this->ExecuteTests(); } -bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i, - const std::vector<std::string>& args, - bool& validArg) +int cmCTest::RunScripts( + std::vector<std::pair<std::string, bool>> const& scripts) { - bool success = true; - std::string const& arg = args[i]; - if (this->CheckArgument(arg, "-T"_s, "--test-action") && - (i < args.size() - 1)) { - validArg = true; - this->Impl->ProduceXML = true; - i++; - if (!this->SetTest(args[i], false)) { - success = false; - cmCTestLog(this, ERROR_MESSAGE, - "CTest -T called with incorrect option: " << args[i] << '\n'); - /* clang-format off */ - cmCTestLog(this, ERROR_MESSAGE, - "Available options are:\n" - " " << ctestExec << " -T all\n" - " " << ctestExec << " -T start\n" - " " << ctestExec << " -T update\n" - " " << ctestExec << " -T configure\n" - " " << ctestExec << " -T build\n" - " " << ctestExec << " -T test\n" - " " << ctestExec << " -T coverage\n" - " " << ctestExec << " -T memcheck\n" - " " << ctestExec << " -T notes\n" - " " << ctestExec << " -T submit\n"); - /* clang-format on */ - } + if (this->Impl->ExtraVerbose) { + cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl); } - return success; -} -bool cmCTest::HandleTestModelArgument(const char* ctestExec, size_t& i, - const std::vector<std::string>& args, - bool& validArg) -{ - bool success = true; - std::string const& arg = args[i]; - if (this->CheckArgument(arg, "-M"_s, "--test-model") && - (i < args.size() - 1)) { - validArg = true; - i++; - std::string const& str = args[i]; - if (cmSystemTools::LowerCase(str) == "nightly"_s) { - this->SetTestModel(cmCTest::NIGHTLY); - } else if (cmSystemTools::LowerCase(str) == "continuous"_s) { - this->SetTestModel(cmCTest::CONTINUOUS); - } else if (cmSystemTools::LowerCase(str) == "experimental"_s) { - this->SetTestModel(cmCTest::EXPERIMENTAL); - } else { - success = false; - cmCTestLog(this, ERROR_MESSAGE, - "CTest -M called with incorrect option: " << str << '\n'); - /* clang-format off */ - cmCTestLog(this, ERROR_MESSAGE, - "Available options are:\n" - " " << ctestExec << " -M Continuous\n" - " " << ctestExec << " -M Experimental\n" - " " << ctestExec << " -M Nightly\n"); - /* clang-format on */ - } + for (auto& handler : this->Impl->GetTestingHandlers()) { + handler->SetVerbose(this->Impl->ExtraVerbose); + handler->SetSubmitIndex(this->Impl->SubmitIndex); } - return success; + + cmCTestScriptHandler* ch = this->GetScriptHandler(); + ch->SetVerbose(this->Impl->Verbose); + for (auto const& script : scripts) { + ch->AddConfigurationScript(script.first, script.second); + } + + int res = ch->ProcessHandler(); + if (res != 0) { + cmCTestLog(this, DEBUG, + "running script failing returning: " << res << std::endl); + } + + return res; } int cmCTest::ExecuteTests() { - int res; - // call process directory - if (this->Impl->RunConfigurationScript) { - if (this->Impl->ExtraVerbose) { - cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl); - } - for (auto& handler : this->Impl->GetTestingHandlers()) { - handler->SetVerbose(this->Impl->ExtraVerbose); - handler->SetSubmitIndex(this->Impl->SubmitIndex); - } - this->GetScriptHandler()->SetVerbose(this->Impl->Verbose); - res = this->GetScriptHandler()->ProcessHandler(); - if (res != 0) { - cmCTestLog(this, DEBUG, - "running script failing returning: " << res << std::endl); - } + this->Impl->ExtraVerbose = this->Impl->Verbose; + this->Impl->Verbose = true; - } else { - // What is this? -V seems to be the same as -VV, - // and Verbose is always on in this case - this->Impl->ExtraVerbose = this->Impl->Verbose; - this->Impl->Verbose = true; - for (auto& handler : this->Impl->GetTestingHandlers()) { - handler->SetVerbose(this->Impl->Verbose); - handler->SetSubmitIndex(this->Impl->SubmitIndex); - } + const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory(); + std::string workDir = currDir; + if (!this->Impl->TestDir.empty()) { + workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir); + } - const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory(); - std::string workDir = currDir; - if (!this->Impl->TestDir.empty()) { - workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir); - } + cmWorkingDirectory changeDir(workDir); + if (changeDir.Failed()) { + cmCTestLog(this, ERROR_MESSAGE, changeDir.GetError() << std::endl); + return 1; + } - if (currDir != workDir) { - if (!this->TryToChangeDirectory(workDir)) { - return 1; - } - } - - if (!this->Initialize(workDir, nullptr)) { - res = 12; + this->InitializeTesting(workDir); + this->GetTestHandler()->SetVerbose(this->Impl->Verbose); + if (this->GetTestHandler()->ProcessHandler() < 0) { + cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest\n"); + if (!this->Impl->OutputTestOutputOnTestFailure) { + const std::string lastTestLog = + this->GetBinaryDir() + "/Testing/Temporary/LastTest.log"; cmCTestLog(this, ERROR_MESSAGE, - "Problem initializing the dashboard." << std::endl); - } else { - res = this->ProcessSteps(); + "Output from these tests are in: " << lastTestLog << '\n'); + cmCTestLog(this, ERROR_MESSAGE, + "Use \"--rerun-failed --output-on-failure\" to re-run the " + "failed cases verbosely.\n"); } - this->Finalize(); + return cmCTest::TEST_ERRORS; + } - if (currDir != workDir) { - cmSystemTools::ChangeDirectory(currDir); - } - } - if (res != 0) { - cmCTestLog(this, DEBUG, - "Running a test(s) failed returning : " << res << std::endl); - } - return res; + return 0; } -int cmCTest::RunCMakeAndTest(std::string* output) +int cmCTest::RunCMakeAndTest() { - this->Impl->Verbose = true; - cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler(); - int retv = handler->ProcessHandler(); - *output = handler->GetOutput(); + int retv = this->Impl->BuildAndTest.Run(); #ifndef CMAKE_BOOTSTRAP cmDynamicLoader::FlushCache(); #endif - if (retv != 0) { - cmCTestLog(this, DEBUG, - "build and test failing returning: " << retv << std::endl); - } return retv; } @@ -3094,8 +2955,8 @@ this->Impl->ScheduleType = type; } -int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir, - cmMakefile* mf) +void cmCTest::ReadCustomConfigurationFileTree(const std::string& dir, + cmMakefile* mf) { bool found = false; cmCTestLog(this, DEBUG, @@ -3151,8 +3012,6 @@ handler.second->PopulateCustomVectors(mf); } } - - return 1; } void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def, @@ -3183,10 +3042,9 @@ std::string cmCTest::GetShortPathToFile(const std::string& cfname) { - const std::string& sourceDir = cmSystemTools::CollapseFullPath( - this->GetCTestConfiguration("SourceDirectory")); - const std::string& buildDir = cmSystemTools::CollapseFullPath( - this->GetCTestConfiguration("BuildDirectory")); + const std::string& sourceDir = + this->GetCTestConfiguration("SourceDirectory"); + const std::string& buildDir = this->GetCTestConfiguration("BuildDirectory"); std::string fname = cmSystemTools::CollapseFullPath(cfname); // Find relative paths to both directories @@ -3409,12 +3267,6 @@ return this->Impl->ExtraVerbose; } -void cmCTest::SetStreams(std::ostream* out, std::ostream* err) -{ - this->Impl->StreamOut = out; - this->Impl->StreamErr = err; -} - bool cmCTest::GetLabelSummary() const { return this->Impl->LabelSummary; @@ -3520,6 +3372,81 @@ return true; } +void cmCTest::SetCMakeVariables(cmMakefile& mf) +{ + auto set = [&](char const* cmake_var, char const* ctest_opt) { + std::string val = this->GetCTestConfiguration(ctest_opt); + if (!val.empty()) { + cmCTestOptionalLog( + this, HANDLER_VERBOSE_OUTPUT, + "SetCMakeVariable:" << cmake_var << ":" << val << std::endl, false); + mf.AddDefinition(cmake_var, val); + } + }; + + set("CTEST_SITE", "Site"); + set("CTEST_BUILD_NAME", "BuildName"); + set("CTEST_NIGHTLY_START_TIME", "NightlyStartTime"); + set("CTEST_SOURCE_DIRECTORY", "SourceDirectory"); + set("CTEST_BINARY_DIRECTORY", "BuildDirectory"); + + // CTest Update Step + set("CTEST_UPDATE_COMMAND", "UpdateCommand"); + set("CTEST_UPDATE_OPTIONS", "UpdateOptions"); + set("CTEST_CVS_COMMAND", "CVSCommand"); + set("CTEST_CVS_UPDATE_OPTIONS", "CVSUpdateOptions"); + set("CTEST_SVN_COMMAND", "SVNCommand"); + set("CTEST_SVN_UPDATE_OPTIONS", "SVNUpdateOptions"); + set("CTEST_SVN_OPTIONS", "SVNOptions"); + set("CTEST_BZR_COMMAND", "BZRCommand"); + set("CTEST_BZR_UPDATE_OPTIONS", "BZRUpdateOptions"); + set("CTEST_GIT_COMMAND", "GITCommand"); + set("CTEST_GIT_UPDATE_OPTIONS", "GITUpdateOptions"); + set("CTEST_GIT_INIT_SUBMODULES", "GITInitSubmodules"); + set("CTEST_GIT_UPDATE_CUSTOM", "GITUpdateCustom"); + set("CTEST_UPDATE_VERSION_ONLY", "UpdateVersionOnly"); + set("CTEST_UPDATE_VERSION_OVERRIDE", "UpdateVersionOverride"); + set("CTEST_HG_COMMAND", "HGCommand"); + set("CTEST_HG_UPDATE_OPTIONS", "HGUpdateOptions"); + set("CTEST_P4_COMMAND", "P4Command"); + set("CTEST_P4_UPDATE_OPTIONS", "P4UpdateOptions"); + set("CTEST_P4_CLIENT", "P4Client"); + set("CTEST_P4_OPTIONS", "P4Options"); + + // CTest Configure Step + set("CTEST_CONFIGURE_COMMAND", "ConfigureCommand"); + set("CTEST_LABELS_FOR_SUBPROJECTS", "LabelsForSubprojects"); + + // CTest Build Step + set("CTEST_BUILD_COMMAND", "MakeCommand"); + set("CTEST_USE_LAUNCHERS", "UseLaunchers"); + + // CTest Coverage Step + set("CTEST_COVERAGE_COMMAND", "CoverageCommand"); + set("CTEST_COVERAGE_EXTRA_FLAGS", "CoverageExtraFlags"); + + // CTest MemCheck Step + set("CTEST_MEMORYCHECK_TYPE", "MemoryCheckType"); + set("CTEST_MEMORYCHECK_SANITIZER_OPTIONS", "MemoryCheckSanitizerOptions"); + set("CTEST_MEMORYCHECK_COMMAND", "MemoryCheckCommand"); + set("CTEST_MEMORYCHECK_COMMAND_OPTIONS", "MemoryCheckCommandOptions"); + set("CTEST_MEMORYCHECK_SUPPRESSIONS_FILE", "MemoryCheckSuppressionFile"); + + // CTest Submit Step + set("CTEST_SUBMIT_URL", "SubmitURL"); + set("CTEST_DROP_METHOD", "DropMethod"); + set("CTEST_DROP_SITE_USER", "DropSiteUser"); + set("CTEST_DROP_SITE_PASSWORD", "DropSitePassword"); + set("CTEST_DROP_SITE", "DropSite"); + set("CTEST_DROP_LOCATION", "DropLocation"); + set("CTEST_TLS_VERIFY", "TLSVerify"); + set("CTEST_TLS_VERSION", "TLSVersion"); + set("CTEST_CURL_OPTIONS", "CurlOptions"); + set("CTEST_SUBMIT_INACTIVITY_TIMEOUT", "SubmitInactivityTimeout"); + + this->GetTestHandler()->SetCMakeVariables(mf); +} + bool cmCTest::RunCommand(std::vector<std::string> const& args, std::string* stdOut, std::string* stdErr, int* retVal, const char* dir, cmDuration timeout, @@ -3663,20 +3590,11 @@ "HANDLER_TEST_PROGRESS_OUTPUT", "HANDLER_VERBOSE_OUTPUT", "WARNING", - "ERROR_MESSAGE", - nullptr }; + "ERROR_MESSAGE" }; -#define cmCTestLogOutputFileLine(stream) \ - do { \ - if (this->Impl->ShowLineNumbers) { \ - (stream) << std::endl << file << ":" << line << " "; \ - } \ - } while (false) - -void cmCTest::Log(int logType, const char* file, int line, const char* msg, - bool suppress) +void cmCTest::Log(LogType logType, std::string msg, bool suppress) { - if (!msg || !*msg) { + if (msg.empty()) { return; } if (suppress && logType != cmCTest::ERROR_MESSAGE) { @@ -3696,49 +3614,38 @@ display = false; } if (display) { - cmCTestLogOutputFileLine(*this->Impl->OutputLogFile); - if (logType != this->Impl->OutputLogFileLastTag) { - *this->Impl->OutputLogFile << "["; - if (logType >= OTHER || logType < 0) { - *this->Impl->OutputLogFile << "OTHER"; - } else { - *this->Impl->OutputLogFile << cmCTestStringLogType[logType]; - } - *this->Impl->OutputLogFile << "] " << std::endl; + if (this->Impl->OutputLogFileLastTag && + logType != *this->Impl->OutputLogFileLastTag) { + *this->Impl->OutputLogFile << "[" << cmCTestStringLogType[logType] + << "] " << std::endl; } *this->Impl->OutputLogFile << msg << std::flush; - if (logType != this->Impl->OutputLogFileLastTag) { + if (this->Impl->OutputLogFileLastTag && + logType != *this->Impl->OutputLogFileLastTag) { *this->Impl->OutputLogFile << std::endl; this->Impl->OutputLogFileLastTag = logType; } } } if (!this->Impl->Quiet) { - std::ostream& out = *this->Impl->StreamOut; - std::ostream& err = *this->Impl->StreamErr; - if (logType == HANDLER_TEST_PROGRESS_OUTPUT) { if (this->Impl->TestProgressOutput) { - cmCTestLogOutputFileLine(out); if (this->Impl->FlushTestProgressLine) { printf("\r"); this->Impl->FlushTestProgressLine = false; - out.flush(); + std::cout.flush(); } - std::string msg_str{ msg }; - auto const lineBreakIt = msg_str.find('\n'); - if (lineBreakIt != std::string::npos) { + if (msg.find('\n') != std::string::npos) { this->Impl->FlushTestProgressLine = true; - msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'), - msg_str.end()); + msg.erase(std::remove(msg.begin(), msg.end(), '\n'), msg.end()); } - out << msg_str; + std::cout << msg; #ifndef _WIN32 printf("\x1B[K"); // move caret to end #endif - out.flush(); + std::cout.flush(); return; } logType = HANDLER_OUTPUT; @@ -3747,41 +3654,29 @@ switch (logType) { case DEBUG: if (this->Impl->Debug) { - cmCTestLogOutputFileLine(out); - out << msg; - out.flush(); + std::cout << msg << std::flush; } break; case OUTPUT: case HANDLER_OUTPUT: if (this->Impl->Debug || this->Impl->Verbose) { - cmCTestLogOutputFileLine(out); - out << msg; - out.flush(); + std::cout << msg << std::flush; } break; case HANDLER_VERBOSE_OUTPUT: if (this->Impl->Debug || this->Impl->ExtraVerbose) { - cmCTestLogOutputFileLine(out); - out << msg; - out.flush(); + std::cout << msg << std::flush; } break; case WARNING: - cmCTestLogOutputFileLine(err); - err << msg; - err.flush(); + std::cerr << msg << std::flush; break; case ERROR_MESSAGE: - cmCTestLogOutputFileLine(err); - err << msg; - err.flush(); + std::cerr << msg << std::flush; cmSystemTools::SetErrorOccurred(); break; default: - cmCTestLogOutputFileLine(out); - out << msg; - out.flush(); + std::cout << msg << std::flush; } } } @@ -3805,20 +3700,6 @@ return cmDuration(1.0e7); } -void cmCTest::SetRunCurrentScript(bool value) -{ - this->GetScriptHandler()->SetRunCurrentScript(value); -} - -void cmCTest::OutputTestErrors(std::vector<char> const& process_output) -{ - std::string test_outputs("\n*** Test Failed:\n"); - if (!process_output.empty()) { - test_outputs.append(process_output.data(), process_output.size()); - } - cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl); -} - bool cmCTest::CompressString(std::string& str) { int ret;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 85f75fd..633725c 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h
@@ -10,6 +10,7 @@ #include <memory> #include <sstream> #include <string> +#include <utility> #include <vector> #include <cm/optional> @@ -19,7 +20,6 @@ #include "cmProcessOutput.h" class cmCTestBuildHandler; -class cmCTestBuildAndTestHandler; class cmCTestCoverageHandler; class cmCTestScriptHandler; class cmCTestTestHandler; @@ -28,7 +28,6 @@ class cmCTestMemCheckHandler; class cmCTestSubmitHandler; class cmCTestUploadHandler; -class cmCTestStartCommand; class cmGeneratedFileStream; class cmMakefile; class cmXMLWriter; @@ -67,30 +66,21 @@ Part GetPartFromName(const std::string& name); /** Process Command line arguments */ - int Run(std::vector<std::string>&, std::string* output = nullptr); + int Run(std::vector<std::string> const& args); + + /** Initialize a dashboard run in the given build tree. */ + void Initialize(std::string const& binary_dir); + + bool CreateNewTag(bool quiet); + bool ReadExistingTag(bool quiet); /** - * Initialize and finalize testing + * Initialize ctest for executing tests. */ - bool InitializeFromCommand(cmCTestStartCommand* command); - void Finalize(); + void InitializeTesting(const std::string& binary_dir); /** * Process the dashboard client steps. - * - * Steps are enabled using SetTest() - * - * The execution of the steps (or #Part) should look like this: - * - * /code - * ctest foo; - * foo.Initialize(); - * // Set some things on foo - * foo.ProcessSteps(); - * foo.Finalize(); - * /endcode - * - * \sa Initialize(), Finalize(), Part, PartInfo, SetTest() */ int ProcessSteps(); @@ -140,7 +130,8 @@ void SetTestModel(int mode); int GetTestModel() const; - std::string GetTestModelString(); + std::string GetTestModelString() const; + std::string GetTestGroupString() const; static int GetTestModelFromString(const std::string& str); static std::string CleanString(const std::string& str, std::string::size_type spos = 0); @@ -299,21 +290,9 @@ void SetProduceXML(bool v); /** - * Run command specialized for tests. Returns process status and retVal is - * return value or exception. If environment is non-null, it is used to set - * environment variables prior to running the test. After running the test, - * environment variables are restored to their previous values. - */ - bool RunTest(const std::vector<std::string>& args, std::string* output, - int* retVal, std::ostream* logfile, cmDuration testTimeOut, - std::vector<std::string>* environment, - Encoding encoding = cmProcessOutput::Auto); - - /** * Get the handler object */ cmCTestBuildHandler* GetBuildHandler(); - cmCTestBuildAndTestHandler* GetBuildAndTestHandler(); cmCTestCoverageHandler* GetCoverageHandler(); cmCTestScriptHandler* GetScriptHandler(); cmCTestTestHandler* GetTestHandler(); @@ -331,6 +310,11 @@ const std::string& cmake_var, bool suppress = false); + /** + * Set CMake variables from CTest Options + */ + void SetCMakeVariables(cmMakefile& mf); + /** Decode a URL to the original string. */ static std::string DecodeURL(const std::string&); @@ -367,9 +351,9 @@ void SetConfigType(const std::string& ct); /** Various log types */ - enum + enum LogType { - DEBUG = 0, + DEBUG, OUTPUT, HANDLER_OUTPUT, HANDLER_PROGRESS_OUTPUT, @@ -377,12 +361,10 @@ HANDLER_VERBOSE_OUTPUT, WARNING, ERROR_MESSAGE, - OTHER }; /** Add log to the output */ - void Log(int logType, const char* file, int line, const char* msg, - bool suppress = false); + void Log(LogType logType, std::string msg, bool suppress = false); /** Color values */ enum class Color @@ -409,7 +391,7 @@ /** * Read the custom configuration files and apply them to the current ctest */ - int ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf); + void ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf); std::vector<std::string>& GetInitialCommandLineArguments(); @@ -425,9 +407,6 @@ bool GetVerbose() const; bool GetExtraVerbose() const; - /** Direct process output to given streams. */ - void SetStreams(std::ostream* out, std::ostream* err); - void AddSiteProperties(cmXMLWriter& xml); bool GetLabelSummary() const; @@ -462,7 +441,8 @@ void GenerateSubprojectsOutput(cmXMLWriter& xml); std::vector<std::string> GetLabelsForSubprojects(); - void SetRunCurrentScript(bool value); + /** Reread the configuration file */ + bool UpdateCTestConfiguration(); private: void SetPersistentOptionIfNotEmpty(const std::string& value, @@ -474,21 +454,11 @@ void BlockTestErrorDiagnostics(); - /** - * Initialize a dashboard run in the given build tree. The "command" - * argument is non-NULL when running from a command-driven (ctest_start) - * dashboard script, and NULL when running from the CTest command - * line. Note that a declarative dashboard script does not actually - * call this method because it sets CTEST_COMMAND to drive a build - * through the ctest command line. - */ - int Initialize(const std::string& binary_dir, cmCTestStartCommand* command); - /** parse the option after -D and convert it into the appropriate steps */ - bool AddTestsForDashboardType(std::string& targ); + bool AddTestsForDashboardType(std::string const& targ); /** read as "emit an error message for an unknown -D value" */ - void ErrorMessageUnknownDashDValue(std::string& val); + void ErrorMessageUnknownDashDValue(std::string const& val); /** add a variable definition from a command line -D value */ bool AddVariableDefinition(const std::string& arg); @@ -496,10 +466,6 @@ /** set command line arguments read from a test preset */ bool SetArgsFromPreset(const std::string& presetName, bool listPresets); - /** parse and process most common command line arguments */ - bool HandleCommandLineArguments(size_t& i, std::vector<std::string>& args, - std::string& errormsg); - #if !defined(_WIN32) /** returns true iff the console supports progress output */ static bool ConsoleIsNotDumb(); @@ -511,13 +477,6 @@ /** returns true iff the console supports colored output */ static bool ColoredOutputSupportedByConsole(); - /** handle the -S -SP and -SR arguments */ - bool HandleScriptArguments(size_t& i, std::vector<std::string>& args, - bool& SRArgumentSpecified); - - /** Reread the configuration file */ - bool UpdateCTestConfiguration(); - /** Create note from files. */ int GenerateCTestNotesOutput(cmXMLWriter& xml, std::vector<std::string> const& files); @@ -526,25 +485,10 @@ static bool CheckArgument(const std::string& arg, cm::string_view varg1, const char* varg2 = nullptr); - /** Output errors from a test */ - void OutputTestErrors(std::vector<char> const& process_output); - - /** Handle the --test-action command line argument */ - bool HandleTestActionArgument(const char* ctestExec, size_t& i, - const std::vector<std::string>& args, - bool& validArg); - - /** Handle the --test-model command line argument */ - bool HandleTestModelArgument(const char* ctestExec, size_t& i, - const std::vector<std::string>& args, - bool& validArg); - - int RunCMakeAndTest(std::string* output); + int RunCMakeAndTest(); + int RunScripts(std::vector<std::pair<std::string, bool>> const& scripts); int ExecuteTests(); - /** return true iff change directory was successful */ - bool TryToChangeDirectory(std::string const& dir); - struct Private; std::unique_ptr<Private> Impl; }; @@ -553,14 +497,12 @@ do { \ std::ostringstream cmCTestLog_msg; \ cmCTestLog_msg << msg; \ - (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__, \ - cmCTestLog_msg.str().c_str()); \ + (ctSelf)->Log(cmCTest::logType, cmCTestLog_msg.str()); \ } while (false) #define cmCTestOptionalLog(ctSelf, logType, msg, suppress) \ do { \ std::ostringstream cmCTestLog_msg; \ cmCTestLog_msg << msg; \ - (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__, \ - cmCTestLog_msg.str().c_str(), suppress); \ + (ctSelf)->Log(cmCTest::logType, cmCTestLog_msg.str(), suppress); \ } while (false)
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index 003e972..15a1f70 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h
@@ -2,7 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once +#include <cctype> + #include <cm/optional> +#include <cm/string_view> #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -126,7 +129,7 @@ if (input.size() == this->Name.size()) { auto nextValueIndex = index + 1; if (nextValueIndex >= allArgs.size() || - allArgs[nextValueIndex][0] == '-') { + IsFlag(allArgs[nextValueIndex])) { if (this->Type == Values::ZeroOrOne) { parseState = this->StoreCall(std::string{}, std::forward<CallState>(state)...) @@ -153,8 +156,8 @@ } } else if (this->Type == Values::Two) { if (input.size() == this->Name.size()) { - if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' || - allArgs[index + 2][0] == '-') { + if (index + 2 >= allArgs.size() || IsFlag(allArgs[index + 1]) || + IsFlag(allArgs[index + 2])) { parseState = ParseMode::ValueError; } else { index += 2; @@ -169,12 +172,12 @@ if (input.size() == this->Name.size()) { auto nextValueIndex = index + 1; if (nextValueIndex >= allArgs.size() || - allArgs[nextValueIndex][0] == '-') { + IsFlag(allArgs[nextValueIndex])) { parseState = ParseMode::ValueError; } else { std::string buffer = allArgs[nextValueIndex++]; while (nextValueIndex < allArgs.size() && - allArgs[nextValueIndex][0] != '-') { + !IsFlag(allArgs[nextValueIndex])) { buffer = cmStrCat(buffer, ";", allArgs[nextValueIndex++]); } parseState = @@ -281,4 +284,10 @@ } return std::string(possible_value); } + + static bool IsFlag(cm::string_view arg) + { + return !arg.empty() && arg[0] == '-' && + !(arg.size() >= 2 && std::isdigit(arg[1])); + } };
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 26ff326..bd40115 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx
@@ -1883,6 +1883,7 @@ // foo ==> -lfoo // libfoo.a ==> -Wl,-Bstatic -lfoo + const cm::string_view LINKER{ "LINKER:" }; BT<std::string> const& item = entry.Item; if (item.Value[0] == '-' || item.Value[0] == '$' || item.Value[0] == '`') { @@ -1905,6 +1906,13 @@ this->Items.emplace_back(item, ItemIsPath::No); return; } + if (cmHasPrefix(item.Value, LINKER)) { + std::vector<BT<std::string>> linkerFlag{ 1, item }; + this->Target->ResolveLinkerWrapper(linkerFlag, this->GetLinkLanguage(), + true); + this->Items.emplace_back(linkerFlag.front(), ItemIsPath::No); + return; + } // Parse out the prefix, base, and suffix components of the // library name. If the name matches that of a shared or static
diff --git a/Source/cmDebuggerAdapter.cxx b/Source/cmDebuggerAdapter.cxx index c2e0d4f..0eacd0c 100644 --- a/Source/cmDebuggerAdapter.cxx +++ b/Source/cmDebuggerAdapter.cxx
@@ -70,7 +70,7 @@ { } - inline void Notify() + void Notify() { std::unique_lock<std::mutex> lock(Mutex); Count++; @@ -78,7 +78,7 @@ Cv.notify_one(); } - inline void Wait() + void Wait() { std::unique_lock<std::mutex> lock(Mutex); while (Count == 0) {
diff --git a/Source/cmDebuggerVariables.h b/Source/cmDebuggerVariables.h index 753b811..0c4a416 100644 --- a/Source/cmDebuggerVariables.h +++ b/Source/cmDebuggerVariables.h
@@ -102,22 +102,16 @@ std::shared_ptr<cmDebuggerVariablesManager> variablesManager, std::string name, bool supportsVariableType, std::function<std::vector<cmDebuggerVariableEntry>()> getKeyValuesFunc); - inline int64_t GetId() const noexcept { return this->Id; } - inline std::string GetName() const noexcept { return this->Name; } - inline std::string GetValue() const noexcept { return this->Value; } - inline void SetValue(std::string const& value) noexcept - { - this->Value = value; - } + int64_t GetId() const noexcept { return this->Id; } + std::string GetName() const noexcept { return this->Name; } + std::string GetValue() const noexcept { return this->Value; } + void SetValue(std::string const& value) noexcept { this->Value = value; } void AddSubVariables(std::shared_ptr<cmDebuggerVariables> const& variables); - inline void SetIgnoreEmptyStringEntries(bool value) noexcept + void SetIgnoreEmptyStringEntries(bool value) noexcept { this->IgnoreEmptyStringEntries = value; } - inline void SetEnableSorting(bool value) noexcept - { - this->EnableSorting = value; - } + void SetEnableSorting(bool value) noexcept { this->EnableSorting = value; } virtual ~cmDebuggerVariables(); };
diff --git a/Source/cmDocumentationEntry.h b/Source/cmDocumentationEntry.h index d971836..2a26ecd 100644 --- a/Source/cmDocumentationEntry.h +++ b/Source/cmDocumentationEntry.h
@@ -17,7 +17,7 @@ } #endif - std::string Name = {}; - std::string Brief = {}; + std::string Name; + std::string Brief; char CustomNamePrefix = ' '; };
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index b85b2f5..310966f 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx
@@ -126,6 +126,8 @@ const std::ptrdiff_t width = this->TextWidth - this->TextIndent; std::ptrdiff_t column = 0; + const auto padding = std::string(this->TextIndent, ' '); + // Loop until the end of the text. for (const char *l = text.c_str(), *r = skipToSpace(text.c_str()); *l; l = skipSpaces(r), r = skipToSpace(l)) { @@ -141,7 +143,7 @@ } else if (!firstLine && this->TextIndent) { // First word on line. Print indentation unless this is the // first line. - os << std::string(this->TextIndent, ' '); + os << padding; } // Print the word. @@ -164,7 +166,7 @@ os << '\n'; firstLine = false; if (r > l) { - os << std::string(this->TextIndent, ' '); + os << padding; os.write(l, r - l); column = r - l; newSentence = (*(r - 1) == '.');
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 003f47b..99d0ba4 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx
@@ -509,7 +509,7 @@ return 0; } ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; - return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j); + return sec.sh_offset + sec.sh_entsize * static_cast<unsigned long>(j); } template <class Types>
diff --git a/Source/cmExportCMakeConfigGenerator.cxx b/Source/cmExportCMakeConfigGenerator.cxx index 4f4765c..522c1c8 100644 --- a/Source/cmExportCMakeConfigGenerator.cxx +++ b/Source/cmExportCMakeConfigGenerator.cxx
@@ -185,7 +185,7 @@ // Isolate the file policy level. // Support CMake versions as far back as the // RequiredCMakeVersion{Major,Minor,Patch}, but also support using NEW - // policy settings for up to CMake 3.29 (this upper limit may be reviewed + // policy settings for up to CMake 3.30 (this upper limit may be reviewed // and increased from time to time). This reduces the opportunity for CMake // warnings when an older export file is later used with newer CMake // versions. @@ -194,7 +194,7 @@ << "cmake_policy(VERSION " << this->RequiredCMakeVersionMajor << '.' << this->RequiredCMakeVersionMinor << '.' - << this->RequiredCMakeVersionPatch << "...3.29)\n"; + << this->RequiredCMakeVersionPatch << "...3.30)\n"; /* clang-format on */ }
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 92e6b3e..9cb8d90 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx
@@ -1420,6 +1420,7 @@ std::string oldPolicyPath = cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory); oldPolicyPath = cmSystemTools::GetRealPath(oldPolicyPath); + oldPolicyPath = cmSystemTools::GetActualCaseForPath(oldPolicyPath); if (warnAbout152) { computeNewPath(input, realPath); if (oldPolicyPath != realPath) { @@ -3852,8 +3853,7 @@ cmWorkingDirectory workdir(destDir); if (workdir.Failed()) { - status.SetError( - cmStrCat("failed to change working directory to: ", destDir)); + status.SetError(workdir.GetError()); cmSystemTools::SetFatalErrorOccurred(); return false; }
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 686162b..47d3d51 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx
@@ -713,7 +713,7 @@ if (!source.empty()) { dir.Load(source); } - unsigned long numFiles = static_cast<unsigned long>(dir.GetNumberOfFiles()); + unsigned long numFiles = dir.GetNumberOfFiles(); for (unsigned long fileNum = 0; fileNum < numFiles; ++fileNum) { if (!(strcmp(dir.GetFile(fileNum), ".") == 0 || strcmp(dir.GetFile(fileNum), "..") == 0)) {
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 81e081c..ed29b82 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx
@@ -56,7 +56,9 @@ } else if (argsIn[j] == "ENV") { if (j + 1 < size) { j++; - cmSystemTools::GetPath(args, argsIn[j].c_str()); + std::vector<std::string> p = + cmSystemTools::GetEnvPathNormalized(argsIn[j]); + std::move(p.begin(), p.end(), std::back_inserter(args)); } } else { args.push_back(argsIn[j]); @@ -338,7 +340,6 @@ struct entry_to_remove { entry_to_remove(std::string const& name, cmMakefile* makefile) - : value() { if (cmValue to_skip = makefile->GetDefinition( cmStrCat("_CMAKE_SYSTEM_PREFIX_PATH_", name, "_PREFIX_COUNT"))) { @@ -404,9 +405,11 @@ cmList expanded{ *prefix_paths }; install_entry.remove_self(expanded); staging_entry.remove_self(expanded); - - paths.AddPrefixPaths(expanded, - this->Makefile->GetCurrentSourceDirectory().c_str()); + for (std::string& p : expanded) { + p = cmSystemTools::CollapseFullPath( + p, this->Makefile->GetCurrentSourceDirectory()); + } + paths.AddPrefixPaths(expanded); } else if (add_install_prefix && !install_prefix_in_list) { paths.AddCMakePrefixPath("CMAKE_INSTALL_PREFIX"); paths.AddCMakePrefixPath("CMAKE_STAGING_PREFIX"); @@ -494,7 +497,6 @@ this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory())) .Normal() .GenericString(); - // value = cmSystemTools::CollapseFullPath(*existingValue); if (!cmSystemTools::FileExists(value, false)) { value = *existingValue; }
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 9df7665..c5a6038 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx
@@ -220,9 +220,6 @@ }; std::vector<Name> Names; - // Current full path under consideration. - std::string TestPath; - void RegexFromLiteral(std::string& out, std::string const& in); void RegexFromList(std::string& out, cmList const& in); size_type GetPrefixIndex(std::string const& prefix) @@ -423,20 +420,17 @@ // one cannot tell just from the library name whether it is a static // library or an import library). if (name.TryRaw) { - this->TestPath = cmStrCat(path, name.Raw); + std::string testPath = cmStrCat(path, name.Raw); - const bool exists = cmSystemTools::FileExists(this->TestPath, true); - if (!exists) { - this->DebugLibraryFailed(name.Raw, path); - } else { - auto testPath = cmSystemTools::CollapseFullPath(this->TestPath); + if (cmSystemTools::FileExists(testPath, true)) { + testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath); if (this->Validate(testPath)) { this->DebugLibraryFound(name.Raw, path); this->BestPath = testPath; return true; } - this->DebugLibraryFailed(name.Raw, path); } + this->DebugLibraryFailed(name.Raw, path); } // No library file has yet been found. @@ -446,9 +440,7 @@ unsigned int bestMinor = 0; // Search for a file matching the library name regex. - std::string dir = path; - cmSystemTools::ConvertToUnixSlashes(dir); - std::set<std::string> const& files = this->GG->GetDirectoryContent(dir); + std::set<std::string> const& files = this->GG->GetDirectoryContent(path); for (std::string const& origName : files) { #if defined(_WIN32) || defined(__APPLE__) std::string testName = cmSystemTools::LowerCase(origName); @@ -456,14 +448,15 @@ std::string const& testName = origName; #endif if (name.Regex.find(testName)) { - this->TestPath = cmStrCat(path, origName); + std::string testPath = cmStrCat(path, origName); // Make sure the path is readable and is not a directory. - if (cmSystemTools::FileExists(this->TestPath, true)) { - if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) { + if (cmSystemTools::FileExists(testPath, true)) { + testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath); + if (!this->Validate(testPath)) { continue; } - this->DebugLibraryFound(name.Raw, dir); + this->DebugLibraryFound(name.Raw, path); // This is a matching file. Check if it is better than the // best name found so far. Earlier prefixes are preferred, // followed by earlier suffixes. For OpenBSD, shared library @@ -480,7 +473,7 @@ (prefix == bestPrefix && suffix == bestSuffix && (major > bestMajor || (major == bestMajor && minor > bestMinor)))) { - this->BestPath = this->TestPath; + this->BestPath = testPath; bestPrefix = prefix; bestSuffix = suffix; bestMajor = major; @@ -491,7 +484,7 @@ } if (this->BestPath.empty()) { - this->DebugLibraryFailed(name.Raw, dir); + this->DebugLibraryFailed(name.Raw, path); } else { this->DebugLibraryFound(name.Raw, this->BestPath); } @@ -560,7 +553,7 @@ for (std::string const& n : this->Names) { fwPath = cmStrCat(d, n, ".xcframework"); if (cmSystemTools::FileIsDirectory(fwPath)) { - auto finalPath = cmSystemTools::CollapseFullPath(fwPath); + auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath); if (this->Validate(finalPath)) { return finalPath; } @@ -568,7 +561,7 @@ fwPath = cmStrCat(d, n, ".framework"); if (cmSystemTools::FileIsDirectory(fwPath)) { - auto finalPath = cmSystemTools::CollapseFullPath(fwPath); + auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath); if (this->Validate(finalPath)) { return finalPath; } @@ -588,7 +581,7 @@ for (std::string const& d : this->SearchPaths) { fwPath = cmStrCat(d, n, ".xcframework"); if (cmSystemTools::FileIsDirectory(fwPath)) { - auto finalPath = cmSystemTools::CollapseFullPath(fwPath); + auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath); if (this->Validate(finalPath)) { return finalPath; } @@ -596,7 +589,7 @@ fwPath = cmStrCat(d, n, ".framework"); if (cmSystemTools::FileIsDirectory(fwPath)) { - auto finalPath = cmSystemTools::CollapseFullPath(fwPath); + auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath); if (this->Validate(finalPath)) { return finalPath; }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index cc150fd..67b42a3 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx
@@ -164,8 +164,7 @@ { public: cmCaseInsensitiveDirectoryListGenerator(cm::string_view name) - : DirectoryLister{} - , DirName{ name } + : DirName{ name } { } @@ -209,7 +208,6 @@ public: cmDirectoryListGenerator(std::vector<std::string> const& names) : Names{ names } - , Matches{} , Current{ this->Matches.cbegin() } { } @@ -332,8 +330,6 @@ public: cmFileListGeneratorGlob(cm::string_view pattern) : Pattern(pattern) - , Files{} - , Current{} { } @@ -1965,11 +1961,13 @@ cmExpandList(*rootDEF, rootPaths); } if (rootEnv) { - std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv); + std::vector<std::string> p = + cmSystemTools::SplitEnvPathNormalized(*rootEnv); std::move(p.begin(), p.end(), std::back_inserter(rootPaths)); } if (rootENV) { - std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV); + std::vector<std::string> p = + cmSystemTools::SplitEnvPathNormalized(*rootENV); std::move(p.begin(), p.end(), std::back_inserter(rootPaths)); } } @@ -2120,9 +2118,9 @@ // Use the system search path to generate prefixes. // Relative paths are interpreted with respect to the current // working directory. - std::vector<std::string> tmp; - cmSystemTools::GetPath(tmp); - for (std::string const& i : tmp) { + std::vector<std::string> envPATH = + cmSystemTools::GetEnvPathNormalized("PATH"); + for (std::string const& i : envPATH) { // If the path is a PREFIX/bin case then add its parent instead. if ((cmHasLiteralSuffix(i, "/bin")) || (cmHasLiteralSuffix(i, "/sbin"))) { paths.AddPath(cmSystemTools::GetFilenamePath(i));
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 74a69d8..b6a7834 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx
@@ -106,7 +106,7 @@ globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); if (!files.empty()) { - std::string fheader = cmSystemTools::CollapseFullPath(files[0]); + std::string fheader = cmSystemTools::ToNormalizedPathOnDisk(files[0]); debug.FoundAt(fheader); if (this->IncludeFileInPath) { return fheader;
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index dd22b41..51be6e0 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx
@@ -48,12 +48,6 @@ // Current names under consideration. std::vector<std::string> Names; - // Current name with extension under consideration. - std::string TestNameExt; - - // Current full path under consideration. - std::string TestPath; - // Debug state cmFindBaseDebugState DebugSearches; cmMakefile* Makefile; @@ -81,8 +75,6 @@ { return std::any_of(this->Names.begin(), this->Names.end(), [this, &path](std::string const& n) -> bool { - // Only perform search relative to current directory - // if the file name contains a directory separator. return this->CheckDirectoryForName(path, n); }); } @@ -93,20 +85,23 @@ if (!ext.empty() && cmHasSuffix(name, ext)) { return false; } - this->TestNameExt = cmStrCat(name, ext); - this->TestPath = cmSystemTools::CollapseFullPath( - this->TestNameExt, path); - bool exists = this->FileIsValid(this->TestPath); - exists ? this->DebugSearches.FoundAt(this->TestPath) - : this->DebugSearches.FailedAt(this->TestPath); - if (exists) { - this->BestPath = this->TestPath; - return true; + std::string testNameExt = cmStrCat(name, ext); + std::string testPath = + cmSystemTools::CollapseFullPath(testNameExt, path); + if (this->FileIsExecutable(testPath)) { + testPath = + cmSystemTools::ToNormalizedPathOnDisk(testPath); + if (this->FindBase->Validate(testPath)) { + this->BestPath = testPath; + this->DebugSearches.FoundAt(testPath); + return true; + } } + this->DebugSearches.FailedAt(testPath); return false; }); } - bool FileIsValid(std::string const& file) const + bool FileIsExecutable(std::string const& file) const { if (!this->FileIsExecutableCMP0109(file)) { return false; @@ -122,7 +117,7 @@ } } #endif - return this->FindBase->Validate(file); + return true; } bool FileIsExecutableCMP0109(std::string const& file) const {
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 1349308..8d21aa8 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h
@@ -72,11 +72,11 @@ static std::string StripEmptyListElements(const std::string& input); - static inline bool StartsWithGeneratorExpression(const std::string& input) + static bool StartsWithGeneratorExpression(const std::string& input) { return input.length() >= 2 && input[0] == '$' && input[1] == '<'; } - static inline bool StartsWithGeneratorExpression(const char* input) + static bool StartsWithGeneratorExpression(const char* input) { return input && input[0] == '$' && input[1] == '<'; }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index fb92771..6bf49a6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx
@@ -2516,8 +2516,8 @@ return; } - return this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "CUDA", - std::move(arch), flags); + this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "CUDA", + std::move(arch), flags); } void cmGeneratorTarget::AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink, @@ -2695,8 +2695,9 @@ } if (this->Makefile->GetSafeDefinition("CMAKE_HIP_PLATFORM") == "nvidia") { - return this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "HIP", - std::move(arch), flags); + this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "HIP", + std::move(arch), flags); + return; } cmList options(arch);
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 1815c4d..6ca5930 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -113,6 +113,7 @@ // Resolve symlinks if possible result = cmSystemTools::GetRealPath(result); } + result = cmSystemTools::GetActualCaseForPath(result); } else { std::string err = "unknown component " + args[2]; status.SetError(err);
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ec44817..3d99aa6 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx
@@ -963,18 +963,24 @@ } // end if in try compile } // end need test language - // load linker configuration - std::string langLinkerLoadedVar = - cmStrCat("CMAKE_", lang, "_LINKER_INFORMATION_LOADED"); - if (!mf->GetDefinition(langLinkerLoadedVar)) { - fpath = cmStrCat("Internal/CMake", lang, "LinkerInformation.cmake"); - std::string informationFile = mf->GetModulesFile(fpath); - if (informationFile.empty()) { - cmSystemTools::Error( - cmStrCat("Could not find cmake module file: ", fpath)); - } else if (!mf->ReadListFile(informationFile)) { - cmSystemTools::Error( - cmStrCat("Could not process cmake module file: ", informationFile)); + // load linker configuration, if required + if (mf->GetDefinition(cmStrCat("CMAKE_", lang, "_USE_LINKER_INFORMATION")) + .IsOn()) { + std::string langLinkerLoadedVar = + cmStrCat("CMAKE_", lang, "_LINKER_INFORMATION_LOADED"); + if (!mf->GetDefinition(langLinkerLoadedVar)) { + fpath = cmStrCat("CMake", lang, "LinkerInformation.cmake"); + std::string informationFile = mf->GetModulesFile(fpath); + if (informationFile.empty()) { + informationFile = mf->GetModulesFile(cmStrCat("Internal/", fpath)); + } + if (informationFile.empty()) { + cmSystemTools::Error( + cmStrCat("Could not find cmake module file: ", fpath)); + } else if (!mf->ReadListFile(informationFile)) { + cmSystemTools::Error(cmStrCat( + "Could not process cmake module file: ", informationFile)); + } } } @@ -1497,12 +1503,14 @@ // This generator does not support duplicate custom targets. std::ostringstream e; + // clang-format off e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS " - << "global property. " - << "The \"" << this->GetName() << "\" generator does not support " - << "duplicate custom targets. " - << "Consider using a Makefiles generator or fix the project to not " - << "use duplicate target names."; + "global property. " + "The \"" << this->GetName() << "\" generator does not support " + "duplicate custom targets. " + "Consider using a Makefiles generator or fix the project to not " + "use duplicate target names."; + // clang-format on cmSystemTools::Error(e.str()); return false; } @@ -1771,11 +1779,12 @@ if (!this->CMP0042WarnTargets.empty()) { std::ostringstream w; - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042) << "\n"; - w << "MACOSX_RPATH is not specified for" + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042) + << "\n" + "MACOSX_RPATH is not specified for" " the following targets:\n"; for (std::string const& t : this->CMP0042WarnTargets) { - w << " " << t << "\n"; + w << ' ' << t << '\n'; } this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); @@ -1792,7 +1801,7 @@ ; /* clang-format on */ for (std::string const& t : this->CMP0068WarnTargets) { - w << " " << t << "\n"; + w << ' ' << t << '\n'; } this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); @@ -2212,9 +2221,9 @@ cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable); std::stringstream ostr; - auto ret = - this->Build(jobs, srcdir, bindir, projectName, newTarget, ostr, "", config, - defaultBuildOptions, true, this->TryCompileTimeout); + auto ret = this->Build(jobs, srcdir, bindir, projectName, newTarget, ostr, + "", config, defaultBuildOptions, true, + this->TryCompileTimeout, cmSystemTools::OUTPUT_NONE); output = ostr.str(); return ret; } @@ -2243,7 +2252,7 @@ const std::string& projectName, const std::vector<std::string>& targets, std::ostream& ostr, const std::string& makeCommandCSTR, const std::string& config, const cmBuildOptions& buildOptions, bool verbose, - cmDuration timeout, cmSystemTools::OutputOption outputflag, + cmDuration timeout, cmSystemTools::OutputOption outputMode, std::vector<std::string> const& nativeOptions) { bool hideconsole = cmSystemTools::GetRunCommandHideConsole(); @@ -2255,8 +2264,7 @@ ostr << "Change Dir: '" << bindir << '\'' << std::endl; if (workdir.Failed()) { cmSystemTools::SetRunCommandHideConsole(hideconsole); - std::string err = cmStrCat("Failed to change directory: ", - std::strerror(workdir.GetLastResult())); + std::string const& err = workdir.GetError(); cmSystemTools::Error(err); ostr << err << std::endl; return 1; @@ -2268,17 +2276,18 @@ int retVal = 0; cmSystemTools::SetRunCommandHideConsole(true); - std::string outputBuffer; - std::string* outputPtr = &outputBuffer; + + // Capture build command output when outputMode == OUTPUT_NONE. + std::string outputBuf; std::vector<GeneratedMakeCommand> makeCommand = this->GenerateBuildCommand( makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose, buildOptions, nativeOptions); // Workaround to convince some commands to produce output. - if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && + if (outputMode == cmSystemTools::OUTPUT_PASSTHROUGH && makeCommand.back().RequiresOutputForward) { - outputflag = cmSystemTools::OUTPUT_FORWARD; + outputMode = cmSystemTools::OUTPUT_FORWARD; } // should we do a clean first? @@ -2297,16 +2306,16 @@ return 1; } if (!cmSystemTools::RunSingleCommand(cleanCommand.front().PrimaryCommand, - outputPtr, outputPtr, &retVal, - nullptr, outputflag, timeout)) { + &outputBuf, &outputBuf, &retVal, + nullptr, outputMode, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::Error("Generator: execution of make clean failed."); - ostr << *outputPtr << "\nGenerator: execution of make clean failed." + ostr << outputBuf << "\nGenerator: execution of make clean failed." << std::endl; return 1; } - ostr << *outputPtr; + ostr << outputBuf; } // now build @@ -2328,22 +2337,22 @@ } ostr << outputMakeCommandStr << std::endl; - if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr, - outputPtr, &retVal, nullptr, - outputflag, timeout)) { + if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, &outputBuf, + &outputBuf, &retVal, nullptr, + outputMode, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::Error( - cmStrCat("Generator: execution of make failed. Make command was: ", + cmStrCat("Generator: build tool execution failed, command was: ", makeCommandStr)); - ostr << *outputPtr - << "\nGenerator: execution of make failed. Make command was: " + ostr << outputBuf + << "\nGenerator: build tool execution failed, command was: " << outputMakeCommandStr << std::endl; return 1; } - ostr << *outputPtr << std::flush; + ostr << outputBuf << std::flush; if (needBuildOutput) { - buildOutput += *outputPtr; + buildOutput += outputBuf; } } ostr << std::endl; @@ -2805,7 +2814,7 @@ bool issueMessage = false; switch (tgt->GetPolicyStatusCMP0037()) { case cmPolicies::WARN: - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n"; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << '\n'; issueMessage = true; CM_FALLTHROUGH; case cmPolicies::OLD: @@ -2819,7 +2828,7 @@ } if (issueMessage) { e << "The target name \"" << targetNameAsWritten << "\" is reserved " - << reason << "."; + << reason << '.'; if (messageType == MessageType::AUTHOR_WARNING) { e << " It may result in undefined behavior."; } @@ -2978,7 +2987,6 @@ } cmCustomCommandLine singleLine; singleLine.push_back(cmSystemTools::GetCTestCommand()); - singleLine.push_back("--force-new-ctest-process"); cmList args(mf->GetDefinition("CMAKE_CTEST_ARGUMENTS")); for (auto const& arg : args) { singleLine.push_back(arg); @@ -3014,7 +3022,7 @@ bool issueMessage = false; switch (policyStatus) { case cmPolicies::WARN: - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0171) << "\n"; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0171) << '\n'; issueMessage = true; CM_FALLTHROUGH; case cmPolicies::OLD: @@ -3121,8 +3129,8 @@ std::set<std::string>* componentsSet = &this->InstallComponents; std::ostringstream ostr; if (!componentsSet->empty()) { - ostr << "Available install components are: "; - ostr << cmWrap('"', *componentsSet, '"', " "); + ostr << "Available install components are: " + << cmWrap('"', *componentsSet, '"', " "); } else { ostr << "Only default component available"; } @@ -3737,7 +3745,7 @@ fout << "# Hashes of file build rules.\n"; for (auto const& rh : this->RuleHashes) { fout.write(rh.second.Data, 32); - fout << " " << rh.first << "\n"; + fout << ' ' << rh.first << '\n'; } } } @@ -3755,7 +3763,7 @@ continue; } this->WriteSummary(tgt.get()); - fout << tgt->GetSupportDirectory() << "\n"; + fout << tgt->GetSupportDirectory() << '\n'; } } } @@ -3793,7 +3801,7 @@ if (!labels.empty()) { fout << "# Target labels\n"; for (std::string const& l : labels) { - fout << " " << l << "\n"; + fout << ' ' << l << '\n'; lj_target_labels.append(l); } } @@ -3816,12 +3824,12 @@ } for (auto const& li : directoryLabelsList) { - fout << " " << li << "\n"; + fout << ' ' << li << '\n'; lj_target_labels.append(li); } for (auto const& li : cmakeDirectoryLabelsList) { - fout << " " << li << "\n"; + fout << ' ' << li << '\n'; lj_target_labels.append(li); } @@ -3838,13 +3846,13 @@ for (cmSourceFile* sf : cmMakeRange(sources.cbegin(), sourcesEnd)) { Json::Value& lj_source = lj_sources.append(Json::objectValue); std::string const& sfp = sf->ResolveFullPath(); - fout << sfp << "\n"; + fout << sfp << '\n'; lj_source["file"] = sfp; if (cmValue svalue = sf->GetProperty("LABELS")) { Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue; labels.assign(*svalue); for (auto const& label : labels) { - fout << " " << label << "\n"; + fout << ' ' << label << '\n'; lj_source_labels.append(label); } }
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index a865adb..2a1afa8 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h
@@ -248,15 +248,14 @@ * empty then all is assumed. clean indicates if a "make clean" should be * done first. */ - int Build( - int jobs, const std::string& srcdir, const std::string& bindir, - const std::string& projectName, - std::vector<std::string> const& targetNames, std::ostream& ostr, - const std::string& makeProgram, const std::string& config, - const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout, - cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE, - std::vector<std::string> const& nativeOptions = - std::vector<std::string>()); + int Build(int jobs, const std::string& srcdir, const std::string& bindir, + const std::string& projectName, + std::vector<std::string> const& targetNames, std::ostream& ostr, + const std::string& makeProgram, const std::string& config, + const cmBuildOptions& buildOptions, bool verbose, + cmDuration timeout, cmSystemTools::OutputOption outputMode, + std::vector<std::string> const& nativeOptions = + std::vector<std::string>()); /** * Open a generated IDE project given the following information.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7fa21d0..e933be7 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1362,12 +1362,20 @@ { std::string const& a = l->GetTarget()->GetName(); std::string const& b = r->GetTarget()->GetName(); + if (a == b) { + return false; + } if (a == "ALL_BUILD"_s) { return true; } if (b == "ALL_BUILD"_s) { return false; } + std::string a_low = cmSystemTools::LowerCase(l->GetTarget()->GetName()); + std::string b_low = cmSystemTools::LowerCase(r->GetTarget()->GetName()); + if (a_low != b_low) { + return a_low < b_low; + } return a < b; } };
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index 3654176..6744bbb 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx
@@ -13,8 +13,6 @@ const std::string cmLinkItem::DEFAULT = "DEFAULT"; -cmLinkItem::cmLinkItem() = default; - cmLinkItem::cmLinkItem(std::string n, bool c, cmListFileBacktrace bt, std::string feature) : String(std::move(n)) @@ -73,11 +71,6 @@ return os << item.AsStr(); } -cmLinkImplItem::cmLinkImplItem() - : cmLinkItem() -{ -} - cmLinkImplItem::cmLinkImplItem(cmLinkItem item, bool checkCMP0027) : cmLinkItem(std::move(item)) , CheckCMP0027(checkCMP0027)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index 4e356b7..70efb16 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h
@@ -29,7 +29,7 @@ // default feature: link library without decoration static const std::string DEFAULT; - cmLinkItem(); + cmLinkItem() = default; cmLinkItem(std::string s, bool c, cmListFileBacktrace bt, std::string feature = DEFAULT); cmLinkItem(cmGeneratorTarget const* t, bool c, cmListFileBacktrace bt, @@ -50,7 +50,7 @@ class cmLinkImplItem : public cmLinkItem { public: - cmLinkImplItem(); + cmLinkImplItem() = default; cmLinkImplItem(cmLinkItem item, bool checkCMP0027); bool CheckCMP0027 = false; };
diff --git a/Source/cmList.h b/Source/cmList.h index e107096..7771a0e 100644 --- a/Source/cmList.h +++ b/Source/cmList.h
@@ -1135,11 +1135,11 @@ // Non-members // =========== - friend inline bool operator==(const cmList& lhs, const cmList& rhs) noexcept + friend bool operator==(const cmList& lhs, const cmList& rhs) noexcept { return lhs.Values == rhs.Values; } - friend inline bool operator!=(const cmList& lhs, const cmList& rhs) noexcept + friend bool operator!=(const cmList& lhs, const cmList& rhs) noexcept { return lhs.Values != rhs.Values; }
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 42b517e..80d8226 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx
@@ -2380,7 +2380,7 @@ dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName); } - dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory()); + dep = cmSystemTools::CollapseFullPath(dep); return true; } @@ -3087,7 +3087,8 @@ cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource( cmGeneratorTarget* target, std::vector<std::string> const& configs, cmRange<std::vector<UnityBatchedSource>::const_iterator> sources, - cmValue beforeInclude, cmValue afterInclude, std::string filename) const + cmValue beforeInclude, cmValue afterInclude, std::string filename, + std::string const& unityFileDirectory, UnityPathMode pathMode) const { cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID"); cmGeneratedFileStream file( @@ -3110,7 +3111,8 @@ } RegisterUnitySources(target, ubs.Source, filename); WriteUnitySourceInclude(file, cond, ubs.Source->ResolveFullPath(), - beforeInclude, afterInclude, uniqueIdName); + beforeInclude, afterInclude, uniqueIdName, + pathMode, unityFileDirectory); } return UnitySource(std::move(filename), perConfig); @@ -3119,28 +3121,35 @@ void cmLocalGenerator::WriteUnitySourceInclude( std::ostream& unity_file, cm::optional<std::string> const& cond, std::string const& sf_full_path, cmValue beforeInclude, cmValue afterInclude, - cmValue uniqueIdName) const + cmValue uniqueIdName, UnityPathMode pathMode, + std::string const& unityFileDirectory) const { if (cond) { unity_file << "#if " << *cond << "\n"; } + std::string pathToHash; + std::string relocatableIncludePath; + auto PathEqOrSubDir = [](std::string const& a, std::string const& b) { + return (cmSystemTools::ComparePath(a, b) || + cmSystemTools::IsSubDirectory(a, b)); + }; + const auto path = cmSystemTools::GetFilenamePath(sf_full_path); + if (PathEqOrSubDir(path, this->GetBinaryDirectory())) { + relocatableIncludePath = + cmSystemTools::RelativePath(unityFileDirectory, sf_full_path); + pathToHash = "BLD_" + + cmSystemTools::RelativePath(this->GetBinaryDirectory(), sf_full_path); + } else if (PathEqOrSubDir(path, this->GetSourceDirectory())) { + relocatableIncludePath = + cmSystemTools::RelativePath(this->GetSourceDirectory(), sf_full_path); + pathToHash = "SRC_" + relocatableIncludePath; + } else { + relocatableIncludePath = sf_full_path; + pathToHash = "ABS_" + sf_full_path; + } + if (cmNonempty(uniqueIdName)) { - std::string pathToHash; - auto PathEqOrSubDir = [](std::string const& a, std::string const& b) { - return (cmSystemTools::ComparePath(a, b) || - cmSystemTools::IsSubDirectory(a, b)); - }; - const auto path = cmSystemTools::GetFilenamePath(sf_full_path); - if (PathEqOrSubDir(path, this->GetBinaryDirectory())) { - pathToHash = "BLD_" + - cmSystemTools::RelativePath(this->GetBinaryDirectory(), sf_full_path); - } else if (PathEqOrSubDir(path, this->GetSourceDirectory())) { - pathToHash = "SRC_" + - cmSystemTools::RelativePath(this->GetSourceDirectory(), sf_full_path); - } else { - pathToHash = "ABS_" + sf_full_path; - } cmCryptoHash hasher(cmCryptoHash::AlgoMD5); unity_file << "/* " << pathToHash << " */\n" << "#undef " << *uniqueIdName << "\n" @@ -3156,7 +3165,11 @@ unity_file << "/* NOLINTNEXTLINE(bugprone-suspicious-include,misc-include-cleaner) " "*/\n"; - unity_file << "#include \"" << sf_full_path << "\"\n"; + if (pathMode == UnityPathMode::Relative) { + unity_file << "#include \"" << relocatableIncludePath << "\"\n"; + } else { + unity_file << "#include \"" << sf_full_path << "\"\n"; + } if (afterInclude) { unity_file << *afterInclude << "\n"; @@ -3192,7 +3205,7 @@ std::vector<std::string> const& configs, std::vector<UnityBatchedSource> const& filtered_sources, cmValue beforeInclude, cmValue afterInclude, - std::string const& filename_base, size_t batchSize) + std::string const& filename_base, UnityPathMode pathMode, size_t batchSize) { if (batchSize == 0) { batchSize = filtered_sources.size(); @@ -3210,7 +3223,7 @@ auto const end = begin + chunk; unity_files.emplace_back(this->WriteUnitySource( target, configs, cmMakeRange(begin, end), beforeInclude, afterInclude, - std::move(filename))); + std::move(filename), filename_base, pathMode)); } return unity_files; } @@ -3221,7 +3234,7 @@ std::vector<std::string> const& configs, std::vector<UnityBatchedSource> const& filtered_sources, cmValue beforeInclude, cmValue afterInclude, - std::string const& filename_base) + std::string const& filename_base, UnityPathMode pathMode) { std::vector<UnitySource> unity_files; @@ -3247,7 +3260,7 @@ cmStrCat(filename_base, "unity_", name, unity_file_extension(lang)); unity_files.emplace_back(this->WriteUnitySource( target, configs, cmMakeRange(item.second), beforeInclude, afterInclude, - std::move(filename))); + std::move(filename), filename_base, pathMode)); } return unity_files; @@ -3305,6 +3318,9 @@ target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE"); cmValue afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE"); cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE"); + UnityPathMode pathMode = target->GetPropertyAsBool("UNITY_BUILD_RELOCATABLE") + ? UnityPathMode::Relative + : UnityPathMode::Absolute; for (std::string lang : { "C", "CXX", "OBJC", "OBJCXX", "CUDA" }) { std::vector<UnityBatchedSource> filtered_sources; @@ -3325,11 +3341,11 @@ if (!unityMode || *unityMode == "BATCH") { unity_files = AddUnityFilesModeAuto( target, lang, configs, filtered_sources, beforeInclude, afterInclude, - filename_base, unityBatchSize); + filename_base, pathMode, unityBatchSize); } else if (unityMode && *unityMode == "GROUP") { - unity_files = - AddUnityFilesModeGroup(target, lang, configs, filtered_sources, - beforeInclude, afterInclude, filename_base); + unity_files = AddUnityFilesModeGroup( + target, lang, configs, filtered_sources, beforeInclude, afterInclude, + filename_base, pathMode); } else { // unity mode is set to an unsupported value std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode + @@ -3348,6 +3364,11 @@ unity->SetProperty("COMPILE_DEFINITIONS", "CMAKE_UNITY_CONFIG_$<UPPER_CASE:$<CONFIG>>"); } + + if (pathMode == UnityPathMode::Relative) { + unity->AppendProperty("INCLUDE_DIRECTORIES", + this->GetSourceDirectory(), false); + } } } }
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 3ec349b..d365af3 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h
@@ -699,28 +699,37 @@ { } }; + /** Whether to insert relative or absolute paths into unity files */ + enum class UnityPathMode + { + Absolute, + Relative + }; UnitySource WriteUnitySource( cmGeneratorTarget* target, std::vector<std::string> const& configs, cmRange<std::vector<UnityBatchedSource>::const_iterator> sources, - cmValue beforeInclude, cmValue afterInclude, std::string filename) const; + cmValue beforeInclude, cmValue afterInclude, std::string filename, + std::string const& unityFileDirectory, UnityPathMode pathMode) const; void WriteUnitySourceInclude(std::ostream& unity_file, cm::optional<std::string> const& cond, std::string const& sf_full_path, cmValue beforeInclude, cmValue afterInclude, - cmValue uniqueIdName) const; + cmValue uniqueIdName, UnityPathMode pathMode, + std::string const& unityFileDirectory) const; std::vector<UnitySource> AddUnityFilesModeAuto( cmGeneratorTarget* target, std::string const& lang, std::vector<std::string> const& configs, std::vector<UnityBatchedSource> const& filtered_sources, cmValue beforeInclude, cmValue afterInclude, - std::string const& filename_base, size_t batchSize); + std::string const& filename_base, UnityPathMode pathMode, + size_t batchSize); std::vector<UnitySource> AddUnityFilesModeGroup( cmGeneratorTarget* target, std::string const& lang, std::vector<std::string> const& configs, std::vector<UnityBatchedSource> const& filtered_sources, cmValue beforeInclude, cmValue afterInclude, - std::string const& filename_base); + std::string const& filename_base, UnityPathMode pathMode); }; namespace detail {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 98da10d..e73a49b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx
@@ -486,10 +486,6 @@ return result; } - if (this->ExecuteCommandCallback) { - this->ExecuteCommandCallback(); - } - // Place this call on the call stack. cmMakefileCall stack_manager(this, lff, std::move(deferId), status); static_cast<void>(stack_manager); @@ -545,6 +541,10 @@ } } + if (this->ExecuteCommandCallback) { + this->ExecuteCommandCallback(); + } + return result; } @@ -2088,7 +2088,7 @@ cmList files(value); for (auto& file : files) { if (!cmIsOff(file)) { - file = cmSystemTools::CollapseFullPath(file); + file = cmSystemTools::ToNormalizedPathOnDisk(file); } } nvalue = files.to_string(); @@ -3722,10 +3722,7 @@ // use the cmake object instead of calling cmake cmWorkingDirectory workdir(bindir); if (workdir.Failed()) { - this->IssueMessage(MessageType::FATAL_ERROR, - cmStrCat("Failed to set working directory to ", bindir, - " : ", - std::strerror(workdir.GetLastResult()))); + this->IssueMessage(MessageType::FATAL_ERROR, workdir.GetError()); cmSystemTools::SetFatalErrorOccurred(); this->IsSourceFileTryCompile = false; return 1; @@ -4645,14 +4642,14 @@ } // Deprecate old policies. - if (status == cmPolicies::OLD && id <= cmPolicies::CMP0129 && + if (status == cmPolicies::OLD && id <= cmPolicies::CMP0139 && !(this->GetCMakeInstance()->GetIsInTryCompile() && ( // Policies set by cmCoreTryCompile::TryCompileCode. id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 || id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104 || id == cmPolicies::CMP0123 || id == cmPolicies::CMP0126 || - id == cmPolicies::CMP0128)) && + id == cmPolicies::CMP0128 || id == cmPolicies::CMP0136)) && (!this->IsSet("CMAKE_WARN_DEPRECATED") || this->IsOn("CMAKE_WARN_DEPRECATED"))) { this->IssueMessage(MessageType::DEPRECATION_WARNING,
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9d0d466..39efca4 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx
@@ -683,9 +683,7 @@ // The object file should be checked for dependency integrity. std::string objFullPath = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj); - objFullPath = cmSystemTools::CollapseFullPath(objFullPath); - std::string const srcFullPath = - cmSystemTools::CollapseFullPath(source.GetFullPath()); + std::string const srcFullPath = source.GetFullPath(); this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang, objFullPath, srcFullPath, scanner); @@ -1560,8 +1558,7 @@ cmOutputConverter::SHELL) << " " << this->LocalGenerator->ConvertToOutputFormat( - cmSystemTools::CollapseFullPath(this->InfoFileNameFull), - cmOutputConverter::SHELL); + this->InfoFileNameFull, cmOutputConverter::SHELL); if (this->LocalGenerator->GetColorMakefile()) { depCmd << " \"--color=$(COLOR)\""; }
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx index a4b2538..3a40069 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx
@@ -26,14 +26,6 @@ namespace { -enum class CheckingType -{ - UNDEFINED, - CHECK_START, - CHECK_PASS, - CHECK_FAIL -}; - std::string IndentText(std::string text, cmMakefile& mf) { auto indent = @@ -106,7 +98,7 @@ auto type = MessageType::MESSAGE; auto fatal = false; auto level = Message::LogLevel::LOG_UNDEFINED; - auto checkingType = CheckingType::UNDEFINED; + auto checkingType = Message::CheckType::UNDEFINED; if (*i == "SEND_ERROR") { type = MessageType::FATAL_ERROR; level = Message::LogLevel::LOG_ERROR; @@ -135,15 +127,15 @@ ++i; } else if (*i == "CHECK_START") { level = Message::LogLevel::LOG_STATUS; - checkingType = CheckingType::CHECK_START; + checkingType = Message::CheckType::CHECK_START; ++i; } else if (*i == "CHECK_PASS") { level = Message::LogLevel::LOG_STATUS; - checkingType = CheckingType::CHECK_PASS; + checkingType = Message::CheckType::CHECK_PASS; ++i; } else if (*i == "CHECK_FAIL") { level = Message::LogLevel::LOG_STATUS; - checkingType = CheckingType::CHECK_FAIL; + checkingType = Message::CheckType::CHECK_FAIL; ++i; } else if (*i == "CONFIGURE_LOG") { #ifndef CMAKE_BOOTSTRAP @@ -217,16 +209,16 @@ case Message::LogLevel::LOG_STATUS: switch (checkingType) { - case CheckingType::CHECK_START: + case Message::CheckType::CHECK_START: mf.DisplayStatus(IndentText(message, mf), -1); mf.GetCMakeInstance()->PushCheckInProgressMessage(message); break; - case CheckingType::CHECK_PASS: + case Message::CheckType::CHECK_PASS: ReportCheckResult("CHECK_PASS"_s, message, mf); break; - case CheckingType::CHECK_FAIL: + case Message::CheckType::CHECK_FAIL: ReportCheckResult("CHECK_FAIL"_s, message, mf); break;
diff --git a/Source/cmMessageType.h b/Source/cmMessageType.h index decb4b3..a877592 100644 --- a/Source/cmMessageType.h +++ b/Source/cmMessageType.h
@@ -6,6 +6,7 @@ enum class MessageType { + UNDEFINED, AUTHOR_WARNING, AUTHOR_ERROR, FATAL_ERROR, @@ -31,4 +32,13 @@ LOG_DEBUG, LOG_TRACE }; + +enum class CheckType +{ + UNDEFINED, + CHECK_START, + CHECK_PASS, + CHECK_FAIL +}; + }
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index 01ff7f0..1583353 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx
@@ -102,11 +102,10 @@ t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) { cmSystemTools::SetErrorOccurred(); md.title = "Error"; - cmSystemTools::Message(msg.str(), md); } else { md.title = "Warning"; - cmSystemTools::Message(msg.str(), md); } + cmSystemTools::Message(msg.str(), md); } void PrintCallStack(std::ostream& out, cmListFileBacktrace bt,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 720020d..36b4f38 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx
@@ -2273,7 +2273,10 @@ } compileObjectVars.Source = escapedSourceFileName.c_str(); - compileObjectVars.Object = objectFileName.c_str(); + std::string escapedObjectFileName = + this->LocalGenerator->ConvertToOutputFormat(objectFileName, + cmOutputConverter::SHELL); + compileObjectVars.Object = escapedObjectFileName.c_str(); compileObjectVars.ObjectDir = objectDir.c_str(); compileObjectVars.ObjectFileDir = objectFileDir.c_str(); compileObjectVars.Flags = fullFlags.c_str();
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 1fd406c..720cfa2 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx
@@ -360,11 +360,11 @@ if (genVars.ExecutableTarget) { dependencies.push_back(genVars.ExecutableTarget->Target->GetName()); } else if (this->MultiConfig && this->UseBetterGraph) { - cm::string_view const& configGenexWithCommandConfig = + cm::string_view const configGenexWithCommandConfig = "$<COMMAND_CONFIG:$<$<CONFIG:"; - cm::string_view const& configGenex = "$<$<CONFIG:"; - cm::string_view const& configGenexEnd = ">"; - cm::string_view const& configGenexEndWithCommandConfig = ">>"; + cm::string_view const configGenex = "$<$<CONFIG:"; + cm::string_view const configGenexEnd = ">"; + cm::string_view const configGenexEndWithCommandConfig = ">>"; auto genexBegin = this->CrossConfig ? configGenexWithCommandConfig : configGenex; auto genexEnd =
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 376ac2a..cbd5949 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx
@@ -439,7 +439,6 @@ // Info file this->InfoFile_ = std::string(infoFile); - cmSystemTools::CollapseFullPath(this->InfoFile_); this->InfoDir_ = cmSystemTools::GetFilenamePath(this->InfoFile_); // Load info file time
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index ec70c05..bf3480f 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx
@@ -62,7 +62,9 @@ // Process them all from the current directory for (std::string const& p : outPaths) { this->AddPathInternal( - p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str()); + cmSystemTools::CollapseFullPath( + p, this->FC->Makefile->GetCurrentSourceDirectory()), + ""); } } @@ -76,15 +78,17 @@ for (std::string const& p : expanded) { this->AddPathInternal( - p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str()); + cmSystemTools::CollapseFullPath( + p, this->FC->Makefile->GetCurrentSourceDirectory()), + ""); } } } void cmSearchPath::AddEnvPath(const std::string& variable) { - std::vector<std::string> expanded; - cmSystemTools::GetPath(expanded, variable.c_str()); + std::vector<std::string> expanded = + cmSystemTools::GetEnvPathNormalized(variable); for (std::string const& p : expanded) { this->AddPathInternal(p, ""); } @@ -97,9 +101,11 @@ // Get a path from a CMake variable. if (cmValue value = this->FC->Makefile->GetDefinition(variable)) { cmList expanded{ *value }; - - this->AddPrefixPaths( - expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str()); + for (std::string& p : expanded) { + p = cmSystemTools::CollapseFullPath( + p, this->FC->Makefile->GetCurrentSourceDirectory()); + } + this->AddPrefixPaths(expanded); } } @@ -114,8 +120,8 @@ void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin) { - std::vector<std::string> expanded; - cmSystemTools::GetPath(expanded, variable.c_str()); + std::vector<std::string> expanded = + cmSystemTools::GetEnvPathNormalized(variable); if (stripBin) { std::transform(expanded.begin(), expanded.end(), expanded.begin(), cmSearchPathStripBin); @@ -151,8 +157,7 @@ } } -void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths, - const char* base) +void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths) { assert(this->FC); @@ -192,52 +197,43 @@ "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) { if (foundUnknown) { this->AddPathInternal(cmStrCat('/', archNoUnknown, dir, subdir), - cmStrCat('/', archNoUnknown, prefix), base); + cmStrCat('/', archNoUnknown, prefix)); } this->AddPathInternal(cmStrCat('/', *arch, dir, subdir), - cmStrCat('/', *arch, prefix), base); + cmStrCat('/', *arch, prefix)); } else { if (foundUnknown) { this->AddPathInternal(cmStrCat(dir, subdir, '/', archNoUnknown), - prefix, base); + prefix); } - this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix, - base); + this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix); } } } std::string add = dir + subdir; if (add != "/") { - this->AddPathInternal(add, prefix, base); + this->AddPathInternal(add, prefix); } if (subdir == "bin") { - this->AddPathInternal(dir + "sbin", prefix, base); + this->AddPathInternal(dir + "sbin", prefix); } if (!subdir.empty() && path != "/") { - this->AddPathInternal(path, prefix, base); + this->AddPathInternal(path, prefix); } } } void cmSearchPath::AddPathInternal(const std::string& path, - const std::string& prefix, const char* base) + const std::string& prefix) { assert(this->FC); - std::string collapsedPath = cmSystemTools::CollapseFullPath(path, base); - - if (collapsedPath.empty()) { + if (path.empty()) { return; } - std::string collapsedPrefix; - if (!prefix.empty()) { - collapsedPrefix = cmSystemTools::CollapseFullPath(prefix, base); - } - // Insert the path if has not already been emitted. - PathWithPrefix pathWithPrefix{ std::move(collapsedPath), - std::move(collapsedPrefix) }; + PathWithPrefix pathWithPrefix{ path, prefix }; if (this->FC->SearchPathsEmitted.insert(pathWithPrefix).second) { this->Paths.emplace_back(std::move(pathWithPrefix)); }
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h index 4c0cabb..895f4a3 100644 --- a/Source/cmSearchPath.h +++ b/Source/cmSearchPath.h
@@ -55,12 +55,10 @@ void AddCMakePrefixPath(const std::string& variable); void AddEnvPrefixPath(const std::string& variable, bool stripBin = false); void AddSuffixes(const std::vector<std::string>& suffixes); - void AddPrefixPaths(const std::vector<std::string>& paths, - const char* base = nullptr); + void AddPrefixPaths(const std::vector<std::string>& paths); protected: - void AddPathInternal(const std::string& path, const std::string& prefix, - const char* base = nullptr); + void AddPathInternal(const std::string& path, const std::string& prefix); cmFindCommon* FC; std::vector<PathWithPrefix> Paths;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 343bee5..104e707 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx
@@ -21,7 +21,6 @@ #include "cmState.h" #include "cmStatePrivate.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" #include "cmValue.h" static std::string const kBINARY_DIR = "BINARY_DIR"; @@ -36,11 +35,9 @@ void cmStateDirectory::SetCurrentSource(std::string const& dir) { - std::string& loc = this->DirectoryState->Location; - loc = dir; - cmSystemTools::ConvertToUnixSlashes(loc); - loc = cmSystemTools::CollapseFullPath(loc); - this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc); + this->DirectoryState->Location = dir; + this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", + this->DirectoryState->Location); } std::string const& cmStateDirectory::GetCurrentBinary() const @@ -50,11 +47,9 @@ void cmStateDirectory::SetCurrentBinary(std::string const& dir) { - std::string& loc = this->DirectoryState->OutputLocation; - loc = dir; - cmSystemTools::ConvertToUnixSlashes(loc); - loc = cmSystemTools::CollapseFullPath(loc); - this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc); + this->DirectoryState->OutputLocation = dir; + this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", + this->DirectoryState->OutputLocation); } cmStateDirectory::cmStateDirectory(
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 5ad0439..dcd90bc 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx
@@ -20,6 +20,8 @@ #include "cmSystemTools.h" +#include <iterator> + #include <cm/optional> #include <cmext/algorithm> #include <cmext/string_view> @@ -133,7 +135,7 @@ # if defined(_WIN32) extern __declspec(dllimport) char** environ; # else -extern char** environ; +extern char** environ; // NOLINT(readability-redundant-declaration) # endif #endif @@ -1614,20 +1616,60 @@ return result; } -std::vector<std::string> cmSystemTools::SplitEnvPath(std::string const& value) +std::vector<std::string> cmSystemTools::GetEnvPathNormalized( + std::string const& var) +{ + std::vector<std::string> result; + if (cm::optional<std::string> env = cmSystemTools::GetEnvVar(var)) { + std::vector<std::string> p = cmSystemTools::SplitEnvPathNormalized(*env); + std::move(p.begin(), p.end(), std::back_inserter(result)); + } + return result; +} + +std::vector<std::string> cmSystemTools::SplitEnvPath(cm::string_view in) { #if defined(_WIN32) && !defined(__CYGWIN__) static cm::string_view sep = ";"_s; #else static cm::string_view sep = ":"_s; #endif - std::vector<std::string> paths = cmTokenize(value, sep); - for (std::string& p : paths) { - SystemTools::ConvertToUnixSlashes(p); + std::vector<std::string> paths; + cm::string_view::size_type e = 0; + for (;;) { + cm::string_view::size_type b = in.find_first_not_of(sep, e); + if (b == cm::string_view::npos) { + break; + } + e = in.find_first_of(sep, b); + if (e == cm::string_view::npos) { + paths.emplace_back(in.substr(b)); + break; + } + paths.emplace_back(in.substr(b, e - b)); } return paths; } +std::vector<std::string> cmSystemTools::SplitEnvPathNormalized( + cm::string_view in) +{ + std::vector<std::string> paths = cmSystemTools::SplitEnvPath(in); + std::transform(paths.begin(), paths.end(), paths.begin(), + cmSystemTools::ToNormalizedPathOnDisk); + return paths; +} + +std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p) +{ + p = cmSystemTools::CollapseFullPath(p); + cmSystemTools::ConvertToUnixSlashes(p); +#ifdef _WIN32 + p = cmSystemTools::GetActualCaseForPathCached(p); +#endif + return p; +} + #ifndef CMAKE_BOOTSTRAP bool cmSystemTools::UnsetEnv(const char* value) { @@ -2739,7 +2781,7 @@ std::string cmSystemTools::GetCurrentWorkingDirectory() { - return cmSystemTools::CollapseFullPath( + return cmSystemTools::ToNormalizedPathOnDisk( cmsys::SystemTools::GetCurrentWorkingDirectory()); }
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 0531f63..5c45cc7 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h
@@ -399,7 +399,12 @@ std::string const& in); static cm::optional<std::string> GetEnvVar(std::string const& var); - static std::vector<std::string> SplitEnvPath(std::string const& value); + static std::vector<std::string> GetEnvPathNormalized(std::string const& var); + + static std::vector<std::string> SplitEnvPath(cm::string_view in); + static std::vector<std::string> SplitEnvPathNormalized(cm::string_view in); + + static std::string ToNormalizedPathOnDisk(std::string p); #ifndef CMAKE_BOOTSTRAP /** Remove an environment variable */
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index f220837..87678b1 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx
@@ -250,7 +250,7 @@ void CopyFromEntries(cmBTStringRange entries) { - return cm::append(this->Entries, entries); + cm::append(this->Entries, entries); } enum class Action @@ -354,6 +354,8 @@ } cm::static_string_view const Name; + // Explicit initialization is needed for AppleClang in Xcode 8 and below + // NOLINTNEXTLINE(readability-redundant-member-init) cm::optional<cm::static_string_view> const Default = {}; InitCondition const InitConditional = InitCondition::Always; Repetition const Repeat = Repetition::Once; @@ -551,6 +553,7 @@ { "UNITY_BUILD_UNIQUE_ID"_s, IC::CanCompileSources }, { "UNITY_BUILD_BATCH_SIZE"_s, "8"_s, IC::CanCompileSources }, { "UNITY_BUILD_MODE"_s, "BATCH"_s, IC::CanCompileSources }, + { "UNITY_BUILD_RELOCATABLE"_s, IC::CanCompileSources }, { "OPTIMIZE_DEPENDENCIES"_s, IC::CanCompileSources }, { "VERIFY_INTERFACE_HEADER_SETS"_s }, // -- Android @@ -2047,10 +2050,13 @@ { ReadOnlyProperty(ReadOnlyCondition cond) : Condition{ cond } - , Policy{} {}; + { + } ReadOnlyProperty(ReadOnlyCondition cond, cmPolicies::PolicyID id) : Condition{ cond } - , Policy{ id } {}; + , Policy{ id } + { + } ReadOnlyCondition Condition; cm::optional<cmPolicies::PolicyID> Policy;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 51dce76..efa8f44 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -97,8 +97,8 @@ if (!target) { MessageType t = MessageType::FATAL_ERROR; // fail by default std::ostringstream e; - e << "Cannot specify link libraries for target \"" << args[0] << "\" " - << "which is not built by this project."; + e << "Cannot specify link libraries for target \"" << args[0] + << "\" which is not built by this project."; // The bad target is the only argument. Check how policy CMP0016 is set, // and accept, warn or fail respectively: if (args.size() < 2) { @@ -107,9 +107,9 @@ t = MessageType::AUTHOR_WARNING; // Print the warning. e << "\n" - << "CMake does not support this but it used to work accidentally " - << "and is being allowed for compatibility." - << "\n" + "CMake does not support this but it used to work accidentally " + "and is being allowed for compatibility." + "\n" << cmPolicies::GetPolicyWarning(cmPolicies::CMP0016); break; case cmPolicies::OLD: // OLD behavior does not warn. @@ -117,7 +117,7 @@ break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: - e << "\n" << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0016); + e << '\n' << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0016); break; case cmPolicies::NEW: // NEW behavior prints the error. break; @@ -145,7 +145,7 @@ MessageType messageType = MessageType::AUTHOR_WARNING; switch (mf.GetPolicyStatus(cmPolicies::CMP0039)) { case cmPolicies::WARN: - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n"; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << '\n'; modal = "should"; CM_FALLTHROUGH; case cmPolicies::OLD: @@ -456,7 +456,7 @@ MessageType messageType = MessageType::AUTHOR_WARNING; switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0023)) { case cmPolicies::WARN: - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n"; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << '\n'; modal = "should"; CM_FALLTHROUGH; case cmPolicies::OLD:
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h index b8b3491..ef88ef1 100644 --- a/Source/cmUVHandlePtr.h +++ b/Source/cmUVHandlePtr.h
@@ -158,10 +158,10 @@ }; template <typename T> -inline uv_handle_ptr_base_<T>::uv_handle_ptr_base_( +uv_handle_ptr_base_<T>::uv_handle_ptr_base_( uv_handle_ptr_base_<T>&&) noexcept = default; template <typename T> -inline uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=( +uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=( uv_handle_ptr_base_<T>&&) noexcept = default; /**
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx index 12fae12..574699c 100644 --- a/Source/cmWorkingDirectory.cxx +++ b/Source/cmWorkingDirectory.cxx
@@ -2,8 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmWorkingDirectory.h" -#include <cerrno> - +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir) @@ -19,11 +18,13 @@ bool cmWorkingDirectory::SetDirectory(std::string const& newdir) { - if (cmSystemTools::ChangeDirectory(newdir)) { - this->ResultCode = 0; + cmsys::Status status = cmSystemTools::ChangeDirectory(newdir); + if (status) { + this->Error.clear(); return true; } - this->ResultCode = errno; + this->Error = cmStrCat("Failed to change working directory to \"", newdir, + "\": ", status.GetString()); return false; }
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h index e593621..82f79bc 100644 --- a/Source/cmWorkingDirectory.h +++ b/Source/cmWorkingDirectory.h
@@ -26,19 +26,11 @@ bool SetDirectory(std::string const& newdir); void Pop(); - bool Failed() const { return this->ResultCode != 0; } - - /** \return 0 if the last attempt to set the working directory was - * successful. If it failed, the value returned will be the - * \c errno value associated with the failure. A description - * of the error code can be obtained by passing the result - * to \c std::strerror(). - */ - int GetLastResult() const { return this->ResultCode; } - + bool Failed() const { return !this->Error.empty(); } + std::string const& GetError() const { return this->Error; } std::string const& GetOldDirectory() const { return this->OldDir; } private: std::string OldDir; - int ResultCode; + std::string Error; };
diff --git a/Source/cmake.cxx b/Source/cmake.cxx index fcee5e5..ffbf706 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx
@@ -7,7 +7,6 @@ #include <chrono> #include <cstdio> #include <cstdlib> -#include <cstring> #include <initializer_list> #include <iomanip> #include <iostream> @@ -690,7 +689,7 @@ cmSystemTools::Stdout("loading initial cache file " + value + "\n"); // Resolve script path specified on command line // relative to $PWD. - auto path = cmSystemTools::CollapseFullPath(value); + auto path = cmSystemTools::ToNormalizedPathOnDisk(value); state->ReadListFile(args, path); return true; } }, @@ -779,10 +778,7 @@ snapshot.SetDefaultDefinitions(); cmMakefile mf(gg, snapshot); if (this->GetWorkingMode() != NORMAL_MODE) { - std::string file(cmSystemTools::CollapseFullPath(path)); - cmSystemTools::ConvertToUnixSlashes(file); - mf.SetScriptModeFile(file); - + mf.SetScriptModeFile(cmSystemTools::ToNormalizedPathOnDisk(path)); mf.SetArgcArgv(args); } if (!cmSystemTools::FileExists(path, true)) { @@ -956,10 +952,8 @@ cmSystemTools::Error("No source directory specified for -S"); return false; } - std::string path = cmSystemTools::CollapseFullPath(value); - cmSystemTools::ConvertToUnixSlashes(path); - - state->SetHomeDirectoryViaCommandLine(path); + state->SetHomeDirectoryViaCommandLine( + cmSystemTools::ToNormalizedPathOnDisk(value)); return true; }; @@ -968,9 +962,8 @@ cmSystemTools::Error("No build directory specified for -B"); return false; } - std::string path = cmSystemTools::CollapseFullPath(value); - cmSystemTools::ConvertToUnixSlashes(path); - state->SetHomeOutputDirectory(path); + state->SetHomeOutputDirectory( + cmSystemTools::ToNormalizedPathOnDisk(value)); haveBArg = true; return true; }; @@ -1074,7 +1067,8 @@ CommandArgument{ "--graphviz", "No file specified for --graphviz", CommandArgument::Values::One, [](std::string const& value, cmake* state) -> bool { - state->SetGraphVizFile(value); + state->SetGraphVizFile( + cmSystemTools::ToNormalizedPathOnDisk(value)); return true; } }, @@ -1278,23 +1272,22 @@ return false; #endif } }, - CommandArgument{ - "--debugger-dap-log", "No file specified for --debugger-dap-log", - CommandArgument::Values::One, - [](std::string const& value, cmake* state) -> bool { + CommandArgument{ "--debugger-dap-log", + "No file specified for --debugger-dap-log", + CommandArgument::Values::One, + [](std::string const& value, cmake* state) -> bool { #ifdef CMake_ENABLE_DEBUGGER - std::string path = cmSystemTools::CollapseFullPath(value); - cmSystemTools::ConvertToUnixSlashes(path); - state->DebuggerDapLogFile = path; - return true; + state->DebuggerDapLogFile = + cmSystemTools::ToNormalizedPathOnDisk(value); + return true; #else - static_cast<void>(value); - static_cast<void>(state); - cmSystemTools::Error( - "CMake was not built with support for --debugger-dap-log"); - return false; + static_cast<void>(value); + static_cast<void>(state); + cmSystemTools::Error("CMake was not built with support " + "for --debugger-dap-log"); + return false; #endif - } }, + } }, }; #if defined(CMAKE_HAVE_VS_GENERATORS) @@ -1316,9 +1309,8 @@ arguments.emplace_back( "--profiling-output", "No path specified for --profiling-output", CommandArgument::Values::One, - [&](std::string const& value, cmake*) -> bool { - profilingOutput = cmSystemTools::CollapseFullPath(value); - cmSystemTools::ConvertToUnixSlashes(profilingOutput); + [&profilingOutput](std::string const& value, cmake*) -> bool { + profilingOutput = cmSystemTools::ToNormalizedPathOnDisk(value); return true; }); arguments.emplace_back("--preset", "No preset specified for --preset", @@ -1588,7 +1580,8 @@ if (!expandedPreset->GraphVizFile.empty()) { if (this->GraphVizFile.empty()) { - this->SetGraphVizFile(expandedPreset->GraphVizFile); + this->SetGraphVizFile( + cmSystemTools::CollapseFullPath(expandedPreset->GraphVizFile)); } } @@ -1779,8 +1772,7 @@ bool is_source_dir = false; bool is_empty_directory = false; if (cmSystemTools::FileIsDirectory(arg)) { - std::string path = cmSystemTools::CollapseFullPath(arg); - cmSystemTools::ConvertToUnixSlashes(path); + std::string path = cmSystemTools::ToNormalizedPathOnDisk(arg); std::string cacheFile = cmStrCat(path, "/CMakeCache.txt"); std::string listFile = cmStrCat(path, "/CMakeLists.txt"); @@ -1795,7 +1787,7 @@ is_source_dir = true; } } else if (cmSystemTools::FileExists(arg)) { - std::string fullPath = cmSystemTools::CollapseFullPath(arg); + std::string fullPath = cmSystemTools::ToNormalizedPathOnDisk(arg); std::string name = cmSystemTools::GetFilenameName(fullPath); name = cmSystemTools::LowerCase(name); if (name == "cmakecache.txt"_s) { @@ -1846,14 +1838,13 @@ if (is_source_dir) { this->SetHomeDirectoryViaCommandLine(listPath); if (no_build_tree) { - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - this->SetHomeOutputDirectory(cwd); + this->SetHomeOutputDirectory( + cmSystemTools::GetCurrentWorkingDirectory()); } } else if (no_source_tree && no_build_tree) { this->SetHomeDirectory(listPath); - - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - this->SetHomeOutputDirectory(cwd); + this->SetHomeOutputDirectory( + cmSystemTools::GetCurrentWorkingDirectory()); } else if (no_build_tree) { this->SetHomeOutputDirectory(listPath); } @@ -1861,18 +1852,16 @@ if (no_source_tree) { // We didn't find a CMakeLists.txt and it wasn't specified // with -S. Assume it is the path to the source tree - std::string full = cmSystemTools::CollapseFullPath(arg); - this->SetHomeDirectory(full); + this->SetHomeDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg)); } if (no_build_tree && !no_source_tree && is_empty_directory) { // passed `-S <path> <build_dir> when build_dir is an empty directory - std::string full = cmSystemTools::CollapseFullPath(arg); - this->SetHomeOutputDirectory(full); + this->SetHomeOutputDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg)); } else if (no_build_tree) { // We didn't find a CMakeCache.txt and it wasn't specified // with -B. Assume the current working directory as the build tree. - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - this->SetHomeOutputDirectory(cwd); + this->SetHomeOutputDirectory( + cmSystemTools::GetCurrentWorkingDirectory()); used_provided_path = false; } } @@ -3548,8 +3537,7 @@ // file to it, so we wouldn't expect to get here unless the default // permissions are questionable or some other process has deleted the // directory - std::cerr << "Failed to change to directory " << destPath << " : " - << std::strerror(workdir.GetLastResult()) << '\n'; + std::cerr << workdir.GetError() << '\n'; return 1; } std::vector<std::string> args2;
diff --git a/Source/cmake.h b/Source/cmake.h index cfe4edd..1f2484b 100644 --- a/Source/cmake.h +++ b/Source/cmake.h
@@ -26,7 +26,6 @@ #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" #include "cmValue.h" #if !defined(CMAKE_BOOTSTRAP) @@ -300,12 +299,7 @@ } //! Set the name of the graphviz file. - void SetGraphVizFile(std::string const& ts) - { - std::string path = cmSystemTools::CollapseFullPath(ts); - cmSystemTools::ConvertToUnixSlashes(path); - this->GraphVizFile = path; - } + void SetGraphVizFile(std::string const& ts) { this->GraphVizFile = ts; } bool IsAKnownSourceExtension(cm::string_view ext) const {
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index b57cdb3..eb4f9f2 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx
@@ -601,7 +601,7 @@ } } if (!matched && i == 0) { - dir = cmSystemTools::CollapseFullPath(arg); + dir = cmSystemTools::ToNormalizedPathOnDisk(arg); matched = true; parsed = true; } @@ -873,7 +873,7 @@ }; if (ac >= 3) { - dir = cmSystemTools::CollapseFullPath(av[2]); + dir = cmSystemTools::ToNormalizedPathOnDisk(av[2]); std::vector<std::string> inputArgs; inputArgs.reserve(ac - 3); @@ -1098,7 +1098,7 @@ for (int i = 2; i < ac; ++i) { switch (doing) { case DoingDir: - dir = cmSystemTools::CollapseFullPath(av[i]); + dir = cmSystemTools::ToNormalizedPathOnDisk(av[i]); doing = DoingNone; break; default:
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index c82cb32..997c1a6 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx
@@ -1347,10 +1347,10 @@ // Create a local generator configured for the directory in // which dependencies will be scanned. - homeDir = cmSystemTools::CollapseFullPath(homeDir); - startDir = cmSystemTools::CollapseFullPath(startDir); - homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir); - startOutDir = cmSystemTools::CollapseFullPath(startOutDir); + homeDir = cmSystemTools::ToNormalizedPathOnDisk(homeDir); + startDir = cmSystemTools::ToNormalizedPathOnDisk(startDir); + homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(homeOutDir); + startOutDir = cmSystemTools::ToNormalizedPathOnDisk(startOutDir); cm.SetHomeDirectory(homeDir); cm.SetHomeOutputDirectory(homeOutDir); cm.GetCurrentSnapshot().SetDefaultDefinitions(); @@ -1643,10 +1643,10 @@ std::string startDir; std::string homeOutDir; std::string startOutDir; - homeDir = cmSystemTools::CollapseFullPath(args[4]); - startDir = cmSystemTools::CollapseFullPath(args[5]); - homeOutDir = cmSystemTools::CollapseFullPath(args[6]); - startOutDir = cmSystemTools::CollapseFullPath(args[7]); + homeDir = cmSystemTools::ToNormalizedPathOnDisk(args[4]); + startDir = cmSystemTools::ToNormalizedPathOnDisk(args[5]); + homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[6]); + startOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[7]); cm.SetHomeDirectory(homeDir); cm.SetHomeOutputDirectory(homeOutDir); cm.GetCurrentSnapshot().SetDefaultDefinitions(); @@ -2413,7 +2413,7 @@ // Create a resource file referencing the manifest. std::string absManifestFile = - cmSystemTools::CollapseFullPath(this->ManifestFile); + cmSystemTools::ToNormalizedPathOnDisk(this->ManifestFile); if (this->Verbose) { std::cout << "Create " << this->ManifestFileRC << '\n'; }
diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 68c36df..99d6cf0 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx
@@ -147,8 +147,6 @@ { "--overwrite", "Overwrite CTest configuration option." }, { "--extra-submit <file>[;<file>]", "Submit extra files to the dashboard." }, { "--http-header <header>", "Append HTTP header when submitting" }, - { "--force-new-ctest-process", - "Run child CTest instances as new processes" }, { "--schedule-random", "Use a random order for scheduling tests" }, { "--submit-index", "Submit individual dashboard tests with specific index" }, @@ -228,9 +226,5 @@ args.emplace_back(argv[i]); } // run ctest - std::string output; - int res = inst.Run(args, &output); - cmCTestLog(&inst, OUTPUT, output); - - return res; + return inst.Run(args); }
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 6cc103d..cb6d73b 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx
@@ -3647,7 +3647,6 @@ SystemTools::CheckTranslationPath(newPath); #endif #ifdef _WIN32 - newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath); SystemTools::ConvertToUnixSlashes(newPath); #endif // Return the reconstructed path. @@ -3762,6 +3761,15 @@ #endif } +std::string SystemTools::GetActualCaseForPathCached(const std::string& p) +{ +#ifdef _WIN32 + return SystemToolsStatic::GetActualCaseForPathCached(p); +#else + return p; +#endif +} + const char* SystemTools::SplitPathRootComponent(const std::string& p, std::string* root) {
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index 294ffca..43663c6 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in
@@ -372,6 +372,7 @@ * This does nothing on non-Windows systems but return the path. */ static std::string GetActualCaseForPath(const std::string& path); + static std::string GetActualCaseForPathCached(const std::string& path); /** * Given the path to a program executable, get the directory part of
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 5b189e7..01ad7b4 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt
@@ -16,6 +16,7 @@ testCTestResourceSpec.cxx testCTestResourceGroups.cxx testDebug.cxx + testDocumentationFormatter.cxx testGccDepfileReader.cxx testGeneratedFileStream.cxx testJSONHelpers.cxx
diff --git a/Tests/CMakeLib/testDocumentationFormatter.cxx b/Tests/CMakeLib/testDocumentationFormatter.cxx new file mode 100644 index 0000000..6f59b1d --- /dev/null +++ b/Tests/CMakeLib/testDocumentationFormatter.cxx
@@ -0,0 +1,138 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include <sstream> +#include <string> +#include <utility> + +#include <cmDocumentationFormatter.h> + +#include "testCommon.h" + +namespace { +using TestCases = + const std::initializer_list<std::pair<std::string, std::string>>; + +bool testPrintFormattedNoIndent() +{ + const TestCases testCases = { + { "", "" }, + { "One line no EOL text", "One line no EOL text\n" }, + { "Short text. Two sentences.", "Short text. Two sentences.\n" }, + { "Short text\non\nmultiple\nlines\n", + "Short text\n\non\n\nmultiple\n\nlines\n\n" }, + { "Just one a very long word: " + "01234567890123456789012345678901234567890123456789012345" + "678901234567890123456789", + "Just one a very long " + "word:\n01234567890123456789012345678901234567890123456789012345" + "678901234567890123456789\n" }, + { " Pre-formatted paragraph with the very long word stays the same: " + "0123456789012345678901234567890123456789012345678901234567890123456789", + " Pre-formatted paragraph with the very long word stays the same: " + "0123456789012345678901234567890123456789012345678901234567890123456789" + "\n" }, + { "Extra spaces are removed. However, \n not in a " + "pre-formatted\n " + "paragraph", + "Extra spaces are removed. However,\n\n not in a pre-formatted\n " + "paragraph\n" }, + { "This is the text paragraph longer than a pre-defined wrapping position " + "of the `cmDocumentationFormatter` class. And it's gonna be wrapped " + "over multiple lines!", + "This is the text paragraph longer than a pre-defined wrapping position " + "of the\n`cmDocumentationFormatter` class. And it's gonna be wrapped " + "over multiple\nlines!\n" } + }; + + cmDocumentationFormatter formatter; + + for (auto& test : testCases) { + std::ostringstream out; + formatter.PrintFormatted(out, test.first); + ASSERT_EQUAL(out.str(), test.second); + } + + return true; +} + +bool testPrintFormattedIndent2() +{ + const TestCases testCases = { + { "", "" }, + { "One line no EOL text", " One line no EOL text\n" }, + { "Short text. Two sentences.", " Short text. Two sentences.\n" }, + { "Short text\non\nmultiple\nlines\n", + " Short text\n\n on\n\n multiple\n\n lines\n\n" }, + { "Just one a very long word: " + "01234567890123456789012345678901234567890123456789012345" + "678901234567890123456789", + " Just one a very long " + "word:\n 01234567890123456789012345678901234567890123456789012345" + "678901234567890123456789\n" }, + { " Pre-formatted paragraph with the very long word stays the same: " + "0123456789012345678901234567890123456789012345678901234567890123456789", + " Pre-formatted paragraph with the very long word stays the same: " + "0123456789012345678901234567890123456789012345678901234567890123456789" + "\n" }, + { "Extra spaces are removed. However, \n not in a " + "pre-formatted\n " + "paragraph", + " Extra spaces are removed. However,\n\n not in a " + "pre-formatted\n " + "paragraph\n" }, + { "This is the text paragraph longer than a pre-defined wrapping position " + "of the `cmDocumentationFormatter` class. And it's gonna be wrapped " + "over multiple lines!", + " This is the text paragraph longer than a pre-defined wrapping " + "position of\n" + " the `cmDocumentationFormatter` class. And it's gonna be wrapped " + "over\n multiple lines!\n" } + }; + + cmDocumentationFormatter formatter; + formatter.SetIndent(2); + + for (auto& test : testCases) { + std::ostringstream out; + formatter.PrintFormatted(out, test.first); + ASSERT_EQUAL(out.str(), test.second); + } + + return true; +} + +bool testPrintFormattedIndent10() +{ + const TestCases testCases = { + { "", "" }, + { "One line no EOL text", " One line no EOL text\n" }, + { "This is the text paragraph longer than a pre-defined wrapping position " + "of the `cmDocumentationFormatter` class. And it's gonna be wrapped " + "over multiple lines!", + " This is the text paragraph longer than a pre-defined " + "wrapping\n" + " position of the `cmDocumentationFormatter` class. " + "And it's gonna\n" + " be wrapped over multiple lines!\n" } + }; + + cmDocumentationFormatter formatter; + formatter.SetIndent(10); + + for (auto& test : testCases) { + std::ostringstream out; + formatter.PrintFormatted(out, test.first); + ASSERT_EQUAL(out.str(), test.second); + } + + return true; +} +} + +int testDocumentationFormatter(int /*unused*/, char* /*unused*/[]) +{ + return runTests({ testPrintFormattedNoIndent, testPrintFormattedIndent2, + testPrintFormattedIndent10 }, + false); +}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 428ec8b..7f642b3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt
@@ -663,7 +663,6 @@ ${build_generator_args} --build-project ExternalDataTest --build-noclean - --force-new-ctest-process --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES} --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V @@ -1383,7 +1382,6 @@ ${build_generator_args} --build-project EnvironmentProj --build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment") @@ -1422,7 +1420,6 @@ ${build_generator_args} --build-project Qt4Targets --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets" - --force-new-ctest-process --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} --test-command ${CMAKE_CTEST_COMMAND} -V @@ -1437,7 +1434,6 @@ ${build_generator_args} --build-project Qt4And5Automoc --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward") @@ -1448,7 +1444,6 @@ ${build_generator_args} --build-project Qt4And5Automoc --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse" - --force-new-ctest-process --build-options -DQT_REVERSE_FIND_ORDER=1 --test-command ${CMAKE_CTEST_COMMAND} -V ) @@ -1645,7 +1640,6 @@ ${build_generator_args} --build-project ExternalProjectTest --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject" - --force-new-ctest-process --build-options ${ExternalProject_BUILD_OPTIONS} --test-command ${CMAKE_CTEST_COMMAND} -V ) @@ -1662,7 +1656,6 @@ "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir" ${build_generator_args} --build-project ExternalProjectSubdir - --force-new-ctest-process ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir") @@ -1673,7 +1666,6 @@ "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir" ${build_generator_args} --build-project ExternalProjectSourceSubdir - --force-new-ctest-process ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir") @@ -1684,7 +1676,6 @@ "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake" ${build_generator_args} --build-project ExternalProjectSourceSubdirNotCMake - --force-new-ctest-process ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake") @@ -1695,7 +1686,6 @@ ${build_generator_args} --build-project ExternalProjectLocalTest --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal") @@ -1710,7 +1700,6 @@ ${build_generator_args} --build-project ExternalProjectUpdateTest --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate") @@ -1766,7 +1755,6 @@ ${build_generator_args} --build-project superpro --build-exe-dir "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}" - --force-new-ctest-process --build-options ${_maybe_BUILD_OPTIONS} "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}/install" @@ -2363,7 +2351,6 @@ --build-generator "Green Hills MULTI" --build-project test --build-config $<CONFIGURATION> - --force-new-ctest-process --build-options ${ghs_target_arch} ${ghs_toolset_name} ${ghs_toolset_root} ${ghs_target_platform} ${ghs_os_root} ${ghs_os_dir} ${ghs_bsp_name} ${_ghs_build_opts} ${_ghs_toolset_extra} ${_ghs_test_command} @@ -2577,7 +2564,6 @@ ${build_generator_args} --build-project TestsWorkingDirectoryProj --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE} ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory") @@ -2589,9 +2575,9 @@ # A simple test for ctest in script mode configure_file("${CMake_SOURCE_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in" "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake" @ONLY) -# add_test(CTest.ScriptMode ${CMAKE_CTEST_COMMAND} -# -S "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake" -# ) + add_test(CTest.ScriptMode ${CMAKE_CTEST_COMMAND} + -S "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake" + ) # Test CTest Update with Subversion if(NOT DEFINED CMake_TEST_CTestUpdate_SVN OR CMake_TEST_CTestUpdate_SVN) @@ -3032,7 +3018,6 @@ ) if(NOT BORLAND) - set(CTestLimitDashJ_CTEST_OPTIONS --force-new-ctest-process) add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4 --output-on-failure -C "\${CTestTest_CONFIG}") endif()
diff --git a/Tests/CTestConfig/ScriptWithArgs.cmake b/Tests/CTestConfig/ScriptWithArgs.cmake index 79896a7..4d63e22 100644 --- a/Tests/CTestConfig/ScriptWithArgs.cmake +++ b/Tests/CTestConfig/ScriptWithArgs.cmake
@@ -1,5 +1,3 @@ -set(CTEST_RUN_CURRENT_SCRIPT 0) - macro(check_arg name expected_value) message("${name}='${${name}}'") if(NOT "${${name}}" STREQUAL "${expected_value}")
diff --git a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake index b09307f..f16deaa 100644 --- a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake +++ b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake
@@ -1,5 +1,3 @@ -set(CTEST_RUN_CURRENT_SCRIPT 0) - if(NOT DEFINED basefilename) message(FATAL_ERROR "pass -Dbasefilename=f1") endif()
diff --git a/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in index 45f0e37..5ff1bf2 100644 --- a/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in +++ b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
@@ -6,9 +6,3 @@ if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_CMAKE_SYSTEM_NAME}") message(FATAL_ERROR "Error: CMAKE_SYSTEM_NAME is \"${CMAKE_SYSTEM_NAME}\", but should be \"@CMAKE_SYSTEM_NAME@\"") endif() - -# this seems to be necessary, otherwise ctest complains that these -# variables are not set: -set(CTEST_COMMAND "\"@CMAKE_CTEST_COMMAND@\"") -set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestScriptMode/") -set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestScriptMode/")
diff --git a/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in index 3f8437c..e71d514 100644 --- a/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in +++ b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
@@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.10) -set(CTEST_RUN_CURRENT_SCRIPT 0) - set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestEmptyBinaryDirectory") set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestEmptyBinaryDirectory")
diff --git a/Tests/CTestTestRunScript/hello.cmake.in b/Tests/CTestTestRunScript/hello.cmake.in index 37905e3..4fa6446 100644 --- a/Tests/CTestTestRunScript/hello.cmake.in +++ b/Tests/CTestTestRunScript/hello.cmake.in
@@ -1,2 +1 @@ -set(CTEST_RUN_CURRENT_SCRIPT 0) message("hello world")
diff --git a/Tests/CTestTestRunScript/test.cmake.in b/Tests/CTestTestRunScript/test.cmake.in index 3074a51..9e50f7f 100644 --- a/Tests/CTestTestRunScript/test.cmake.in +++ b/Tests/CTestTestRunScript/test.cmake.in
@@ -1,2 +1 @@ -set(CTEST_RUN_CURRENT_SCRIPT 0) CTEST_RUN_SCRIPT("CTestTestRunScript/hello.cmake" RETURN_VALUE res RETURN_VALUE)
diff --git a/Tests/CTestTestSerialInDepends/test.ctest b/Tests/CTestTestSerialInDepends/test.ctest index cf0d314..71c6da2 100644 --- a/Tests/CTestTestSerialInDepends/test.ctest +++ b/Tests/CTestTestSerialInDepends/test.ctest
@@ -1,5 +1,3 @@ -set(CTEST_RUN_CURRENT_SCRIPT 0) - set(LOCK_FILE "${TEST_NAME}.lock") # Delete the old lock file in case it's lingering from a previous failed test run
diff --git a/Tests/FindGTK2/CMakeLists.txt b/Tests/FindGTK2/CMakeLists.txt index 0105fae..15a7c29 100644 --- a/Tests/FindGTK2/CMakeLists.txt +++ b/Tests/FindGTK2/CMakeLists.txt
@@ -11,7 +11,6 @@ --build-target gtk-all-libs --build-project gtk --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -25,7 +24,6 @@ --build-target gtkmm-all-libs --build-project gtkmm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -40,7 +38,6 @@ ${build_generator_args} --build-project glib --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glib" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -53,7 +50,6 @@ ${build_generator_args} --build-project gobject --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gobject" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -66,7 +62,6 @@ ${build_generator_args} --build-project gio --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gio" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -79,7 +74,6 @@ ${build_generator_args} --build-project gmodule --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gmodule" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -92,7 +86,6 @@ ${build_generator_args} --build-project gthread --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gthread" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -105,7 +98,6 @@ ${build_generator_args} --build-project atk --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atk" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -118,7 +110,6 @@ ${build_generator_args} --build-project gdk_pixbuf --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk_pixbuf" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -131,7 +122,6 @@ ${build_generator_args} --build-project cairo --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairo" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -144,7 +134,6 @@ ${build_generator_args} --build-project pango --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pango" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -157,7 +146,6 @@ ${build_generator_args} --build-project pangocairo --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangocairo" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -170,7 +158,6 @@ ${build_generator_args} --build-project pangoxft --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoxft" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -183,7 +170,6 @@ ${build_generator_args} --build-project pangoft2 --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoft2" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -196,7 +182,6 @@ ${build_generator_args} --build-project gdk --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -209,7 +194,6 @@ ${build_generator_args} --build-project gtk --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtk" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -222,7 +206,6 @@ ${build_generator_args} --build-project sigc++ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/sigc++" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -235,7 +218,6 @@ ${build_generator_args} --build-project glibmm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glibmm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -248,7 +230,6 @@ ${build_generator_args} --build-project giomm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/giomm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -261,7 +242,6 @@ ${build_generator_args} --build-project atkmm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atkmm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -274,7 +254,6 @@ ${build_generator_args} --build-project cairomm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairomm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -287,7 +266,6 @@ ${build_generator_args} --build-project pangomm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangomm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -300,7 +278,6 @@ ${build_generator_args} --build-project gdkmm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/GTK2Targets/gdkmm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif() @@ -314,7 +291,6 @@ --build-target gtkmm-target --build-project gtkmm --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm" - --force-new-ctest-process --test-command ${CMAKE_CTEST_COMMAND} -V ) endif()
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 73d3fb4..e92c6bb 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -204,7 +204,7 @@ # The result must preserve the /symlink/ path. set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/symlink/cmake") if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}") - message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")") + message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n \"${SetFoundResolved_DIR}\"\nnot the expected\n \"${SetFoundResolved_EXPECTED}\"") endif() # This part of the test only works if there are no symlinks in our path. @@ -217,7 +217,7 @@ # ./symlink points back here so it should be gone when resolved. set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/cmake") if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}") - message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")") + message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n \"${SetFoundResolved_DIR}\"\nnot the expected\n \"${SetFoundResolved_EXPECTED}\"") endif() endif() @@ -492,15 +492,15 @@ include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake") if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include") - message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")") + message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/include\"") endif() if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/") - message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")") + message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n \"${RELOC_SHARE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/share/\"") endif() if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")") + message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n \"${RELOC_BUILD_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}\"") endif() if(NOT DEFINED Relocatable_FOUND) @@ -527,15 +527,15 @@ include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake") if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include") - message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")") + message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/include\"") endif() if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/") - message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")") + message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n \"${RELOC_SHARE_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}/share/\"") endif() if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")") + message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n \"${RELOC_BUILD_DIR}\"\nnot the expected\n \"${CMAKE_CURRENT_BINARY_DIR}\"") endif() if(NOT DEFINED Relocatable_FOUND)
diff --git a/Tests/FindProtobuf/CMakeLists.txt b/Tests/FindProtobuf/CMakeLists.txt index b4ca29b..8e46ff8 100644 --- a/Tests/FindProtobuf/CMakeLists.txt +++ b/Tests/FindProtobuf/CMakeLists.txt
@@ -9,3 +9,4 @@ "-DCMake_TEST_FindProtobuf_gRPC=${CMake_TEST_FindProtobuf_gRPC}" --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) +set_property(TEST FindProtobuf.Test PROPERTY FAIL_REGULAR_EXPRESSION PROTOC_EXE)
diff --git a/Tests/FindProtobuf/Test/CMakeLists.txt b/Tests/FindProtobuf/Test/CMakeLists.txt index 2859c48..1409bd9 100644 --- a/Tests/FindProtobuf/Test/CMakeLists.txt +++ b/Tests/FindProtobuf/Test/CMakeLists.txt
@@ -70,7 +70,7 @@ # NOTE: with IMPORT_DIRS msgs/, generated files will be placed under ${CMAKE_CURRENT_BINARY_DIR}/grpc/ target_include_directories(msgs_grpc_IMPORT_DIRS PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/grpc/) target_link_libraries(msgs_grpc_IMPORT_DIRS PUBLIC ${Protobuf_LIBRARIES}) - protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE cpp IMPORT_DIRS msgs/) + protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE cpp IMPORT_DIRS msgs/ PROTOC_EXE ${Protobuf_PROTOC_EXECUTABLE}) protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE grpc IMPORT_DIRS msgs/ GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}") add_executable(test_generate_grpc_IMPORT_DIRS main-generate-grpc.cxx) target_link_libraries(test_generate_grpc_IMPORT_DIRS PRIVATE msgs_grpc_IMPORT_DIRS)
diff --git a/Tests/QtAutogen/TestMacros.cmake b/Tests/QtAutogen/TestMacros.cmake index 529592e..a2e0fca 100644 --- a/Tests/QtAutogen/TestMacros.cmake +++ b/Tests/QtAutogen/TestMacros.cmake
@@ -48,7 +48,6 @@ --build-project ${NAME} ${Autogen_CTEST_OPTIONS} --build-exe-dir "${_BuildDir}" - --force-new-ctest-process --build-options ${build_options} ${Autogen_BUILD_OPTIONS} ${_TestCommand} )
diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt b/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt new file mode 100644 index 0000000..025665d --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-OLD-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0132-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0132 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/CMP0135/CMP0135-OLD-stderr.txt b/Tests/RunCMake/CMP0135/CMP0135-OLD-stderr.txt new file mode 100644 index 0000000..59a7a58 --- /dev/null +++ b/Tests/RunCMake/CMP0135/CMP0135-OLD-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0135-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0135 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/CMP0139/CMP0139-OLD-stderr.txt b/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt index 1cfb319..b04cd1a 100644 --- a/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt +++ b/Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
@@ -1,3 +1,14 @@ +^CMake Deprecation Warning at CMP0139-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0139 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 CMP0139-OLD.cmake:[0-9]+ \(if\): if given arguments: @@ -5,4 +16,4 @@ Unknown arguments specified Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\) + CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 0a96aef..85da0cd 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt
@@ -875,6 +875,7 @@ -DCMAKE_IMPORT_LIBRARY_PREFIX=${CMAKE_IMPORT_LIBRARY_PREFIX} -DCMAKE_IMPORT_LIBRARY_SUFFIX=${CMAKE_IMPORT_LIBRARY_SUFFIX} -DCMAKE_LINK_LIBRARY_FLAG=${CMAKE_LINK_LIBRARY_FLAG}) +add_RunCMake_test(target_link_libraries-LINKER-prefix -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
diff --git a/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in b/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in index 4e2c085..d8f2e7b 100644 --- a/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in +++ b/Tests/RunCMake/CMakeRoleGlobalProperty/test.cmake.in
@@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 3.12) -set(CTEST_RUN_CURRENT_SCRIPT 0) get_property(role GLOBAL PROPERTY CMAKE_ROLE) if(NOT role STREQUAL "CTEST")
diff --git a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt new file mode 100644 index 0000000..f5c8955 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-result.txt
@@ -0,0 +1 @@ +32
diff --git a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt index e6f9325..f6d28a1 100644 --- a/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt +++ b/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-stderr.txt
@@ -1,3 +1,3 @@ Cannot find file: [^ ]*/Tests/RunCMake/CTestCommandLine/EmptyDirCoverage-ctest-build/DartConfiguration.tcl -Binary directory is not set. No coverage checking will be performed.$ +CTEST_BINARY_DIRECTORY not set
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index b2374ca..e5e385e 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -355,6 +355,9 @@ set(RunCMake_TEST_NO_CLEAN 1) file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/DartConfiguration.tcl" " +BuildDirectory: ${RunCMake_TEST_BINARY_DIR} +") file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" " add_test(PassingTest \"${CMAKE_COMMAND}\" -E echo PassingTestOutput) add_test(FailingTest \"${CMAKE_COMMAND}\" -E no_such_command) @@ -375,6 +378,9 @@ set(TRUNCATED_OUTPUT ${expected}) # used in TestOutputTruncation-check.cmake file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/DartConfiguration.tcl" " +BuildDirectory: ${RunCMake_TEST_BINARY_DIR} +") file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" " add_test(Truncation_${mode} \"${CMAKE_COMMAND}\" -E echo 123456789) ")
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt deleted file mode 100644 index 19310b8..0000000 --- a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt +++ /dev/null
@@ -1,2 +0,0 @@ -^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputSize/DartConfiguration.tcl -Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt deleted file mode 100644 index 30b46ce..0000000 --- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_head-stderr.txt +++ /dev/null
@@ -1 +0,0 @@ -^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt deleted file mode 100644 index 30b46ce..0000000 --- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_middle-stderr.txt +++ /dev/null
@@ -1 +0,0 @@ -^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt deleted file mode 100644 index 30b46ce..0000000 --- a/Tests/RunCMake/CTestCommandLine/TestOutputTruncation_tail-stderr.txt +++ /dev/null
@@ -1 +0,0 @@ -^Cannot find file: .*/Tests/RunCMake/CTestCommandLine/TestOutputTruncation.*/DartConfiguration.tcl
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt index 017ccb0..6b16868 100644 --- a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt +++ b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt
@@ -1 +1 @@ -Failed to change working directory to ".*/non-existing-dir" : No such file or directory +Failed to change working directory to ".*/non-existing-dir": No such file or directory
diff --git a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt deleted file mode 100644 index ddcd238..0000000 --- a/Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt +++ /dev/null
@@ -1 +0,0 @@ -Internal ctest changing into directory: .*/non-existing-dir
diff --git a/Tests/RunCMake/CXXModules/check-json.cmake b/Tests/RunCMake/CXXModules/check-json.cmake index 8d95973..ec15f14 100644 --- a/Tests/RunCMake/CXXModules/check-json.cmake +++ b/Tests/RunCMake/CXXModules/check-json.cmake
@@ -50,8 +50,8 @@ function (check_json_value path actual_type expect_type actual_value expect_value) if (NOT actual_type STREQUAL expect_type) - list(APPEND RunCMake_TEST_FAILED - "Type mismatch at ${path}: ${actual_type} vs. ${expect_type}") + string(APPEND RunCMake_TEST_FAILED + "Type mismatch at:\n ${path}\nexpected:\n ${expect_type}\nactual:\n ${actual_type}\n") set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE) return () endif () @@ -60,13 +60,13 @@ # Nothing to check elseif (actual_type STREQUAL BOOLEAN) if (NOT actual_value STREQUAL expect_value) - list(APPEND RunCMake_TEST_FAILED - "Boolean mismatch at ${path}: ${actual_value} vs. ${expect_value}") + string(APPEND RunCMake_TEST_FAILED + "Boolean mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n") endif () elseif (actual_type STREQUAL NUMBER) if (NOT actual_value EQUAL expect_value) - list(APPEND RunCMake_TEST_FAILED - "Number mismatch at ${path}: ${actual_value} vs. ${expect_value}") + string(APPEND RunCMake_TEST_FAILED + "Number mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n") endif () elseif (actual_type STREQUAL STRING) # Allow some values to be ignored. @@ -79,24 +79,24 @@ string(REPLACE "\\" "/" actual_value_check "${actual_value}") string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}") if (NOT actual_value_check MATCHES "^${expect_value_expanded}$") - list(APPEND RunCMake_TEST_FAILED - "String mismatch (path regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$") + string(APPEND RunCMake_TEST_FAILED + "String mismatch (path regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n") endif () elseif (expect_value MATCHES "^REGEX:") if (NOT actual_value MATCHES "^${expect_value_expanded}$") - list(APPEND RunCMake_TEST_FAILED - "String mismatch (regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$") + string(APPEND RunCMake_TEST_FAILED + "String mismatch (regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n") endif () elseif (expect_value MATCHES "^PATH:") string(REPLACE "\\" "/" actual_value_check "${actual_value}") string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}") if (NOT actual_value_check STREQUAL "${expect_value_expanded}") - list(APPEND RunCMake_TEST_FAILED - "String mismatch (path) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$") + string(APPEND RunCMake_TEST_FAILED + "String mismatch (path) at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n") endif () elseif (NOT actual_value STREQUAL expect_value_expanded) - list(APPEND RunCMake_TEST_FAILED - "String mismatch at ${path}: ${actual_value} vs. ${expect_value_expanded}") + string(APPEND RunCMake_TEST_FAILED + "String mismatch at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n") endif () elseif (actual_type STREQUAL ARRAY) check_json_array("${path}" "${actual_value}" "${expect_value}") @@ -130,11 +130,11 @@ set(iter_len "${actual_len}") if (actual_len LESS expect_len) - list(APPEND RunCMake_TEST_FAILED - "Missing array items at ${path}") + string(APPEND RunCMake_TEST_FAILED + "Missing array items at:\n ${path}\n") elseif (expect_len LESS actual_len) - list(APPEND RunCMake_TEST_FAILED - "Extra array items at ${path}") + string(APPEND RunCMake_TEST_FAILED + "Extra array items at:\n ${path}\n") set(iter_len "${expect_len}") endif () @@ -200,13 +200,13 @@ if (actual_keys_missed) string(REPLACE ";" ", " actual_keys_missed_text "${actual_keys_missed}") - list(APPEND RunCMake_TEST_FAILED - "Extra unexpected members at ${path}: ${actual_keys_missed_text}") + string(APPEND RunCMake_TEST_FAILED + "Extra unexpected members at:\n ${path}\nactual:\n ${actual_keys_missed_text}\n") endif () if (expect_keys_missed) string(REPLACE ";" ", " expect_keys_missed_text "${expect_keys_missed}") - list(APPEND RunCMake_TEST_FAILED - "Missing expected members at ${path}: ${expect_keys_missed_text}") + string(APPEND RunCMake_TEST_FAILED + "Missing expected members at\n ${path}\nactual:\n ${expect_keys_missed_text}\n") endif () foreach (key IN LISTS common_keys)
diff --git a/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt b/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt new file mode 100644 index 0000000..375ab1d --- /dev/null +++ b/Tests/RunCMake/CheckIPOSupported/CMP0138-OLD-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0138-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0138 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/CommandLine/C_basic-stdout.txt b/Tests/RunCMake/CommandLine/C_basic-stdout.txt index 74a938e..1cb0322 100644 --- a/Tests/RunCMake/CommandLine/C_basic-stdout.txt +++ b/Tests/RunCMake/CommandLine/C_basic-stdout.txt
@@ -1 +1 @@ -loading initial cache file ../C_basic_initial-cache.txt +loading initial cache file \.\./C_basic_initial-cache.txt
diff --git a/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt b/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt index 32724f5..700e449 100644 --- a/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt +++ b/Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt
@@ -1 +1,2 @@ -loading initial cache file .*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt +loading initial cache file [^ +]*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt
diff --git a/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt b/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt index 862cfeb..c73adbd 100644 --- a/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt +++ b/Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt
@@ -1,2 +1,2 @@ -loading initial cache file .*initial-cache.txt -.* +loading initial cache file [^ +]*initial-cache.txt
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt index b664fa0..01d446c 100644 --- a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt +++ b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env-stderr.txt
@@ -19,7 +19,7 @@ .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) - .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env/test\.cmake:10 \(ctest_read_custom_files\) + .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-env/test\.cmake:5 \(ctest_read_custom_files\) Problem reading custom configuration: .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt index bc89703..2e81bcb 100644 --- a/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt +++ b/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var-stderr.txt
@@ -19,7 +19,7 @@ .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake:3 \(ctest_read_custom_files\) - .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var/test\.cmake:10 \(ctest_read_custom_files\) + .*/Tests/RunCMake/MaxRecursionDepth/ctest_read_custom_files-var/test\.cmake:5 \(ctest_read_custom_files\) Problem reading custom configuration: .*/Tests/RunCMake/MaxRecursionDepth/CTestCustom\.cmake
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt index b10b26d..0586d4f 100644 --- a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt +++ b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var-stderr.txt
@@ -11,41 +11,41 @@ Maximum recursion depth of 10 exceeded -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_10\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_10\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_9\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_9\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_8\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_8\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_7\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_7\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_6\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_6\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_5\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_5\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_4\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_4\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_3\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_3\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_2\.cmake:13 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script_2\.cmake:8 \(message\): Nested script failed -CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var/test\.cmake:19 \(message\): +CMake Error at .*/Tests/RunCMake/MaxRecursionDepth/ctest_run_script-var/test\.cmake:14 \(message\): Nested script failed$
diff --git a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in index d4f28c4..5646a00 100644 --- a/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in +++ b/Tests/RunCMake/MaxRecursionDepth/ctest_run_script.cmake.in
@@ -1,12 +1,7 @@ cmake_minimum_required(VERSION 3.12) -set(CTEST_RUN_CURRENT_SCRIPT 0) message("@LEVEL_CURRENT@") -set(CTEST_SOURCE_DIRECTORY "@CTEST_SOURCE_DIRECTORY@") -set(CTEST_BINARY_DIRECTORY "@CTEST_BINARY_DIRECTORY@") -set(CTEST_COMMAND "@CTEST_COMMAND@") - ctest_run_script("${CMAKE_CURRENT_LIST_DIR}/ctest_run_script_@LEVEL_NEXT@.cmake" RETURN_VALUE val) if(NOT val EQUAL 0)
diff --git a/Tests/RunCMake/MaxRecursionDepth/test.cmake.in b/Tests/RunCMake/MaxRecursionDepth/test.cmake.in index fd1fc10..62c8e41 100644 --- a/Tests/RunCMake/MaxRecursionDepth/test.cmake.in +++ b/Tests/RunCMake/MaxRecursionDepth/test.cmake.in
@@ -1,9 +1,4 @@ cmake_minimum_required(VERSION 3.12) -set(CTEST_RUN_CURRENT_SCRIPT 0) - -set(CTEST_SOURCE_DIRECTORY "@RunCMake_SOURCE_DIR@") -set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@") -set(CTEST_COMMAND "${CMAKE_CTEST_COMMAND}") if(TEST_NAME STREQUAL "ctest_read_custom_files") set(x 2)
diff --git a/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-clang.input b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-clang.input new file mode 100644 index 0000000..7f84f44 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-clang.input
@@ -0,0 +1,38 @@ +CMAKE_LANG=Fortran +CMAKE_LINKER=/usr/bin/ld +CMAKE_Fortran_COMPILER_ABI=ELF +CMAKE_Fortran_COMPILER_AR= +CMAKE_Fortran_COMPILER_ARCHITECTURE_ID= +CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN= +CMAKE_Fortran_COMPILER_ID=LFortran +CMAKE_Fortran_COMPILER_LAUNCHER= +CMAKE_Fortran_COMPILER_LOADED=1 +CMAKE_Fortran_COMPILER_RANLIB= +CMAKE_Fortran_COMPILER_TARGET= +CMAKE_Fortran_COMPILER_VERSION=0.41.0 +CMAKE_Fortran_COMPILER_VERSION_INTERAL= +Change Dir: '/tmp/ii/CMakeFiles/CMakeTmp' + +Run Build Command(s): /tmp/CMake/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_e3038/fast +/usr/bin/gmake -f CMakeFiles/cmTC_e3038.dir/build.make CMakeFiles/cmTC_e3038.dir/build +gmake[1]: Entering directory '/tmp/ii/CMakeFiles/CMakeTmp' +Building Fortran object CMakeFiles/cmTC_e3038.dir/CMakeFortranCompilerABI.F.o +/usr/bin/lfortran --cpp-infer -v -Wl,-v --generate-object-code -c /tmp/CMake/Modules/CMakeFortranCompilerABI.F -o CMakeFiles/cmTC_e3038.dir/CMakeFortranCompilerABI.F.o +Linking Fortran executable cmTC_e3038 +/tmp/CMake/bin/cmake -E cmake_link_script CMakeFiles/cmTC_e3038.dir/link.txt --verbose=1 +clang -o cmTC_e3038 CMakeFiles/cmTC_e3038.dir/CMakeFortranCompilerABI.F.o -L"/usr/bin/../lib64" -Wl,-rpath,"/usr/bin/../lib64" -Wl,-v -llfortran_runtime -lm -v +clang version 19.1.0 (Fedora 19.1.0-1.fc41) +Target: x86_64-redhat-linux-gnu +Thread model: posix +InstalledDir: /usr/bin +Configuration file: /etc/clang/x86_64-redhat-linux-gnu-clang.cfg +System configuration file directory: /etc/clang/ +Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/14 +Selected GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/14 +Candidate multilib: .@m64 +Candidate multilib: 32@m32 +Selected multilib: .@m64 + "/usr/bin/ld" --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTC_e3038 /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crt1.o /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crti.o /usr/bin/../lib/gcc/x86_64-redhat-linux/14/crtbegin.o -L/usr/bin/../lib64 -L/usr/bin/../lib/clang/19/lib/x86_64-redhat-linux-gnu -L/usr/bin/../lib/gcc/x86_64-redhat-linux/14 -L/usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/lib -L/usr/lib CMakeFiles/cmTC_e3038.dir/CMakeFortranCompilerABI.F.o -rpath /usr/bin/../lib64 -v -llfortran_runtime -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-redhat-linux/14/crtend.o /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crtn.o +GNU ld version 2.43.1-2.fc41 +/usr/bin/lfortran -v -Wl,-v CMakeFiles/cmTC_e3038.dir/CMakeFortranCompilerABI.F.o -o cmTC_e3038 +gmake[1]: Leaving directory '/tmp/ii/CMakeFiles/CMakeTmp'
diff --git a/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-gcc.input b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-gcc.input new file mode 100644 index 0000000..4a79262 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitData/linux-Fortran-LFortran-0.41.0-gcc.input
@@ -0,0 +1,43 @@ +CMAKE_LANG=Fortran +CMAKE_LINKER=/usr/bin/ld +CMAKE_Fortran_COMPILER_ABI=ELF +CMAKE_Fortran_COMPILER_AR= +CMAKE_Fortran_COMPILER_ARCHITECTURE_ID= +CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN= +CMAKE_Fortran_COMPILER_ID=LFortran +CMAKE_Fortran_COMPILER_LAUNCHER= +CMAKE_Fortran_COMPILER_LOADED=1 +CMAKE_Fortran_COMPILER_RANLIB= +CMAKE_Fortran_COMPILER_TARGET= +CMAKE_Fortran_COMPILER_VERSION=0.41.0 +CMAKE_Fortran_COMPILER_VERSION_INTERAL= +Change Dir: '/tmp/ii/CMakeFiles/CMakeTmp' + +Run Build Command(s): /tmp/CMake/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_fdc77/fast +/usr/bin/gmake -f CMakeFiles/cmTC_fdc77.dir/build.make CMakeFiles/cmTC_fdc77.dir/build +gmake[1]: Entering directory '/tmp/ii/CMakeFiles/CMakeTmp' +Building Fortran object CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o +/usr/bin/lfortran --cpp-infer --link-with-gcc -v -Wl,-v --generate-object-code -c /tmp/CMake/Modules/CMakeFortranCompilerABI.F -o CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o +Linking Fortran executable cmTC_fdc77 +/tmp/CMake/bin/cmake -E cmake_link_script CMakeFiles/cmTC_fdc77.dir/link.txt --verbose=1 +gcc -o cmTC_fdc77 CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o -L"/usr/bin/../lib64" -Wl,-rpath,"/usr/bin/../lib64" -Wl,-v -llfortran_runtime -lm -v +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-redhat-linux +Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-14.2.1-build/gcc-14.2.1-20240912/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1 +Thread model: posix +Supported LTO compression algorithms: zlib zstd +gcc version 14.2.1 20240912 (Red Hat 14.2.1-3) (GCC) +COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/14/:/usr/libexec/gcc/x86_64-redhat-linux/14/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/14/:/usr/lib/gcc/x86_64-redhat-linux/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/14/:/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/14/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-o' 'cmTC_fdc77' '-L/usr/bin/../lib64' '-foffload-options=-l_GCC_m' '-v' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_fdc77.' + /usr/libexec/gcc/x86_64-redhat-linux/14/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper -plugin-opt=-fresolution=/tmp/ccg4ypde.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTC_fdc77 /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/14/crtbegin.o -L/usr/bin/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/14 -L/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/14/../../.. CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o -rpath /usr/bin/../lib64 -v -llfortran_runtime -lm -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-redhat-linux/14/crtend.o /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crtn.o +collect2 version 14.2.1 20240912 (Red Hat 14.2.1-3) +/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/14/lto-wrapper -plugin-opt=-fresolution=/tmp/ccg4ypde.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o cmTC_fdc77 /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/14/crtbegin.o -L/usr/bin/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/14 -L/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/14/../../.. CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o -rpath /usr/bin/../lib64 -v -llfortran_runtime -lm -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-redhat-linux/14/crtend.o /usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/crtn.o +GNU ld version 2.43.1-2.fc41 +COLLECT_GCC_OPTIONS='-o' 'cmTC_fdc77' '-L/usr/bin/../lib64' '-foffload-options=-l_GCC_m' '-v' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_fdc77.' +/usr/bin/lfortran -v -Wl,-v --link-with-gcc CMakeFiles/cmTC_fdc77.dir/CMakeFortranCompilerABI.F.o -o cmTC_fdc77 +gmake[1]: Leaving directory '/tmp/ii/CMakeFiles/CMakeTmp'
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake index 121a1d2..5b4b8d8 100644 --- a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake +++ b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake
@@ -43,6 +43,8 @@ linux-Fortran-LLVMFlang-15.0.0 linux-Fortran-LFortran-0.35.0-clang linux-Fortran-LFortran-0.35.0-gcc + linux-Fortran-LFortran-0.41.0-clang + linux-Fortran-LFortran-0.41.0-gcc linux-custom_clang-C-Clang-13.0.0 linux-custom_clang-CXX-Clang-13.0.0 mingw.org-C-GNU-4.9.3 mingw.org-CXX-GNU-4.9.3 netbsd-C-GNU-4.8.5 netbsd-CXX-GNU-4.8.5
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-clang.output b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-clang.output new file mode 100644 index 0000000..e0af3e3 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-clang.output
@@ -0,0 +1,4 @@ +libs=lfortran_runtime;m;gcc;gcc_s;c;gcc;gcc_s +dirs=/usr/lib64;/usr/lib/clang/19/lib/x86_64-redhat-linux-gnu;/usr/lib/gcc/x86_64-redhat-linux/14;/lib64;/lib;/usr/lib +library_arch=x86_64-redhat-linux-gnu +linker_tool=/usr/bin/ld
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-gcc.output b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-gcc.output new file mode 100644 index 0000000..f1b1993 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-LFortran-0.41.0-gcc.output
@@ -0,0 +1,4 @@ +libs=lfortran_runtime;m;gcc;gcc_s;c;gcc;gcc_s +dirs=/usr/lib64;/usr/lib/gcc/x86_64-redhat-linux/14;/lib64;/usr/lib +library_arch= +linker_tool=/usr/bin/ld
diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake index 78996e4..423262b 100644 --- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
@@ -8,10 +8,16 @@ endfunction() run_cmake(unitybuild_c) +run_cmake(unitybuild_c_absolute_path) +run_cmake(unitybuild_c_relocatable_path) run_cmake(unitybuild_c_batch) run_cmake(unitybuild_c_group) run_cmake(unitybuild_cxx) +run_cmake(unitybuild_cxx_absolute_path) +run_cmake(unitybuild_cxx_relocatable_path) run_cmake(unitybuild_cxx_group) +run_cmake(unitybuild_c_and_cxx_absolute_path) +run_cmake(unitybuild_c_and_cxx_relocatable_path) run_cmake(unitybuild_c_and_cxx) run_cmake(unitybuild_c_and_cxx_group) if(CMake_TEST_OBJC) @@ -37,6 +43,7 @@ run_build(unitybuild_anon_ns) run_build(unitybuild_anon_ns_no_unity_build) run_build(unitybuild_anon_ns_group_mode) +run_cmake(unitybuild_relocatable_locations) function(run_per_config name) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
diff --git a/Tests/RunCMake/UnityBuild/relocatable/foo.c b/Tests/RunCMake/UnityBuild/relocatable/foo.c new file mode 100644 index 0000000..de1160c --- /dev/null +++ b/Tests/RunCMake/UnityBuild/relocatable/foo.c
@@ -0,0 +1,5 @@ +int foo(int x) +{ + (void)x; + return 0; +}
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake new file mode 100644 index 0000000..e716e93 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-check.cmake
@@ -0,0 +1,17 @@ +set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c}") + set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s1\.c"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s2\.c"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path-build/s3\.c"]] +) + +file(STRINGS ${unitybuild_c} unitybuild_c_strings) +if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain absolute paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake new file mode 100644 index 0000000..0fe6fbf --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_absolute_path.cmake
@@ -0,0 +1,13 @@ +project(unitybuild_c_absolute_path C) + +set(srcs "") +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake new file mode 100644 index 0000000..aa41f78 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-check.cmake
@@ -0,0 +1,35 @@ +set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s1\.c"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s2\.c"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s3\.c"]] +) + +file(STRINGS ${unitybuild_c} unitybuild_c_strings) +if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain absolute paths") + return() +endif() + +set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx") +if(NOT EXISTS "${unitybuild_cxx}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT_CXX + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s1\.cxx"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s2\.cxx"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path-build/s3\.cxx"]] +) + +file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings) +if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT_CXX}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain absolute paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake new file mode 100644 index 0000000..9c6b0e4 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_absolute_path.cmake
@@ -0,0 +1,18 @@ +project(unitybuild_c_and_cxx_absolute_path C CXX) + +set(srcs "") +foreach(s RANGE 1 3) + set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n") + + set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx") + file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n") + + list(APPEND srcs "${src_c}") + list(APPEND srcs "${src_cxx}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake new file mode 100644 index 0000000..e5fd4df --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path-check.cmake
@@ -0,0 +1,35 @@ +set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "\.\./\.\./\.\./s1\.c"]] + [[#include "\.\./\.\./\.\./s2\.c"]] + [[#include "\.\./\.\./\.\./s3\.c"]] +) + +file(STRINGS ${unitybuild_c} unitybuild_c_strings) +if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths") + return() +endif() + +set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx") +if(NOT EXISTS "${unitybuild_cxx}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT_CXX + [[#include "\.\./\.\./\.\./s1\.cxx"]] + [[#include "\.\./\.\./\.\./s2\.cxx"]] + [[#include "\.\./\.\./\.\./s3\.cxx"]] +) + +file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings) +if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT_CXX}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain relative paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake new file mode 100644 index 0000000..21257f4 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_relocatable_path.cmake
@@ -0,0 +1,18 @@ +project(unitybuild_c_and_cxx_relocatable_path C CXX) + +set(srcs "") +foreach(s RANGE 1 3) + set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n") + + set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx") + file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n") + + list(APPEND srcs "${src_c}") + list(APPEND srcs "${src_cxx}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake new file mode 100644 index 0000000..f8e41ce --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path-check.cmake
@@ -0,0 +1,17 @@ +set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c}") + set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "\.\./\.\./\.\./s1\.c"]] + [[#include "\.\./\.\./\.\./s2\.c"]] + [[#include "\.\./\.\./\.\./s3\.c"]] +) + +file(STRINGS ${unitybuild_c} unitybuild_c_strings) +if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake new file mode 100644 index 0000000..e6046e6 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_relocatable_path.cmake
@@ -0,0 +1,14 @@ +project(unitybuild_c_relocatable_path C) + +set(srcs "") +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE TRUE + UNITY_BUILD_UNIQUE_ID "anon")
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake new file mode 100644 index 0000000..95d96ec --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-check.cmake
@@ -0,0 +1,17 @@ +set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx") +if(NOT EXISTS "${unitybuild_cxx}") + set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_cxx} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s1\.cxx"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s2\.cxx"]] + [[#include "([A-Za-z]:)?/[^"]*/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path-build/s3\.cxx"]] +) + +file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings) +if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain absolute paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake new file mode 100644 index 0000000..07543f4 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_absolute_path.cmake
@@ -0,0 +1,13 @@ +project(unitybuild_cxx_absolute_path CXX) + +set(srcs "") +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE FALSE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake new file mode 100644 index 0000000..d06547d --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path-check.cmake
@@ -0,0 +1,17 @@ +set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_cxx.cxx") +if(NOT EXISTS "${unitybuild_cxx}") + set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_cxx} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "\.\./\.\./\.\./s1\.cxx"]] + [[#include "\.\./\.\./\.\./s2\.cxx"]] + [[#include "\.\./\.\./\.\./s3\.cxx"]] +) + +file(STRINGS ${unitybuild_cxx} unitybuild_cxx_strings) +if(NOT unitybuild_cxx_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_cxx} doesn't contain relative paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake new file mode 100644 index 0000000..abf672d --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_relocatable_path.cmake
@@ -0,0 +1,13 @@ +project(unitybuild_cxx_relocatable_path CXX) + +set(srcs "") +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake new file mode 100644 index 0000000..565920c --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations-check.cmake
@@ -0,0 +1,22 @@ +set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c}") + set(RunCMake_TEST_FAILED "Generated unity source file ${unitybuild_c} does not exist.") + return() +endif() + +string(JOIN ".*" EXPECTED_UNITY_FILE_CONTENT + [[#include "\.\./\.\./\.\./s1\.c"]] + [[#include "\.\./\.\./\.\./s2\.c"]] + [[#include "\.\./\.\./\.\./s3\.c"]] + [[#include "\.\./\.\./\.\./subFolder/sub1\.c"]] + [[#include "\.\./\.\./\.\./subFolder/sub2\.c"]] + [[#include "\.\./\.\./\.\./subFolder/sub3\.c"]] + [[#include "f\.c"]] + [[#include "relocatable/foo\.c"]] +) + +file(STRINGS ${unitybuild_c} unitybuild_c_strings) +if(NOT unitybuild_c_strings MATCHES "${EXPECTED_UNITY_FILE_CONTENT}") + set(RunCMake_TEST_FAILED "Generated unity file ${unitybuild_c} doesn't contain relative paths") + return() +endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake new file mode 100644 index 0000000..a28d89e --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_relocatable_locations.cmake
@@ -0,0 +1,23 @@ +project(unitybuild_relocatable_locations C) + +# Binary path relative source file +set(srcs "") +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() +foreach(s RANGE 1 3) + set(src "${CMAKE_CURRENT_BINARY_DIR}/subFolder/sub${s}.c") + file(WRITE "${src}" "int sub${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +# Source path relative source file +list(APPEND srcs "${CMAKE_SOURCE_DIR}/f.c") +list(APPEND srcs "${CMAKE_SOURCE_DIR}/relocatable/foo.c") + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_RELOCATABLE TRUE)
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp similarity index 100% rename from Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp rename to Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake index 9c9409c..5d1ee3e 100644 --- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
@@ -11,7 +11,7 @@ set(SOURCE_GROUPS_TO_FIND "CSharpSourceGroup\\\\foo\\.cs" "CSharpSourceGroup\\\\nested\\\\baz\\.cs" - "CSharpSourceGroup\\\\images\\\\empty\\.bmp" + "Images\\\\empty\\.bmp" "VsCsharpSourceGroup\\.png" "AssemblyInfo\\.cs" )
diff --git a/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt b/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt index da89317..a0098e7 100644 --- a/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt +++ b/Tests/RunCMake/WorkingDirectory/buildAndTestNoBuildDir-stdout.txt
@@ -1 +1 @@ -Failed to change working directory to .*[/\\]buildAndTestNoBuildDir[/\\]CMakeLists.txt : +Failed to change working directory to ".*[/\\]buildAndTestNoBuildDir[/\\]CMakeLists.txt": (Not a directory|Invalid argument)
diff --git a/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt b/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt index 3cea890..21d288e 100644 --- a/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt +++ b/Tests/RunCMake/WorkingDirectory/dirNotExist-stderr.txt
@@ -1 +1 @@ -Failed to change working directory to .*[/\\]dirNotExist-build[/\\]thisDirWillNotExist : +Failed to change working directory to ".*[/\\]dirNotExist-build[/\\]thisDirWillNotExist": No such file or directory
diff --git a/Tests/RunCMake/block/Scope-POLICIES-stderr.txt b/Tests/RunCMake/block/Scope-POLICIES-stderr.txt new file mode 100644 index 0000000..84b99aa --- /dev/null +++ b/Tests/RunCMake/block/Scope-POLICIES-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Scope-POLICIES\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0139 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/block/Scope-VARIABLES-stderr.txt b/Tests/RunCMake/block/Scope-VARIABLES-stderr.txt new file mode 100644 index 0000000..458daa7 --- /dev/null +++ b/Tests/RunCMake/block/Scope-VARIABLES-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Scope-VARIABLES\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0139 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/block/Scope-stderr.txt b/Tests/RunCMake/block/Scope-stderr.txt new file mode 100644 index 0000000..af84e88 --- /dev/null +++ b/Tests/RunCMake/block/Scope-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Scope\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0139 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/find_file/Registry-query-stderr.txt b/Tests/RunCMake/find_file/Registry-query-stderr.txt new file mode 100644 index 0000000..0532022 --- /dev/null +++ b/Tests/RunCMake/find_file/Registry-query-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0134 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/find_library/Registry-query-stderr.txt b/Tests/RunCMake/find_library/Registry-query-stderr.txt new file mode 100644 index 0000000..0532022 --- /dev/null +++ b/Tests/RunCMake/find_library/Registry-query-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0134 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/find_package/Registry-query-stderr.txt b/Tests/RunCMake/find_package/Registry-query-stderr.txt new file mode 100644 index 0000000..0532022 --- /dev/null +++ b/Tests/RunCMake/find_package/Registry-query-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0134 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/find_path/Registry-query-stderr.txt b/Tests/RunCMake/find_path/Registry-query-stderr.txt new file mode 100644 index 0000000..0532022 --- /dev/null +++ b/Tests/RunCMake/find_path/Registry-query-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0134 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/find_program/Registry-query-stderr.txt b/Tests/RunCMake/find_program/Registry-query-stderr.txt new file mode 100644 index 0000000..0532022 --- /dev/null +++ b/Tests/RunCMake/find_program/Registry-query-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at Registry-query\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0134 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/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake index c2762ad..34af12e 100644 --- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake +++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -1,7 +1,7 @@ # Assertion macro macro(check desc actual expect) if(NOT "x${actual}" STREQUAL "x${expect}") - message(SEND_ERROR "${desc}: got \"${actual}\", not \"${expect}\"") + message(SEND_ERROR "${desc}: got\n \"${actual}\"\nnot\n \"${expect}\"") endif() endmacro()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt new file mode 100644 index 0000000..a8cb6d1 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/CMakeLists.txt
@@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.30...3.32) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake new file mode 100644 index 0000000..99f5aa3 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER-check.cmake
@@ -0,0 +1,3 @@ + +set(reference_file "LINKER.txt") +include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake new file mode 100644 index 0000000..99f5aa3 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_CONSUMER-check.cmake
@@ -0,0 +1,3 @@ + +set(reference_file "LINKER.txt") +include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake new file mode 100644 index 0000000..99f5aa3 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-LINKER_SHELL-check.cmake
@@ -0,0 +1,3 @@ + +set(reference_file "LINKER.txt") +include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake new file mode 100644 index 0000000..27adde6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion-validation.cmake
@@ -0,0 +1,15 @@ + +if (actual_stdout MATCHES "LINKER:" AND NOT linker_prefix_expected) + set (RunCMake_TEST_FAILED "LINKER: prefix was not expanded.") + return() +endif() + +if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${reference_file}") + set (RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/${reference_file}: Reference file not found.") + return() +endif() +file(READ "${RunCMake_TEST_BINARY_DIR}/${reference_file}" linker_flag) + +if (NOT actual_stdout MATCHES "${linker_flag}") + set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.") +endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake new file mode 100644 index 0000000..f71efbd --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LINKER_expansion.cmake
@@ -0,0 +1,63 @@ + +enable_language(C) + +set(cfg_dir) +get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(_isMultiConfig) + set(cfg_dir /Debug) +endif() +set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}") + +add_executable(dump dump.c) + +# ensure no temp file nor response file will be used +set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 0) +string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}") +string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}") + +function (add_test_library target_name) + add_library(${target_name} SHARED LinkOptionsLib.c) + + # use LAUNCH facility to dump linker command + set_property(TARGET ${target_name} PROPERTY RULE_LAUNCH_LINK "\"${DUMP_EXE}\"") + + add_dependencies(${target_name} dump) +endfunction() + +# Use LINKER alone +add_test_library(linker) +target_link_libraries(linker PRIVATE "LINKER:-foo,bar") + +# Use LINKER with SHELL +add_test_library(linker_shell) +target_link_libraries(linker_shell PRIVATE "LINKER:SHELL:-foo bar") + +# Propagate LINKER +add_library(linker_interface INTERFACE) +target_link_libraries(linker_interface INTERFACE "LINKER:-foo,bar") +add_test_library(linker_consumer) +target_link_libraries(linker_consumer PRIVATE linker_interface) + +# generate reference for LINKER flag +if (CMAKE_C_LINKER_WRAPPER_FLAG) + set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG}) + list(GET linker_flag -1 linker_space) + if (linker_space STREQUAL " ") + list(REMOVE_AT linker_flag -1) + else() + set(linker_space) + endif() + list (JOIN linker_flag " " linker_flag) + if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP) + set(linker_sep "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}") + + string (APPEND linker_flag "${linker_space}" "-foo${linker_sep}bar") + else() + set(linker_prefix "${linker_flag}${linker_space}") + + set (linker_flag "${linker_prefix}-foo ${linker_prefix}bar") + endif() +else() + set(linker_flag "-foo bar") +endif() +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c new file mode 100644 index 0000000..9bbd24c --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/LinkOptionsLib.c
@@ -0,0 +1,7 @@ +#if defined(_WIN32) +__declspec(dllexport) +#endif + int flags_lib(void) +{ + return 0; +}
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake new file mode 100644 index 0000000..cabf2cc --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/RunCMakeTest.cmake
@@ -0,0 +1,22 @@ + +include(RunCMake) + +macro(run_cmake_target test subtest target) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN}) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) +endmacro() + + +run_cmake(bad_SHELL_usage) + +if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)") + run_cmake(LINKER_expansion) + + run_cmake_target(LINKER_expansion LINKER linker) + run_cmake_target(LINKER_expansion LINKER_SHELL linker_shell) + run_cmake_target(LINKER_expansion LINKER_CONSUMER linker_consumer) +endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt new file mode 100644 index 0000000..d6a298d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage-stderr.txt
@@ -0,0 +1,4 @@ +CMake Error at bad_SHELL_usage.cmake:[0-9]+ \(add_library\): + 'SHELL:' prefix is not supported as part of 'LINKER:' arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake new file mode 100644 index 0000000..e25bef6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/bad_SHELL_usage.cmake
@@ -0,0 +1,5 @@ + +enable_language(C) + +add_library(example SHARED LinkOptionsLib.c) +target_link_libraries(example PRIVATE "LINKER:-foo,SHELL:-bar")
diff --git a/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c b/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c new file mode 100644 index 0000000..8baa313 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINKER-prefix/dump.c
@@ -0,0 +1,13 @@ + +#include "stdio.h" + +int main(int argc, char* argv[]) +{ + int i; + + for (i = 1; i < argc; i++) + printf("%s ", argv[i]); + printf("\n"); + + return 0; +}
diff --git a/Tests/RunCMake/while/CMP0130-OLD-stderr.txt b/Tests/RunCMake/while/CMP0130-OLD-stderr.txt new file mode 100644 index 0000000..e673966 --- /dev/null +++ b/Tests/RunCMake/while/CMP0130-OLD-stderr.txt
@@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0130-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0130 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/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt index 111bd6f..64f9a3f 100644 --- a/Utilities/Doxygen/CMakeLists.txt +++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeDeveloperReference_STANDALONE 1) - cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR) + cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index ed7b631..a919b91 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeHelp_STANDALONE 1) - cmake_minimum_required(VERSION 3.13...3.29 FATAL_ERROR) + cmake_minimum_required(VERSION 3.13...3.30 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)