• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Collects information about the SDK and return them as JSON file."""
6
7import argparse
8import json
9import os
10import re
11import subprocess
12import sys
13
14# Patterns used to extract the Xcode version and build version.
15XCODE_VERSION_PATTERN = re.compile(r'Xcode (\d+)\.(\d+)')
16XCODE_BUILD_PATTERN = re.compile(r'Build version (.*)')
17
18
19def GetCommandOutput(command):
20  """Returns the output of `command` as a string."""
21  return subprocess.check_output(command, encoding='utf-8')
22
23
24def GetAppleCpuName(target_cpu):
25  """Returns the name of the |target_cpu| using Apple's convention."""
26  return {
27      'x64': 'x86_64',
28      'arm': 'armv7',
29      'x86': 'i386'
30  }.get(target_cpu, target_cpu)
31
32
33def GetPlatform(target_environment):
34  """Returns the platform for |target_environment|."""
35  return {
36      'simulator': 'iphonesimulator',
37      'device': 'iphoneos'
38  }[target_environment]
39
40
41def GetPlaformDisplayName(target_environment):
42  """Returns the platform display name for |target_environment|."""
43  return {
44      'simulator': 'iPhoneSimulator',
45      'device': 'iPhoneOS'
46  }[target_environment]
47
48
49def ExtractOSVersion():
50  """Extract the version of macOS of the current machine."""
51  return GetCommandOutput(['sw_vers', '-buildVersion']).strip()
52
53
54def ExtractXcodeInfo():
55  """Extract Xcode version and build version."""
56  version, build = None, None
57  for line in GetCommandOutput(['xcodebuild', '-version']).splitlines():
58    match = XCODE_VERSION_PATTERN.search(line)
59    if match:
60      major, minor = match.group(1), match.group(2)
61      version = major.rjust(2, '0') + minor.ljust(2, '0')
62      continue
63
64    match = XCODE_BUILD_PATTERN.search(line)
65    if match:
66      build = match.group(1)
67      continue
68
69  assert version is not None and build is not None
70  return version, build
71
72
73def ExtractSDKInfo(info, sdk):
74  """Extract information about the SDK."""
75  return GetCommandOutput(['xcrun', '--sdk', sdk, '--show-sdk-' + info]).strip()
76
77
78def GetDeveloperDir():
79  """Returns the developer dir."""
80  return GetCommandOutput(['xcode-select', '-print-path']).strip()
81
82
83def GetSDKInfoForCpu(target_cpu, environment, sdk_version, deployment_target):
84  """Returns a dictionary with information about the SDK."""
85  platform = GetPlatform(environment)
86  sdk_version = sdk_version or ExtractSDKInfo('version', platform)
87  deployment_target = deployment_target or sdk_version
88
89  target = target_cpu + '-apple-ios' + deployment_target
90  if environment == 'simulator':
91    target = target + '-simulator'
92
93  xcode_version, xcode_build = ExtractXcodeInfo()
94  effective_sdk = platform + sdk_version
95
96  sdk_info = {}
97  sdk_info['compiler'] = 'com.apple.compilers.llvm.clang.1_0'
98  sdk_info['is_simulator'] = environment == 'simulator'
99  sdk_info['macos_build'] = ExtractOSVersion()
100  sdk_info['platform'] = platform
101  sdk_info['platform_name'] = GetPlaformDisplayName(environment)
102  sdk_info['sdk'] = effective_sdk
103  sdk_info['sdk_build'] = ExtractSDKInfo('build-version', effective_sdk)
104  sdk_info['sdk_path'] = ExtractSDKInfo('path', effective_sdk)
105  sdk_info['toolchain_path'] = os.path.join(
106      GetDeveloperDir(), 'Toolchains/XcodeDefault.xctoolchain')
107  sdk_info['sdk_version'] = sdk_version
108  sdk_info['target'] = target
109  sdk_info['xcode_build'] = xcode_build
110  sdk_info['xcode_version'] = xcode_version
111
112  return sdk_info
113
114
115def ParseArgs(argv):
116  """Parses command line arguments."""
117  parser = argparse.ArgumentParser(
118      description=__doc__,
119      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
120
121  parser.add_argument(
122      '-t', '--target-cpu', default='x64',
123      choices=('x86', 'x64', 'arm', 'arm64'),
124      help='target cpu')
125  parser.add_argument(
126      '-e',
127      '--target-environment',
128      default='simulator',
129      choices=('simulator', 'device'),
130      help='target environment')
131  parser.add_argument(
132      '-s', '--sdk-version',
133      help='version of the sdk')
134  parser.add_argument(
135      '-d', '--deployment-target',
136      help='iOS deployment target')
137  parser.add_argument(
138      '-o', '--output', default='-',
139      help='path of the output file to create; - means stdout')
140
141  return parser.parse_args(argv)
142
143
144def main(argv):
145  args = ParseArgs(argv)
146
147  sdk_info = GetSDKInfoForCpu(
148      GetAppleCpuName(args.target_cpu), args.target_environment,
149      args.sdk_version, args.deployment_target)
150
151  if args.output == '-':
152    sys.stdout.write(json.dumps(sdk_info))
153  else:
154    with open(args.output, 'w') as output:
155      output.write(json.dumps(sdk_info))
156
157
158if __name__ == '__main__':
159  sys.exit(main(sys.argv[1:]))
160