From 2638bc7a8597a0002c40aa6e7a0ed58bf0ca4725 Mon Sep 17 00:00:00 2001
From: Matthew Leibowitz <mattleibow@live.com>
Date: Sat, 14 Mar 2020 00:19:46 +0200
Subject: [PATCH] Support building with VS2017 and VS2019

---
 gn/BUILD.gn              | 28 +++++++---------------
 gn/BUILDCONFIG.gn        | 52 ++++------------------------------------
 gn/find_msvc.py          | 26 ++++++++++++++++++++
 gn/lowest_version_dir.py |  9 ++++++-
 gn/toolchain/BUILD.gn    | 15 +++---------
 5 files changed, 50 insertions(+), 80 deletions(-)
 create mode 100644 gn/find_msvc.py

diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index b7112ae22b5a..25cc3eb58bf1 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -59,12 +59,8 @@ config("default") {
       "NOMINMAX",
     ]
 
-    if (msvc == 2015) {
-      _include_dirs = [ "$win_vc/include" ]
-    } else {  # 2017
-      _include_dirs = [ "$win_vc/Tools/MSVC/$win_toolchain_version/include" ]
-    }
-    _include_dirs += [
+    _include_dirs = [
+      "$win_vc/Tools/MSVC/$win_toolchain_version/include",
       "$win_sdk/Include/$win_sdk_version/shared",
       "$win_sdk/Include/$win_sdk_version/ucrt",
       "$win_sdk/Include/$win_sdk_version/um",
@@ -82,24 +78,16 @@ config("default") {
       include_dirs = _include_dirs
     }
 
+    _is_store = ""
+    if (is_winrt) {
+      _is_store = "/store"
+    }
+
     lib_dirs = [
       "$win_sdk/Lib/$win_sdk_version/ucrt/$target_cpu",
       "$win_sdk/Lib/$win_sdk_version/um/$target_cpu",
+      "$win_vc/Tools/MSVC/$win_toolchain_version/lib/$target_cpu$_is_store",
     ]
-    if (msvc == 2015) {
-      if (target_cpu == "x86") {
-        lib_dirs += [ "$win_vc/lib" ]
-      } else {
-        lib_dirs += [ "$win_vc/lib/amd64" ]
-      }
-    } else {  # 2017
-      _is_store = ""
-      if (is_winrt) {
-        _is_store = "/store"
-      }
-      lib_dirs +=
-          [ "$win_vc/Tools/MSVC/$win_toolchain_version/lib/$target_cpu$_is_store" ]
-    }
   } else {
     cflags += [
       "-fstrict-aliasing",
diff --git a/gn/BUILDCONFIG.gn b/gn/BUILDCONFIG.gn
index 8d099eeeb646..2f98e0b2aaac 100644
--- a/gn/BUILDCONFIG.gn
+++ b/gn/BUILDCONFIG.gn
@@ -28,6 +28,7 @@ declare_args() {
   cxx = "c++"
 
   win_sdk = "C:/Program Files (x86)/Windows Kits/10"
+  min_win_sdk_version = "10.0.10240.0"
   win_sdk_version = ""
 
   win_vc = ""
@@ -140,62 +141,18 @@ if (is_android) {
   }
 }
 
-msvc = ""
 if (is_win) {
-  # By default we look for 2017 (Pro & Community), then 2015. If MSVC is installed in a
+  # By default we look for 2017 (Enterprise, Pro, and Community), then 2015. If MSVC is installed in a
   # non-default location, you can set win_vc to inform us where it is.
-  vc_2017_ent_default =
-      "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC"
-  vc_2017_pro_default =
-      "C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC"
-  vc_2017_com_default =
-      "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC"
-  vc_2017_bt_default =
-      "C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC"
-  vc_2015_default = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC"
 
   if (win_vc == "") {
-    if ("True" == exec_script("//gn/checkdir.py",
-                              [ "$vc_2017_ent_default" ],
-                              "trim string")) {
-      win_vc = vc_2017_ent_default
-      msvc = 2017
-    } else if ("True" == exec_script("//gn/checkdir.py",
-                              [ "$vc_2017_pro_default" ],
-                              "trim string")) {
-      win_vc = vc_2017_pro_default
-      msvc = 2017
-    } else if ("True" == exec_script("//gn/checkdir.py",
-                                     [ "$vc_2017_com_default" ],
-                                     "trim string")) {
-      win_vc = vc_2017_com_default
-      msvc = 2017
-    } else if ("True" == exec_script("//gn/checkdir.py",
-                                     [ "$vc_2017_bt_default" ],
-                                     "trim string")) {
-      win_vc = vc_2017_bt_default
-      msvc = 2017
-    } else if ("True" == exec_script("//gn/checkdir.py",
-                                     [ "$vc_2015_default" ],
-                                     "trim string")) {
-      win_vc = vc_2015_default
-      msvc = 2015
-    }
+    win_vc = exec_script("//gn/find_msvc.py", [], "trim string")
   }
   assert(win_vc != "")  # Could not find VC installation. Set win_vc to your VC directory.
-
-  if (msvc == "") {
-    if ("True" ==
-        exec_script("//gn/checkdir.py", [ "$win_vc/Tools" ], "trim string")) {
-      msvc = 2017
-    } else {
-      msvc = 2015
-    }
-  }
 }
 
 if (is_win) {
-  if (msvc == 2017 && win_toolchain_version == "") {
+  if (win_toolchain_version == "") {
     win_toolchain_version = exec_script("//gn/highest_version_dir.py",
                                         [
                                           "$win_vc/Tools/MSVC",
@@ -208,6 +165,7 @@ if (is_win) {
                                   [
                                     "$win_sdk/Include",
                                     "[0-9]{2}\.[0-9]\.[0-9]{5}\.[0-9]",
+                                    min_win_sdk_version
                                   ],
                                   "trim string")
   }
diff --git a/gn/find_msvc.py b/gn/find_msvc.py
new file mode 100644
index 000000000000..864db094a3a3
--- /dev/null
+++ b/gn/find_msvc.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# Copyright 2019 Google Inc.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import sys
+
+'''
+Look for the first match in the format
+    C:\\Program Files (x86)\\Microsoft Visual Studio\\${RELEASE}\\${VERSION}\\VC
+'''
+def find_msvc():
+  if sys.platform.startswith('win'):
+    default_dir = r'C:\Program Files (x86)\Microsoft Visual Studio'
+    for release in ['2019', '2017']:
+      for version in ['Enterprise', 'Professional', 'Community', 'BuildTools']:
+        path = os.path.join(default_dir, release, version, 'VC')
+        if os.path.isdir(path):
+          return path
+  return None
+
+if __name__ == '__main__':
+  result = find_msvc()
+  if result:
+    sys.stdout.write(result + '\n')
diff --git a/gn/lowest_version_dir.py b/gn/lowest_version_dir.py
index b493d7f1458e..b835faa460a7 100644
--- a/gn/lowest_version_dir.py
+++ b/gn/lowest_version_dir.py
@@ -11,5 +11,12 @@
 
 dirpath = sys.argv[1]
 regex = re.compile(sys.argv[2])
+minimum = sys.argv[3]
 
-print sorted(filter(regex.match, os.listdir(dirpath)))[0]
+matches = sorted(filter(regex.match, os.listdir(dirpath)))
+for match in matches:
+    if (match >= minimum):
+        path = os.path.join(dirpath, match)
+        if os.path.isdir(path):
+            print match
+            break
diff --git a/gn/toolchain/BUILD.gn b/gn/toolchain/BUILD.gn
index 76ae752f1764..355d8f5a471f 100644
--- a/gn/toolchain/BUILD.gn
+++ b/gn/toolchain/BUILD.gn
@@ -41,15 +41,7 @@ if (host_os == "win") {
 toolchain("msvc") {
   lib_dir_switch = "/LIBPATH:"
 
-  if (msvc == 2015) {
-    if (target_cpu == "x86") {
-      bin = "$win_vc/bin"
-    } else {
-      bin = "$win_vc/bin/amd64"
-    }
-  } else {
-    bin = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu"
-  }
+  bin = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu"
 
   if (target_cpu == "x64") {
     _target = "amd64"
@@ -57,10 +49,9 @@ toolchain("msvc") {
     _target = "amd64_" + target_cpu
   }
   if (is_winrt) {
-    _target += " uwp 10.0.10240.0 -vcvars_ver=14.2"
-  } else {
-    _target += " 10.0.10240.0 -vcvars_ver=14.2"
+    _target += " uwp"
   }
+  _target += " " + win_sdk_version + " -vcvars_ver=14.2"
 
   _vcvarsall = "$win_vc/Auxiliary/Build/vcvarsall.bat"
   env_setup = "cmd /c set __VSCMD_ARG_NO_LOGO=1 && set VSCMD_START_DIR=%CD% && \"$_vcvarsall\" $_target && "