xref: /aosp_15_r20/external/angle/scripts/export_targets.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#! /usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Workerassert __name__ == '__main__'
3*8975f5c5SAndroid Build Coastguard Worker
4*8975f5c5SAndroid Build Coastguard Worker'''
5*8975f5c5SAndroid Build Coastguard WorkerTo update ANGLE in Gecko, use Windows with git-bash, and setup depot_tools, python2, and
6*8975f5c5SAndroid Build Coastguard Workerpython3. Because depot_tools expects `python` to be `python2` (shame!), python2 must come
7*8975f5c5SAndroid Build Coastguard Workerbefore python3 in your path.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard WorkerUpstream: https://chromium.googlesource.com/angle/angle
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard WorkerOur repo: https://github.com/mozilla/angle
12*8975f5c5SAndroid Build Coastguard WorkerIt has branches like 'firefox-60' which is the branch we use for pulling into
13*8975f5c5SAndroid Build Coastguard WorkerGecko with this script.
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard WorkerThis script leaves a record of the merge-base and cherry-picks that we pull into
16*8975f5c5SAndroid Build Coastguard WorkerGecko. (gfx/angle/cherries.log)
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard WorkerANGLE<->Chrome version mappings are here: https://omahaproxy.appspot.com/
19*8975f5c5SAndroid Build Coastguard WorkerAn easy choice is to grab Chrome's Beta's ANGLE branch.
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker## Usage
22*8975f5c5SAndroid Build Coastguard Worker
23*8975f5c5SAndroid Build Coastguard WorkerPrepare your env:
24*8975f5c5SAndroid Build Coastguard Worker
25*8975f5c5SAndroid Build Coastguard Worker~~~
26*8975f5c5SAndroid Build Coastguard Workerexport PATH="$PATH:/path/to/depot_tools"
27*8975f5c5SAndroid Build Coastguard Worker~~~
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard WorkerIf this is a new repo, don't forget:
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker~~~
32*8975f5c5SAndroid Build Coastguard Worker# In the angle repo:
33*8975f5c5SAndroid Build Coastguard Worker./scripts/bootstrap.py
34*8975f5c5SAndroid Build Coastguard Workergclient sync
35*8975f5c5SAndroid Build Coastguard Worker~~~
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard WorkerUpdate: (in the angle repo)
38*8975f5c5SAndroid Build Coastguard Worker
39*8975f5c5SAndroid Build Coastguard Worker~~~
40*8975f5c5SAndroid Build Coastguard Worker# In the angle repo:
41*8975f5c5SAndroid Build Coastguard Worker/path/to/gecko/gfx/angle/update-angle.py origin/chromium/XXXX
42*8975f5c5SAndroid Build Coastguard Workergit push moz # Push the firefox-XX branch to github.com/mozilla/angle
43*8975f5c5SAndroid Build Coastguard Worker~~~~
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker'''
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Workerimport json
48*8975f5c5SAndroid Build Coastguard Workerimport os
49*8975f5c5SAndroid Build Coastguard Workerimport pathlib
50*8975f5c5SAndroid Build Coastguard Workerimport re
51*8975f5c5SAndroid Build Coastguard Workerimport shutil
52*8975f5c5SAndroid Build Coastguard Workerimport subprocess
53*8975f5c5SAndroid Build Coastguard Workerimport sys
54*8975f5c5SAndroid Build Coastguard Workerfrom typing import * # mypy annotations
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard WorkerSCRIPT_DIR = os.path.dirname(__file__)
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard WorkerGN_ENV = dict(os.environ)
59*8975f5c5SAndroid Build Coastguard Worker# We need to set DEPOT_TOOLS_WIN_TOOLCHAIN to 0 for non-Googlers, but otherwise
60*8975f5c5SAndroid Build Coastguard Worker# leave it unset since vs_toolchain.py assumes that the user is a Googler with
61*8975f5c5SAndroid Build Coastguard Worker# the Visual Studio files in depot_tools if DEPOT_TOOLS_WIN_TOOLCHAIN is not
62*8975f5c5SAndroid Build Coastguard Worker# explicitly set to 0.
63*8975f5c5SAndroid Build Coastguard Workervs_found = False
64*8975f5c5SAndroid Build Coastguard Workervs_dir = os.path.join(SCRIPT_DIR, '..', 'third_party', 'depot_tools', 'win_toolchain', 'vs_files')
65*8975f5c5SAndroid Build Coastguard Workerif not os.path.isdir(vs_dir):
66*8975f5c5SAndroid Build Coastguard Worker    GN_ENV['DEPOT_TOOLS_WIN_TOOLCHAIN'] = '0'
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Workerif len(sys.argv) < 3:
69*8975f5c5SAndroid Build Coastguard Worker    sys.exit('Usage: export_targets.py OUT_DIR ROOTS...')
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker(OUT_DIR, *ROOTS) = sys.argv[1:]
72*8975f5c5SAndroid Build Coastguard Workerfor x in ROOTS:
73*8975f5c5SAndroid Build Coastguard Worker    assert x.startswith('//:')
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker# ------------------------------------------------------------------------------
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Workerdef run_checked(*args, **kwargs):
78*8975f5c5SAndroid Build Coastguard Worker    print(' ', args, file=sys.stderr)
79*8975f5c5SAndroid Build Coastguard Worker    sys.stderr.flush()
80*8975f5c5SAndroid Build Coastguard Worker    return subprocess.run(args, check=True, **kwargs)
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Workerdef sortedi(x):
84*8975f5c5SAndroid Build Coastguard Worker    return sorted(x, key=str.lower)
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Workerdef dag_traverse(root_keys: Sequence[str], pre_recurse_func: Callable[[str], list]):
88*8975f5c5SAndroid Build Coastguard Worker    visited_keys: Set[str] = set()
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker    def recurse(key):
91*8975f5c5SAndroid Build Coastguard Worker        if key in visited_keys:
92*8975f5c5SAndroid Build Coastguard Worker            return
93*8975f5c5SAndroid Build Coastguard Worker        visited_keys.add(key)
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker        t = pre_recurse_func(key)
96*8975f5c5SAndroid Build Coastguard Worker        try:
97*8975f5c5SAndroid Build Coastguard Worker            (next_keys, post_recurse_func) = t
98*8975f5c5SAndroid Build Coastguard Worker        except ValueError:
99*8975f5c5SAndroid Build Coastguard Worker            (next_keys,) = t
100*8975f5c5SAndroid Build Coastguard Worker            post_recurse_func = None
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker        for x in next_keys:
103*8975f5c5SAndroid Build Coastguard Worker            recurse(x)
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker        if post_recurse_func:
106*8975f5c5SAndroid Build Coastguard Worker            post_recurse_func(key)
107*8975f5c5SAndroid Build Coastguard Worker        return
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker    for x in root_keys:
110*8975f5c5SAndroid Build Coastguard Worker        recurse(x)
111*8975f5c5SAndroid Build Coastguard Worker    return
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker# ------------------------------------------------------------------------------
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Workerprint('Importing graph', file=sys.stderr)
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Workertry:
118*8975f5c5SAndroid Build Coastguard Worker    p = run_checked('gn', 'desc', '--format=json', str(OUT_DIR), '*', stdout=subprocess.PIPE,
119*8975f5c5SAndroid Build Coastguard Worker                env=GN_ENV, shell=(True if sys.platform == 'win32' else False))
120*8975f5c5SAndroid Build Coastguard Workerexcept subprocess.CalledProcessError:
121*8975f5c5SAndroid Build Coastguard Worker    sys.stderr.buffer.write(b'"gn desc" failed. Is depot_tools in your PATH?\n')
122*8975f5c5SAndroid Build Coastguard Worker    exit(1)
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker# -
125*8975f5c5SAndroid Build Coastguard Worker
126*8975f5c5SAndroid Build Coastguard Workerprint('\nProcessing graph', file=sys.stderr)
127*8975f5c5SAndroid Build Coastguard Workerdescs = json.loads(p.stdout.decode())
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Worker# Ready to traverse
130*8975f5c5SAndroid Build Coastguard Worker# ------------------------------------------------------------------------------
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard WorkerLIBRARY_TYPES = ('shared_library', 'static_library')
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Workerdef flattened_target(target_name: str, descs: dict, stop_at_lib: bool =True) -> dict:
135*8975f5c5SAndroid Build Coastguard Worker    flattened = dict(descs[target_name])
136*8975f5c5SAndroid Build Coastguard Worker
137*8975f5c5SAndroid Build Coastguard Worker    EXPECTED_TYPES = LIBRARY_TYPES + ('source_set', 'group', 'action')
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker    def pre(k):
140*8975f5c5SAndroid Build Coastguard Worker        dep = descs[k]
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker        dep_type = dep['type']
143*8975f5c5SAndroid Build Coastguard Worker        deps = dep['deps']
144*8975f5c5SAndroid Build Coastguard Worker        if stop_at_lib and dep_type in LIBRARY_TYPES:
145*8975f5c5SAndroid Build Coastguard Worker            return ((),)
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Worker        if dep_type == 'copy':
148*8975f5c5SAndroid Build Coastguard Worker            assert not deps, (target_name, dep['deps'])
149*8975f5c5SAndroid Build Coastguard Worker        else:
150*8975f5c5SAndroid Build Coastguard Worker            assert dep_type in EXPECTED_TYPES, (k, dep_type)
151*8975f5c5SAndroid Build Coastguard Worker            for (k,v) in dep.items():
152*8975f5c5SAndroid Build Coastguard Worker                if type(v) in (list, tuple, set):
153*8975f5c5SAndroid Build Coastguard Worker                    # This is a workaround for
154*8975f5c5SAndroid Build Coastguard Worker                    # https://bugs.chromium.org/p/gn/issues/detail?id=196, where
155*8975f5c5SAndroid Build Coastguard Worker                    # the value of "public" can be a string instead of a list.
156*8975f5c5SAndroid Build Coastguard Worker                    existing = flattened.get(k, [])
157*8975f5c5SAndroid Build Coastguard Worker                    if isinstance(existing, str):
158*8975f5c5SAndroid Build Coastguard Worker                      existing = [existing]
159*8975f5c5SAndroid Build Coastguard Worker                    # Use temporary sets then sort them to avoid a bottleneck here
160*8975f5c5SAndroid Build Coastguard Worker                    if not isinstance(existing, set):
161*8975f5c5SAndroid Build Coastguard Worker                        flattened[k] = set(existing)
162*8975f5c5SAndroid Build Coastguard Worker                    flattened[k].update(v)
163*8975f5c5SAndroid Build Coastguard Worker                else:
164*8975f5c5SAndroid Build Coastguard Worker                    #flattened.setdefault(k, v)
165*8975f5c5SAndroid Build Coastguard Worker                    pass
166*8975f5c5SAndroid Build Coastguard Worker        return (deps,)
167*8975f5c5SAndroid Build Coastguard Worker
168*8975f5c5SAndroid Build Coastguard Worker    dag_traverse(descs[target_name]['deps'], pre)
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker    for k, v in flattened.items():
171*8975f5c5SAndroid Build Coastguard Worker        if isinstance(v, set):
172*8975f5c5SAndroid Build Coastguard Worker            flattened[k] = sortedi(v)
173*8975f5c5SAndroid Build Coastguard Worker    return flattened
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker# ------------------------------------------------------------------------------
176*8975f5c5SAndroid Build Coastguard Worker# Check that includes are valid. (gn's version of this check doesn't seem to work!)
177*8975f5c5SAndroid Build Coastguard Worker
178*8975f5c5SAndroid Build Coastguard WorkerINCLUDE_REGEX = re.compile(b'^ *# *include +([<"])([^>"]+)[>"].*$', re.MULTILINE)
179*8975f5c5SAndroid Build Coastguard Workerassert INCLUDE_REGEX.findall(b' #  include <foo>  //comment\n#include "bar"') == [(b'<', b'foo'), (b'"', b'bar')]
180*8975f5c5SAndroid Build Coastguard Worker
181*8975f5c5SAndroid Build Coastguard Worker# Most of these are ignored because this script does not currently handle
182*8975f5c5SAndroid Build Coastguard Worker# #includes in #ifdefs properly, so they will erroneously be marked as being
183*8975f5c5SAndroid Build Coastguard Worker# included, but not part of the source list.
184*8975f5c5SAndroid Build Coastguard WorkerIGNORED_INCLUDES = {
185*8975f5c5SAndroid Build Coastguard Worker    b'absl/container/flat_hash_map.h',
186*8975f5c5SAndroid Build Coastguard Worker    b'absl/container/flat_hash_set.h',
187*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/glsl/TranslatorESSL.h',
188*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/glsl/TranslatorGLSL.h',
189*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/hlsl/TranslatorHLSL.h',
190*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/msl/TranslatorMSL.h',
191*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/null/TranslatorNULL.h',
192*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/spirv/TranslatorSPIRV.h',
193*8975f5c5SAndroid Build Coastguard Worker    b'compiler/translator/wgsl/TranslatorWGSL.h',
194*8975f5c5SAndroid Build Coastguard Worker    b'contrib/optimizations/slide_hash_neon.h',
195*8975f5c5SAndroid Build Coastguard Worker    b'dirent_on_windows.h',
196*8975f5c5SAndroid Build Coastguard Worker    b'dlopen_fuchsia.h',
197*8975f5c5SAndroid Build Coastguard Worker    b'kernel/image.h',
198*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/d3d/d3d11/Device11.h',
199*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h',
200*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/d3d/DisplayD3D.h',
201*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/d3d/RenderTargetD3D.h',
202*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/cgl/DisplayCGL.h',
203*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/egl/android/DisplayAndroid.h',
204*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/egl/DisplayEGL.h',
205*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/egl/gbm/DisplayGbm.h',
206*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/glx/DisplayGLX.h',
207*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/glx/DisplayGLX_api.h',
208*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/gl/wgl/DisplayWGL.h',
209*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/metal/DisplayMtl_api.h',
210*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/null/DisplayNULL.h',
211*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/android/AHBFunctions.h',
212*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/android/DisplayVkAndroid.h',
213*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/DisplayVk_api.h',
214*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h',
215*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/ggp/DisplayVkGGP.h',
216*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/mac/DisplayVkMac.h',
217*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/win32/DisplayVkWin32.h',
218*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h',
219*8975f5c5SAndroid Build Coastguard Worker    b'libANGLE/renderer/vulkan/wayland/DisplayVkWayland.h',
220*8975f5c5SAndroid Build Coastguard Worker    b'loader_cmake_config.h',
221*8975f5c5SAndroid Build Coastguard Worker    b'loader_linux.h',
222*8975f5c5SAndroid Build Coastguard Worker    b'loader_windows.h',
223*8975f5c5SAndroid Build Coastguard Worker    b'optick.h',
224*8975f5c5SAndroid Build Coastguard Worker    b'spirv-tools/libspirv.h',
225*8975f5c5SAndroid Build Coastguard Worker    b'third_party/volk/volk.h',
226*8975f5c5SAndroid Build Coastguard Worker    b'vk_loader_extensions.c',
227*8975f5c5SAndroid Build Coastguard Worker    b'vk_snippets.h',
228*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_android.h',
229*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_beta.h',
230*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_directfb.h',
231*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_fuchsia.h',
232*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_ggp.h',
233*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_ios.h',
234*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_macos.h',
235*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_metal.h',
236*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_sci.h',
237*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_vi.h',
238*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_wayland.h',
239*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_win32.h',
240*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_xcb.h',
241*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_xlib.h',
242*8975f5c5SAndroid Build Coastguard Worker    b'vulkan_xlib_xrandr.h',
243*8975f5c5SAndroid Build Coastguard Worker    # rapidjson adds these include stubs into their documentation
244*8975f5c5SAndroid Build Coastguard Worker    # comments. Since the script doesn't skip comments they are
245*8975f5c5SAndroid Build Coastguard Worker    # erroneously marked as valid includes
246*8975f5c5SAndroid Build Coastguard Worker    b'rapidjson/...',
247*8975f5c5SAndroid Build Coastguard Worker    # Validation layers support building with robin hood hashing, but we are not enabling that
248*8975f5c5SAndroid Build Coastguard Worker    # See http://anglebug.com/42264327
249*8975f5c5SAndroid Build Coastguard Worker    b'robin_hood.h',
250*8975f5c5SAndroid Build Coastguard Worker    # Validation layers optionally use mimalloc
251*8975f5c5SAndroid Build Coastguard Worker    b'mimalloc-new-delete.h',
252*8975f5c5SAndroid Build Coastguard Worker    # From the Vulkan-Loader
253*8975f5c5SAndroid Build Coastguard Worker    b'winres.h',
254*8975f5c5SAndroid Build Coastguard Worker    # From a comment in vulkan-validation-layers/src/layers/vk_mem_alloc.h
255*8975f5c5SAndroid Build Coastguard Worker    b'my_custom_assert.h',
256*8975f5c5SAndroid Build Coastguard Worker    b'my_custom_min.h',
257*8975f5c5SAndroid Build Coastguard Worker    # https://bugs.chromium.org/p/gn/issues/detail?id=311
258*8975f5c5SAndroid Build Coastguard Worker    b'spirv/unified1/spirv.hpp11',
259*8975f5c5SAndroid Build Coastguard Worker    # Behind #if defined(QAT_COMPRESSION_ENABLED) in third_party/zlib/deflate.c
260*8975f5c5SAndroid Build Coastguard Worker    b'contrib/qat/deflate_qat.h',
261*8975f5c5SAndroid Build Coastguard Worker    # Behind #if defined(TRACY_ENABLE) in third_party/vulkan-validation-layers/src/layers/vulkan/generated/chassis.cpp
262*8975f5c5SAndroid Build Coastguard Worker    b'profiling/profiling.h',
263*8975f5c5SAndroid Build Coastguard Worker}
264*8975f5c5SAndroid Build Coastguard Worker
265*8975f5c5SAndroid Build Coastguard WorkerIGNORED_INCLUDE_PREFIXES = {
266*8975f5c5SAndroid Build Coastguard Worker    b'android',
267*8975f5c5SAndroid Build Coastguard Worker    b'Carbon',
268*8975f5c5SAndroid Build Coastguard Worker    b'CoreFoundation',
269*8975f5c5SAndroid Build Coastguard Worker    b'CoreServices',
270*8975f5c5SAndroid Build Coastguard Worker    b'IOSurface',
271*8975f5c5SAndroid Build Coastguard Worker    b'mach',
272*8975f5c5SAndroid Build Coastguard Worker    b'mach-o',
273*8975f5c5SAndroid Build Coastguard Worker    b'OpenGL',
274*8975f5c5SAndroid Build Coastguard Worker    b'pci',
275*8975f5c5SAndroid Build Coastguard Worker    b'sys',
276*8975f5c5SAndroid Build Coastguard Worker    b'wrl',
277*8975f5c5SAndroid Build Coastguard Worker    b'X11',
278*8975f5c5SAndroid Build Coastguard Worker}
279*8975f5c5SAndroid Build Coastguard Worker
280*8975f5c5SAndroid Build Coastguard WorkerIGNORED_DIRECTORIES = {
281*8975f5c5SAndroid Build Coastguard Worker    '//buildtools/third_party/libc++',
282*8975f5c5SAndroid Build Coastguard Worker    '//third_party/libc++/src',
283*8975f5c5SAndroid Build Coastguard Worker    '//third_party/abseil-cpp',
284*8975f5c5SAndroid Build Coastguard Worker    '//third_party/SwiftShader',
285*8975f5c5SAndroid Build Coastguard Worker    '//third_party/dawn',
286*8975f5c5SAndroid Build Coastguard Worker}
287*8975f5c5SAndroid Build Coastguard Worker
288*8975f5c5SAndroid Build Coastguard Workerdef has_all_includes(target_name: str, descs: dict) -> bool:
289*8975f5c5SAndroid Build Coastguard Worker    for ignored_directory in IGNORED_DIRECTORIES:
290*8975f5c5SAndroid Build Coastguard Worker        if target_name.startswith(ignored_directory):
291*8975f5c5SAndroid Build Coastguard Worker            return True
292*8975f5c5SAndroid Build Coastguard Worker
293*8975f5c5SAndroid Build Coastguard Worker    flat = flattened_target(target_name, descs, stop_at_lib=False)
294*8975f5c5SAndroid Build Coastguard Worker    acceptable_sources = flat.get('sources', []) + flat.get('outputs', [])
295*8975f5c5SAndroid Build Coastguard Worker    acceptable_sources = {x.rsplit('/', 1)[-1].encode() for x in acceptable_sources}
296*8975f5c5SAndroid Build Coastguard Worker
297*8975f5c5SAndroid Build Coastguard Worker    ret = True
298*8975f5c5SAndroid Build Coastguard Worker    desc = descs[target_name]
299*8975f5c5SAndroid Build Coastguard Worker    for cur_file in desc.get('sources', []):
300*8975f5c5SAndroid Build Coastguard Worker        assert cur_file.startswith('/'), cur_file
301*8975f5c5SAndroid Build Coastguard Worker        if not cur_file.startswith('//'):
302*8975f5c5SAndroid Build Coastguard Worker            continue
303*8975f5c5SAndroid Build Coastguard Worker        cur_file = pathlib.Path(cur_file[2:])
304*8975f5c5SAndroid Build Coastguard Worker        text = cur_file.read_bytes()
305*8975f5c5SAndroid Build Coastguard Worker        for m in INCLUDE_REGEX.finditer(text):
306*8975f5c5SAndroid Build Coastguard Worker            if m.group(1) == b'<':
307*8975f5c5SAndroid Build Coastguard Worker                continue
308*8975f5c5SAndroid Build Coastguard Worker            include = m.group(2)
309*8975f5c5SAndroid Build Coastguard Worker            if include in IGNORED_INCLUDES:
310*8975f5c5SAndroid Build Coastguard Worker                continue
311*8975f5c5SAndroid Build Coastguard Worker            try:
312*8975f5c5SAndroid Build Coastguard Worker                (prefix, _) = include.split(b'/', 1)
313*8975f5c5SAndroid Build Coastguard Worker                if prefix in IGNORED_INCLUDE_PREFIXES:
314*8975f5c5SAndroid Build Coastguard Worker                    continue
315*8975f5c5SAndroid Build Coastguard Worker            except ValueError:
316*8975f5c5SAndroid Build Coastguard Worker                pass
317*8975f5c5SAndroid Build Coastguard Worker
318*8975f5c5SAndroid Build Coastguard Worker            include_file = include.rsplit(b'/', 1)[-1]
319*8975f5c5SAndroid Build Coastguard Worker            if include_file not in acceptable_sources:
320*8975f5c5SAndroid Build Coastguard Worker                #print('  acceptable_sources:')
321*8975f5c5SAndroid Build Coastguard Worker                #for x in sorted(acceptable_sources):
322*8975f5c5SAndroid Build Coastguard Worker                #    print('   ', x)
323*8975f5c5SAndroid Build Coastguard Worker                print('Warning in {}: {}: Included file must be listed in the GN target or its public dependency: {}'.format(target_name, cur_file, include), file=sys.stderr)
324*8975f5c5SAndroid Build Coastguard Worker                ret = False
325*8975f5c5SAndroid Build Coastguard Worker            #print('Looks valid:', m.group())
326*8975f5c5SAndroid Build Coastguard Worker            continue
327*8975f5c5SAndroid Build Coastguard Worker
328*8975f5c5SAndroid Build Coastguard Worker    return ret
329*8975f5c5SAndroid Build Coastguard Worker
330*8975f5c5SAndroid Build Coastguard Worker# -
331*8975f5c5SAndroid Build Coastguard Worker# Gather real targets:
332*8975f5c5SAndroid Build Coastguard Worker
333*8975f5c5SAndroid Build Coastguard Workerdef gather_libraries(roots: Sequence[str], descs: dict) -> Set[str]:
334*8975f5c5SAndroid Build Coastguard Worker    libraries = set()
335*8975f5c5SAndroid Build Coastguard Worker    def fn(target_name):
336*8975f5c5SAndroid Build Coastguard Worker        cur = descs[target_name]
337*8975f5c5SAndroid Build Coastguard Worker        print('  ' + cur['type'], target_name, file=sys.stderr)
338*8975f5c5SAndroid Build Coastguard Worker        assert has_all_includes(target_name, descs), target_name
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker        if cur['type'] in ('shared_library', 'static_library'):
341*8975f5c5SAndroid Build Coastguard Worker            libraries.add(target_name)
342*8975f5c5SAndroid Build Coastguard Worker        return (cur['deps'], )
343*8975f5c5SAndroid Build Coastguard Worker
344*8975f5c5SAndroid Build Coastguard Worker    dag_traverse(roots, fn)
345*8975f5c5SAndroid Build Coastguard Worker    return libraries
346*8975f5c5SAndroid Build Coastguard Worker
347*8975f5c5SAndroid Build Coastguard Worker# -
348*8975f5c5SAndroid Build Coastguard Worker
349*8975f5c5SAndroid Build Coastguard Workerlibraries = gather_libraries(ROOTS, descs)
350*8975f5c5SAndroid Build Coastguard Workerprint(f'\n{len(libraries)} libraries:', file=sys.stderr)
351*8975f5c5SAndroid Build Coastguard Workerfor k in libraries:
352*8975f5c5SAndroid Build Coastguard Worker    print(f'  {k}', file=sys.stderr)
353*8975f5c5SAndroid Build Coastguard Workerprint('\nstdout begins:', file=sys.stderr)
354*8975f5c5SAndroid Build Coastguard Workersys.stderr.flush()
355*8975f5c5SAndroid Build Coastguard Worker
356*8975f5c5SAndroid Build Coastguard Worker# ------------------------------------------------------------------------------
357*8975f5c5SAndroid Build Coastguard Worker# Output
358*8975f5c5SAndroid Build Coastguard Worker
359*8975f5c5SAndroid Build Coastguard Workerout = {k: flattened_target(k, descs) for k in libraries}
360*8975f5c5SAndroid Build Coastguard Worker
361*8975f5c5SAndroid Build Coastguard Workerfor (k,desc) in out.items():
362*8975f5c5SAndroid Build Coastguard Worker    dep_libs: Set[str] = set()
363*8975f5c5SAndroid Build Coastguard Worker    for dep_name in set(desc['deps']):
364*8975f5c5SAndroid Build Coastguard Worker        dep = descs[dep_name]
365*8975f5c5SAndroid Build Coastguard Worker        if dep['type'] in LIBRARY_TYPES:
366*8975f5c5SAndroid Build Coastguard Worker            dep_libs.add(dep_name)
367*8975f5c5SAndroid Build Coastguard Worker    desc['dep_libs'] = sortedi(dep_libs)
368*8975f5c5SAndroid Build Coastguard Worker
369*8975f5c5SAndroid Build Coastguard Workerjson.dump(out, sys.stdout, indent='  ')
370*8975f5c5SAndroid Build Coastguard Workerexit(0)
371