Merge branch 'FindGLEW-macOS' into release-3.15

Merge-request: !3656
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 8be781a..037c33b 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -124,6 +124,22 @@
   elseif(CMAKE_C_PLATFORM_ID MATCHES "Cygwin")
     set(CMAKE_COMPILER_IS_CYGWIN 1)
   endif()
+else()
+  if(NOT DEFINED CMAKE_C_COMPILER_FRONTEND_VARIANT)
+    # Some toolchain files set our internal CMAKE_C_COMPILER_ID_RUN
+    # variable but are not aware of CMAKE_C_COMPILER_FRONTEND_VARIANT.
+    # They pre-date our support for the GNU-like variant targeting the
+    # MSVC ABI so we do not consider that here.
+    if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+      if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
+        set(CMAKE_C_COMPILER_FRONTEND_VARIANT "MSVC")
+      else()
+        set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU")
+      endif()
+    else()
+      set(CMAKE_C_COMPILER_FRONTEND_VARIANT "")
+    endif()
+  endif()
 endif()
 
 if (NOT _CMAKE_TOOLCHAIN_LOCATION)
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 00ef5b9..7274eec 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -119,6 +119,22 @@
   elseif(CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
     set(CMAKE_COMPILER_IS_CYGWIN 1)
   endif()
+else()
+  if(NOT DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
+    # Some toolchain files set our internal CMAKE_CXX_COMPILER_ID_RUN
+    # variable but are not aware of CMAKE_CXX_COMPILER_FRONTEND_VARIANT.
+    # They pre-date our support for the GNU-like variant targeting the
+    # MSVC ABI so we do not consider that here.
+    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+      if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+        set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "MSVC")
+      else()
+        set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
+      endif()
+    else()
+      set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
+    endif()
+  endif()
 endif()
 
 if (NOT _CMAKE_TOOLCHAIN_LOCATION)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 6083358..02bc14b 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -138,7 +138,7 @@
 
   set(_variant "")
   if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang")
-    if(CMAKE_HOST_WIN32 AND "x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
+    if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
       if(CMAKE_GENERATOR MATCHES "Visual Studio")
         set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC")
       else()
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 0fb166a..6025025 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -1025,12 +1025,9 @@
 Json::Value Target::DumpInstallDestinations()
 {
   Json::Value destinations = Json::arrayValue;
-  auto installGens = this->GT->Makefile->GetInstallGenerators();
-  for (auto iGen : installGens) {
-    auto itGen = dynamic_cast<cmInstallTargetGenerator*>(iGen);
-    if (itGen != nullptr && itGen->GetTarget() == this->GT) {
-      destinations.append(this->DumpInstallDestination(itGen));
-    }
+  auto installGens = this->GT->Target->GetInstallGenerators();
+  for (auto itGen : installGens) {
+    destinations.append(this->DumpInstallDestination(itGen));
   }
   return destinations;
 }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 1d4a8ed..171fa77 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -507,7 +507,9 @@
         loadedPackage = true;
       } else {
         // The package was not loaded. Report errors.
-        HandlePackageMode(HandlePackageModeType::Module);
+        if (HandlePackageMode(HandlePackageModeType::Module)) {
+          loadedPackage = true;
+        }
       }
     }
   } else {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4eba4ff..9afc15a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -339,15 +339,16 @@
   bool failed = false;
   for (cmLocalGenerator* generator : this->LocalGenerators) {
     for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
-      std::vector<std::string> configs;
-      target->Makefile->GetConfigurations(configs);
-      if (configs.empty()) {
-        configs.emplace_back();
-      }
+      if (target->GetType() == cmStateEnums::EXECUTABLE &&
+          target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+        std::vector<std::string> configs;
+        target->Makefile->GetConfigurations(configs);
+        if (configs.empty()) {
+          configs.emplace_back();
+        }
 
-      for (std::string const& config : configs) {
-        if (target->GetLinkerLanguage(config) == "Swift") {
-          if (target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+        for (std::string const& config : configs) {
+          if (target->GetLinkerLanguage(config) == "Swift") {
             this->GetCMakeInstance()->IssueMessage(
               MessageType::FATAL_ERROR,
               "WIN32_EXECUTABLE property is not supported on Swift "
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index dba4bbb..c9e6923 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -43,11 +43,13 @@
   target.SetHaveInstallRule(true);
   const char* component = namelink ? args.GetNamelinkComponent().c_str()
                                    : args.GetComponent().c_str();
-  return new cmInstallTargetGenerator(
+  auto g = new cmInstallTargetGenerator(
     target.GetName(), destination.c_str(), impLib,
     args.GetPermissions().c_str(), args.GetConfigurations(), component,
     message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
     backtrace);
+  target.AddInstallGenerator(g);
+  return g;
 }
 
 static cmInstallTargetGenerator* CreateInstallTargetGenerator(
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 5cdacaa..04b4d72 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -63,15 +63,6 @@
   return true;
 }
 
-std::string prepareFilePathForTree(const std::string& path,
-                                   const std::string& currentSourceDir)
-{
-  if (!cmSystemTools::FileIsFullPath(path)) {
-    return cmSystemTools::CollapseFullPath(currentSourceDir + "/" + path);
-  }
-  return cmSystemTools::CollapseFullPath(path);
-}
-
 std::vector<std::string> prepareFilesPathsForTree(
   const std::vector<std::string>& filesPaths,
   const std::string& currentSourceDir)
@@ -80,9 +71,11 @@
   prepared.reserve(filesPaths.size());
 
   for (auto const& filePath : filesPaths) {
+    std::string fullPath =
+      cmSystemTools::CollapseFullPath(filePath, currentSourceDir);
     // If provided file path is actually not a file, silently ignore it.
-    if (cmSystemTools::FileExists(filePath, /*isFile=*/true)) {
-      prepared.push_back(prepareFilePathForTree(filePath, currentSourceDir));
+    if (cmSystemTools::FileExists(fullPath, /*isFile=*/true)) {
+      prepared.emplace_back(std::move(fullPath));
     }
   }
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cd67586..a67122c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -177,6 +177,7 @@
   std::vector<cmCustomCommand> PreBuildCommands;
   std::vector<cmCustomCommand> PreLinkCommands;
   std::vector<cmCustomCommand> PostBuildCommands;
+  std::vector<cmInstallTargetGenerator*> InstallGenerators;
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
   std::vector<std::string> IncludeDirectoriesEntries;
@@ -857,6 +858,17 @@
   impl->HaveInstallRule = hir;
 }
 
+void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
+{
+  impl->InstallGenerators.emplace_back(g);
+}
+
+std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
+  const
+{
+  return impl->InstallGenerators;
+}
+
 bool cmTarget::GetIsGeneratorProvided() const
 {
   return impl->IsGeneratorProvided;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index fdcca47..2bd9e6d 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -20,6 +20,7 @@
 
 class cmCustomCommand;
 class cmGlobalGenerator;
+class cmInstallTargetGenerator;
 class cmMakefile;
 class cmMessenger;
 class cmPropertyMap;
@@ -146,6 +147,9 @@
   bool GetHaveInstallRule() const;
   void SetHaveInstallRule(bool hir);
 
+  void AddInstallGenerator(cmInstallTargetGenerator* g);
+  std::vector<cmInstallTargetGenerator*> const& GetInstallGenerators() const;
+
   /**
    * Get/Set whether this target was auto-created by a generator.
    */
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8c6ba4e..7d25713 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1229,8 +1229,11 @@
   if (this->IPOEnabledConfigurations.count(config) > 0) {
     e1.Element("WholeProgramOptimization", "true");
   }
-  if (this->SpectreMitigationConfigurations.count(config) > 0) {
-    e1.Element("SpectreMitigation", "Spectre");
+  {
+    auto s = this->SpectreMitigation.find(config);
+    if (s != this->SpectreMitigation.end()) {
+      e1.Element("SpectreMitigation", s->second);
+    }
   }
 }
 
@@ -2760,8 +2763,8 @@
     }
   }
 
-  if (clOptions.HasFlag("SpectreMitigation")) {
-    this->SpectreMitigationConfigurations.insert(configName);
+  if (const char* s = clOptions.GetFlag("SpectreMitigation")) {
+    this->SpectreMitigation[configName] = s;
     clOptions.RemoveFlag("SpectreMitigation");
   }
 
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 860b809..6607e77 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -215,7 +215,7 @@
   unsigned int NsightTegraVersion[4];
   bool TargetCompileAsWinRT;
   std::set<std::string> IPOEnabledConfigurations;
-  std::set<std::string> SpectreMitigationConfigurations;
+  std::map<std::string, std::string> SpectreMitigation;
   cmGlobalVisualStudio10Generator* const GlobalGenerator;
   cmLocalVisualStudio10Generator* const LocalGenerator;
   std::set<std::string> CSharpCustomCommandNames;
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index da79f5d..1b9c973 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -625,3 +625,9 @@
 if(ACME_FOUND)
     message(SEND_ERROR "Should not find ACME package")
 endif()
+
+############################################################################
+##Test find_package CMAKE_FIND_PACKAGE_PREFER_CONFIG with unknown package
+
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+find_package(DoesNotExist)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index 18b9347..3096358 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -2087,7 +2087,40 @@
             ],
             "build": "^cxx$",
             "source": "^cxx$",
-            "install": None,
+            "install": {
+                "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+                "destinations": [
+                    {
+                        "path": "bin",
+                        "backtrace": [
+                            {
+                                "file": "^codemodel-v2\\.cmake$",
+                                "line": 37,
+                                "command": "install",
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^codemodel-v2\\.cmake$",
+                                "line": None,
+                                "command": None,
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^CMakeLists\\.txt$",
+                                "line": 3,
+                                "command": "include",
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^CMakeLists\\.txt$",
+                                "line": None,
+                                "command": None,
+                                "hasParent": False,
+                            },
+                        ],
+                    },
+                ],
+            },
             "link": {
                 "language": "CXX",
                 "lto": None,
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index 72073d5..c98a84c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -33,3 +33,5 @@
   set_property(TARGET c_static_lib PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
   file(WRITE "${CMAKE_BINARY_DIR}/ipo_enabled.txt" "")
 endif()
+
+install(TARGETS cxx_exe)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 55ca9ea..27b81b7 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -26,3 +26,7 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
   run_cmake(VsJustMyCode)
 endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20)
+  run_cmake(VsSpectreMitigation)
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake b/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake
new file mode 100644
index 0000000..6117763
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake
@@ -0,0 +1,30 @@
+macro(VsSpectreMitigation_check tgt spectre_expect)
+  set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj")
+  if(NOT EXISTS "${vcProjectFile}")
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.")
+    return()
+  endif()
+
+  set(HAVE_SpectreMitigation 0)
+
+  file(STRINGS "${vcProjectFile}" lines)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "^ *<SpectreMitigation>([^<>]+)</SpectreMitigation>")
+      set(spectre_actual "${CMAKE_MATCH_1}")
+      if(NOT "${spectre_actual}" STREQUAL "${spectre_expect}")
+        set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has <SpectreMitigation> '${spectre_actual}', not '${spectre_expect}'.")
+        return()
+      endif()
+      set(HAVE_SpectreMitigation 1)
+      break()
+    endif()
+  endforeach()
+
+  if(NOT HAVE_SpectreMitigation AND NOT "${spectre_expect}" STREQUAL "")
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <SpectreMitigation> field.")
+    return()
+  endif()
+endmacro()
+
+VsSpectreMitigation_check(SpectreMitigationOn-C "Spectre")
+VsSpectreMitigation_check(SpectreMitigationOff-C "false")
diff --git a/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake b/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake
new file mode 100644
index 0000000..b3779d7
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(C)
+
+add_library(SpectreMitigationOn-C empty.c)
+target_compile_options(SpectreMitigationOn-C PRIVATE -Qspectre)
+
+add_library(SpectreMitigationOff-C empty.c)
+target_compile_options(SpectreMitigationOff-C PRIVATE -Qspectre-)
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index e5f8588..f4cbac2 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -8,3 +8,6 @@
 endif()
 
 add_executable(SwiftOnly main.swift)
+
+# Dummy to make sure generation works with such targets.
+add_library(SwiftIface INTERFACE)