1 #! /usr/bin/env python3
2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 assert __name__
== "__main__"
9 To update ANGLE in Gecko, use Windows with git-bash, and setup depot_tools, python2, and
10 python3. Because depot_tools expects `python` to be `python2` (shame!), python2 must come
11 before python3 in your path.
13 Upstream: https://chromium.googlesource.com/angle/angle
15 Our repo: https://github.com/mozilla/angle
16 It has branches like 'firefox-60' which is the branch we use for pulling into
17 Gecko with this script.
19 This script leaves a record of the merge-base and cherry-picks that we pull into
20 Gecko. (gfx/angle/cherries.log)
22 ANGLE<->Chrome version mappings are here: https://omahaproxy.appspot.com/
23 An easy choice is to grab Chrome's Beta's ANGLE branch.
30 export PATH="$PATH:/path/to/depot_tools"
33 If this is a new repo, don't forget:
37 ./scripts/bootstrap.py
41 Update: (in the angle repo)
45 /path/to/gecko/gfx/angle/update-angle.py origin/chromium/XXXX
46 git push moz # Push the firefox-XX branch to github.com/mozilla/angle
58 from typing
import * # mypy annotations
60 REPO_DIR
= pathlib
.Path
.cwd()
61 GECKO_ANGLE_DIR
= pathlib
.Path(__file__
).parent
63 OUT_DIR
= pathlib
.Path("out")
66 "# Generated by update-angle.py",
68 'include("../../moz.build.common")',
71 ROOTS
= ["//:translator", "//:libEGL", "//:libGLESv2"]
83 GN_ENV
= dict(os
.environ
)
84 GN_ENV
["DEPOT_TOOLS_WIN_TOOLCHAIN"] = "0"
86 (GIT_REMOTE
,) = args
# Not always 'origin'!
88 # ------------------------------------------------------------------------------
91 def run_checked(*args
, **kwargs
):
94 return subprocess
.run(args
, check
=True, **kwargs
)
98 for k
in sorted(x
.keys()):
102 def collapse_dotdots(path
):
103 split
= path
.split("/")
107 if x
== ".." and ret
:
116 def dag_traverse(root_keys
: Sequence
[str], pre_recurse_func
: Callable
[[str], list]):
117 visited_keys
: Set
[str] = set()
120 if key
in visited_keys
:
122 visited_keys
.add(key
)
124 t
= pre_recurse_func(key
)
126 (next_keys
, post_recurse_func
) = t
129 post_recurse_func
= None
134 if post_recurse_func
:
135 post_recurse_func(key
)
143 # ------------------------------------------------------------------------------
145 print("Importing graph")
147 # shutil.rmtree(str(OUT_DIR), True)
148 OUT_DIR
.mkdir(exist_ok
=True)
151 # Build arguments go here.
152 # See "gn args <out_dir> --list" for available build arguments.
155 angle_build_all = false
156 angle_enable_abseil = false
157 angle_enable_gl = false
158 angle_enable_null = false
159 angle_enable_vulkan = false
160 use_custom_libcxx = false
164 args_gn_path
= OUT_DIR
/ "args.gn"
165 args_gn_path
.write_bytes(GN_ARGS
)
168 run_checked("gn", "gen", str(OUT_DIR
), shell
=True, env
=GN_ENV
)
169 except subprocess
.CalledProcessError
:
170 sys
.stderr
.buffer.write(b
"`gn` failed. Is depot_tools in your PATH?\n")
175 "scripts/export_targets.py",
178 stdout
=subprocess
.PIPE
,
185 print("\nProcessing graph")
186 libraries
= json
.loads(p
.stdout
.decode())
189 # HACKHACKHACK: Inject linux/mac sources instead of trying to merge graphs of different
191 # descs["//:angle_common"]["sources"] +=
192 EXTRA_ANGLE_COMMON_SOURCES
= [
193 "//src/common/system_utils_linux.cpp",
194 "//src/common/system_utils_mac.cpp",
195 "//src/common/system_utils_posix.cpp",
198 angle_common
= libraries
["//:angle_common"]
199 angle_common
["sources"] += EXTRA_ANGLE_COMMON_SOURCES
200 angle_common
["sources"] = sorted(angle_common
["sources"])
205 del libraries
["//third_party/zlib:zlib"]
210 print("\n--check complete.")
213 # ------------------------------------------------------------------------------
214 # Output to moz.builds
216 import vendor_from_git
219 vendor_from_git
.record_cherry_picks(GECKO_ANGLE_DIR
, GIT_REMOTE
)
225 return sorted(x
, key
=str.lower
)
228 def append_arr(dest
, name
, vals
, indent
=0):
232 dest
.append("{}{} += [".format(" " * 4 * indent
, name
))
233 for x
in sortedi(vals
):
234 dest
.append('{}"{}",'.format(" " * 4 * (indent
+ 1), x
))
235 dest
.append("{}]".format(" " * 4 * indent
))
240 REGISTERED_DEFINES
= {
241 "ADLER32_SIMD_SSSE3": False,
242 "ANGLE_CAPTURE_ENABLED": True,
243 "ANGLE_EGL_LIBRARY_NAME": False,
244 "ANGLE_ENABLE_D3D11": True,
245 "ANGLE_ENABLE_D3D9": True,
246 "ANGLE_ENABLE_DEBUG_ANNOTATIONS": True,
247 "ANGLE_ENABLE_NULL": False,
248 "ANGLE_ENABLE_OPENGL": False,
249 "ANGLE_ENABLE_OPENGL_NULL": False,
250 "ANGLE_ENABLE_ESSL": True,
251 "ANGLE_ENABLE_GLSL": True,
252 "ANGLE_ENABLE_HLSL": True,
253 "ANGLE_GENERATE_SHADER_DEBUG_INFO": True,
254 "ANGLE_GLESV2_LIBRARY_NAME": True,
255 "ANGLE_IS_64_BIT_CPU": False,
256 "ANGLE_IS_WIN": False,
257 "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES": False,
258 "ANGLE_USE_EGL_LOADER": True,
259 "CERT_CHAIN_PARA_HAS_EXTRA_FIELDS": False,
260 "CHROMIUM_BUILD": False,
261 "COMPONENT_BUILD": False,
262 "CRC32_SIMD_SSE42_PCLMUL": False,
263 "DEFLATE_FILL_WINDOW_SSE2": False,
264 "DYNAMIC_ANNOTATIONS_ENABLED": True,
265 "EGL_EGL_PROTOTYPES": True,
266 "EGL_EGLEXT_PROTOTYPES": True,
268 "FIELDTRIAL_TESTING_ENABLED": False,
269 "FULL_SAFE_BROWSING": False,
272 "GL_GLES_PROTOTYPES": True,
273 "GL_GLEXT_PROTOTYPES": True,
274 "GPU_INFO_USE_SETUPAPI": True,
275 "INFLATE_CHUNK_READ_64LE": False,
276 "INFLATE_CHUNK_SIMD_SSE2": False,
277 "LIBANGLE_IMPLEMENTATION": True,
278 "LIBEGL_IMPLEMENTATION": True,
279 "LIBGLESV2_IMPLEMENTATION": True,
281 "NO_TCMALLOC": False,
282 # Else: gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp(89): error C2787: 'IDCompositionDevice': no GUID has been associated with this object
283 "NTDDI_VERSION": False,
284 "PSAPI_VERSION": False,
285 "SAFE_BROWSING_CSD": False,
286 "SAFE_BROWSING_DB_LOCAL": False,
289 "V8_DEPRECATION_WARNINGS": False,
290 "VK_USE_PLATFORM_WIN32_KHR": False,
292 "WIN32_LEAN_AND_MEAN": False,
293 "WINAPI_FAMILY": False,
296 # gfx/angle/targets/libANGLE
297 # In file included from c:/dev/mozilla/gecko4/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp:10:
298 # In file included from c:/dev/mozilla/gecko4/gfx/angle/checkout/src\libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h:17:
299 # C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt\Windows.ui.composition.interop.h(103,20): error: unknown type name 'POINTER_INFO'
300 # _In_ const POINTER_INFO& pointerInfo
302 "WTF_USE_DYNAMIC_ANNOTATIONS": False,
303 "X86_WINDOWS": False,
304 "ZLIB_IMPLEMENTATION": True,
305 "_ATL_NO_OPENGL": True,
306 "_CRT_NONSTDC_NO_DEPRECATE": True,
307 "_CRT_NONSTDC_NO_WARNINGS": True,
309 "_CRT_SECURE_NO_DEPRECATE": True,
311 "_HAS_EXCEPTIONS": True,
312 "_HAS_ITERATOR_DEBUGGING": False,
313 "_SCL_SECURE_NO_DEPRECATE": True,
316 "_USING_V110_SDK71_": False,
317 "_WIN32_WINNT": False,
321 "CR_CLANG_REVISION": True,
324 "_HAS_NODISCARD": False,
329 print("\nRun actions")
330 required_files
: Set
[str] = set()
332 run_checked("ninja", "-C", str(OUT_DIR
), ":angle_commit_id")
333 required_files
.add("//out/gen/angle/angle_commit.h")
338 print("\nExport targets")
340 # Clear our dest directories
341 targets_dir
= pathlib
.Path(GECKO_ANGLE_DIR
, "targets")
342 checkout_dir
= pathlib
.Path(GECKO_ANGLE_DIR
, "checkout")
344 shutil
.rmtree(targets_dir
, True)
345 shutil
.rmtree(checkout_dir
, True)
346 targets_dir
.mkdir(exist_ok
=True)
347 checkout_dir
.mkdir(exist_ok
=True)
351 RE_TARGET_NAME
= re
.compile("//(.*):(.+)")
354 def export_target(target_full_name
) -> Set
[str]:
355 # print(' ', target_full_name)
357 desc
= descs
[target_name
]
360 m
= RE_TARGET_NAME
.match(target_name
)
361 assert m
, target_name
364 required_files
: Set
[str] = set(flat
["sources"])
366 # Create our manifest lines
367 target_dir
= targets_dir
/ name
368 target_dir
.mkdir(exist_ok
=True)
370 lines
= list(COMMON_HEADER
)
373 for x
in sorted(set(desc
["defines"])):
375 (k
, v
) = x
.split("=", 1)
376 if v
.startswith('"'):
383 line
= f
'DEFINES["{k}"] = {v}'
385 if REGISTERED_DEFINES
[k
] == False:
388 print(f
"[{name}] Unrecognized define: {k}")
389 line
= "# Unrecognized: " + line
393 cxxflags
= set(desc
["cflags"] + desc
["cflags_cc"])
395 def fixup_paths(listt
):
397 assert x
.startswith("//"), x
398 yield "../../checkout/" + x
[2:]
400 sources_by_config
: Dict
[str, List
[str]] = {}
401 extras
: Dict
[str, str] = dict()
402 for x
in fixup_paths(flat
["sources"]):
404 (b
, e
) = x
.rsplit(".", 1)
405 if e
in ["h", "hpp", "y", "l", "inc", "inl"]:
407 elif e
in ["cpp", "cc", "c"]:
408 if b
.endswith("_win") or b
.endswith("_win32"):
409 config
= 'CONFIG["OS_ARCH"] == "WINNT"'
410 elif b
.endswith("_linux"):
411 # Include these on BSDs too.
412 config
= 'CONFIG["OS_ARCH"] not in ("Darwin", "WINNT")'
413 elif b
.endswith("_mac"):
414 config
= 'CONFIG["OS_ARCH"] == "Darwin"'
415 elif b
.endswith("_posix"):
416 config
= 'CONFIG["OS_ARCH"] != "WINNT"'
418 config
= "" # None can't compare against str.
420 sources_by_config
.setdefault(config
, []).append(x
)
423 assert "RCFILE" not in extras
, (target_name
, extras
["RCFILE"], x
)
424 extras
["RCFILE"] = f
'"{x}"'
427 assert "DEFFILE" not in extras
, (target_name
, extras
["DEFFILE"], x
)
428 extras
["DEFFILE"] = f
'"{x}"'
431 assert False, ("Unhandled ext:", x
)
433 ldflags
= set(desc
["ldflags"])
435 for x
in set(ldflags
):
436 if x
.startswith(DEF_PREFIX
):
437 def_path
= x
[len(DEF_PREFIX
) :]
438 required_files
.add(def_path
)
439 assert "DEFFILE" not in extras
442 def_path
= str(OUT_DIR
) + "/" + def_path
443 def_path
= "//" + collapse_dotdots(def_path
)
445 def_rel_path
= list(fixup_paths([def_path
]))[0]
446 extras
["DEFFILE"] = '"{}"'.format(def_rel_path
)
448 os_libs
= list(map(lambda x
: x
[: -len(".lib")], set(desc
.get("libs", []))))
450 def append_arr_commented(dest
, name
, src
):
452 append_arr(lines
, name
, src
)
459 lines
= map(comment
, lines
)
462 append_arr(lines
, "LOCAL_INCLUDES", fixup_paths(desc
["include_dirs"]))
463 append_arr_commented(lines
, "CXXFLAGS", cxxflags
)
465 for (config
, v
) in sorted_items(sources_by_config
):
468 lines
.append("if {}:".format(config
))
470 append_arr(lines
, "SOURCES", v
, indent
=indent
)
472 dep_libs
: Set
[str] = set()
473 for dep_full_name
in set(flat
["dep_libs"]):
474 assert dep_full_name
.startswith("//"), dep_name
475 (_
, dep_name
) = dep_full_name
.split(":")
476 dep_libs
.add(dep_name
)
478 dep_dirs
= set(dep_libs
)
479 dep_dirs
.discard("zlib")
481 append_arr(lines
, "USE_LIBS", dep_libs
)
482 append_arr(lines
, "DIRS", ["../" + x
for x
in dep_dirs
])
483 append_arr(lines
, "OS_LIBS", os_libs
)
484 append_arr_commented(lines
, "LDFLAGS", ldflags
)
486 for (k
, v
) in sorted(extras
.items()):
487 lines
.append("{} = {}".format(k
, v
))
489 lib_type
= desc
["type"]
490 if lib_type
== "shared_library":
491 lines
.append(f
'GeckoSharedLibrary("{name}", linkage=None)')
492 elif lib_type
== "static_library":
493 lines
.append(f
'Library("{name}")')
495 assert False, lib_type
502 mozbuild
= target_dir
/ "moz.build"
503 print(" ", " ", f
"Writing {mozbuild}")
504 data
= b
"\n".join((x
.encode() for x
in lines
))
505 mozbuild
.write_bytes(data
)
507 return required_files
512 for target_name
in libraries
:
513 reqs
= export_target(target_name
)
514 required_files |
= reqs
518 print("\nMigrate required files")
521 for x
in required_files
:
523 sys
.stdout
.write(f
"\r Copying {i}/{len(required_files)}")
525 assert x
.startswith("//"), x
529 dest
= checkout_dir
/ x
531 dest
.parent
.mkdir(parents
=True, exist_ok
=True)
532 data
= src
.read_bytes()
533 data
= data
.replace(b
"\r\n", b
"\n")
534 dest
.write_bytes(data
)