xref: /aosp_15_r20/external/ruy/cmake/bazel_to_cmake.py (revision bb86c7ed5fb1b98a7eac808e443a46cc8b90dfc0)
1*bb86c7edSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*bb86c7edSAndroid Build Coastguard Worker# Copyright 2021 Google LLC
3*bb86c7edSAndroid Build Coastguard Worker#
4*bb86c7edSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*bb86c7edSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*bb86c7edSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*bb86c7edSAndroid Build Coastguard Worker#
8*bb86c7edSAndroid Build Coastguard Worker#      https://www.apache.org/licenses/LICENSE-2.0
9*bb86c7edSAndroid Build Coastguard Worker#
10*bb86c7edSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*bb86c7edSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
12*bb86c7edSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bb86c7edSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*bb86c7edSAndroid Build Coastguard Worker# limitations under the License.
15*bb86c7edSAndroid Build Coastguard Worker
16*bb86c7edSAndroid Build Coastguard Worker"""This is yet another bazel-to-cmake converter. It's independently written from
17*bb86c7edSAndroid Build Coastguard Workerscratch but relies on the same basic idea as others (including IREE's), namely:
18*bb86c7edSAndroid Build Coastguard Workerto let the python interpreter do the bulk of the work, exploiting the fact that
19*bb86c7edSAndroid Build Coastguard Workerboth Bazel's BUILD syntax and Starlark (".bzl") languages are more or less
20*bb86c7edSAndroid Build Coastguard Workersubsets of Python.
21*bb86c7edSAndroid Build Coastguard Worker
22*bb86c7edSAndroid Build Coastguard WorkerThe main features that this converter supports and that others don't, justifying
23*bb86c7edSAndroid Build Coastguard Workerits existence as of early 2021, are:
24*bb86c7edSAndroid Build Coastguard Worker  1. Ad-hoc support for select(), generating CMake if()...elseif()... chains
25*bb86c7edSAndroid Build Coastguard Worker     parsing the condition keys (e.g. anything ending in ":windows" is
26*bb86c7edSAndroid Build Coastguard Worker     interpreted as the condition "the target platform is Windows"). This allows
27*bb86c7edSAndroid Build Coastguard Worker     to just ignore config_setting, as we only care about the config_setting
28*bb86c7edSAndroid Build Coastguard Worker     names, not their actual implementation, as well as all the variants from
29*bb86c7edSAndroid Build Coastguard Worker     the Bazel 'selects' library.
30*bb86c7edSAndroid Build Coastguard Worker  2. Support for load(), loading macros from Starlark files.
31*bb86c7edSAndroid Build Coastguard Worker"""
32*bb86c7edSAndroid Build Coastguard Worker
33*bb86c7edSAndroid Build Coastguard Workerimport re
34*bb86c7edSAndroid Build Coastguard Workerimport os
35*bb86c7edSAndroid Build Coastguard Workerimport os.path
36*bb86c7edSAndroid Build Coastguard Workerimport pickle
37*bb86c7edSAndroid Build Coastguard Workerimport sys
38*bb86c7edSAndroid Build Coastguard Workerimport datetime
39*bb86c7edSAndroid Build Coastguard Workerimport itertools
40*bb86c7edSAndroid Build Coastguard Worker
41*bb86c7edSAndroid Build Coastguard Worker# Ruy's dependencies.
42*bb86c7edSAndroid Build Coastguard Workerexternal_targets = ['gtest', 'gtest_main', 'cpuinfo']
43*bb86c7edSAndroid Build Coastguard Worker
44*bb86c7edSAndroid Build Coastguard Worker# Text replacements [oldstring, newstring] pairs, applied on all BUILD and
45*bb86c7edSAndroid Build Coastguard Worker# Starlark files that we load. Only used by preprocess_input_text.
46*bb86c7edSAndroid Build Coastguard Workerreplacements = [
47*bb86c7edSAndroid Build Coastguard Worker    ['$(STACK_FRAME_UNLIMITED)', ''],
48*bb86c7edSAndroid Build Coastguard Worker    ['native.cc_', 'cc_'],
49*bb86c7edSAndroid Build Coastguard Worker    ['selects.config_setting_group', 'config_setting_group'],
50*bb86c7edSAndroid Build Coastguard Worker    ['@com_google_googletest//:gtest', 'gtest'],
51*bb86c7edSAndroid Build Coastguard Worker    ['@com_google_googletest//:gtest_main', 'gtest_main'],
52*bb86c7edSAndroid Build Coastguard Worker    ['@cpuinfo', 'cpuinfo::cpuinfo'],
53*bb86c7edSAndroid Build Coastguard Worker]
54*bb86c7edSAndroid Build Coastguard Worker
55*bb86c7edSAndroid Build Coastguard Worker
56*bb86c7edSAndroid Build Coastguard Workerdef preprocess_input_text(text):
57*bb86c7edSAndroid Build Coastguard Worker  result = text
58*bb86c7edSAndroid Build Coastguard Worker  for replacement in replacements:
59*bb86c7edSAndroid Build Coastguard Worker    result = result.replace(replacement[0], replacement[1])
60*bb86c7edSAndroid Build Coastguard Worker  return result
61*bb86c7edSAndroid Build Coastguard Worker
62*bb86c7edSAndroid Build Coastguard Worker
63*bb86c7edSAndroid Build Coastguard Workerdef set_cmake_list(list_name, values, indent):
64*bb86c7edSAndroid Build Coastguard Worker  semicolon_separated = ';'.join(values)
65*bb86c7edSAndroid Build Coastguard Worker  print(f'{indent}set({list_name} "{semicolon_separated}")')
66*bb86c7edSAndroid Build Coastguard Worker
67*bb86c7edSAndroid Build Coastguard Worker
68*bb86c7edSAndroid Build Coastguard Workerdef generate_cmake_select(select_name, dict):
69*bb86c7edSAndroid Build Coastguard Worker  new_if_branch_keyword = 'if'
70*bb86c7edSAndroid Build Coastguard Worker  default_value = []
71*bb86c7edSAndroid Build Coastguard Worker  for key in dict:
72*bb86c7edSAndroid Build Coastguard Worker    condition = ''
73*bb86c7edSAndroid Build Coastguard Worker    if key == '//conditions:default':
74*bb86c7edSAndroid Build Coastguard Worker      default_value = dict[key]
75*bb86c7edSAndroid Build Coastguard Worker      continue
76*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':windows$', key):
77*bb86c7edSAndroid Build Coastguard Worker      condition = 'CMAKE_SYSTEM_NAME STREQUAL Windows'
78*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':ppc$', key):
79*bb86c7edSAndroid Build Coastguard Worker      condition = ('CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64 OR '
80*bb86c7edSAndroid Build Coastguard Worker                   'CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le')
81*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':s390x$', key):
82*bb86c7edSAndroid Build Coastguard Worker      condition = ('CMAKE_SYSTEM_PROCESSOR STREQUAL s390 OR '
83*bb86c7edSAndroid Build Coastguard Worker                   'CMAKE_SYSTEM_PROCESSOR STREQUAL s390x')
84*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':fuchsia$', key):
85*bb86c7edSAndroid Build Coastguard Worker      condition = 'CMAKE_SYSTEM_NAME STREQUAL Fuchsia'
86*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':arm32_assuming_neon$', key):
87*bb86c7edSAndroid Build Coastguard Worker      condition = 'CMAKE_SYSTEM_PROCESSOR STREQUAL arm'
88*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':do_not_want_O3$', key):
89*bb86c7edSAndroid Build Coastguard Worker      # Ruy is a specialist library: we always want code to be compiled
90*bb86c7edSAndroid Build Coastguard Worker      # with -O3 unless the build type is Debug or the compiler does not
91*bb86c7edSAndroid Build Coastguard Worker      # support that flag syntax.
92*bb86c7edSAndroid Build Coastguard Worker      condition = '(CMAKE_BUILD_TYPE STREQUAL Debug) OR MSVC'
93*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':x86_64_and_not_msvc$', key):
94*bb86c7edSAndroid Build Coastguard Worker      condition = ('(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR '
95*bb86c7edSAndroid Build Coastguard Worker                   'CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) AND NOT MSVC')
96*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':windows_msvc$', key):
97*bb86c7edSAndroid Build Coastguard Worker      condition = 'MSVC'
98*bb86c7edSAndroid Build Coastguard Worker    elif re.search(r':ruy_profiler$', key):
99*bb86c7edSAndroid Build Coastguard Worker      condition = '${RUY_PROFILER}'
100*bb86c7edSAndroid Build Coastguard Worker    else:
101*bb86c7edSAndroid Build Coastguard Worker      raise ValueError(f'Unhandled key in select: {key}')
102*bb86c7edSAndroid Build Coastguard Worker
103*bb86c7edSAndroid Build Coastguard Worker    print(f'{new_if_branch_keyword}({condition})')
104*bb86c7edSAndroid Build Coastguard Worker    set_cmake_list(select_name, dict[key], '  ')
105*bb86c7edSAndroid Build Coastguard Worker    new_if_branch_keyword = 'elseif'
106*bb86c7edSAndroid Build Coastguard Worker
107*bb86c7edSAndroid Build Coastguard Worker  print('else()')
108*bb86c7edSAndroid Build Coastguard Worker  set_cmake_list(select_name, default_value, '  ')
109*bb86c7edSAndroid Build Coastguard Worker
110*bb86c7edSAndroid Build Coastguard Worker  print('endif()\n')
111*bb86c7edSAndroid Build Coastguard Worker
112*bb86c7edSAndroid Build Coastguard Worker
113*bb86c7edSAndroid Build Coastguard Workerdef trim_multiple_ruy_prefixes(name):
114*bb86c7edSAndroid Build Coastguard Worker  return re.sub(r'(ruy_)+ruy', 'ruy', name)
115*bb86c7edSAndroid Build Coastguard Worker
116*bb86c7edSAndroid Build Coastguard Worker
117*bb86c7edSAndroid Build Coastguard Workerdef get_cmake_local_target_name(name):
118*bb86c7edSAndroid Build Coastguard Worker  global package_prefix
119*bb86c7edSAndroid Build Coastguard Worker  return trim_multiple_ruy_prefixes(f'ruy_{package_prefix}_{name}')
120*bb86c7edSAndroid Build Coastguard Worker
121*bb86c7edSAndroid Build Coastguard Worker
122*bb86c7edSAndroid Build Coastguard Workerdef get_cmake_dep_target_name(name):
123*bb86c7edSAndroid Build Coastguard Worker  if name in external_targets:
124*bb86c7edSAndroid Build Coastguard Worker    return name
125*bb86c7edSAndroid Build Coastguard Worker  if name.startswith('$'):
126*bb86c7edSAndroid Build Coastguard Worker    # Happens for deps that are the result of expanding a select() that we
127*bb86c7edSAndroid Build Coastguard Worker    # have compiled to expanding a variable.
128*bb86c7edSAndroid Build Coastguard Worker    return name
129*bb86c7edSAndroid Build Coastguard Worker  if name.startswith('//'):
130*bb86c7edSAndroid Build Coastguard Worker    after_last_slash = name.split('/')[-1]
131*bb86c7edSAndroid Build Coastguard Worker    if ':' not in after_last_slash:
132*bb86c7edSAndroid Build Coastguard Worker      name = f'{name}:{after_last_slash}'
133*bb86c7edSAndroid Build Coastguard Worker    raw = name[2:].replace('/', '_').replace(':', '_')
134*bb86c7edSAndroid Build Coastguard Worker    return trim_multiple_ruy_prefixes(raw)
135*bb86c7edSAndroid Build Coastguard Worker  if name.startswith(':'):
136*bb86c7edSAndroid Build Coastguard Worker    name = name[1:]
137*bb86c7edSAndroid Build Coastguard Worker  return get_cmake_local_target_name(name)
138*bb86c7edSAndroid Build Coastguard Worker
139*bb86c7edSAndroid Build Coastguard Worker
140*bb86c7edSAndroid Build Coastguard Worker#
141*bb86c7edSAndroid Build Coastguard Worker# Functions implementing BUILD functions
142*bb86c7edSAndroid Build Coastguard Worker#
143*bb86c7edSAndroid Build Coastguard Worker
144*bb86c7edSAndroid Build Coastguard Worker
145*bb86c7edSAndroid Build Coastguard Workerdef package(**kwargs):
146*bb86c7edSAndroid Build Coastguard Worker  pass
147*bb86c7edSAndroid Build Coastguard Worker
148*bb86c7edSAndroid Build Coastguard Worker
149*bb86c7edSAndroid Build Coastguard Workerdef exports_files(*args):
150*bb86c7edSAndroid Build Coastguard Worker  pass
151*bb86c7edSAndroid Build Coastguard Worker
152*bb86c7edSAndroid Build Coastguard Worker
153*bb86c7edSAndroid Build Coastguard Workerdef load(filename, *args):
154*bb86c7edSAndroid Build Coastguard Worker  if filename.startswith('@'):
155*bb86c7edSAndroid Build Coastguard Worker    return
156*bb86c7edSAndroid Build Coastguard Worker  elif filename.startswith(':'):
157*bb86c7edSAndroid Build Coastguard Worker    filename = os.path.join(bazel_package_dir, filename[1:])
158*bb86c7edSAndroid Build Coastguard Worker  elif filename.startswith('//'):
159*bb86c7edSAndroid Build Coastguard Worker    split = filename[2:].split(':')
160*bb86c7edSAndroid Build Coastguard Worker    filename = os.path.join(bazel_workspace_dir, split[0], split[1])
161*bb86c7edSAndroid Build Coastguard Worker
162*bb86c7edSAndroid Build Coastguard Worker  src_file_content = open(filename).read()
163*bb86c7edSAndroid Build Coastguard Worker  processed_file_content = preprocess_input_text(src_file_content)
164*bb86c7edSAndroid Build Coastguard Worker  exec(processed_file_content, globals(), globals())
165*bb86c7edSAndroid Build Coastguard Worker
166*bb86c7edSAndroid Build Coastguard Worker
167*bb86c7edSAndroid Build Coastguard Workerdef config_setting(**kwargs):
168*bb86c7edSAndroid Build Coastguard Worker  # Nothing to do since our implementation of select() is based on parsing
169*bb86c7edSAndroid Build Coastguard Worker  # the names of config_settings, not looking deep into their actual
170*bb86c7edSAndroid Build Coastguard Worker  # implementation.
171*bb86c7edSAndroid Build Coastguard Worker  pass
172*bb86c7edSAndroid Build Coastguard Worker
173*bb86c7edSAndroid Build Coastguard Worker
174*bb86c7edSAndroid Build Coastguard Workerdef filegroup(**kwargs):
175*bb86c7edSAndroid Build Coastguard Worker  pass
176*bb86c7edSAndroid Build Coastguard Worker
177*bb86c7edSAndroid Build Coastguard Worker
178*bb86c7edSAndroid Build Coastguard Workerdef config_setting_group(**kwargs):
179*bb86c7edSAndroid Build Coastguard Worker  # See config_setting.
180*bb86c7edSAndroid Build Coastguard Worker  pass
181*bb86c7edSAndroid Build Coastguard Worker
182*bb86c7edSAndroid Build Coastguard Worker
183*bb86c7edSAndroid Build Coastguard Workerdef bzl_library(**kwargs):
184*bb86c7edSAndroid Build Coastguard Worker  pass
185*bb86c7edSAndroid Build Coastguard Worker
186*bb86c7edSAndroid Build Coastguard Worker
187*bb86c7edSAndroid Build Coastguard Workerselect_index = 0
188*bb86c7edSAndroid Build Coastguard Workerselect_cache = {}
189*bb86c7edSAndroid Build Coastguard Worker
190*bb86c7edSAndroid Build Coastguard Worker
191*bb86c7edSAndroid Build Coastguard Workerdef select(select_dict):
192*bb86c7edSAndroid Build Coastguard Worker  global select_index
193*bb86c7edSAndroid Build Coastguard Worker  global select_cache
194*bb86c7edSAndroid Build Coastguard Worker  global package_prefix
195*bb86c7edSAndroid Build Coastguard Worker  key = pickle.dumps(sorted(select_dict.items()))
196*bb86c7edSAndroid Build Coastguard Worker  if key in select_cache:
197*bb86c7edSAndroid Build Coastguard Worker    select_name = select_cache[key]
198*bb86c7edSAndroid Build Coastguard Worker  else:
199*bb86c7edSAndroid Build Coastguard Worker    unique_values = sorted(
200*bb86c7edSAndroid Build Coastguard Worker        set(itertools.chain.from_iterable(select_dict.values()))
201*bb86c7edSAndroid Build Coastguard Worker    )  # sorting ensures determinism, no spurious diffs
202*bb86c7edSAndroid Build Coastguard Worker    description = '_'.join(unique_values)
203*bb86c7edSAndroid Build Coastguard Worker    select_name = f'{package_prefix}_{select_index}_{description}'
204*bb86c7edSAndroid Build Coastguard Worker    select_name = select_name.replace('c++', 'cxx')
205*bb86c7edSAndroid Build Coastguard Worker    select_name = re.sub(r'[^a-zA-Z0-9]+', '_', select_name)
206*bb86c7edSAndroid Build Coastguard Worker    select_index = select_index + 1
207*bb86c7edSAndroid Build Coastguard Worker    select_cache[key] = select_name
208*bb86c7edSAndroid Build Coastguard Worker    generate_cmake_select(select_name, select_dict)
209*bb86c7edSAndroid Build Coastguard Worker
210*bb86c7edSAndroid Build Coastguard Worker  return [f'${{{select_name}}}']
211*bb86c7edSAndroid Build Coastguard Worker
212*bb86c7edSAndroid Build Coastguard Worker
213*bb86c7edSAndroid Build Coastguard Workerdef generic_rule(rule_name, **kwargs):
214*bb86c7edSAndroid Build Coastguard Worker  print(f'{rule_name}(')
215*bb86c7edSAndroid Build Coastguard Worker  for key in kwargs.keys():
216*bb86c7edSAndroid Build Coastguard Worker    values = kwargs[key]
217*bb86c7edSAndroid Build Coastguard Worker    if type(values) is bool:
218*bb86c7edSAndroid Build Coastguard Worker      if values:
219*bb86c7edSAndroid Build Coastguard Worker        print(f'  {key.upper()}')
220*bb86c7edSAndroid Build Coastguard Worker        continue
221*bb86c7edSAndroid Build Coastguard Worker      else:
222*bb86c7edSAndroid Build Coastguard Worker        raise ValueError('Cannot specify FALSE boolean args in CMake')
223*bb86c7edSAndroid Build Coastguard Worker    if key == 'visibility':
224*bb86c7edSAndroid Build Coastguard Worker      if values == ['//visibility:public']:
225*bb86c7edSAndroid Build Coastguard Worker        print(f'  PUBLIC')
226*bb86c7edSAndroid Build Coastguard Worker      continue
227*bb86c7edSAndroid Build Coastguard Worker    if key == 'tags':
228*bb86c7edSAndroid Build Coastguard Worker      values = list(filter(lambda x: not x.startswith('req_dep'), values))
229*bb86c7edSAndroid Build Coastguard Worker    if not values:
230*bb86c7edSAndroid Build Coastguard Worker      continue
231*bb86c7edSAndroid Build Coastguard Worker    print(f'  {key.upper()}')
232*bb86c7edSAndroid Build Coastguard Worker    if type(values) is list:
233*bb86c7edSAndroid Build Coastguard Worker      for value in values:
234*bb86c7edSAndroid Build Coastguard Worker        if key == 'deps':
235*bb86c7edSAndroid Build Coastguard Worker          target_name = get_cmake_dep_target_name(value)
236*bb86c7edSAndroid Build Coastguard Worker          print(f'    {target_name}')
237*bb86c7edSAndroid Build Coastguard Worker        else:
238*bb86c7edSAndroid Build Coastguard Worker          print(f'    {value}')
239*bb86c7edSAndroid Build Coastguard Worker    else:
240*bb86c7edSAndroid Build Coastguard Worker      if key == 'name':
241*bb86c7edSAndroid Build Coastguard Worker        target_name = get_cmake_local_target_name(values)
242*bb86c7edSAndroid Build Coastguard Worker        print(f'    {target_name}')
243*bb86c7edSAndroid Build Coastguard Worker      else:
244*bb86c7edSAndroid Build Coastguard Worker        print(f'    {values}')
245*bb86c7edSAndroid Build Coastguard Worker  print(')\n')
246*bb86c7edSAndroid Build Coastguard Worker
247*bb86c7edSAndroid Build Coastguard Worker
248*bb86c7edSAndroid Build Coastguard Workerdef cc_library(**kwargs):
249*bb86c7edSAndroid Build Coastguard Worker  generic_rule('ruy_cc_library', **kwargs)
250*bb86c7edSAndroid Build Coastguard Worker
251*bb86c7edSAndroid Build Coastguard Worker
252*bb86c7edSAndroid Build Coastguard Workerdef cc_test(**kwargs):
253*bb86c7edSAndroid Build Coastguard Worker  generic_rule('ruy_cc_test', **kwargs)
254*bb86c7edSAndroid Build Coastguard Worker
255*bb86c7edSAndroid Build Coastguard Worker
256*bb86c7edSAndroid Build Coastguard Workerdef cc_binary(**kwargs):
257*bb86c7edSAndroid Build Coastguard Worker  generic_rule('ruy_cc_binary', **kwargs)
258*bb86c7edSAndroid Build Coastguard Worker
259*bb86c7edSAndroid Build Coastguard Worker
260*bb86c7edSAndroid Build Coastguard Worker#
261*bb86c7edSAndroid Build Coastguard Worker# Program entry point.
262*bb86c7edSAndroid Build Coastguard Worker#
263*bb86c7edSAndroid Build Coastguard Workerif __name__ == "__main__":
264*bb86c7edSAndroid Build Coastguard Worker  if len(sys.argv) != 3:
265*bb86c7edSAndroid Build Coastguard Worker    print('Usage: bazel_to_cmake.py bazel_workspace_dir bazel_package_dir')
266*bb86c7edSAndroid Build Coastguard Worker    sys.exit(1)
267*bb86c7edSAndroid Build Coastguard Worker
268*bb86c7edSAndroid Build Coastguard Worker  bazel_workspace_dir = sys.argv[1]
269*bb86c7edSAndroid Build Coastguard Worker  bazel_package_dir = sys.argv[2]
270*bb86c7edSAndroid Build Coastguard Worker  bazel_package_relative_dir = os.path.relpath(bazel_package_dir,
271*bb86c7edSAndroid Build Coastguard Worker                                               bazel_workspace_dir)
272*bb86c7edSAndroid Build Coastguard Worker  package_prefix = bazel_package_relative_dir.replace(os.path.sep, '_')
273*bb86c7edSAndroid Build Coastguard Worker
274*bb86c7edSAndroid Build Coastguard Worker  print("""# This file is generated (whence no license header). Do not edit!
275*bb86c7edSAndroid Build Coastguard Worker# To regenerate, run:
276*bb86c7edSAndroid Build Coastguard Worker#   cmake/bazel_to_cmake.sh
277*bb86c7edSAndroid Build Coastguard Worker""")
278*bb86c7edSAndroid Build Coastguard Worker
279*bb86c7edSAndroid Build Coastguard Worker  src_build_file = os.path.join(bazel_package_dir, 'BUILD')
280*bb86c7edSAndroid Build Coastguard Worker  src_build_content = open(src_build_file).read()
281*bb86c7edSAndroid Build Coastguard Worker  processed_build_content = preprocess_input_text(src_build_content)
282*bb86c7edSAndroid Build Coastguard Worker  exec(processed_build_content)
283*bb86c7edSAndroid Build Coastguard Worker
284*bb86c7edSAndroid Build Coastguard Worker  print('ruy_add_all_subdirs()')
285