• 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 GetAppleCpuName(target_cpu):
20  """Returns the name of the |target_cpu| using Apple's convention."""
21  return {
22      'x64': 'x86_64',
23      'arm': 'armv7',
24      'x86': 'i386'
25  }.get(target_cpu, target_cpu)
26
27
28def IsSimulator(target_cpu):
29  """Returns whether the |target_cpu| corresponds to a simulator build."""
30  return not target_cpu.startswith('arm')
31
32
33def GetPlatform(target_cpu):
34  """Returns the platform for the |target_cpu|."""
35  if IsSimulator(target_cpu):
36    return 'iphonesimulator'
37  else:
38    return 'iphoneos'
39
40
41def GetPlaformDisplayName(target_cpu):
42  """Returns the platform display name for the |target_cpu|."""
43  if IsSimulator(target_cpu):
44    return 'iPhoneSimulator'
45  else:
46    return 'iPhoneOS'
47
48
49def ExtractOSVersion():
50  """Extract the version of macOS of the current machine."""
51  return subprocess.check_output(['sw_vers', '-buildVersion']).strip()
52
53
54def ExtractXcodeInfo():
55  """Extract Xcode version and build version."""
56  version, build = None, None
57  for line in subprocess.check_output(['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 subprocess.check_output(
76      ['xcrun', '--sdk', sdk, '--show-sdk-' + info]).strip()
77
78
79def GetDeveloperDir():
80  """Returns the developer dir."""
81  return subprocess.check_output(['xcode-select', '-print-path']).strip()
82
83
84def GetSDKInfoForCpu(target_cpu, sdk_version, deployment_target):
85  """Returns a dictionary with information about the SDK."""
86  platform = GetPlatform(target_cpu)
87  sdk_version = sdk_version or ExtractSDKInfo('version', platform)
88  deployment_target = deployment_target or sdk_version
89
90  target = target_cpu + '-apple-ios' + deployment_target
91  if IsSimulator(target_cpu):
92    target = target + '-simulator'
93
94  xcode_version, xcode_build = ExtractXcodeInfo()
95  effective_sdk = platform + sdk_version
96
97  sdk_info = {}
98  sdk_info['compiler'] = 'com.apple.compilers.llvm.clang.1_0'
99  sdk_info['is_simulator'] = IsSimulator(target_cpu)
100  sdk_info['macos_build'] = ExtractOSVersion()
101  sdk_info['platform'] = platform
102  sdk_info['platform_name'] = GetPlaformDisplayName(target_cpu)
103  sdk_info['sdk'] = effective_sdk
104  sdk_info['sdk_build'] = ExtractSDKInfo('build-version', effective_sdk)
105  sdk_info['sdk_path'] = ExtractSDKInfo('path', effective_sdk)
106  sdk_info['toolchain_path'] = os.path.join(
107      GetDeveloperDir(), 'Toolchains/XcodeDefault.xctoolchain')
108  sdk_info['sdk_version'] = sdk_version
109  sdk_info['target'] = target
110  sdk_info['xcode_build'] = xcode_build
111  sdk_info['xcode_version'] = xcode_version
112
113  return sdk_info
114
115
116def ParseArgs(argv):
117  """Parses command line arguments."""
118  parser = argparse.ArgumentParser(
119      description=__doc__,
120      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
121
122  parser.add_argument(
123      '-t', '--target-cpu', default='x64',
124      choices=('x86', 'x64', 'arm', 'arm64'),
125      help='target cpu')
126  parser.add_argument(
127      '-s', '--sdk-version',
128      help='version of the sdk')
129  parser.add_argument(
130      '-d', '--deployment-target',
131      help='iOS deployment target')
132  parser.add_argument(
133      '-o', '--output', default='-',
134      help='path of the output file to create; - means stdout')
135
136  return parser.parse_args(argv)
137
138
139def main(argv):
140  args = ParseArgs(argv)
141
142  sdk_info = GetSDKInfoForCpu(
143      GetAppleCpuName(args.target_cpu),
144      args.sdk_version,
145      args.deployment_target)
146
147  if args.output == '-':
148    sys.stdout.write(json.dumps(sdk_info))
149  else:
150    with open(args.output, 'w') as output:
151      output.write(json.dumps(sdk_info))
152
153
154if __name__ == '__main__':
155  sys.exit(main(sys.argv[1:]))
156