• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2025 Google Inc.
2#
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6
7from recipe_engine import recipe_api
8
9
10class SkiaXCodeApi(recipe_api.RecipeApi):
11  XCODE_BUILD_VERSION = '16a242d' # Xcode 16.0
12
13  @property
14  def version(self):
15    return self.XCODE_BUILD_VERSION
16
17  @property
18  def path(self):
19    return self.m.vars.cache_dir.joinpath('Xcode.app')
20
21  def install(self):
22    # XCode build is listed in parentheses after the version at
23    # https://developer.apple.com/news/releases/, or on Wikipedia here:
24    # https://en.wikipedia.org/wiki/Xcode#Version_comparison_table
25    # Use lowercase letters.
26    # https://chrome-infra-packages.appspot.com/p/infra_internal/ios/xcode
27
28    # Copied from
29    # https://chromium.googlesource.com/chromium/tools/build/+/e19b7d9390e2bb438b566515b141ed2b9ed2c7c2/scripts/slave/recipe_modules/ios/self.mpy#322
30    with self.m.step.nest('ensure xcode') as step_result:
31      mac_toolchain_cmd = self.m.vars.workdir.joinpath(
32          'mac_toolchain', 'mac_toolchain')
33      # Download mac_toolchain if necessary.
34      if not self.m.path.exists(mac_toolchain_cmd):
35        package_path = 'infra/tools/mac_toolchain'
36        self.m.cipd.ensure_tool(
37            package_path + '/${platform}',
38            'git_revision:0cb1e51344de158f72524c384f324465aebbcef2',
39            'mac_toolchain')
40        # Find where CIPD downloaded the package.
41        search_dir = self.m.vars.workdir.joinpath('cipd_tool', package_path)
42        contents = self.m.file.listdir('locate mac_toolchain', search_dir, test_data=['abc123'])
43        if len(contents) != 1:
44          raise Exception('Expected exactly one subdirectory in %s but found: %v' % (
45              search_dir, contents))  # pragma: nocover
46        self.m.step('ls -R cipd_tool', ['ls', '-R', self.m.vars.workdir.joinpath('cipd_tool')])
47        self.m.step('ls -R cipd_tool', ['ls', '-R', search_dir])
48        mac_toolchain_cmd = contents[0].join('mac_toolchain')
49        self.m.step('ls -alh mac_toolchain', ['ls', '-alh', mac_toolchain_cmd])
50
51      # Ensure XCode is installed.
52      xcode_app_path = self.path
53      step_result.step_summary_text = (
54          'Ensuring Xcode version %s in %s' % (
55              self.version, xcode_app_path))
56      install_xcode_cmd = [
57          mac_toolchain_cmd, 'install',
58          # "ios" is needed for simulator builds
59          # (Build-Mac-Clang-x64-Release-iOS).
60          '-kind', 'ios',
61          '-xcode-version', self.version,
62          '-output-dir', xcode_app_path,
63      ]
64      self.m.step('install xcode', install_xcode_cmd)
65      self.m.step('select xcode', [
66          'sudo', 'xcode-select', '-switch', xcode_app_path])
67