From 28e0717a104c7a9bf8f91c978441aec93f57805f Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Thu, 8 Dec 2022 19:29:53 -0500
Subject: [PATCH] Copy MSVC redist as SxS

---
 indra/cmake/Copy3rdPartyLibs.cmake | 66 ++++++++++++++++++++++++++++++
 indra/newview/viewer_manifest.py   | 13 +++++-
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 2ce9ee73d40..1877c4dae46 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -125,6 +125,72 @@ if(WINDOWS)
       list(APPEND debug_files kdud.dll)
       list(APPEND release_files kdu.dll)
     endif (USE_KDU)
+    
+    #*******************************
+    # Copy MS C runtime dlls, required for packaging.
+    if (MSVC80)
+        set(MSVC_VER 80)
+    elseif (MSVC_VERSION EQUAL 1600) # VisualStudio 2010
+        MESSAGE(STATUS "MSVC_VERSION ${MSVC_VERSION}")
+    elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12
+        set(MSVC_VER 120)
+    elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1940) # Visual Studio 2017 through 2022
+        set(MSVC_VER 140)
+    elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019
+        set(MSVC_VER 140)
+    elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1940) # Visual Studio 2019
+        set(MSVC_VER 140)        
+    else (MSVC80)
+        MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
+    endif (MSVC80)
+
+    if(ADDRESS_SIZE EQUAL 32)
+        # this folder contains the 32bit DLLs.. (yes really!)
+        set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64")
+    else(ADDRESS_SIZE EQUAL 32)
+        # this folder contains the 64bit DLLs.. (yes really!)
+        set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32")
+    endif(ADDRESS_SIZE EQUAL 32)
+
+    # Having a string containing the system registry path is a start, but to
+    # get CMake to actually read the registry, we must engage some other
+    # operation.
+    get_filename_component(registry_path "${registry_find_path}" ABSOLUTE)
+
+    # These are candidate DLL names. Empirically, VS versions before 2015 have
+    # msvcp*.dll and msvcr*.dll. VS 2017 has msvcp*.dll and vcruntime*.dll.
+    # Check each of them.
+    foreach(release_msvc_file
+            concrt${MSVC_VER}.dll
+            msvcp${MSVC_VER}.dll
+            msvcp${MSVC_VER}_1.dll
+            msvcp${MSVC_VER}_2.dll
+            msvcp${MSVC_VER}_atomic_wait.dll
+            msvcp${MSVC_VER}_codecvt_ids.dll
+            vccorlib${MSVC_VER}.dll
+            vcruntime${MSVC_VER}.dll
+            vcruntime${MSVC_VER}_1.dll
+            )
+        if(EXISTS "${registry_path}/${release_msvc_file}")
+            to_relwithdeb_staging_dirs(
+                ${registry_path}
+                third_party_targets
+                ${release_msvc_file})
+            to_release_staging_dirs(
+                ${registry_path}
+                third_party_targets
+                ${release_msvc_file})
+        else()
+            # This isn't a WARNING because, as noted above, every VS version
+            # we've observed has only a subset of the specified DLL names.
+            MESSAGE(STATUS "Redist lib ${release_msvc_file} not found")
+        endif()
+    endforeach()
+    MESSAGE(STATUS "Will copy redist files for MSVC ${MSVC_VER}:")
+    foreach(target ${third_party_targets})
+        MESSAGE(STATUS "${target}")
+    endforeach()
+
 elseif(DARWIN)
     set(SHARED_LIB_STAGING_DIR_DEBUG            "${SHARED_LIB_STAGING_DIR}/Debug/Resources")
     set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO   "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources")
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 507e33c388d..07b924a1698 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -509,7 +509,18 @@ def construct(self):
                     self.path("kdud.dll", "kdud.dll")
                 else:
                     self.path(src="kdu.dll", dst="kdu.dll")
-            self.path_optional("vcruntime140_1.dll")
+					
+            # These need to be installed as a SxS assembly, currently a 'private' assembly.
+            # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
+            self.path("concrt140.dll")
+            self.path("msvcp140.dll")
+            self.path("msvcp140_1.dll")
+            self.path("msvcp140_2.dll")
+            self.path("msvcp140_atomic_wait.dll")
+            self.path("msvcp140_codecvt_ids.dll")
+            self.path("vccorlib140.dll")
+            self.path("vcruntime140.dll")
+            self.path("vcruntime140_1.dll")
 
             # SLVoice executable
             with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
-- 
GitLab