Fixes to run apple SDK finders as gclient hooks (#825)

Supports https://github.com/flutter/engine/pull/50957
diff --git a/build/config/ios/ios_sdk.gni b/build/config/ios/ios_sdk.gni
index 1d71239..e2f79fd 100644
--- a/build/config/ios/ios_sdk.gni
+++ b/build/config/ios/ios_sdk.gni
@@ -56,7 +56,6 @@
     ios_simulator_sdk_path = _ios_sim_sdk_result[0]
   }
 
-  # Compute default target.
   if (use_ios_simulator) {
     assert(ios_simulator_sdk_path != "")
     ios_sdk_path = ios_simulator_sdk_path
diff --git a/build/config/ios/ios_sdk.py b/build/config/ios/ios_sdk.py
index a16eba7..5b86450 100644
--- a/build/config/ios/ios_sdk.py
+++ b/build/config/ios/ios_sdk.py
@@ -5,45 +5,89 @@
 import argparse
 import errno
 import os
+import shutil
 import subprocess
 import sys
 
-sys.path.insert(1, '../../build')
+sys.path.insert(1, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
 from pyutil.file_util import symlink
 
-# This script returns the path to the SDK of the given type. Pass the type of
-# SDK you want, which is typically 'iphone' or 'iphonesimulator'.
+# This script creates symlinks under flutter/prebuilts to the iphone and
+# iphone simulator SDKs.
+
+SDKs = ['iphoneos', 'iphonesimulator']
+
+PREBUILTS = os.path.realpath(os.path.join(
+  os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, 'flutter', 'prebuilts',
+))
 
 def main(argv):
   parser = argparse.ArgumentParser()
-  parser.add_argument('--symlink',
-                      help='Whether to create a symlink in the buildroot to the SDK.')
-  parser.add_argument('--sdk',
-                      choices=['iphoneos', 'iphonesimulator'],
-                      help='Which SDK to find.')
+  parser.add_argument(
+      '--as-gclient-hook',
+      default=False,
+      action='store_true',
+      help='Whether the script is running as a gclient hook.',
+  )
+  parser.add_argument(
+    '--symlink',
+    type=str,
+    help='Whether to create a symlink in the buildroot to the SDK.',
+  )
+  parser.add_argument(
+    '--sdk',
+    choices=['iphoneos', 'iphonesimulator'],
+    help='Which SDK to find.',
+  )
   args = parser.parse_args()
 
-  command =  [
-    'xcodebuild',
-    '-version',
-    '-sdk',
-    args.sdk,
-    'Path'
-  ]
+  # On CI, Xcode is not yet installed when gclient hooks are being run.
+  # This is because the version of Xcode that CI installs might depend on the
+  # contents of the repo, so the repo must be set up first, which includes
+  # running the gclient hooks. Instead, on CI, this script will be run during
+  # GN.
+  running_on_luci = os.environ.get('LUCI_CONTEXT') is not None
+  if running_on_luci and args.as_gclient_hook:
+    return 0
 
-  sdk_output = subprocess.check_output(command).decode('utf-8').strip()
-  if args.symlink:
-    symlink_target = os.path.join(args.symlink, 'SDKs', os.path.basename(sdk_output))
-    symlink(sdk_output, symlink_target)
-    frameworks_location = os.path.join(sdk_output, '..', '..', 'Library', 'Frameworks')
-    frameworks_symlink = os.path.join(args.symlink, 'Library', 'Frameworks')
-    symlink(frameworks_location, frameworks_symlink)
+  symlink_path = args.symlink
+  if not running_on_luci and symlink_path is None:
+    symlink_path = PREBUILTS
 
-    sdk_output = symlink_target
+  sdks = [args.sdk] if args.sdk is not None else SDKs
 
-  print(sdk_output)
+  sdks_path = None
+  libraries_path = None
+  if symlink_path:
+    sdks_path = os.path.join(symlink_path, 'SDKs')
+    libraries_path = os.path.join(symlink_path, 'Library')
+    # Remove any old files created by this script under PREBUILTS/SDKs.
+    if args.as_gclient_hook:
+      if os.path.isdir(sdks_path):
+        shutil.rmtree(sdks_path)
+      if os.path.isdir(libraries_path):
+        shutil.rmtree(libraries_path)
+
+  for sdk in sdks:
+    command =  [
+      'xcodebuild',
+      '-version',
+      '-sdk',
+      sdk,
+      'Path'
+    ]
+    sdk_output = subprocess.check_output(command).decode('utf-8').strip()
+    if symlink_path:
+      symlink_target = os.path.join(sdks_path, os.path.basename(sdk_output))
+      symlink(sdk_output, symlink_target)
+      frameworks_location = os.path.join(sdk_output, '..', '..', 'Library', 'Frameworks')
+      frameworks_symlink = os.path.join(libraries_path, 'Frameworks')
+      symlink(frameworks_location, frameworks_symlink)
+      sdk_output = symlink_target
+    print(sdk_output)
   return 0
 
+
 if __name__ == '__main__':
   if sys.platform != 'darwin':
     raise Exception('This script only runs on Mac')
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index ed23dd5..8956918 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -7,11 +7,11 @@
 
 declare_args() {
   # Minimum supported version of the Mac SDK.
-  mac_sdk_min = "10.14"
+  mac_sdk_min = ""
 
   # The MACOSX_DEPLOYMENT_TARGET variable used when compiling.
   # Must be of the form x.x.x for Info.plist files.
-  mac_deployment_target = "10.14.0"
+  mac_deployment_target = ""
 
   # Path to a specific version of the Mac SDK, not including a backslash at
   # the end. If empty, the path to the lowest version greater than or equal to
@@ -19,6 +19,9 @@
   mac_sdk_path = ""
 }
 
+assert(mac_sdk_min != "")
+assert(mac_deployment_target != "")
+
 if (mac_sdk_path == "") {
   find_sdk_args = []
   if ((use_goma || use_rbe) && create_xcode_symlinks) {
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
index da621ab..06261c1 100755
--- a/build/mac/find_sdk.py
+++ b/build/mac/find_sdk.py
@@ -22,6 +22,9 @@
 sys.path.append(os.path.dirname(os.path.dirname(__file__)))
 from pyutil.file_util import symlink
 
+PREBUILTS = os.path.realpath(os.path.join(
+  os.path.dirname(__file__), os.pardir, os.pardir, 'flutter', 'prebuilts',
+))
 
 def parse_version(version_str):
   """'10.6' => [10, 6]"""
@@ -30,21 +33,31 @@
 
 def main():
   parser = OptionParser()
-  parser.add_option("--verify",
-                    action="store_true", dest="verify", default=False,
-                    help="return the sdk argument and warn if it doesn't exist")
-  parser.add_option("--sdk_path",
-                    action="store", type="string", dest="sdk_path", default="",
-                    help="user-specified SDK path; bypasses verification")
   parser.add_option("--print_sdk_path",
                     action="store_true", dest="print_sdk_path", default=False,
                     help="Additionaly print the path the SDK (appears first).")
+  parser.add_option("--as-gclient-hook",
+                    action="store_true", dest="as_gclient_hook", default=False,
+                    help="Whether the script is running as a gclient hook.")
   parser.add_option("--symlink",
-                    action="store", type="string", dest="symlink", default="",
+                    action="store", type="string", dest="symlink",
                     help="Whether to create a symlink in the buildroot to the SDK.")
   (options, args) = parser.parse_args()
   min_sdk_version = args[0]
 
+  # On CI, Xcode is not yet installed when gclient hooks are being run.
+  # This is because the version of Xcode that CI installs might depend on the
+  # contents of the repo, so the repo must be set up first, which includes
+  # running the gclient hooks. Instead, on CI, this script will be run during
+  # GN.
+  running_on_luci = os.environ.get('LUCI_CONTEXT') is not None
+  if running_on_luci and options.as_gclient_hook:
+    return 0
+
+  symlink_path = options.symlink
+  if not running_on_luci and symlink_path is None:
+    symlink_path = PREBUILTS
+
   job = subprocess.Popen(['xcode-select', '-print-path'],
                          universal_newlines=True,
                          stdout=subprocess.PIPE,
@@ -82,29 +95,13 @@
     print(sdk_json_output)
     raise Exception('No %s+ SDK found' % min_sdk_version)
 
-  if options.verify and best_sdk != min_sdk_version and not options.sdk_path:
-    print(sdk_json_output)
-    sys.stderr.writelines([
-      '',
-      '                                           vvvvvvv',
-      '',
-      'This build requires the %s SDK, but it was not found on your system.' \
-        % min_sdk_version,
-      'Either install it, or explicitly set mac_sdk in your gn args.',
-      '',
-      '                                           ^^^^^^^',
-      ''])
-    return min_sdk_version
+  if symlink_path:
+    sdks_path = os.path.join(symlink_path, 'SDKs')
+    symlink_target = os.path.join(sdks_path, os.path.basename(sdk_output))
+    symlink(sdk_output, symlink_target)
+    sdk_output = symlink_target
 
-  if options.symlink or options.print_sdk_path:
-    if options.symlink:
-      symlink_target = os.path.join(options.symlink, 'SDKs', os.path.basename(sdk_output))
-      symlink(sdk_output, symlink_target)
-      sdk_output = symlink_target
-
-    if options.print_sdk_path:
-      print(sdk_output)
-
+  print(sdk_output)
   return best_sdk