Merge topic 'patch-CheckIPOSupported' a04fd272c2 CheckIPOSupported: Update documentation Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !10443
diff --git a/.gitlab/ci/configure_macos_common.cmake b/.gitlab/ci/configure_macos_common.cmake index e78c9ce..614f211 100644 --- a/.gitlab/ci/configure_macos_common.cmake +++ b/.gitlab/ci/configure_macos_common.cmake
@@ -16,3 +16,9 @@ # when CMake itself is configured. Use a version that is not # newer than the macOS version running on any CI host. set(CMake_TEST_XCTest_DEPLOYMENT_TARGET "10.15" CACHE STRING "") + +if("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos_arm64") + set(CMake_TEST_APPLE_SILICON ON CACHE BOOL "") +else() + set(CMake_TEST_APPLE_SILICON OFF CACHE BOOL "") +endif()
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index b7232d6..089a3d6 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst
@@ -956,3 +956,37 @@ .. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema .. |cps-version_schema| replace:: ``version_schema`` + +CPS Transitive Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A |CPS| package description consists of one or more components which may in +turn depend on other components either internal or external to the package. +When external components are required, the providing package is noted as +a package-level requirement of the package. Additionally, the set of required +components is typically noted in said external package requirement. + +Where a CMake-script package description would use the +:command:`find_dependency` command to handle transitive dependencies, CMake +handles transitive dependencies for CPS itself using an internally nested +``find_package`` call. This call can resolve CPS package dependencies via +*either* another CPS package, or via a CMake-script package. The manner in +which the CPS component dependencies are handled is subject to some caveats. + +When the candidate for resolving a transitive dependency is another CPS +package, things are simple; ``COMPONENTS`` and CPS "components" are directly +comparable (and are effectively synonymous with CMake "imported targets"). +CMake-script packages, however, are encouraged to (and often do) check that +required components were found, whether or not the package describes separate +components. Additionally, even those that do describe components typically do +not have the same correlation to imported targets that is normal for CPS. As +a result, passing the set of required components declared by a CPS package to +``COMPONENTS`` would result in spurious failures to resolve dependencies. + +To address this, if a candidate for resolving a CPS transitive dependency is a +CMake-script package, CMake passes the required components as declared by the +consuming CPS package as ``OPTIONAL_COMPONENTS`` and performs a separate, +internal check that the candidate package supplied the required imported +targets. Those targets must be named ``<PackageName>::<ComponentName>``, in +conformance with CPS convention, or the check will consider the package not +found.
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index f3e3d1f..9fe3951 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -67,6 +67,8 @@ # executables. This may lead to issues when their stderr output (which # contains the relevant compiler internals) becomes interweaved. string(REGEX REPLACE "(^| )-pipe( |$)" " " ${v} "${${v}}") + # Suppress any formatting of warnings and/or errors + string(REGEX REPLACE "(-f|/)diagnostics(-|:)color(=[a-z]+)?" "" ${v} "${${v}}") endforeach() # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake index f070ba5..a3a2cee 100644 --- a/Modules/CheckIncludeFile.cmake +++ b/Modules/CheckIncludeFile.cmake
@@ -35,9 +35,24 @@ .. include:: /module/CMAKE_REQUIRED_QUIET.txt -See the :module:`CheckIncludeFiles` module to check for multiple headers -at once. See the :module:`CheckIncludeFileCXX` module to check for headers -using the ``CXX`` language. +Examples +^^^^^^^^ + +Checking whether the ``C`` header ``<unistd.h>`` exists and storing the check +result in the ``HAVE_UNISTD_H`` cache variable: + +.. code-block:: cmake + + include(CheckIncludeFile) + + check_include_file(unistd.h HAVE_UNISTD_H) + +See Also +^^^^^^^^ + +* The :module:`CheckIncludeFileCXX` module to check for single ``C++`` header. +* The :module:`CheckIncludeFiles` module to check for one or more ``C`` or + ``C++`` headers at once. #]=======================================================================] include_guard(GLOBAL)
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake index ec02b36..756abf1 100644 --- a/Modules/CheckIncludeFileCXX.cmake +++ b/Modules/CheckIncludeFileCXX.cmake
@@ -35,8 +35,24 @@ .. include:: /module/CMAKE_REQUIRED_QUIET.txt -See modules :module:`CheckIncludeFile` and :module:`CheckIncludeFiles` -to check for one or more ``C`` headers. +Examples +^^^^^^^^ + +Checking whether the ``C++23`` header ``<stdfloat>`` exists and storing the +check result in the ``HAVE_STDFLOAT_HEADER`` cache variable: + +.. code-block:: cmake + + include(CheckIncludeFileCXX) + + check_include_file_cxx(stdfloat HAVE_STDFLOAT_HEADER) + +See Also +^^^^^^^^ + +* The :module:`CheckIncludeFile` module to check for single ``C`` header. +* The :module:`CheckIncludeFiles` module to check for one or more ``C`` or + ``C++`` headers at once. #]=======================================================================] include_guard(GLOBAL)
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake index 6dfb41d..855d450 100644 --- a/Modules/CheckIncludeFiles.cmake +++ b/Modules/CheckIncludeFiles.cmake
@@ -41,8 +41,41 @@ .. include:: /module/CMAKE_REQUIRED_QUIET.txt -See modules :module:`CheckIncludeFile` and :module:`CheckIncludeFileCXX` -to check for a single header file in ``C`` or ``CXX`` languages. +Examples +^^^^^^^^ + +Checking whether one or more ``C`` headers exist and storing the check result +in cache variables: + +.. code-block:: cmake + + include(CheckIncludeFiles) + + check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) + + if(HAVE_SYS_SOCKET_H) + # The <net/if.h> header on Darwin and BSD-like systems is not self-contained + # and also requires <sys/socket.h> + check_include_files("sys/socket.h;net/if.h" HAVE_NET_IF_H) + else() + check_include_files(net/if.h HAVE_NET_IF_H) + endif() + +The ``LANGUAGE`` option can be used to specify which compiler to use. For +example, checking multiple ``C++`` headers, when both ``C`` and ``CXX`` +languages are enabled in the project: + +.. code-block:: cmake + + include(CheckIncludeFiles) + + check_include_files("header_1.hpp;header_2.hpp" HAVE_HEADERS LANGUAGE CXX) + +See Also +^^^^^^^^ + +* The :module:`CheckIncludeFile` module to check for single ``C`` header. +* The :module:`CheckIncludeFileCXX` module to check for single ``C++`` header. #]=======================================================================] include_guard(GLOBAL)
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 2f0c3c1..89058ca 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake
@@ -218,6 +218,13 @@ set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc) endif() +# Prefer h5hl<LANG> compilers if HDF5_FIND_HL is enabled +if(HDF5_FIND_HL) + list(PREPEND HDF5_C_COMPILER_NAMES h5hlcc) + list(PREPEND HDF5_CXX_COMPILER_NAMES h5hlc++) + list(PREPEND HDF5_Fortran_COMPILER_NAMES h5hlfc) +endif() + # Test first if the current compilers automatically wrap HDF5 function(_HDF5_test_regular_compiler_C success version is_parallel) if(NOT ${success} OR
diff --git a/Modules/FindSQLite3.cmake b/Modules/FindSQLite3.cmake index fcacbef..60eb541 100644 --- a/Modules/FindSQLite3.cmake +++ b/Modules/FindSQLite3.cmake
@@ -66,7 +66,7 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(SQLite3 - REQUIRED_VARS SQLite3_INCLUDE_DIR SQLite3_LIBRARY + REQUIRED_VARS SQLite3_LIBRARY SQLite3_INCLUDE_DIR VERSION_VAR SQLite3_VERSION) # Create the imported target
diff --git a/Modules/Use_wxWindows.cmake b/Modules/Use_wxWindows.cmake index 5f46784..e3c1870 100644 --- a/Modules/Use_wxWindows.cmake +++ b/Modules/Use_wxWindows.cmake
@@ -7,39 +7,41 @@ .. deprecated:: 2.8.10 - Use ``find_package(wxWidgets)`` and ``include(${wxWidgets_USE_FILE})`` instead. + Use :module:`find_package(wxWidgets) <FindwxWidgets>` instead. -This convenience include finds if wxWindows is installed and set the -appropriate libs, incdirs, flags etc. author Jan Woetzel <jw -at- -mip.informatik.uni-kiel.de> (07/2003) +This convenience include finds if wxWindows library is installed and sets the +appropriate libraries, include directories, flags, etc. -USAGE: +Examples +^^^^^^^^ -:: +Include ``Use_wxWindows`` module in project's ``CMakeLists.txt``: - just include Use_wxWindows.cmake - in your projects CMakeLists.txt +.. code-block:: cmake -include( ${CMAKE_MODULE_PATH}/Use_wxWindows.cmake) + # CMakeLists.txt + include(Use_wxWindows) -:: +When the GL support is required, set ``WXWINDOWS_USE_GL`` *before* including +this module: - if you are sure you need GL then +.. code-block:: cmake -set(WXWINDOWS_USE_GL 1) - -:: - - *before* you include this file. + set(WXWINDOWS_USE_GL ON) + include(Use_wxWindows) #]=======================================================================] +# Author: Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> (07/2003) + # ----------------------------------------------------- # 16.Feb.2004: changed INCLUDE to FIND_PACKAGE to read from users own non-system CMAKE_MODULE_PATH (Jan Woetzel JW) # 07/2006: rewrite as FindwxWidgets.cmake, kept for backward compatibility JW -message(STATUS "Use_wxWindows.cmake is DEPRECATED. \n" -"Please use find_package(wxWidgets) and include(${wxWidgets_USE_FILE}) instead. (JW)") - +message( + DEPRECATION + "Use_wxWindows module is DEPRECATED.\n" + "Please use find_package(wxWidgets) instead. (JW)" +) # ------------------------
diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake index 7152afe..3751025 100644 --- a/Modules/UsewxWidgets.cmake +++ b/Modules/UsewxWidgets.cmake
@@ -5,39 +5,46 @@ UsewxWidgets ------------ -Convenience include for using wxWidgets library. +This module calls :command:`include_directories` and +:command:`link_directories`, sets compile definitions for the current directory +and appends some compile flags to use wxWidgets library after calling the +:module:`find_package(wxWidgets) <FindwxWidgets>`. -Determines if wxWidgets was FOUND and sets the appropriate libs, -incdirs, flags, etc. INCLUDE_DIRECTORIES and LINK_DIRECTORIES are -called. +Examples +^^^^^^^^ -USAGE +Include ``UsewxWidgets`` module in project's ``CMakeLists.txt``: .. code-block:: cmake - # Note that for MinGW users the order of libs is important! + # Note that for MinGW users the order of libraries is important. find_package(wxWidgets REQUIRED net gl core base) + + # Above also sets the wxWidgets_USE_FILE variable that points to this module. include(${wxWidgets_USE_FILE}) - # and for each of your dependent executable/library targets: - target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES}) + # Link wxWidgets libraries for each dependent executable/library target. + target_link_libraries(<ProjectTarget> ${wxWidgets_LIBRARIES}) +As of CMake 3.27, a better approach is to link only the +:module:`wxWidgets::wxWidgets <FindwxWidgets>` ``IMPORTED`` target to specific +targets that require it, rather than including this module. Imported targets +provide better control of the package usage properties, such as include +directories and compile flags, by applying them only to the targets they are +linked to, avoiding unnecessary propagation to all targets in the current +directory. -DEPRECATED +.. code-block:: cmake -:: + # CMakeLists.txt + find_package(wxWidgets) - LINK_LIBRARIES is not called in favor of adding dependencies per target. - - - -AUTHOR - -:: - - Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> + # Link the imported target for each dependent executable/library target. + target_link_libraries(<ProjectTarget> wxWidgets::wxWidgets) #]=======================================================================] +# Author: Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> + if (wxWidgets_FOUND) if (wxWidgets_INCLUDE_DIRS) if(wxWidgets_INCLUDE_DIRS_NO_SYSTEM)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 30dfb3b..45be758 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 4) set(CMake_VERSION_MINOR 0) -set(CMake_VERSION_PATCH 20250308) +set(CMake_VERSION_PATCH 20250311) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx index 1b8c765..4d8d6a5 100644 --- a/Source/cmCurl.cxx +++ b/Source/cmCurl.cxx
@@ -179,7 +179,7 @@ std::string const& netrc_file) { std::string e; - CURL_NETRC_OPTION curl_netrc_level = CURL_NETRC_LAST; + long curl_netrc_level = CURL_NETRC_LAST; ::CURLcode res; if (!netrc_level.empty()) {
diff --git a/Source/cmPathResolver.cxx b/Source/cmPathResolver.cxx index 71ce7b4..32f3ef7 100644 --- a/Source/cmPathResolver.cxx +++ b/Source/cmPathResolver.cxx
@@ -492,6 +492,14 @@ static constexpr Options::Symlinks Symlinks = Options::Symlinks::None; static constexpr Options::Existence Existence = Options::Existence::Agnostic; }; +struct CasePath +{ +#if defined(_WIN32) || defined(__APPLE__) + static constexpr Options::ActualCase ActualCase = Options::ActualCase::Yes; +#endif + static constexpr Options::Symlinks Symlinks = Options::Symlinks::None; + static constexpr Options::Existence Existence = Options::Existence::Agnostic; +}; struct RealPath { #if defined(_WIN32) || defined(__APPLE__) @@ -512,6 +520,8 @@ #if defined(__SUNPRO_CC) constexpr Options::Symlinks NaivePath::Symlinks; constexpr Options::Existence NaivePath::Existence; +constexpr Options::Symlinks CasePath::Symlinks; +constexpr Options::Existence CasePath::Existence; constexpr Options::Symlinks RealPath::Symlinks; constexpr Options::Existence RealPath::Existence; constexpr Options::Symlinks LogicalPath::Symlinks; @@ -535,6 +545,7 @@ template class Resolver<Policies::LogicalPath>; template class Resolver<Policies::RealPath>; +template class Resolver<Policies::CasePath>; template class Resolver<Policies::NaivePath>; }
diff --git a/Source/cmPathResolver.h b/Source/cmPathResolver.h index 1f96e0a..e2399ba 100644 --- a/Source/cmPathResolver.h +++ b/Source/cmPathResolver.h
@@ -78,13 +78,18 @@ /** Normalizes paths while resolving symlinks only when followed by '..' components. Does not require paths to exist, but - reads on-disk case of paths that do exist (on Windows). */ + reads on-disk case of paths that do exist (on Windows and macOS). */ struct LogicalPath; -/** Normalizes paths while resolving all symlinks. - Requires paths to exist, and reads their on-disk case (on Windows). */ +/** Normalizes paths while resolving all symlinks. Requires paths to exist, + and reads their on-disk case (on Windows and macOS). */ struct RealPath; +/** Normalizes paths while assuming components followed by '..' + components are not symlinks. Does not require paths to exist, but + reads on-disk case of paths that do exist (on Windows and macOS). */ +struct CasePath; + /** Normalizes paths in memory without disk access. Assumes components followed by '..' components are not symlinks. */ struct NaivePath; @@ -94,6 +99,7 @@ extern template class Resolver<Policies::LogicalPath>; extern template class Resolver<Policies::RealPath>; +extern template class Resolver<Policies::CasePath>; extern template class Resolver<Policies::NaivePath>; }
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 45e59ec..0755148 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx
@@ -1305,23 +1305,77 @@ return filepath_.empty(); } +std::string cmSystemTools::GetRealPathResolvingWindowsSubst( + std::string const& path, std::string* errorMessage) +{ +#ifdef _WIN32 + // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found + std::string resolved_path; + uv_fs_t req; + int err = uv_fs_realpath(nullptr, &req, path.c_str(), nullptr); + if (!err) { + resolved_path = std::string((char*)req.ptr); + cmSystemTools::ConvertToUnixSlashes(resolved_path); + } else if (err == UV_ENOSYS) { + resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage); + } else if (errorMessage) { + cmsys::Status status = + cmsys::Status::Windows(uv_fs_get_system_error(&req)); + *errorMessage = status.GetString(); + resolved_path.clear(); + } else { + resolved_path = path; + } + // Normalize to upper-case drive letter as cm::PathResolver does. + if (resolved_path.size() > 1 && resolved_path[1] == ':') { + resolved_path[0] = toupper(resolved_path[0]); + } + return resolved_path; +#else + return cmsys::SystemTools::GetRealPath(path, errorMessage); +#endif +} + std::string cmSystemTools::GetRealPath(std::string const& path, std::string* errorMessage) { #ifdef _WIN32 - std::string resolved_path; - using namespace cm::PathResolver; - // IWYU pragma: no_forward_declare cm::PathResolver::Policies::RealPath - static Resolver<Policies::RealPath> const resolver(RealOS); - cmsys::Status status = resolver.Resolve(path, resolved_path); - if (!status) { - if (errorMessage) { - *errorMessage = status.GetString(); - resolved_path.clear(); - } else { - resolved_path = path; + std::string resolved_path = + cmSystemTools::GetRealPathResolvingWindowsSubst(path, errorMessage); + + // If the original path used a subst drive and the real path starts + // with the substitution, restore the subst drive prefix. This may + // incorrectly restore a subst drive if the underlying drive was + // encountered via an absolute symlink, but this is an acceptable + // limitation to otherwise preserve susbt drives. + if (resolved_path.size() >= 2 && resolved_path[1] == ':' && + path.size() >= 2 && path[1] == ':' && + toupper(resolved_path[0]) != toupper(path[0])) { + // FIXME: Add thread_local or mutex if we use threads. + static std::map<char, std::string> substMap; + char const drive = static_cast<char>(toupper(path[0])); + std::string maybe_subst = cmStrCat(drive, ":/"); + auto smi = substMap.find(drive); + if (smi == substMap.end()) { + smi = substMap + .emplace( + drive, + cmSystemTools::GetRealPathResolvingWindowsSubst(maybe_subst)) + .first; + } + std::string const& resolved_subst = smi->second; + std::string::size_type const ns = resolved_subst.size(); + if (ns > 0) { + std::string::size_type const np = resolved_path.size(); + if (ns == np && resolved_path == resolved_subst) { + resolved_path = maybe_subst; + } else if (ns > 0 && ns < np && resolved_path[ns] == '/' && + resolved_path.compare(0, ns, resolved_subst) == 0) { + resolved_path.replace(0, ns + 1, maybe_subst); + } } } + return resolved_path; #else return cmsys::SystemTools::GetRealPath(path, errorMessage); @@ -1991,8 +2045,13 @@ std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p) { using namespace cm::PathResolver; +#ifdef _WIN32 + // IWYU pragma: no_forward_declare cm::PathResolver::Policies::CasePath + static Resolver<Policies::CasePath> const resolver(RealOS); +#else // IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath static Resolver<Policies::LogicalPath> const resolver(RealOS); +#endif resolver.Resolve(std::move(p), p); return p; }
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index f7ac20b..16c5caa 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h
@@ -441,9 +441,11 @@ /** Convert an input path to an absolute path with no '/..' components. Backslashes in the input path are converted to forward slashes. Relative paths are interpreted w.r.t. GetLogicalWorkingDirectory. - On Windows, the on-disk capitalization is loaded for existing paths. This is similar to 'realpath', but preserves symlinks that are - not erased by '../' components. */ + not erased by '../' components. + + On Windows and macOS, the on-disk capitalization is loaded for + existing paths. */ static std::string ToNormalizedPathOnDisk(std::string p); #ifndef CMAKE_BOOTSTRAP @@ -649,6 +651,12 @@ static std::string GetComspec(); #endif + /** Get the real path for a given path, removing all symlinks. + This variant of GetRealPath also works on Windows but will + resolve subst drives too. */ + static std::string GetRealPathResolvingWindowsSubst( + std::string const& path, std::string* errorMessage = nullptr); + /** Get the real path for a given path, removing all symlinks. */ static std::string GetRealPath(std::string const& path, std::string* errorMessage = nullptr);
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index d921a89..35913c7 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx
@@ -63,7 +63,8 @@ std::string const& formatString, bool utcFlag) const { - std::string real_path = cmSystemTools::GetRealPath(path); + std::string real_path = + cmSystemTools::GetRealPathResolvingWindowsSubst(path); if (!cmsys::SystemTools::FileExists(real_path)) { return std::string();
diff --git a/Tests/CMakeLib/testPathResolver.cxx b/Tests/CMakeLib/testPathResolver.cxx index d79afd9..d5cee74 100644 --- a/Tests/CMakeLib/testPathResolver.cxx +++ b/Tests/CMakeLib/testPathResolver.cxx
@@ -24,6 +24,7 @@ // IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath // IWYU pragma: no_forward_declare cm::PathResolver::Policies::NaivePath +// IWYU pragma: no_forward_declare cm::PathResolver::Policies::CasePath // IWYU pragma: no_forward_declare cm::PathResolver::Policies::RealPath namespace { @@ -213,6 +214,22 @@ }); { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("/link-a", "/link-a"); + EXPECT_RESOLVE("/link-a-excess", "/link-a-excess"); + EXPECT_RESOLVE("/link-a-excess/b", "/link-a-excess/b"); + EXPECT_RESOLVE("/link-broken", "/link-broken"); + EXPECT_RESOLVE("/link-a/../missing", "/missing"); + EXPECT_RESOLVE("/a/b/link-c", "/a/b/link-c"); + EXPECT_RESOLVE("/a/link-b/c", "/a/link-b/c"); + EXPECT_RESOLVE("/a/link-b/link-c/..", "/a/link-b"); + EXPECT_RESOLVE("/a/b/c/link-..|..", "/a/b/c/link-..|.."); + EXPECT_RESOLVE("/a/b/c/link-..|../link-b", "/a/b/c/link-..|../link-b"); + EXPECT_RESOLVE("/a/link-|1|2/3", "/a/link-|1|2/3"); + EXPECT_RESOLVE("/a/link-|1|2/../2/3", "/a/2/3"); + } + + { Resolver<Policies::LogicalPath> const r(os); EXPECT_RESOLVE("/link-a", "/link-a"); EXPECT_RESOLVE("/link-a-excess", "/link-a-excess"); @@ -264,6 +281,16 @@ }); { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("/mIxEd/MiSsInG", "/MiXeD/MiSsInG"); + EXPECT_RESOLVE("/mIxEd/link-MiXeD", "/MiXeD/LiNk-MiXeD"); + EXPECT_RESOLVE("/mIxEd/link-c-MiXeD", "/MiXeD/LiNk-C-MiXeD"); + EXPECT_RESOLVE("/upper/mIsSiNg", "/UPPER/mIsSiNg"); + EXPECT_RESOLVE("/upper/link-upper", "/UPPER/LINK-UPPER"); + EXPECT_RESOLVE("/upper/link-c-upper", "/UPPER/LINK-C-UPPER"); + } + + { Resolver<Policies::LogicalPath> const r(os); EXPECT_RESOLVE("/mIxEd/MiSsInG", "/MiXeD/MiSsInG"); EXPECT_RESOLVE("/mIxEd/link-MiXeD", "/MiXeD/LiNk-MiXeD"); @@ -302,6 +329,16 @@ EXPECT_RESOLVE("C:/..", "C:/"); EXPECT_RESOLVE("c:/../", "c:/"); } + { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("c:/", "C:/"); + EXPECT_RESOLVE("C:/", "C:/"); + EXPECT_RESOLVE("c://", "C:/"); + EXPECT_RESOLVE("C:/.", "C:/"); + EXPECT_RESOLVE("c:/./", "C:/"); + EXPECT_RESOLVE("C:/..", "C:/"); + EXPECT_RESOLVE("c:/../", "C:/"); + } os.SetPaths({ { "c:/", { {}, {} } }, { "//host/", { {}, {} } }, @@ -361,6 +398,16 @@ }); { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG"); + EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/LiNk-MiXeD"); + EXPECT_RESOLVE("c:/mIxEd/link-c-MiXeD", "C:/MiXeD/LiNk-C-MiXeD"); + EXPECT_RESOLVE("c:/upper/mIsSiNg", "C:/UPPER/mIsSiNg"); + EXPECT_RESOLVE("c:/upper/link-upper", "C:/UPPER/LINK-UPPER"); + EXPECT_RESOLVE("c:/upper/link-c-upper", "C:/UPPER/LINK-C-UPPER"); + } + + { Resolver<Policies::LogicalPath> const r(os); EXPECT_RESOLVE("c:/mIxEd/MiSsInG", "C:/MiXeD/MiSsInG"); EXPECT_RESOLVE("c:/mIxEd/link-MiXeD", "C:/MiXeD/LiNk-MiXeD"); @@ -441,6 +488,27 @@ EXPECT_RESOLVE("E:.", "E:/"); EXPECT_RESOLVE("E:..", "E:/"); } + { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("c:", "C:/cwd"); + EXPECT_RESOLVE("c:.", "C:/cwd"); + EXPECT_RESOLVE("c:..", "C:/"); + EXPECT_RESOLVE("C:", "C:/cwd"); + EXPECT_RESOLVE("C:.", "C:/cwd"); + EXPECT_RESOLVE("C:..", "C:/"); + EXPECT_RESOLVE("d:", "D:/cwd-d"); + EXPECT_RESOLVE("d:.", "D:/cwd-d"); + EXPECT_RESOLVE("d:..", "D:/"); + EXPECT_RESOLVE("D:", "D:/cwd-d"); + EXPECT_RESOLVE("D:.", "D:/cwd-d"); + EXPECT_RESOLVE("D:..", "D:/"); + EXPECT_RESOLVE("e:", "E:/"); + EXPECT_RESOLVE("e:.", "E:/"); + EXPECT_RESOLVE("e:..", "E:/"); + EXPECT_RESOLVE("E:", "E:/"); + EXPECT_RESOLVE("E:.", "E:/"); + EXPECT_RESOLVE("E:..", "E:/"); + } os.SetPaths({ { "c:/", { {}, {} } }, { "c:/cwd", { {}, {} } }, @@ -496,6 +564,13 @@ EXPECT_RESOLVE("link-to-host-share/..", "//host/"); EXPECT_RESOLVE("link-to-host-share/../missing", "//host/missing"); } + + { + Resolver<Policies::CasePath> const r(os); + EXPECT_RESOLVE("link-to-host-share", "C:/cwd/link-to-host-share"); + EXPECT_RESOLVE("link-to-host-share/..", "C:/cwd"); + EXPECT_RESOLVE("link-to-host-share/../missing", "C:/cwd/missing"); + } return true; } #endif
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/CheckCompilerLinkerId.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/CheckCompilerLinkerId.cmake new file mode 100644 index 0000000..a6a56ca --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/CheckCompilerLinkerId.cmake
@@ -0,0 +1,5 @@ +enable_language(C) + +if(NOT CMAKE_C_COMPILER_LINKER OR NOT CMAKE_C_COMPILER_LINKER_ID) + message(FATAL_ERROR "Failed to determine Linker.") +endif()
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake index d50d403..df03f15 100644 --- a/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake
@@ -39,3 +39,7 @@ ) endif() endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES Clang) + run_cmake_with_options(CheckCompilerLinkerId "-DCMAKE_C_FLAGS=-fdiagnostics-color=always") +endif()