Merge branch 'vs-win-sdk' into release-3.14

Merge-request: !2989
diff --git a/Help/command/file.rst b/Help/command/file.rst
index db4d6fc..465e567 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -26,8 +26,8 @@
     file(`MAKE_DIRECTORY`_ [<dir>...])
     file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
     file(`SIZE`_ <filename> <out-var>)
-    file(`READ_SYMLINK`_ <filename> <out-var>)
-    file(`CREATE_LINK`_ <file> <new-file> [...])
+    file(`READ_SYMLINK`_ <linkname> <out-var>)
+    file(`CREATE_LINK`_ <original> <linkname> [...])
 
   `Path Conversion`_
     file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
@@ -350,22 +350,22 @@
 
 .. code-block:: cmake
 
-  file(READ_SYMLINK <filename> <variable>)
+  file(READ_SYMLINK <linkname> <variable>)
 
-Read the symlink at ``<filename>`` and put the result in ``<variable>``.
-Requires that ``<filename>`` is a valid path pointing to a symlink. If
-``<filename>`` does not exist, or is not a symlink, an error is thrown.
+This subcommand queries the symlink ``<linkname>`` and stores the path it
+points to in the result ``<variable>``.  If ``<linkname>`` does not exist or
+is not a symlink, CMake issues a fatal error.
 
 Note that this command returns the raw symlink path and does not resolve
-relative symlinks. If you want to resolve the relative symlink yourself, you
-could do something like this:
+a relative path.  The following is an example of how to ensure that an
+absolute path is obtained:
 
 .. code-block:: cmake
 
-  set(filename "/path/to/foo.sym")
-  file(READ_SYMLINK "${filename}" result)
+  set(linkname "/path/to/foo.sym")
+  file(READ_SYMLINK "${linkname}" result)
   if(NOT IS_ABSOLUTE "${result}")
-    get_filename_component(dir "${filename}" DIRECTORY)
+    get_filename_component(dir "${linkname}" DIRECTORY)
     set(result "${dir}/${result}")
   endif()
 
@@ -373,23 +373,23 @@
 
 .. code-block:: cmake
 
-  file(CREATE_LINK <file> <new-file>
+  file(CREATE_LINK <original> <linkname>
        [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC])
 
-Create a link to ``<file>`` at ``<new-file>``.
+Create a link ``<linkname>`` that points to ``<original>``.
+It will be a hard link by default, but providing the ``SYMBOLIC`` option
+results in a symbolic link instead.  Hard links require that ``original``
+exists and is a file, not a directory.  If ``<linkname>`` already exists,
+it will be overwritten.
 
-It is a hard link by default. This can be changed to symbolic links by
-using ``SYMBOLIC``.  The original file needs to exist for hard links.
-
-The ``<result>`` variable, if specified, gets the status of the operation.
-It is set to ``0`` in case of success. Otherwise, it contains the error
-generated. In case of failures, if ``RESULT`` is not specified, a fatal error
-is emitted.
+The ``<result>`` variable, if specified, receives the status of the operation.
+It is set to ``0`` upon success or an error message otherwise.  If ``RESULT``
+is not specified and the operation fails, a fatal error is emitted.
 
 Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if
-creating the link fails.
-
-Overwrites the ``<new-file>`` if it exists.
+creating the link fails.  It can be useful for handling situations such as
+``<original>`` and ``<linkname>`` being on different drives or mount points,
+which would make them unable to support a hard link.
 
 Path Conversion
 ^^^^^^^^^^^^^^^
diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst
index f55499a..9bbf877 100644
--- a/Help/command/get_filename_component.rst
+++ b/Help/command/get_filename_component.rst
@@ -15,14 +15,13 @@
  NAME      = File name without directory
  EXT       = File name longest extension (.b.c from d/a.b.c)
  NAME_WE   = File name without directory or longest extension
- LAST_EXT  = File name last extention (.c from d/a.b.c)
+ LAST_EXT  = File name last extension (.c from d/a.b.c)
  NAME_WLE  = File name without directory or last extension
  PATH      = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
 
 Paths are returned with forward slashes and have no trailing slashes.
-The longest file extension is always considered.  If the optional
-``CACHE`` argument is specified, the result variable is added to the
-cache.
+If the optional ``CACHE`` argument is specified, the result variable is
+added to the cache.
 
 .. code-block:: cmake
 
diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst
index 13d209f..a04005c 100644
--- a/Help/release/3.14.rst
+++ b/Help/release/3.14.rst
@@ -172,7 +172,7 @@
 * The :module:`ExternalProject` module :command:`ExternalProject_Add` command
   gained ``LOG_PATCH`` to optionally log the patch step.
 
-* The :module:`ExternalProject` module's ``ExternalProject_Add`` command
+* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
   learned to apply ``SOURCE_SUBDIR`` when ``BUILD_IN_SOURCE`` is also used.
   The ``BUILD_COMMAND`` is run in the given ``SOURCE_SUBDIR`` of the
   ``SOURCE_DIR``.
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index dbc41c8..ac27f87 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -83,7 +83,7 @@
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_XL "XL C")
 
   list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS MSVC )
-  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "/?")
+  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "-?")
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft")
 
   list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI )
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index fd1d5fb..e0d2449 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -96,6 +96,12 @@
         file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
           "Parsed ${lang} implicit include dir info from above output: rv=${rv}\n${log}\n\n")
         if("${rv}" STREQUAL "done")
+          # Entries that we have been told to explicitly pass as standard include
+          # directories will not be implicitly added by the compiler.
+          if(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES)
+            list(REMOVE_ITEM implicit_incdirs ${CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES})
+          endif()
+
           # We parsed implicit include directories, so override the default initializer.
           set(_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT "${implicit_incdirs}")
         endif()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 83ce392..8ba4246 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -824,7 +824,7 @@
   endif()
 
   # Test whether an MSVC-like command-line option works.
-  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" /?
+  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -?
     RESULT_VARIABLE _clang_result
     OUTPUT_VARIABLE _clang_stdout
     ERROR_VARIABLE _clang_stderr)
diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake
index 9edc309..a3c4d9c 100644
--- a/Modules/CMakeDetermineVSServicePack.cmake
+++ b/Modules/CMakeDetermineVSServicePack.cmake
@@ -79,7 +79,7 @@
 function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR  _VERSION_VAR)
     if(EXISTS ${CMAKE_CXX_COMPILER})
       execute_process(
-          COMMAND ${CMAKE_CXX_COMPILER} /?
+          COMMAND ${CMAKE_CXX_COMPILER} -?
           ERROR_VARIABLE _output
           OUTPUT_QUIET
         )
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index c5d6b45..e097894 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -550,7 +550,8 @@
       When enabled, the output of the test step is logged to files.
 
     ``LOG_MERGED_STDOUTERR <bool>``
-      When enabled, the output the step is not split by stdout and stderr.
+      When enabled, stdout and stderr will be merged for any step whose
+      output is being logged to files.
 
     ``LOG_OUTPUT_ON_FAILURE <bool>``
       This option only has an effect if at least one of the other ``LOG_<step>``
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 8c112d4..7882c4b 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -1807,10 +1807,12 @@
     foreach(compiler IN LISTS _boost_COMPILER)
       list(APPEND _boost_RELEASE_NAMES
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+        ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} )
     endforeach()
     list(APPEND _boost_RELEASE_NAMES
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} )
@@ -1819,10 +1821,12 @@
       foreach(compiler IN LISTS _boost_COMPILER)
         list(APPEND _boost_RELEASE_NAMES
           ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+          ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}
           ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
       endforeach()
       list(APPEND _boost_RELEASE_NAMES
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+        ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
     endif()
   endforeach()
@@ -1860,10 +1864,12 @@
     foreach(compiler IN LISTS _boost_COMPILER)
       list(APPEND _boost_DEBUG_NAMES
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+        ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} )
     endforeach()
     list(APPEND _boost_DEBUG_NAMES
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}
       ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} )
@@ -1872,10 +1878,12 @@
       foreach(compiler IN LISTS _boost_COMPILER)
         list(APPEND _boost_DEBUG_NAMES
           ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+          ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}
           ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
       endforeach()
       list(APPEND _boost_DEBUG_NAMES
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION}
+        ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}
         ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
     endif()
   endforeach()
diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake
index 46c24bb..97f744d 100644
--- a/Modules/Platform/UnixPaths.cmake
+++ b/Modules/Platform/UnixPaths.cmake
@@ -63,21 +63,29 @@
   /lib /lib32 /lib64 /usr/lib /usr/lib32 /usr/lib64
   )
 
+if(CMAKE_SYSROOT_COMPILE)
+  set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}")
+else()
+  set(_cmake_sysroot_compile "${CMAKE_SYSROOT}")
+endif()
+
 # Default per-language values.  These may be later replaced after
 # parsing the implicit directory information from compiler output.
 set(_CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES_INIT
   ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}
-  /usr/include
+  "${_cmake_sysroot_compile}/usr/include"
   )
 set(_CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES_INIT
   ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}
-  /usr/include
+  "${_cmake_sysroot_compile}/usr/include"
   )
 set(_CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES_INIT
   ${CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES}
-  /usr/include
+  "${_cmake_sysroot_compile}/usr/include"
   )
 
+unset(_cmake_sysroot_compile)
+
 # Enable use of lib32 and lib64 search path variants by default.
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE)
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 8090e00..8b01af1 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -920,6 +920,20 @@
     return result;
   }
 
+  // Standard include directories to be added unconditionally at the end.
+  // These are intended to simulate additional implicit include directories.
+  std::vector<std::string> userStandardDirs;
+  {
+    std::string key = "CMAKE_";
+    key += lang;
+    key += "_STANDARD_INCLUDE_DIRECTORIES";
+    std::string const value = this->Makefile->GetSafeDefinition(key);
+    cmSystemTools::ExpandListArgument(value, userStandardDirs);
+    for (std::string& usd : userStandardDirs) {
+      cmSystemTools::ConvertToUnixSlashes(usd);
+    }
+  }
+
   // Implicit include directories
   std::vector<std::string> implicitDirs;
   std::set<std::string> implicitSet;
@@ -928,24 +942,21 @@
     return (implicitSet.find(dir) == implicitSet.end());
   };
   {
-    std::string rootPath;
-    if (const char* sysrootCompile =
-          this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) {
-      rootPath = sysrootCompile;
-    } else {
-      rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
-    }
-    cmSystemTools::ConvertToUnixSlashes(rootPath);
-
     // Raw list of implicit include directories
-    std::vector<std::string> impDirVec;
+    // Start with "standard" directories that we unconditionally add below.
+    std::vector<std::string> impDirVec = userStandardDirs;
 
     // Load implicit include directories for this language.
     std::string key = "CMAKE_";
     key += lang;
     key += "_IMPLICIT_INCLUDE_DIRECTORIES";
     if (const char* value = this->Makefile->GetDefinition(key)) {
+      size_t const impDirVecOldSize = impDirVec.size();
       cmSystemTools::ExpandListArgument(value, impDirVec);
+      // FIXME: Use cmRange with 'advance()' when it supports non-const.
+      for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
+        cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
+      }
     }
 
     // The Platform/UnixPaths module used to hard-code /usr/include for C, CXX,
@@ -965,13 +976,8 @@
     }
 
     for (std::string const& i : impDirVec) {
-      std::string imd = i;
-      cmSystemTools::ConvertToUnixSlashes(imd);
-      if (!rootPath.empty() && !cmHasPrefix(imd, rootPath)) {
-        imd = rootPath + imd;
-      }
-      if (implicitSet.insert(imd).second) {
-        implicitDirs.emplace_back(std::move(imd));
+      if (implicitSet.insert(i).second) {
+        implicitDirs.emplace_back(i);
       }
     }
   }
@@ -1010,23 +1016,10 @@
   MoveSystemIncludesToEnd(result, config, lang, target);
 
   // Append standard include directories for this language.
-  {
-    std::vector<std::string> userStandardDirs;
-    {
-      std::string key = "CMAKE_";
-      key += lang;
-      key += "_STANDARD_INCLUDE_DIRECTORIES";
-      std::string const value = this->Makefile->GetSafeDefinition(key);
-      cmSystemTools::ExpandListArgument(value, userStandardDirs);
-    }
-    userDirs.reserve(userDirs.size() + userStandardDirs.size());
-    for (std::string& usd : userStandardDirs) {
-      cmSystemTools::ConvertToUnixSlashes(usd);
-      if (notImplicit(usd)) {
-        emitDir(usd);
-      }
-      userDirs.emplace_back(std::move(usd));
-    }
+  userDirs.reserve(userDirs.size() + userStandardDirs.size());
+  for (std::string& usd : userStandardDirs) {
+    emitDir(usd);
+    userDirs.emplace_back(std::move(usd));
   }
 
   // Append compiler implicit include directories