diff options
29 files changed, 401 insertions, 112 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbed2e2..d224088 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,7 +52,7 @@ prep:doc-package: - .cmake_doc_artifacts - .run_only_for_package -.upload:source-package: +upload:source-package: extends: - .rsync_upload_binary - .run_only_for_package @@ -70,7 +70,7 @@ build:help:master: - .cmake_org_help - .run_only_for_continuous_master -.upload:help:master: +upload:help:master: extends: - .rsync_upload_help - .run_only_for_continuous_master @@ -86,7 +86,7 @@ build:help:stage: - .cmake_org_help - .run_only_for_continuous_stage -.upload:help:stage: +upload:help:stage: extends: - .rsync_upload_help - .run_only_for_continuous_stage @@ -495,7 +495,7 @@ build:linux-x86_64-package: needs: - prep:doc-package -.upload:linux-x86_64-package: +upload:linux-x86_64-package: extends: - .rsync_upload_binary - .run_only_for_package @@ -519,7 +519,7 @@ build:linux-aarch64-package: needs: - prep:doc-package -.upload:linux-aarch64-package: +upload:linux-aarch64-package: extends: - .rsync_upload_binary - .run_only_for_package @@ -656,7 +656,7 @@ build:macos-package: needs: - prep:doc-package -.upload:macos-package: +upload:macos-package: extends: - .rsync_upload_binary - .run_only_for_package @@ -679,7 +679,7 @@ build:macos10.10-package: needs: - prep:doc-package -.upload:macos10.10-package: +upload:macos10.10-package: extends: - .rsync_upload_binary - .run_only_for_package diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst index 2153c90..03ec1a4 100644 --- a/Help/command/ctest_test.rst +++ b/Help/command/ctest_test.rst @@ -270,3 +270,18 @@ The following example demonstrates how to specify a custom value for the std::cout << "<CTestDetails>My Custom Details Value</CTestDetails>" << std::endl; + +Additional Labels +""""""""""""""""" + +The following example demonstrates how to add additional labels to a test +at runtime. + +.. code-block:: c++ + + std::cout << + "<CTestLabel>Custom Label 1</CTestLabel>\n" << + "<CTestLabel>Custom Label 2</CTestLabel>" << std::endl; + +Use the :prop_test:`LABELS` test property instead for labels that can be +determined at configure time. 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/FindPkgConfig-PKG_CONFIG-args.rst b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst new file mode 100644 index 0000000..44c26b5 --- /dev/null +++ b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst @@ -0,0 +1,5 @@ +FindPkgConfig-PKG_CONFIG-args +----------------------------- + +* The :module:`FindPkgConfig` module gained a :variable:`PKG_CONFIG_ARGN` + variable to specify arguments to ``pkg-config`` calls. diff --git a/Help/release/dev/ctest-runtime-labels.rst b/Help/release/dev/ctest-runtime-labels.rst new file mode 100644 index 0000000..7ce0b64 --- /dev/null +++ b/Help/release/dev/ctest-runtime-labels.rst @@ -0,0 +1,7 @@ +ctest-runtime-labels +-------------------- + +* :manual:`ctest(1)` learned to recognize labels attached to a test at run time. + Previously it was only possible to attach labels to tests at configure time + by using the :prop_test:`LABELS` test property. + See :ref:`Additional Test Measurements` for more information. diff --git a/Help/release/dev/msvc-isystem.rst b/Help/release/dev/msvc-isystem.rst new file mode 100644 index 0000000..4a5d79f --- /dev/null +++ b/Help/release/dev/msvc-isystem.rst @@ -0,0 +1,7 @@ +msvc-isystem +------------ + +* The MSVC compilers learned to pass the ``-external:I`` flag for system + includes when using the :generator:`Ninja` and :generator:`NMake Makefiles` + generators. This became available as of Visual Studio 16.10 (toolchain + version 14.29.30037). diff --git a/Help/release/index.rst b/Help/release/index.rst index 75667e5..5938878 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -7,6 +7,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake index 9a5104b..73cca36 100644 --- a/Modules/Compiler/MSVC-C.cmake +++ b/Modules/Compiler/MSVC-C.cmake @@ -63,3 +63,9 @@ endmacro() if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05) set(CMAKE_C_COMPILE_OPTIONS_JMC "-JMC") endif() + +# The `/external:I` flag was made non-experimental in 19.29.30036.3. +if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3) + set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I ") + set(_CMAKE_INCLUDE_SYSTEM_FLAG_C_WARNING "-external:W0 ") +endif () diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake index f1c7450..09fe851 100644 --- a/Modules/Compiler/MSVC-CXX.cmake +++ b/Modules/Compiler/MSVC-CXX.cmake @@ -79,3 +79,9 @@ endif() if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05) set(CMAKE_CXX_COMPILE_OPTIONS_JMC "-JMC") endif() + +# The `/external:I` flag was made non-experimental in 19.29.30036.3. +if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3) + set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I ") + set(_CMAKE_INCLUDE_SYSTEM_FLAG_CXX_WARNING "-external:W0 ") +endif () diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index 3bc9dba..bd54fd9 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -15,6 +15,8 @@ following variables will also be set: if pkg-config executable was found ``PKG_CONFIG_EXECUTABLE`` pathname of the pkg-config program +``PKG_CONFIG_ARGN`` + list of arguments to pass to pkg-config ``PKG_CONFIG_VERSION_STRING`` version of pkg-config (since CMake 2.8.8) @@ -29,7 +31,15 @@ set(PKG_CONFIG_VERSION 1) # find pkg-config, use PKG_CONFIG if set if((NOT PKG_CONFIG_EXECUTABLE) AND (NOT "$ENV{PKG_CONFIG}" STREQUAL "")) - set(PKG_CONFIG_EXECUTABLE "$ENV{PKG_CONFIG}" CACHE FILEPATH "pkg-config executable") + separate_arguments(PKG_CONFIG_FROM_ENV_SPLIT NATIVE_COMMAND PROGRAM SEPARATE_ARGS "$ENV{PKG_CONFIG}") + list(LENGTH PKG_CONFIG_FROM_ENV_SPLIT PKG_CONFIG_FROM_ENV_SPLIT_ARGC) + if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 0) + list(GET PKG_CONFIG_FROM_ENV_SPLIT 0 PKG_CONFIG_FROM_ENV_ARGV0) + if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 1) + list(SUBLIST PKG_CONFIG_FROM_ENV_SPLIT 1 -1 PKG_CONFIG_ARGN) + endif() + set(PKG_CONFIG_EXECUTABLE "${PKG_CONFIG_FROM_ENV_ARGV0}" CACHE FILEPATH "pkg-config executable") + endif() endif() set(PKG_CONFIG_NAMES "pkg-config") @@ -43,9 +53,12 @@ find_program(PKG_CONFIG_EXECUTABLE DOC "pkg-config executable") mark_as_advanced(PKG_CONFIG_EXECUTABLE) +set(PKG_CONFIG_ARGN "${PKG_CONFIG_ARGN}" CACHE STRING "Arguments to supply to pkg-config") +mark_as_advanced(PKG_CONFIG_ARGN) + set(_PKG_CONFIG_FAILURE_MESSAGE "") if (PKG_CONFIG_EXECUTABLE) - execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} --version OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE _PKG_CONFIG_VERSION_ERROR ERROR_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _PKG_CONFIG_VERSION_RESULT @@ -53,14 +66,18 @@ if (PKG_CONFIG_EXECUTABLE) if (NOT _PKG_CONFIG_VERSION_RESULT EQUAL 0) string(REPLACE "\n" "\n " _PKG_CONFIG_VERSION_ERROR " ${_PKG_CONFIG_VERSION_ERROR}") + if(PKG_CONFIG_ARGN) + string(REPLACE ";" " " PKG_CONFIG_ARGN " ${PKG_CONFIG_ARGN}") + endif() string(APPEND _PKG_CONFIG_FAILURE_MESSAGE "The command\n" - " \"${PKG_CONFIG_EXECUTABLE}\" --version\n" + " \"${PKG_CONFIG_EXECUTABLE}\"${PKG_CONFIG_ARGN} --version\n" " failed with output:\n${PKG_CONFIG_VERSION_STRING}\n" " stderr: \n${_PKG_CONFIG_VERSION_ERROR}\n" " result: \n${_PKG_CONFIG_VERSION_RESULT}" ) set(PKG_CONFIG_EXECUTABLE "") + set(PKG_CONFIG_ARGN "") unset(PKG_CONFIG_VERSION_STRING) endif () unset(_PKG_CONFIG_VERSION_RESULT) @@ -91,7 +108,7 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp) set(_pkgconfig_invoke_result) execute_process( - COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist} + COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${ARGN} ${_pkglist} OUTPUT_VARIABLE _pkgconfig_invoke_result RESULT_VARIABLE _pkgconfig_failed OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -533,7 +550,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma # execute the query execute_process( - COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query} + COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${_pkg_check_modules_exist_query} RESULT_VARIABLE _pkgconfig_retval ERROR_VARIABLE _pkgconfig_error ERROR_STRIP_TRAILING_WHITESPACE) @@ -892,6 +909,18 @@ Variables Affecting Behavior .. versionadded:: 3.1 The ``PKG_CONFIG`` environment variable can be used as a hint. +.. variable:: PKG_CONFIG_ARGN + + .. versionadded:: 3.22 + + This can be set to a list of arguments to additionally pass to pkg-config + if needed. If not provided, it will be an empty string, however, if the + environment variable ``PKG_CONFIG`` is provided, this will be set to the + result of splitting the variable. + + The ``PKG_CONFIG`` environment variable can be used to provide both + ``PKG_CONFIG_EXECUTABLE`` and ``PKG_CONFIG_ARGN`` + .. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH .. versionadded:: 3.1 diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ad174a7..894f119 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 21) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 0) +set(CMake_VERSION_PATCH 20210623) +#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/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index a892113..50072c5 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestRunTest.h" +#include <algorithm> #include <chrono> #include <cstddef> // IWYU pragma: keep #include <cstdint> @@ -44,7 +45,9 @@ void cmCTestRunTest::CheckOutput(std::string const& line) // Check for special CTest XML tags in this line of output. // If any are found, this line is excluded from ProcessOutput. if (!line.empty() && line.find("<CTest") != std::string::npos) { + bool ctest_tag_found = false; if (this->TestHandler->CustomCompletionStatusRegex.find(line)) { + ctest_tag_found = true; this->TestResult.CustomCompletionStatus = this->TestHandler->CustomCompletionStatusRegex.match(1); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -52,6 +55,20 @@ void cmCTestRunTest::CheckOutput(std::string const& line) << "Test Details changed to '" << this->TestResult.CustomCompletionStatus << "'" << std::endl); + } else if (this->TestHandler->CustomLabelRegex.find(line)) { + ctest_tag_found = true; + auto label = this->TestHandler->CustomLabelRegex.match(1); + auto& labels = this->TestProperties->Labels; + if (std::find(labels.begin(), labels.end(), label) == labels.end()) { + labels.push_back(label); + std::sort(labels.begin(), labels.end()); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + this->GetIndex() + << ": " + << "Test Label added: '" << label << "'" << std::endl); + } + } + if (ctest_tag_found) { return; } } diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 730ec0f..aeaf696 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -312,6 +312,8 @@ cmCTestTestHandler::cmCTestTestHandler() // regex to detect <CTestDetails>...</CTestDetails> this->CustomCompletionStatusRegex.compile( "<CTestDetails>(.*)</CTestDetails>"); + // regex to detect <CTestLabel>...</CTestLabel> + this->CustomLabelRegex.compile("<CTestLabel>(.*)</CTestLabel>"); } void cmCTestTestHandler::Initialize() diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index bd51738..cc19984 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -360,6 +360,7 @@ private: size_t TotalNumberOfTests; cmsys::RegularExpression DartStuff; cmsys::RegularExpression CustomCompletionStatusRegex; + cmsys::RegularExpression CustomLabelRegex; std::ostream* LogFile; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3b282de..a14f085 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -878,9 +878,12 @@ std::string cmLocalGenerator::GetIncludeFlags( // Support special system include flag if it is available and the // normal flag is repeated for each directory. cmProp sysIncludeFlag = nullptr; + cmProp sysIncludeFlagWarning = nullptr; if (repeatFlag) { sysIncludeFlag = this->Makefile->GetDefinition( cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang)); + sysIncludeFlagWarning = this->Makefile->GetDefinition( + cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", lang, "_WARNING")); } cmProp fwSearchFlag = this->Makefile->GetDefinition( @@ -889,6 +892,7 @@ std::string cmLocalGenerator::GetIncludeFlags( cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG")); bool flagUsed = false; + bool sysIncludeFlagUsed = false; std::set<std::string> emitted; #ifdef __APPLE__ emitted.insert("/System/Library/Frameworks"); @@ -915,6 +919,7 @@ std::string cmLocalGenerator::GetIncludeFlags( if (sysIncludeFlag && target && target->IsSystemIncludeDirectory(i, config, lang)) { includeFlags << *sysIncludeFlag; + sysIncludeFlagUsed = true; } else { includeFlags << includeFlag; } @@ -931,6 +936,9 @@ std::string cmLocalGenerator::GetIncludeFlags( } includeFlags << sep; } + if (sysIncludeFlagUsed && sysIncludeFlagWarning) { + includeFlags << *sysIncludeFlagWarning; + } std::string flags = includeFlags.str(); // remove trailing separators if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 10d2e50..488e69c 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -48,6 +48,8 @@ #if defined(CMake_USE_ELF_PARSER) # include "cmELF.h" +#else +class cmELF; #endif #if defined(CMake_USE_MACH_PARSER) @@ -2491,7 +2493,6 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath, return false; } -#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER) std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have, cm::string_view const& want) { @@ -2523,9 +2524,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have, // The desired rpath was not found. return std::string::npos; } -#endif -#if defined(CMake_USE_ELF_PARSER) namespace { struct cmSystemToolsRPathInfo { @@ -2539,11 +2538,19 @@ using EmptyCallback = std::function<bool(std::string*, const cmELF&)>; using AdjustCallback = std::function<bool( cm::optional<std::string>&, const std::string&, const char*, std::string*)>; -// FIXME: Dispatch if multiple formats are supported. -bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback, - const AdjustCallback& adjustCallback, std::string* emsg, - bool* changed) +cm::optional<bool> AdjustRPathELF(std::string const& file, + const EmptyCallback& emptyCallback, + const AdjustCallback& adjustCallback, + std::string* emsg, bool* changed) { +#if !defined(CMake_USE_ELF_PARSER) + (void)file; + (void)emptyCallback; + (void)adjustCallback; + (void)emsg; + (void)changed; + return cm::nullopt; // Cannot handle ELF files. +#else if (changed) { *changed = false; } @@ -2553,6 +2560,9 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback, { // Parse the ELF binary. cmELF elf(file.c_str()); + if (!elf) { + return cm::nullopt; // Not a valid ELF file. + } // Get the RPATH and RUNPATH entries from it. int se_count = 0; @@ -2668,6 +2678,7 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback, *changed = true; } return true; +#endif } std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback( @@ -2679,21 +2690,26 @@ std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback( // okay. return true; } +#if defined(CMake_USE_ELF_PARSER) if (emsg) { *emsg = cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ", elf.GetErrorMessage()); } +#else + static_cast<void>(emsg); + static_cast<void>(elf); +#endif return false; }; -}; +} } -bool cmSystemTools::ChangeRPath(std::string const& file, - std::string const& oldRPath, - std::string const& newRPath, - bool removeEnvironmentRPath, std::string* emsg, - bool* changed) +cm::optional<bool> ChangeRPathELF(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, + std::string* emsg, bool* changed) { auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath]( cm::optional<std::string>& outRPath, @@ -2741,13 +2757,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file, return true; }; - return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg, - changed); + return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback, + emsg, changed); } -bool cmSystemTools::SetRPath(std::string const& file, - std::string const& newRPath, std::string* emsg, - bool* changed) +static cm::optional<bool> SetRPathELF(std::string const& file, + std::string const& newRPath, + std::string* emsg, bool* changed) { auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath, const std::string& inRPath, @@ -2759,22 +2775,31 @@ bool cmSystemTools::SetRPath(std::string const& file, return true; }; - return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg, - changed); + return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback, + emsg, changed); } -#elif defined(CMake_USE_XCOFF_PARSER) -bool cmSystemTools::ChangeRPath(std::string const& file, - std::string const& oldRPath, - std::string const& newRPath, - bool removeEnvironmentRPath, std::string* emsg, - bool* changed) +static cm::optional<bool> ChangeRPathXCOFF(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, + std::string* emsg, bool* changed) { if (changed) { *changed = false; } - +#if !defined(CMake_USE_XCOFF_PARSER) + (void)file; + (void)oldRPath; + (void)newRPath; + (void)removeEnvironmentRPath; + (void)emsg; + return cm::nullopt; +#else bool chg = false; cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite); + if (!xcoff) { + return cm::nullopt; // Not a valid XCOFF file + } if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) { cm::string_view libPath = *maybeLibPath; // Make sure the current rpath contains the old rpath. @@ -2830,31 +2855,47 @@ bool cmSystemTools::ChangeRPath(std::string const& file, *changed = chg; } return true; +#endif } -bool cmSystemTools::SetRPath(std::string const& /*file*/, - std::string const& /*newRPath*/, - std::string* /*emsg*/, bool* /*changed*/) +static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/, + std::string const& /*newRPath*/, + std::string* /*emsg*/, + bool* /*changed*/) { - return false; + return cm::nullopt; // Not implemented. } -#else -bool cmSystemTools::ChangeRPath(std::string const& /*file*/, - std::string const& /*oldRPath*/, - std::string const& /*newRPath*/, - bool /*removeEnvironmentRPath*/, - std::string* /*emsg*/, bool* /*changed*/) + +bool cmSystemTools::ChangeRPath(std::string const& file, + std::string const& oldRPath, + std::string const& newRPath, + bool removeEnvironmentRPath, std::string* emsg, + bool* changed) { + if (cm::optional<bool> result = ChangeRPathELF( + file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) { + return result.value(); + } + if (cm::optional<bool> result = ChangeRPathXCOFF( + file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) { + return result.value(); + } return false; } -bool cmSystemTools::SetRPath(std::string const& /*file*/, - std::string const& /*newRPath*/, - std::string* /*emsg*/, bool* /*changed*/) +bool cmSystemTools::SetRPath(std::string const& file, + std::string const& newRPath, std::string* emsg, + bool* changed) { + if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) { + return result.value(); + } + if (cm::optional<bool> result = + SetRPathXCOFF(file, newRPath, emsg, changed)) { + return result.value(); + } return false; } -#endif bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, const char* lhss, const char* rhss) @@ -2989,11 +3030,15 @@ int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs) return cm_strverscmp(lhs.c_str(), rhs.c_str()); } -// FIXME: Dispatch if multiple formats are supported. -#if defined(CMake_USE_ELF_PARSER) -bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - bool* removed) +static cm::optional<bool> RemoveRPathELF(std::string const& file, + std::string* emsg, bool* removed) { +#if !defined(CMake_USE_ELF_PARSER) + (void)file; + (void)emsg; + (void)removed; + return cm::nullopt; // Cannot handle ELF files. +#else if (removed) { *removed = false; } @@ -3005,6 +3050,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, { // Parse the ELF binary. cmELF elf(file.c_str()); + if (!elf) { + return cm::nullopt; // Not a valid ELF file. + } // Get the RPATH and RUNPATH entries from it and sort them by index // in the dynamic section header. @@ -3130,16 +3178,24 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, *removed = true; } return true; +#endif } -#elif defined(CMake_USE_XCOFF_PARSER) -bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - bool* removed) + +static cm::optional<bool> RemoveRPathXCOFF(std::string const& file, + std::string* emsg, bool* removed) { if (removed) { *removed = false; } - +#if !defined(CMake_USE_XCOFF_PARSER) + (void)file; + (void)emsg; + return cm::nullopt; // Cannot handle XCOFF files. +#else cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite); + if (!xcoff) { + return cm::nullopt; // Not a valid XCOFF file. + } bool rm = xcoff.RemoveLibPath(); if (!xcoff) { if (emsg) { @@ -3152,55 +3208,62 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, *removed = rm; } return true; +#endif } -#else -bool cmSystemTools::RemoveRPath(std::string const& /*file*/, - std::string* /*emsg*/, bool* /*removed*/) +bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, + bool* removed) { + if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) { + return result.value(); + } + if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) { + return result.value(); + } return false; } -#endif -// FIXME: Dispatch if multiple formats are supported. bool cmSystemTools::CheckRPath(std::string const& file, std::string const& newRPath) { #if defined(CMake_USE_ELF_PARSER) // Parse the ELF binary. cmELF elf(file.c_str()); - - // Get the RPATH or RUNPATH entry from it. - cmELF::StringEntry const* se = elf.GetRPath(); - if (!se) { - se = elf.GetRunPath(); - } - - // Make sure the current rpath contains the new rpath. - if (newRPath.empty()) { + if (elf) { + // Get the RPATH or RUNPATH entry from it. + cmELF::StringEntry const* se = elf.GetRPath(); if (!se) { - return true; + se = elf.GetRunPath(); } - } else { - if (se && - cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) { - return true; + + // Make sure the current rpath contains the new rpath. + if (newRPath.empty()) { + if (!se) { + return true; + } + } else { + if (se && + cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) { + return true; + } } + return false; } - return false; -#elif defined(CMake_USE_XCOFF_PARSER) +#endif +#if defined(CMake_USE_XCOFF_PARSER) // Parse the XCOFF binary. cmXCOFF xcoff(file.c_str()); - if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) { - if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) { - return true; + if (xcoff) { + if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) { + if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) { + return true; + } } + return false; } - return false; -#else +#endif (void)file; (void)newRPath; return false; -#endif } bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 11a8b1f..82880a9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3543,8 +3543,6 @@ void cmVisualStudio10TargetGenerator::WriteNasmOptions( } Elem e2(e1, "NASM"); - std::vector<std::string> includes = - this->GetIncludes(configName, "ASM_NASM"); OptionsHelper nasmOptions(*(this->NasmOptions[configName]), e2); nasmOptions.OutputAdditionalIncludeDirectories("ASM_NASM"); nasmOptions.OutputFlagMap(); diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt index d4c19c7..4c488e6 100644 --- a/Tests/IncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/CMakeLists.txt @@ -2,17 +2,25 @@ cmake_minimum_required (VERSION 2.6) project(IncludeDirectories) if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4) - OR (CMAKE_C_COMPILER_ID STREQUAL Clang AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") OR CMAKE_C_COMPILER_ID STREQUAL AppleClang) + OR (CMAKE_C_COMPILER_ID STREQUAL Clang AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + OR CMAKE_C_COMPILER_ID STREQUAL AppleClang + OR ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3" AND + NOT CMAKE_GENERATOR MATCHES "Visual Studio")) # No support for VS generators yet. AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja" OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0))) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test) - if(run_sys_includes_test) - # The Bullseye wrapper appears to break the -isystem effect. - execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out) - if("x${out}" MATCHES "Bullseye") - set(run_sys_includes_test 0) + if ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC") + set(run_sys_includes_test 1) + else () + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test) + if(run_sys_includes_test) + # The Bullseye wrapper appears to break the -isystem effect. + execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out) + if("x${out}" MATCHES "Bullseye") + set(run_sys_includes_test 0) + endif() endif() endif() if (run_sys_includes_test) diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt index dee39c8..a746a68 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt @@ -6,9 +6,17 @@ project(SystemIncludeDirectories) add_library(systemlib systemlib.cpp) target_include_directories(systemlib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/systemlib") +function (apply_error_flags target) + if (MSVC) + target_compile_options(${target} PRIVATE /we4101) + else () + target_compile_options(${target} PRIVATE -Werror=unused-variable) + endif () +endfunction () + add_library(upstream upstream.cpp) target_link_libraries(upstream LINK_PUBLIC systemlib) -target_compile_options(upstream PRIVATE -Werror=unused-variable) +apply_error_flags(upstream) target_include_directories(upstream SYSTEM PUBLIC $<TARGET_PROPERTY:systemlib,INTERFACE_INCLUDE_DIRECTORIES> @@ -29,7 +37,7 @@ endif() add_library(consumer consumer.cpp) target_link_libraries(consumer upstream config_specific) -target_compile_options(consumer PRIVATE -Werror=unused-variable) +apply_error_flags(consumer) add_library(iface IMPORTED INTERFACE) set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES @@ -38,21 +46,21 @@ set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES add_library(imported_consumer imported_consumer.cpp) target_link_libraries(imported_consumer iface) -target_compile_options(imported_consumer PRIVATE -Werror=unused-variable) +apply_error_flags(imported_consumer) add_library(imported_consumer2 imported_consumer.cpp) target_link_libraries(imported_consumer2 imported_consumer) -target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable) +apply_error_flags(imported_consumer2) # add a target which has a relative system include add_library(somelib imported_consumer.cpp) target_include_directories(somelib SYSTEM PUBLIC "systemlib_header_only") -target_compile_options(somelib PRIVATE -Werror=unused-variable) +apply_error_flags(somelib) # add a target which consumes a relative system include add_library(otherlib upstream.cpp) target_link_libraries(otherlib PUBLIC somelib) -target_compile_options(somelib PRIVATE -Werror=unused-variable) +apply_error_flags(otherlib) macro(do_try_compile error_option) set(TC_ARGS @@ -61,7 +69,11 @@ macro(do_try_compile error_option) LINK_LIBRARIES iface ) if (${error_option} STREQUAL WITH_ERROR) - list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable) + if (MSVC) + list(APPEND TC_ARGS COMPILE_DEFINITIONS /we4101) + else () + list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable) + endif () endif() try_compile(${TC_ARGS}) endmacro() diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp index a13f08f..3da308d 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp @@ -1,5 +1,6 @@ -#include "config_iface.h" +#include <config_iface.h> + #include "upstream.h" int consumer() diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp index 1dbe819..53759b1 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp @@ -1,5 +1,5 @@ -#include "systemlib.h" +#include <systemlib.h> int main() { diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h index a670c2a..3daf69e 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h @@ -2,7 +2,7 @@ #ifndef UPSTREAM_H #define UPSTREAM_H -#include "systemlib.h" +#include <systemlib.h> #ifdef _WIN32 __declspec(dllexport) diff --git a/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt index 70dfa01..5d58633 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt +++ b/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt @@ -7,14 +7,14 @@ set_target_properties(c_interface PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}>" INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}>" ) -target_compile_options(c_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:C,GNU,Clang>:-Werror=unused-variable>") +target_compile_options(c_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:C,GNU,Clang>:-Werror=unused-variable>;$<$<COMPILE_LANG_AND_ID:C,MSVC>:/we4101>") add_library(cxx_interface INTERFACE) set_target_properties(cxx_interface PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_system_include>" INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_system_include>" ) -target_compile_options(cxx_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:-Werror=unused-variable>") +target_compile_options(cxx_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:-Werror=unused-variable>;$<$<COMPILE_LANG_AND_ID:C,MSVC>:/we4101>") # The C header must come before the C++ header for this test to smoke out the # failure. The order of sources is how CMake determines the include cache diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake new file mode 100644 index 0000000..e49ff22 --- /dev/null +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake @@ -0,0 +1,17 @@ +if(WIN32) + set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat\" --static --print-errors") +else() + set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh\" --static --print-errors") +endif() + +find_package(PkgConfig REQUIRED) + +if(NOT PKG_CONFIG_ARGN STREQUAL "--static;--print-errors") + message(SEND_ERROR "PKG_CONFIG_ARGN has wrong value '${PKG_CONFIG_ARGN}'") +endif() + +_pkgconfig_invoke("none" "prefix" "output" "") + +if(NOT prefix_output STREQUAL "Received;--static;Received;--print-errors") + message(SEND_ERROR "prefix_output has wrong value '${prefix_output}'") +endif() diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake index e7f008c..17e046a 100644 --- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake @@ -12,6 +12,7 @@ run_cmake(FindPkgConfig_PKGCONFIG_PATH) run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH) run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH) run_cmake(FindPkgConfig_extract_frameworks) +run_cmake(FindPkgConfig_GET_MATCHING_ARGN) if(APPLE) run_cmake(FindPkgConfig_extract_frameworks_target) diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat index b038370..c91713b 100755 --- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat +++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat @@ -1,5 +1,10 @@ @ECHO OFF +rem variables to get around `--static --version` printing the received +rem message and then version +set static=false +set print_errors=false + :LOOP IF "%1"=="" ( @@ -21,7 +26,19 @@ IF "%1"=="--exists" ( EXIT /B 0 ) ) +IF "%1"=="--static" ( + set static=true +) +IF "%1"=="--print-errors" ( + set print_errors=true +) SHIFT IF NOT "%~1"=="" GOTO LOOP +IF "%static%"=="true" ECHO Received --static +IF "%print_errors%"=="true" ECHO Received --print-errors + +IF "%static%"=="true" GOTO :EOF +IF "%print_errors%"=="true" GOTO :EOF + EXIT /B 255 diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh index 56bba30..4021bf7 100755 --- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh +++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh @@ -4,6 +4,11 @@ # to the --exists argument with the PKG_CONFIG_PATH environment variable # and returns 1 if they are different. +# variables to get around `--static --version` printing the received +# message and then version +static=false +print_errors=false + while [ $# -gt 0 ]; do case $1 in --version) @@ -17,7 +22,21 @@ while [ $# -gt 0 ]; do echo "Found: ${PKG_CONFIG_PATH}" [ "${last}" = "${PKG_CONFIG_PATH}" ] && exit 0 || exit 1 ;; + --static) + static=true + ;; + --print-errors) + print_errors=true + ;; esac shift done + +$static && echo "Received --static" +$print_errors && echo "Received --print-errors" + +if $static || $print_errors; then + exit 0 +fi + exit 255 diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index f07a12b..31bc075 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake @@ -181,3 +181,16 @@ add_test( run_ctest(TestCompletionStatus) endfunction() run_completion_status() + +# Verify that test output can add additional labels +function(run_extra_labels) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test( + NAME custom_labels + COMMAND ${CMAKE_COMMAND} -E + echo before\n<CTestLabel>label2</CTestLabel>\n<CTestLabel>label1</CTestLabel>\n<CTestLabel>label3</CTestLabel>\n<CTestLabel>label2</CTestLabel>\nafter) +set_tests_properties(custom_labels PROPERTIES LABELS "label1") + ]]) + run_ctest(TestExtraLabels) +endfunction() +run_extra_labels() diff --git a/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake b/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake new file mode 100644 index 0000000..beb39de --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake @@ -0,0 +1,28 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag) +string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}") +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/Test.xml" _test_contents) + +# Check labels. +STRING(REGEX MATCHALL [[<Label>label1</Label>]] matches "${_test_contents}") +list(LENGTH matches n_matches) +if(NOT n_matches EQUAL 1) + string(APPEND RunCMake_TEST_FAILED "expected 1 match for label1, found ${n_matches}") +endif() +STRING(REGEX MATCHALL [[<Label>label2</Label>]] matches "${_test_contents}") +list(LENGTH matches n_matches) +if(NOT n_matches EQUAL 1) + string(APPEND RunCMake_TEST_FAILED "expected 1 match for label2, found ${n_matches}") +endif() +STRING(REGEX MATCHALL [[<Label>label3</Label>]] matches "${_test_contents}") +list(LENGTH matches n_matches) +if(NOT n_matches EQUAL 1) + string(APPEND RunCMake_TEST_FAILED "expected 1 match for label3, found ${n_matches}") +endif() + +# Check test output. +if(NOT _test_contents MATCHES "before") + string(APPEND RunCMake_TEST_FAILED "Could not find expected string 'before' in Test.xml") +endif() +if(NOT _test_contents MATCHES "after") + string(APPEND RunCMake_TEST_FAILED "Could not find expected string 'after' in Test.xml") +endif() |