xref: /aosp_15_r20/external/skia/tools/BUILD_simulator.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker#!/usr/bin/env python
2*c8dee2aaSAndroid Build Coastguard Worker#
3*c8dee2aaSAndroid Build Coastguard Worker# Copyright 2015 Google Inc.
4*c8dee2aaSAndroid Build Coastguard Worker#
5*c8dee2aaSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
6*c8dee2aaSAndroid Build Coastguard Worker# found in the LICENSE file.
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker# This script does a very rough simulation of BUILD file expansion,
9*c8dee2aaSAndroid Build Coastguard Worker# mostly to see the effects of glob().
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard Worker# We start by adding some symbols to our namespace that BUILD.public calls.
12*c8dee2aaSAndroid Build Coastguard Worker
13*c8dee2aaSAndroid Build Coastguard Workerimport glob
14*c8dee2aaSAndroid Build Coastguard Workerimport os
15*c8dee2aaSAndroid Build Coastguard Workerimport pprint
16*c8dee2aaSAndroid Build Coastguard Workerimport re
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard Workerdef noop(*args, **kwargs):
19*c8dee2aaSAndroid Build Coastguard Worker  pass
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Workerdef select_simulator(d):
22*c8dee2aaSAndroid Build Coastguard Worker  result = []
23*c8dee2aaSAndroid Build Coastguard Worker  for k in d:
24*c8dee2aaSAndroid Build Coastguard Worker    result.append("*** BEGIN %s ***" % k)
25*c8dee2aaSAndroid Build Coastguard Worker    result.extend(d[k])
26*c8dee2aaSAndroid Build Coastguard Worker    result.append("*** END %s ***" % k)
27*c8dee2aaSAndroid Build Coastguard Worker  return result
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard WorkerDOUBLE_STAR_RE = re.compile(r'/\*\*/')
30*c8dee2aaSAndroid Build Coastguard WorkerSTAR_RE = re.compile(r'\*')
31*c8dee2aaSAndroid Build Coastguard WorkerDOUBLE_STAR_PLACEHOLDER = "xxxdoublestarxxx"
32*c8dee2aaSAndroid Build Coastguard WorkerSTAR_PLACEHOLDER = "xxxstarxxx"
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker# Returns a set of files that match pattern.
35*c8dee2aaSAndroid Build Coastguard Workerdef BUILD_glob_single(pattern):
36*c8dee2aaSAndroid Build Coastguard Worker  if pattern.find('**') < 0:
37*c8dee2aaSAndroid Build Coastguard Worker    # If pattern doesn't include **, glob.glob more-or-less does the right
38*c8dee2aaSAndroid Build Coastguard Worker    # thing.
39*c8dee2aaSAndroid Build Coastguard Worker    return glob.glob(pattern)
40*c8dee2aaSAndroid Build Coastguard Worker  # First transform pattern into a regexp.
41*c8dee2aaSAndroid Build Coastguard Worker  # Temporarily remove ** and *.
42*c8dee2aaSAndroid Build Coastguard Worker  pattern2 = DOUBLE_STAR_RE.sub(DOUBLE_STAR_PLACEHOLDER, pattern)
43*c8dee2aaSAndroid Build Coastguard Worker  pattern3 = STAR_RE.sub(STAR_PLACEHOLDER, pattern2)
44*c8dee2aaSAndroid Build Coastguard Worker  # Replace any regexp special characters.
45*c8dee2aaSAndroid Build Coastguard Worker  pattern4 = re.escape(pattern3)
46*c8dee2aaSAndroid Build Coastguard Worker  # Replace * with [^/]* and ** with .*.
47*c8dee2aaSAndroid Build Coastguard Worker  pattern5 = pattern4.replace(STAR_PLACEHOLDER, '[^/]*')
48*c8dee2aaSAndroid Build Coastguard Worker  pattern6 = pattern5.replace(DOUBLE_STAR_PLACEHOLDER, '.*/')
49*c8dee2aaSAndroid Build Coastguard Worker  # Anchor the match at the beginning and end.
50*c8dee2aaSAndroid Build Coastguard Worker  pattern7 = "^" + pattern6 + "$"
51*c8dee2aaSAndroid Build Coastguard Worker  pattern_re = re.compile(pattern7)
52*c8dee2aaSAndroid Build Coastguard Worker  matches = set()
53*c8dee2aaSAndroid Build Coastguard Worker  for root, _, files in os.walk('.'):
54*c8dee2aaSAndroid Build Coastguard Worker    for fname in files:
55*c8dee2aaSAndroid Build Coastguard Worker      # Remove initial "./".
56*c8dee2aaSAndroid Build Coastguard Worker      path = os.path.join(root, fname)[2:]
57*c8dee2aaSAndroid Build Coastguard Worker      if pattern_re.match(path):
58*c8dee2aaSAndroid Build Coastguard Worker        matches.add(path)
59*c8dee2aaSAndroid Build Coastguard Worker  return matches
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker# Simulates BUILD file glob().
62*c8dee2aaSAndroid Build Coastguard Workerdef BUILD_glob(include, exclude=()):
63*c8dee2aaSAndroid Build Coastguard Worker  files = set()
64*c8dee2aaSAndroid Build Coastguard Worker  for pattern in include:
65*c8dee2aaSAndroid Build Coastguard Worker    files.update(BUILD_glob_single(pattern))
66*c8dee2aaSAndroid Build Coastguard Worker  for pattern in exclude:
67*c8dee2aaSAndroid Build Coastguard Worker    files.difference_update(BUILD_glob_single(pattern))
68*c8dee2aaSAndroid Build Coastguard Worker  return list(sorted(files))
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker# With these namespaces, we can treat BUILD.public as if it were
71*c8dee2aaSAndroid Build Coastguard Worker# Python code.  This pulls its variable definitions (SRCS, HDRS,
72*c8dee2aaSAndroid Build Coastguard Worker# DEFINES, etc.) into local_names.
73*c8dee2aaSAndroid Build Coastguard Workerglobal_names = {
74*c8dee2aaSAndroid Build Coastguard Worker  'cc_library': noop,
75*c8dee2aaSAndroid Build Coastguard Worker  'cc_test': noop,
76*c8dee2aaSAndroid Build Coastguard Worker  'exports_files': noop,
77*c8dee2aaSAndroid Build Coastguard Worker  'glob': BUILD_glob,
78*c8dee2aaSAndroid Build Coastguard Worker  'select': select_simulator,
79*c8dee2aaSAndroid Build Coastguard Worker  'BASE_DIR': '',
80*c8dee2aaSAndroid Build Coastguard Worker  'BASE_EXTERNAL_DEPS_ANDROID': [],
81*c8dee2aaSAndroid Build Coastguard Worker  'BASE_EXTERNAL_DEPS_IOS': [],
82*c8dee2aaSAndroid Build Coastguard Worker  'BASE_EXTERNAL_DEPS_UNIX': [],
83*c8dee2aaSAndroid Build Coastguard Worker  'CONDITION_ANDROID': 'CONDITION_ANDROID',
84*c8dee2aaSAndroid Build Coastguard Worker  'CONDITION_IOS': 'CONDITION_IOS',
85*c8dee2aaSAndroid Build Coastguard Worker  'DM_EXTERNAL_DEPS': [],
86*c8dee2aaSAndroid Build Coastguard Worker  'EXTERNAL_DEPS_ALL': [],
87*c8dee2aaSAndroid Build Coastguard Worker  'EXTERNAL_INCLUDES': [],
88*c8dee2aaSAndroid Build Coastguard Worker}
89*c8dee2aaSAndroid Build Coastguard Workerlocal_names = {}
90*c8dee2aaSAndroid Build Coastguard Workerexecfile('BUILD.public', global_names, local_names)
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Workerwith open('tools/BUILD.public.expected', 'w') as out:
93*c8dee2aaSAndroid Build Coastguard Worker  print >>out, "This file is auto-generated by tools/BUILD_simulator.py."
94*c8dee2aaSAndroid Build Coastguard Worker  print >>out, "It expands BUILD.public to make it easy to see changes."
95*c8dee2aaSAndroid Build Coastguard Worker  for name, value in sorted(local_names.items()):
96*c8dee2aaSAndroid Build Coastguard Worker    print >>out, name, '= ',
97*c8dee2aaSAndroid Build Coastguard Worker    pprint.pprint(value, out)
98