[M73 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / build / mac_toolchain.py
1 #!/usr/bin/env python
2 # Copyright 2018 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """
7 If should_use_hermetic_xcode.py emits "1", and the current toolchain is out of
8 date:
9   * Downloads the hermetic mac toolchain
10     * Requires CIPD authentication. Run `cipd auth-login`, use Google account.
11   * Accepts the license.
12     * If xcode-select and xcodebuild are not passwordless in sudoers, requires
13       user interaction.
14
15 The toolchain version can be overridden by setting MAC_TOOLCHAIN_REVISION with
16 the full revision, e.g. 9A235.
17 """
18
19 import os
20 import platform
21 import shutil
22 import subprocess
23 import sys
24
25
26 # This can be changed after running:
27 #    mac_toolchain upload -xcode-path path/to/Xcode.app
28 MAC_TOOLCHAIN_VERSION = '8E2002'
29
30 # The toolchain will not be downloaded if the minimum OS version is not met.
31 # 16 is the major version number for macOS 10.12.
32 MAC_MINIMUM_OS_VERSION = 16
33
34 # The toolchain will not be downloaded if the maximum OS version is exceeded.
35 # 17 is the major version number for macOS 10.13. Xcode 8 does not run on macOS
36 # 10.14.
37 # TODO(https://crbug.com/780980): Once we build with 10.13 SDK, Xcode 9, we
38 # should be able to remove this upper bound.
39 MAC_MAXIMUM_OS_VERSION = 17
40
41 MAC_TOOLCHAIN_INSTALLER = 'mac_toolchain'
42
43 # Absolute path to src/ directory.
44 REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
45
46 # Absolute path to a file with gclient solutions.
47 GCLIENT_CONFIG = os.path.join(os.path.dirname(REPO_ROOT), '.gclient')
48
49 BASE_DIR = os.path.abspath(os.path.dirname(__file__))
50 TOOLCHAIN_ROOT = os.path.join(BASE_DIR, 'mac_files')
51 TOOLCHAIN_BUILD_DIR = os.path.join(TOOLCHAIN_ROOT, 'Xcode.app')
52 STAMP_FILE = os.path.join(TOOLCHAIN_ROOT, 'toolchain_build_revision')
53
54
55 def PlatformMeetsHermeticXcodeRequirements():
56   major_version = int(platform.release().split('.')[0])
57   return (major_version >= MAC_MINIMUM_OS_VERSION and
58           major_version <= MAC_MAXIMUM_OS_VERSION)
59
60
61 def _UseHermeticToolchain():
62   current_dir = os.path.dirname(os.path.realpath(__file__))
63   script_path = os.path.join(current_dir, 'mac/should_use_hermetic_xcode.py')
64   proc = subprocess.Popen([script_path, 'mac'], stdout=subprocess.PIPE)
65   return '1' in proc.stdout.readline()
66
67
68 def RequestCipdAuthentication():
69   """Requests that the user authenticate to access Xcode CIPD packages."""
70
71   print 'Access to Xcode CIPD package requires authentication.'
72   print '-----------------------------------------------------------------'
73   print
74   print 'You appear to be a Googler.'
75   print
76   print 'I\'m sorry for the hassle, but you may need to do a one-time manual'
77   print 'authentication. Please run:'
78   print
79   print '    cipd auth-login'
80   print
81   print 'and follow the instructions.'
82   print
83   print 'NOTE: Use your google.com credentials, not chromium.org.'
84   print
85   print '-----------------------------------------------------------------'
86   print
87   sys.stdout.flush()
88
89
90 def PrintError(message):
91   # Flush buffers to ensure correct output ordering.
92   sys.stdout.flush()
93   sys.stderr.write(message + '\n')
94   sys.stderr.flush()
95
96
97 def InstallXcode(xcode_build_version, installer_cmd, xcode_app_path):
98   """Installs the requested Xcode build version.
99
100   Args:
101     xcode_build_version: (string) Xcode build version to install.
102     installer_cmd: (string) Path to mac_toolchain command to install Xcode.
103       See https://chromium.googlesource.com/infra/infra/+/master/go/src/infra/cmd/mac_toolchain/
104     xcode_app_path: (string) Path to install the contents of Xcode.app.
105
106   Returns:
107     True if installation was successful. False otherwise.
108   """
109   args = [
110       installer_cmd, 'install',
111       '-kind', 'mac',
112       '-xcode-version', xcode_build_version.lower(),
113       '-output-dir', xcode_app_path,
114   ]
115
116   # Buildbot slaves need to use explicit credentials. LUCI bots should NOT set
117   # this variable.
118   creds = os.environ.get('MAC_TOOLCHAIN_CREDS')
119   if creds:
120     args.extend(['--service-account-json', creds])
121
122   try:
123     subprocess.check_call(args)
124   except subprocess.CalledProcessError as e:
125     PrintError('Xcode build version %s failed to install: %s\n' % (
126         xcode_build_version, e))
127     RequestCipdAuthentication()
128     return False
129   except OSError as e:
130     PrintError(('Xcode installer "%s" failed to execute'
131                 ' (not on PATH or not installed).') % installer_cmd)
132     return False
133
134   return True
135
136
137 def main():
138   if sys.platform != 'darwin':
139     return 0
140
141   if not _UseHermeticToolchain():
142     print 'Skipping Mac toolchain installation for mac'
143     return 0
144
145   if not PlatformMeetsHermeticXcodeRequirements():
146     print 'OS version does not support toolchain.'
147     return 0
148
149   toolchain_version = os.environ.get('MAC_TOOLCHAIN_REVISION',
150                                       MAC_TOOLCHAIN_VERSION)
151
152   # On developer machines, mac_toolchain tool is provided by
153   # depot_tools. On the bots, the recipe is responsible for installing
154   # it and providing the path to the executable.
155   installer_cmd = os.environ.get('MAC_TOOLCHAIN_INSTALLER',
156                                  MAC_TOOLCHAIN_INSTALLER)
157
158   toolchain_root = TOOLCHAIN_ROOT
159   xcode_app_path = TOOLCHAIN_BUILD_DIR
160   stamp_file = STAMP_FILE
161
162   # Delete the old "hermetic" installation if detected.
163   # TODO(crbug.com/797051): remove this once the old "hermetic" solution is no
164   # longer in use.
165   if os.path.exists(stamp_file):
166     print 'Detected old hermetic installation at %s. Deleting.' % (
167       toolchain_root)
168     shutil.rmtree(toolchain_root)
169
170   success = InstallXcode(toolchain_version, installer_cmd, xcode_app_path)
171   if not success:
172     return 1
173
174   return 0
175
176
177 if __name__ == '__main__':
178   sys.exit(main())