Browse Source

Build fixes

Frank-Rainer Grahl 3 weeks ago
parent
commit
cfe09d6a3f

+ 3 - 9
mozilla-release/patches/1602259-2-VS2019-gyp-25310.patch → mozilla-release/patches/1602259-2-VS2019-gyp-25320.patch

@@ -1,23 +1,17 @@
 # HG changeset patch
 # HG changeset patch
 # User Frank-Rainer Grahl <frgrahl@gmx.net>
 # User Frank-Rainer Grahl <frgrahl@gmx.net>
 # Date 1574532060 -3600
 # Date 1574532060 -3600
-# Parent  5ceed416d20344a71b6be49e1a8fabbe06b7bf1c
+# Parent  e812606d004c59900e85c88bc333778fcc92ceda
 Bug 1602259 - Support VS2019 projects in gyp. r=IanN a=IanN
 Bug 1602259 - Support VS2019 projects in gyp. r=IanN a=IanN
 
 
 diff --git a/third_party/python/gyp/pylib/gyp/MSVSVersion.py b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 diff --git a/third_party/python/gyp/pylib/gyp/MSVSVersion.py b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 --- a/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 --- a/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 +++ b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 +++ b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
-@@ -258,22 +258,22 @@ def _CreateVersion(name, path, sdk_based
-   passed in that doesn't match a value in versions python will throw a error.
-   """
-   if path:
-     path = os.path.normpath(path)
-   versions = {
+@@ -277,17 +277,17 @@ def _CreateVersion(name, path, sdk_based
        '2019': VisualStudioVersion('2019',
        '2019': VisualStudioVersion('2019',
                                    'Visual Studio 2019',
                                    'Visual Studio 2019',
                                    solution_version='12.00',
                                    solution_version='12.00',
--                                  project_version='15.0',
-+                                  project_version='16.0',
+                                   project_version='16.0',
                                    flat_sln=False,
                                    flat_sln=False,
                                    uses_vcxproj=True,
                                    uses_vcxproj=True,
                                    path=path,
                                    path=path,

+ 304 - 0
mozilla-release/patches/1664083-82a1.patch

@@ -0,0 +1,304 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1599709470 0
+# Node ID 808a836d9f2b54b8e386cfe7647851259de98abd
+# Parent  e2bcb16778f78bef1bda5639abeac792884dcf22
+Bug 1664083 - Remove support for external source directories. r=nalexander
+
+It was there for comm-central, and hasn't been used since bug 1479904.
+
+Differential Revision: https://phabricator.services.mozilla.com/D89691
+
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -127,43 +127,29 @@ add_old_configure_assignment(
+ option(env='MOZ_AUTOMATION', help='Enable options for automated builds')
+ set_config('MOZ_AUTOMATION', depends_if('MOZ_AUTOMATION')(lambda x: True))
+ 
+ 
+ option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
+ 
+ option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
+ 
+-option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1,
+-       help='External directory containing additional build files')
+-
+-
+-@depends('--with-external-source-dir')
+-def external_source_dir(value):
+-    if value:
+-        return value[0]
+-
+-
+-set_config('EXTERNAL_SOURCE_DIR', external_source_dir)
+-add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
+ 
+ # Read user mozconfig
+ # ==============================================================
+ # Note: the dependency on --help is only there to always read the mozconfig,
+ # even when --help is passed. Without this dependency, the function wouldn't
+ # be called when --help is passed, and the mozconfig wouldn't be read.
+ 
+ 
+-@depends('MOZCONFIG', 'OLD_CONFIGURE',
+-         check_build_environment, '--with-external-source-dir',
++@depends('MOZCONFIG', 'OLD_CONFIGURE', check_build_environment,
+          '--help')
+ @imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
+ @imports(_from='mozboot.mozconfig', _import='find_mozconfig')
+-def mozconfig(mozconfig, old_configure, build_env,
+-              external_source_dir, help):
++def mozconfig(mozconfig, old_configure, build_env, help):
+     if not old_configure and not help:
+         die('The OLD_CONFIGURE environment variable must be set')
+ 
+     # Don't read the mozconfig for the js configure (yay backwards
+     # compatibility)
+     # While the long term goal is that js and top-level use the same configure
+     # and the same overall setup, including the possibility to use mozconfigs,
+     # figuring out what we want to do wrt mozconfig vs. command line and
+@@ -177,18 +163,16 @@ def mozconfig(mozconfig, old_configure, 
+     # configure is the js configure. The indirect way is to look at the
+     # OLD_CONFIGURE path, which points to js/src/old-configure.
+     # I expect we'll have figured things out for mozconfigs well before
+     # old-configure dies.
+     if old_configure and os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'):
+         return {'path': None}
+ 
+     topsrcdir = build_env.topsrcdir
+-    if external_source_dir:
+-        topsrcdir = external_source_dir[0]
+     loader = MozconfigLoader(topsrcdir)
+     mozconfig = mozconfig[0] if mozconfig else None
+     mozconfig = find_mozconfig(topsrcdir, env={'MOZCONFIG': mozconfig})
+     mozconfig = loader.read_mozconfig(mozconfig)
+ 
+     return mozconfig
+ 
+ 
+@@ -1031,27 +1015,23 @@ set_define('XP_FREEBSD', target_is_freeb
+ def target_is_solaris(target):
+     if target.kernel == 'SunOS':
+         return True
+ 
+ 
+ set_define('XP_SOLARIS', target_is_solaris)
+ 
+ 
+-@depends('--enable-project', '--with-external-source-dir',
+-         check_build_environment, '--help')
++@depends('--enable-project', check_build_environment, '--help')
+ @imports(_from='os.path', _import='exists')
+-def include_project_configure(project, external_source_dir, build_env, help):
++def include_project_configure(project, build_env, help):
+     if not project:
+         die('--enable-project is required.')
+ 
+     base_dir = build_env.topsrcdir
+-    if external_source_dir:
+-        base_dir = os.path.join(base_dir, external_source_dir[0])
+-
+     path = os.path.join(base_dir, project[0], 'moz.configure')
+     if not exists(path):
+         die('Cannot find project %s', project[0])
+     return path
+ 
+ 
+ @depends(include_project_configure, check_build_environment)
+ def build_project(include_project_configure, build_env):
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -1755,18 +1755,16 @@ MOZ_ARG_WITH_STRING(branding,
+ 
+ REAL_BRANDING_DIRECTORY="${MOZ_BRANDING_DIRECTORY}"
+ if test -z "$REAL_BRANDING_DIRECTORY"; then
+   REAL_BRANDING_DIRECTORY=${MOZ_BUILD_APP}/branding/nightly
+ fi
+ 
+ if test -f "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
+   . "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"
+-elif test -f "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
+-  . "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh"
+ fi
+ 
+ AC_SUBST(MOZ_BRANDING_DIRECTORY)
+ 
+ dnl ========================================================
+ dnl = Distribution ID
+ dnl ========================================================
+ MOZ_ARG_WITH_STRING(distribution-id,
+diff --git a/python/mozbuild/mozbuild/backend/configenvironment.py b/python/mozbuild/mozbuild/backend/configenvironment.py
+--- a/python/mozbuild/mozbuild/backend/configenvironment.py
++++ b/python/mozbuild/mozbuild/backend/configenvironment.py
+@@ -176,24 +176,16 @@ class ConfigEnvironment(object):
+             sorted([
+                 '%s =' % name
+                 for name in self.substs if not self.substs[name]
+                 ])
+             )
+ 
+         self.substs = ReadOnlyDict(self.substs)
+ 
+-        self.external_source_dir = None
+-        external = self.substs.get('EXTERNAL_SOURCE_DIR', '')
+-        if external:
+-            external = mozpath.normpath(external)
+-            if not os.path.isabs(external):
+-                external = mozpath.join(self.topsrcdir, external)
+-            self.external_source_dir = mozpath.normpath(external)
+-
+     @property
+     def is_artifact_build(self):
+         return self.substs.get('MOZ_ARTIFACT_BUILDS', False)
+ 
+     @memoized_property
+     def acdefines(self):
+         acdefines = dict((name, self.defines[name])
+                          for name in self.defines
+diff --git a/python/mozbuild/mozbuild/frontend/context.py b/python/mozbuild/mozbuild/frontend/context.py
+--- a/python/mozbuild/mozbuild/frontend/context.py
++++ b/python/mozbuild/mozbuild/frontend/context.py
+@@ -678,21 +678,16 @@ class SourcePath(Path):
+         if value.startswith('!'):
+             raise ValueError('Object directory paths are not allowed')
+         if value.startswith('%'):
+             raise ValueError('Filesystem absolute paths are not allowed')
+         self = super(SourcePath, cls).__new__(cls, context, value)
+ 
+         if value.startswith('/'):
+             path = None
+-            # If the path starts with a '/' and is actually relative to an
+-            # external source dir, use that as base instead of topsrcdir.
+-            if context.config.external_source_dir:
+-                path = mozpath.join(context.config.external_source_dir,
+-                                    value[1:])
+             if not path or not os.path.exists(path):
+                 path = mozpath.join(context.config.topsrcdir,
+                                     value[1:])
+         else:
+             path = mozpath.join(self.srcdir, value)
+         self.full_path = mozpath.normpath(path)
+         return self
+ 
+diff --git a/python/mozbuild/mozbuild/frontend/reader.py b/python/mozbuild/mozbuild/frontend/reader.py
+--- a/python/mozbuild/mozbuild/frontend/reader.py
++++ b/python/mozbuild/mozbuild/frontend/reader.py
+@@ -118,17 +118,16 @@ class EmptyConfig(object):
+     }
+ 
+     def __init__(self, topsrcdir, substs=None):
+         self.topsrcdir = topsrcdir
+         self.topobjdir = ''
+ 
+         self.substs = self.PopulateOnGetDict(EmptyValue, substs or self.default_substs)
+         self.defines = self.substs
+-        self.external_source_dir = None
+         self.error_is_fatal = False
+ 
+ 
+ def is_read_allowed(path, config):
+     """Whether we are allowed to load a mozbuild file at the specified path.
+ 
+     This is used as cheap security to ensure the build is isolated to known
+     source directories.
+@@ -141,22 +140,16 @@ def is_read_allowed(path, config):
+     assert os.path.isabs(config.topsrcdir)
+ 
+     path = mozpath.normpath(path)
+     topsrcdir = mozpath.normpath(config.topsrcdir)
+ 
+     if mozpath.basedir(path, [topsrcdir]):
+         return True
+ 
+-    if config.external_source_dir:
+-        external_dir = os.path.normcase(config.external_source_dir)
+-        norm_path = os.path.normcase(path)
+-        if mozpath.basedir(norm_path, [external_dir]):
+-            return True
+-
+     return False
+ 
+ 
+ class SandboxCalledError(SandboxError):
+     """Represents an error resulting from calling the error() function."""
+ 
+     def __init__(self, file_stack, message):
+         SandboxError.__init__(self, file_stack)
+@@ -1100,33 +1093,24 @@ class BuildReader(object):
+             return
+ 
+         self._read_files.add(path)
+ 
+         time_start = time.time()
+ 
+         topobjdir = config.topobjdir
+ 
+-        if not mozpath.basedir(path, [config.topsrcdir]):
+-            external = config.external_source_dir
+-            if external and mozpath.basedir(path, [external]):
+-                config = ConfigEnvironment.from_config_status(
+-                    mozpath.join(topobjdir, 'config.status'))
+-                config.topsrcdir = external
+-                config.external_source_dir = None
+-
+         relpath = mozpath.relpath(path, config.topsrcdir)
+         reldir = mozpath.dirname(relpath)
+ 
+         if mozpath.dirname(relpath) == 'js/src' and \
+                 not config.substs.get('JS_STANDALONE'):
+             config = ConfigEnvironment.from_config_status(
+                 mozpath.join(topobjdir, reldir, 'config.status'))
+             config.topobjdir = topobjdir
+-            config.external_source_dir = None
+ 
+         context = Context(VARIABLES, config, self.finder)
+         sandbox = MozbuildSandbox(context, metadata=metadata,
+                                   finder=self.finder)
+         sandbox.exec_file(path)
+         self._execution_time += time.time() - time_start
+         self._file_count += len(context.all_paths)
+ 
+diff --git a/python/mozbuild/mozbuild/test/common.py b/python/mozbuild/mozbuild/test/common.py
+--- a/python/mozbuild/mozbuild/test/common.py
++++ b/python/mozbuild/mozbuild/test/common.py
+@@ -56,17 +56,16 @@ class MockConfig(object):
+             'MOZ_TRUE': '1',
+             'MOZ_FALSE': '',
+             'DLL_PREFIX': 'lib',
+             'DLL_SUFFIX': '.so'
+         }, **extra_substs)
+ 
+         self.defines = self.substs
+ 
+-        self.external_source_dir = None
+         self.lib_prefix = 'lib'
+         self.rust_lib_prefix = 'lib'
+         self.lib_suffix = '.a'
+         self.rust_lib_suffix = '.a'
+         self.import_prefix = 'lib'
+         self.import_suffix = '.so'
+         self.dll_prefix = 'lib'
+         self.dll_suffix = '.so'
+diff --git a/python/mozbuild/mozbuild/test/frontend/test_context.py b/python/mozbuild/mozbuild/test/frontend/test_context.py
+--- a/python/mozbuild/mozbuild/test/frontend/test_context.py
++++ b/python/mozbuild/mozbuild/test/frontend/test_context.py
+@@ -281,17 +281,16 @@ class TestSymbols(unittest.TestCase):
+ class TestPaths(unittest.TestCase):
+     @classmethod
+     def setUpClass(cls):
+         class Config(object):
+             pass
+         cls.config = config = Config()
+         config.topsrcdir = mozpath.abspath(os.curdir)
+         config.topobjdir = mozpath.abspath('obj')
+-        config.external_source_dir = None
+ 
+     def test_path(self):
+         config = self.config
+         ctxt1 = Context(config=config)
+         ctxt1.push_source(mozpath.join(config.topsrcdir, 'foo', 'moz.build'))
+         ctxt2 = Context(config=config)
+         ctxt2.push_source(mozpath.join(config.topsrcdir, 'bar', 'moz.build'))
+ 

+ 118 - 0
mozilla-release/patches/1683797-1-88a1.patch

@@ -0,0 +1,118 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1615301124 0
+# Node ID 3457334cbaf9f6afac6c5e8e9e2d46b988e9ff9f
+# Parent  e2bcb16778f78bef1bda5639abeac792884dcf22
+Bug 1683797: Removes unnecessary lines from client.mk r=sheehan,firefox-build-system-reviewers,glandium
+
+CWD and BUILDSTATUS are never used.
+
+Differential Revision: https://phabricator.services.mozilla.com/D102661
+
+diff --git a/client.mk b/client.mk
+--- a/client.mk
++++ b/client.mk
+@@ -9,75 +9,51 @@
+ # This make file should not be invoked directly. Instead, use
+ # `mach` (likely `mach build`) for invoking the build system.
+ #
+ # Options:
+ #   MOZ_OBJDIR           - Destination object directory
+ #   MOZ_MAKE_FLAGS       - Flags to pass to $(MAKE)
+ #
+ #######################################################################
+-# Defines
+-
+-ifdef MACH
+-ifndef NO_BUILDSTATUS_MESSAGES
+-define BUILDSTATUS
+-@echo 'BUILDSTATUS $1'
+-
+-endef
+-endif
++ifndef MACH
++$(error client.mk must be used via `mach`. Try running \
++`./mach $(firstword $(MAKECMDGOALS) $(.DEFAULT_GOAL))`)
+ endif
+ 
+-
+-CWD := $(CURDIR)
+-
+-ifeq "$(CWD)" "/"
+-CWD   := /.
+-endif
+-
+-PYTHON3 ?= python3
+-
+-####################################
+-# Load mozconfig Options
+-
++### Load mozconfig options
+ include $(OBJDIR)/.mozconfig-client-mk
+ 
+ ifdef MOZ_PARALLEL_BUILD
+   MOZ_MAKE_FLAGS := $(filter-out -j%,$(MOZ_MAKE_FLAGS))
+   MOZ_MAKE_FLAGS += -j$(MOZ_PARALLEL_BUILD)
+ endif
+ 
+ # Automatically add -jN to make flags if not defined. N defaults to number of cores.
+ ifeq (,$(findstring -j,$(MOZ_MAKE_FLAGS)))
+-  cores=$(shell $(PYTHON3) -c 'import multiprocessing; print(multiprocessing.cpu_count())')
++  cores=$(shell python3 -c 'import multiprocessing; print(multiprocessing.cpu_count())')
+   MOZ_MAKE_FLAGS += -j$(cores)
+ endif
+ 
++### Set up make flags
+ ifdef MOZ_AUTOMATION
+ ifeq (4.0,$(firstword $(sort 4.0 $(MAKE_VERSION))))
+ MOZ_MAKE_FLAGS += --output-sync=line
+ endif
+ endif
+ 
+ MOZ_MAKE = $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
+ 
+ # 'configure' scripts generated by autoconf.
+ CONFIGURES := $(TOPSRCDIR)/configure
+ CONFIGURES += $(TOPSRCDIR)/js/src/configure
+ 
+-#######################################################################
+-# Rules
+-
+-# The default rule is build
++### Rules
+ build::
+ 
+-ifndef MACH
+-$(error client.mk must be used via `mach`. Try running \
+-`./mach $(firstword $(MAKECMDGOALS) $(.DEFAULT_GOAL))`)
+-endif
+-
+ # In automation, manage an sccache daemon. The starting of the server
+ # needs to be in a make file so sccache inherits the jobserver.
+ ifdef MOZBUILD_MANAGE_SCCACHE_DAEMON
+ build::
+ 	# Terminate any sccache server that might still be around.
+ 	-$(MOZBUILD_MANAGE_SCCACHE_DAEMON) --stop-server > /dev/null 2>&1
+ 	# Start a new server, ensuring it gets the jobserver file descriptors
+ 	# from make (but don't use the + prefix when make -n is used, so that
+@@ -112,19 +88,17 @@ configure:: $(CONFIGURES)
+ 	@echo cd $(OBJDIR);
+ 	@echo $(CONFIGURE) $(CONFIGURE_ARGS)
+ 	@cd $(OBJDIR) && $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
+ 	  || ( echo '*** Fix above errors and then restart with\
+                "./mach build"' && exit 1 )
+ 	@touch $(OBJDIR)/Makefile
+ 	$(call BUILDSTATUS,TIER_FINISH configure)
+ 
+-####################################
+-# Build it
+-
++### Build it
+ build::
+ 	+$(MOZ_MAKE)
+ 
+ ifdef MOZ_AUTOMATION
+ build::
+ 	+$(MOZ_MAKE) automation/build
+ endif
+ 

+ 43 - 0
mozilla-release/patches/1683797-2-88a1.patch

@@ -0,0 +1,43 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1615301125 0
+# Node ID 697524537cc4d91ba6f65c4ff5886dcebb4cc238
+# Parent  34edec64f5b652975bdeea055c16ef89c854879f
+Bug 1683797: Removes redundant path parsing r=sheehan,firefox-build-system-reviewers,glandium
+
+We already know the project name, we should unbundle it
+from the project path.
+
+This change is possible due to the work in 1664083,
+and puts us back to the state before 1255185.
+
+Differential Revision: https://phabricator.services.mozilla.com/D106293
+
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -1028,21 +1028,19 @@ def include_project_configure(project, b
+ 
+     base_dir = build_env.topsrcdir
+     path = os.path.join(base_dir, project[0], 'moz.configure')
+     if not exists(path):
+         die('Cannot find project %s', project[0])
+     return path
+ 
+ 
+-@depends(include_project_configure, check_build_environment)
+-def build_project(include_project_configure, build_env):
+-    ret = os.path.dirname(os.path.relpath(include_project_configure,
+-                                          build_env.topsrcdir))
+-    return ret
++@depends("--enable-project")
++def build_project(project):
++    return project[0]
+ 
+ 
+ set_config('MOZ_BUILD_APP', build_project)
+ set_define('MOZ_BUILD_APP', build_project)
+ add_old_configure_assignment('MOZ_BUILD_APP', build_project)
+ 
+ 
+ # This is temporary until js/src/configure and configure are merged.

+ 64 - 0
mozilla-release/patches/1683797-4-88a1.patch

@@ -0,0 +1,64 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1615301126 0
+# Node ID 00d3fcc38474ba7152f280d79816b7312d605956
+# Parent  6056883293de31595fe94e03b374865f53cc8216
+Bug 1683797: Remove obsolete "build_targets" option from CI r=sheehan,releng-reviewers,jmaher
+
+Rusttests were the only remaining usage.
+
+Differential Revision: https://phabricator.services.mozilla.com/D106295
+
+diff --git a/testing/mozharness/mozharness/mozilla/building/buildbase.py.1683797.later b/testing/mozharness/mozharness/mozilla/building/buildbase.py.1683797.later
+new file mode 100644
+--- /dev/null
++++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py.1683797.later
+@@ -0,0 +1,23 @@
++--- buildbase.py
+++++ buildbase.py
++@@ -780,20 +780,16 @@ items from that key's value."
++         self._create_mozbuild_dir()
++         self._ensure_upload_path()
++ 
++     def build(self):
++         """builds application."""
++ 
++         args = ["build", "-v"]
++ 
++-        custom_build_targets = self.config.get("build_targets")
++-        if custom_build_targets:
++-            args += custom_build_targets
++-
++         # This will error on non-0 exit code.
++         self._run_mach_command_in_build_env(args)
++ 
++         self._generate_build_stats()
++ 
++     def static_analysis_autotest(self):
++         """Run mach static-analysis autotest, in order to make sure we dont regress"""
++         self.preflight_build()
+diff --git a/third_party/python/gyp/pylib/gyp/generator/analyzer.py b/third_party/python/gyp/pylib/gyp/generator/analyzer.py
+--- a/third_party/python/gyp/pylib/gyp/generator/analyzer.py
++++ b/third_party/python/gyp/pylib/gyp/generator/analyzer.py
+@@ -519,21 +519,16 @@ def _WriteOutput(params, **values):
+     print('Supplied targets that depend on changed files:')
+     for target in values['targets']:
+       print('\t', target)
+   if 'invalid_targets' in values:
+     values['invalid_targets'].sort()
+     print('The following targets were not found:')
+     for target in values['invalid_targets']:
+       print('\t', target)
+-  if 'build_targets' in values:
+-    values['build_targets'].sort()
+-    print('Targets that require a build:')
+-    for target in values['build_targets']:
+-      print('\t', target)
+   if 'compile_targets' in values:
+     values['compile_targets'].sort()
+     print('Targets that need to be built:')
+     for target in values['compile_targets']:
+       print('\t', target)
+   if 'test_targets' in values:
+     values['test_targets'].sort()
+     print('Test targets:')

+ 144 - 0
mozilla-release/patches/1716972-91a1.patch

@@ -0,0 +1,144 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1623923455 0
+# Node ID 79e9fb0fdfac5a0ef178d5c09161a5711e6fac5e
+# Parent  39b976c7b734a6a6706cb686b2faaffb2e35c7d8
+Bug 1716972 - Remove leftover from bug 1695773. r=firefox-build-system-reviewers,andi
+
+Differential Revision: https://phabricator.services.mozilla.com/D118153
+
+diff --git a/build/debian-packages/python-zstandard-buster.diff b/build/debian-packages/python-zstandard-buster.diff
+deleted file mode 100644
+--- a/build/debian-packages/python-zstandard-buster.diff
++++ /dev/null
+@@ -1,61 +0,0 @@
+-diff --git a/debian/changelog b/debian/changelog
+-index 84028db..d6c86c4 100644
+---- a/debian/changelog
+-+++ b/debian/changelog
+-@@ -1,3 +1,10 @@
+-+python-zstandard (0.15.2-1.deb10moz1) buster; urgency=low
+-+
+-+  * Mozilla backport for buster.
+-+  * Apply https://github.com/indygreg/python-zstandard/pull/139.
+-+
+-+ -- Mike Hommey <glandium@mozilla.com>  Fri, 12 Feb 2021 13:22:31 +0900
+-+
+- python-zstandard (0.15.0~dev0-1) unstable; urgency=low
+-
+-   * New version.
+-diff --git a/debian/control b/debian/control
+-index 1835727..f8a1a7c 100644
+---- a/debian/control
+-+++ b/debian/control
+-@@ -5,13 +5,9 @@ Priority: optional
+- Build-Depends:
+-   debhelper (>= 7),
+-   dh-python,
+--  python-all-dev,
+-   python3-all-dev,
+--  python-hypothesis,
+-   python3-hypothesis,
+--  python-pytest,
+-   python3-pytest,
+--  python-setuptools,
+-   python3-setuptools
+- Standards-Version: 3.9.1
+- X-Python3-Version: >= 3.5
+-@@ -19,17 +14,6 @@ Homepage: https://github.com/indygreg/python-zstandard
+- Vcs-Browser: https://github.com/indygreg/python-zstandard.git
+- Vcs-Git: https://github.com/indygreg/python-zstandard.git
+- 
+--Package: python-zstandard
+--Architecture: any
+--Depends:
+--  ${misc:Depends},
+--  ${python:Depends},
+--  ${shlibs:Depends}
+--Provides:
+-- ${python:Provides}
+--Description: Zstandard bindings for Python
+--  Python bindings to zstandard compression library.
+--
+- Package: python3-zstandard
+- Architecture: any
+- Depends:
+-diff --git a/debian/rules b/debian/rules
+-index 751826f..3a2c1b5 100755
+---- a/debian/rules
+-+++ b/debian/rules
+-@@ -6,4 +6,4 @@ export PYBUILD_NAME=zstandard
+- export PYBUILD_TEST_ARGS=-I fuzzing
+- 
+- %:
+--	dh $@ --parallel --with python2,python3 --buildsystem=pybuild
+-+	dh $@ --parallel --with python3 --buildsystem=pybuild
+diff --git a/build/debian-packages/python-zstandard-jessie.diff.1857492.later b/build/debian-packages/python-zstandard-jessie.diff.1857492.later
+new file mode 100644
+--- /dev/null
++++ b/build/debian-packages/python-zstandard-jessie.diff.1857492.later
+@@ -0,0 +1,64 @@
++--- python-zstandard-jessie.diff
+++++ python-zstandard-jessie.diff
++@@ -1,61 +0,0 @@
++-diff --git a/debian/changelog b/debian/changelog
++-index 84028db..d6c86c4 100644
++---- a/debian/changelog
++-+++ b/debian/changelog
++-@@ -1,3 +1,10 @@
++-+python-zstandard (0.15.2-1.deb8moz1) jessie; urgency=low
++-+
++-+  * Remove build dependencies so package builds on jessie.
++-+  * Apply https://github.com/indygreg/python-zstandard/pull/139.
++-+
++-+ -- Mike Hommey <glandium@mozilla.com>  Fri, 12 Feb 2021 13:22:31 +0900
++-+
++- python-zstandard (0.15.0~dev0-1) unstable; urgency=low
++-
++-   * New version.
++-diff --git a/debian/control b/debian/control
++-index 1835727..f8a1a7c 100644
++---- a/debian/control
++-+++ b/debian/control
++-@@ -5,13 +5,8 @@ Priority: optional
++- Build-Depends:
++-   debhelper (>= 7),
++-   dh-python,
++--  python-all-dev,
++-   python3-all-dev,
++--  python-hypothesis,
++--  python3-hypothesis,
++--  python-pytest,
++-   python3-pytest,
++--  python-setuptools,
++-   python3-setuptools
++- Standards-Version: 3.9.1
++- X-Python3-Version: >= 3.5
++-@@ -19,17 +14,6 @@ Homepage: https://github.com/indygreg/python-zstandard
++- Vcs-Browser: https://github.com/indygreg/python-zstandard.git
++- Vcs-Git: https://github.com/indygreg/python-zstandard.git
++- 
++--Package: python-zstandard
++--Architecture: any
++--Depends:
++--  ${misc:Depends},
++--  ${python:Depends},
++--  ${shlibs:Depends}
++--Provides:
++-- ${python:Provides}
++--Description: Zstandard bindings for Python
++--  Python bindings to zstandard compression library.
++--
++- Package: python3-zstandard
++- Architecture: any
++- Depends:
++-diff --git a/debian/rules b/debian/rules
++-index 751826f..3a2c1b5 100755
++---- a/debian/rules
++-+++ b/debian/rules
++-@@ -6,4 +6,4 @@ export PYBUILD_NAME=zstandard
++- export PYBUILD_TEST_ARGS=-I fuzzing
++- 
++- %:
++--	dh $@ --parallel --with python2,python3 --buildsystem=pybuild
++-+	dh $@ --parallel --with python3 --buildsystem=pybuild

+ 59 - 0
mozilla-release/patches/1722540-92a1.patch

@@ -0,0 +1,59 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1627515254 0
+# Node ID e1e0316f3b91ff0732512d384054865da10980a1
+# Parent  278f815cc8a2c56da106de1565717e2424f9f134
+Bug 1722540 - Fix `gyp.common.RelativePath`'s handling of case. r=firefox-build-system-reviewers,nalexander
+
+For some reason, it's not using os.path.relpath, but also doesn't handle
+case sensitivity correctly, which os.path.relpath does. However, it
+has some differences with os.path.relpath that need to be kept:
+- os.path.relpath throws an exception when both paths have a different
+drive letter.
+- os.path.relpath returns os.path.curdir when both paths are identical.
+- the follow_path_symlink flag is not supported by os.path.relpath.
+
+Differential Revision: https://phabricator.services.mozilla.com/D121145
+
+diff --git a/third_party/python/gyp/pylib/gyp/common.py b/third_party/python/gyp/pylib/gyp/common.py
+--- a/third_party/python/gyp/pylib/gyp/common.py
++++ b/third_party/python/gyp/pylib/gyp/common.py
+@@ -150,34 +150,22 @@ def RelativePath(path, relative_to, foll
+ 
+   # On Windows, we can't create a relative path to a different drive, so just
+   # use the absolute path.
+   if sys.platform == 'win32':
+     if (os.path.splitdrive(path)[0].lower() !=
+         os.path.splitdrive(relative_to)[0].lower()):
+       return path
+ 
+-  # Split the paths into components.
+-  path_split = path.split(os.path.sep)
+-  relative_to_split = relative_to.split(os.path.sep)
+-
+-  # Determine how much of the prefix the two paths share.
+-  prefix_len = len(os.path.commonprefix([path_split, relative_to_split]))
+-
+-  # Put enough ".." components to back up out of relative_to to the common
+-  # prefix, and then append the part of path_split after the common prefix.
+-  relative_split = [os.path.pardir] * (len(relative_to_split) - prefix_len) + \
+-                   path_split[prefix_len:]
+-
+-  if len(relative_split) == 0:
++  relative = os.path.relpath(path, relative_to)
++  if relative == os.path.curdir:
+     # The paths were the same.
+     return ''
+ 
+-  # Turn it back into a string and we're done.
+-  return os.path.join(*relative_split)
++  return relative
+ 
+ 
+ @memoize
+ def InvertRelativePath(path, toplevel_dir=None):
+   """Given a path like foo/bar that is relative to toplevel_dir, return
+   the inverse relative path back to the toplevel_dir.
+ 
+   E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path)))
+

+ 11 - 19
mozilla-release/patches/1728988-2-VS2022-gyp-25310.patch → mozilla-release/patches/1728988-2-VS2022-gyp-25320.patch

@@ -1,7 +1,7 @@
 # HG changeset patch
 # HG changeset patch
 # User Frank-Rainer Grahl <frgrahl@gmx.net>
 # User Frank-Rainer Grahl <frgrahl@gmx.net>
 # Date 1628946407 -7200
 # Date 1628946407 -7200
-# Parent  20043fc1a456c62d9065bc2e13b7d486f80085d2
+# Parent  ba35fdb92d57084d07affbbbab64bb2414229c98
 Bug 1728988 - Support VS2022 projects in gyp. r=IanN a=IanN
 Bug 1728988 - Support VS2022 projects in gyp. r=IanN a=IanN
 SeaMonkey release branch only.
 SeaMonkey release branch only.
 Just to get over possible compile errors for now.
 Just to get over possible compile errors for now.
@@ -9,24 +9,16 @@ Just to get over possible compile errors for now.
 diff --git a/third_party/python/gyp/pylib/gyp/MSVSVersion.py b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 diff --git a/third_party/python/gyp/pylib/gyp/MSVSVersion.py b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 --- a/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 --- a/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 +++ b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
 +++ b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
-@@ -255,16 +255,26 @@ def _CreateVersion(name, path, sdk_based
- 
-   Setup is based off the GYP_MSVS_VERSION environment variable or whatever is
-   autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
-   passed in that doesn't match a value in versions python will throw a error.
-   """
-   if path:
-     path = os.path.normpath(path)
-   versions = {
-+      '2022': VisualStudioVersion('2022',
-+                                  'Visual Studio 2022',
-+                                  solution_version='12.00',
-+                                  project_version='17.0',
-+                                  flat_sln=False,
-+                                  uses_vcxproj=True,
-+                                  path=path,
-+                                  sdk_based=sdk_based,
-+                                  default_toolset='v143',
+@@ -268,17 +268,17 @@ def _CreateVersion(name, path, sdk_based
+                                   'Visual Studio 2022',
+                                   solution_version='12.00',
+                                   project_version='17.0',
+                                   flat_sln=False,
+                                   uses_vcxproj=True,
+                                   path=path,
+                                   sdk_based=sdk_based,
+                                   default_toolset='v143',
+-                                  compatible_sdks=['v8.1', 'v10.0']),
 +                                  compatible_sdks=['v10.0']),
 +                                  compatible_sdks=['v10.0']),
        '2019': VisualStudioVersion('2019',
        '2019': VisualStudioVersion('2019',
                                    'Visual Studio 2019',
                                    'Visual Studio 2019',

+ 1070 - 0
mozilla-release/patches/1833379-115a1.patch

@@ -0,0 +1,1070 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1684303075 0
+# Node ID cb2b2e214902550af28ed8fdcf620add4e5d4df6
+# Parent  262196104100e2767433a1488935608e9a85d341
+Bug 1833379 - Update vendored gyp to c6d8b9f7ee355cff1531b0f369cd338a50baeb07. r=firefox-build-system-reviewers,andi
+
+It brings, among other things, support for MSVC 2022. It also fixes a
+number of issues we had local patches for, but we still need to apply
+the patches from bug 1628954 and bug 1722540.
+
+Differential Revision: https://phabricator.services.mozilla.com/D178240
+
+diff --git a/third_party/python/gyp/.travis.yml b/third_party/python/gyp/.travis.yml
+deleted file mode 100644
+--- a/third_party/python/gyp/.travis.yml
++++ /dev/null
+@@ -1,23 +0,0 @@
+-language: cpp
+-matrix:
+-  include:
+-    - os: linux
+-      compiler: clang
+-    - os: osx
+-      compiler: clang
+-    - python: 2.7
+-      language: python
+-      before_install: pip install flake8
+-      script: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
+-    - python: 3.7
+-      language: python
+-      before_install: pip install flake8
+-      script: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
+-      dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069)
+-
+-before_install: ./buildbot/travis-checkout.sh
+-script: ./buildbot/travis-test.sh
+-
+-branches:
+-  only:
+-  - master
+diff --git a/third_party/python/gyp/gyp b/third_party/python/gyp/gyp
+--- a/third_party/python/gyp/gyp
++++ b/third_party/python/gyp/gyp
+@@ -1,8 +1,13 @@
+ #!/bin/sh
+ # Copyright 2013 The Chromium Authors. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+-set -e
++set -eu
+ base=$(dirname "$0")
+-exec python "${base}/gyp_main.py" "$@"
++if type python3 >& /dev/null; then
++  python=python3
++else
++  python=python
++fi
++exec "${python}" "${base}/gyp_main.py" "$@"
+diff --git a/third_party/python/gyp/gyp_main.py b/third_party/python/gyp/gyp_main.py
+--- a/third_party/python/gyp/gyp_main.py
++++ b/third_party/python/gyp/gyp_main.py
+@@ -1,9 +1,9 @@
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ 
+ # Copyright (c) 2009 Google Inc. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ import os
+ import sys
+ 
+diff --git a/third_party/python/gyp/pylib/gyp/MSVSVersion.py b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
+--- a/third_party/python/gyp/pylib/gyp/MSVSVersion.py
++++ b/third_party/python/gyp/pylib/gyp/MSVSVersion.py
+@@ -12,16 +12,20 @@ import sys
+ import gyp
+ import glob
+ 
+ 
+ def JoinPath(*args):
+   return os.path.normpath(os.path.join(*args))
+ 
+ 
++def version_to_tuple(version_str):
++  return tuple(int(x) for x in version_str.split('.'))
++
++
+ class VisualStudioVersion(object):
+   """Information regarding a version of Visual Studio."""
+ 
+   def __init__(self, short_name, description,
+                solution_version, project_version, flat_sln, uses_vcxproj,
+                path, sdk_based, default_toolset=None, compatible_sdks=None):
+     self.short_name = short_name
+     self.description = description
+@@ -255,20 +259,30 @@ def _CreateVersion(name, path, sdk_based
+ 
+   Setup is based off the GYP_MSVS_VERSION environment variable or whatever is
+   autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is
+   passed in that doesn't match a value in versions python will throw a error.
+   """
+   if path:
+     path = os.path.normpath(path)
+   versions = {
++      '2022': VisualStudioVersion('2022',
++                                  'Visual Studio 2022',
++                                  solution_version='12.00',
++                                  project_version='17.0',
++                                  flat_sln=False,
++                                  uses_vcxproj=True,
++                                  path=path,
++                                  sdk_based=sdk_based,
++                                  default_toolset='v143',
++                                  compatible_sdks=['v8.1', 'v10.0']),
+       '2019': VisualStudioVersion('2019',
+                                   'Visual Studio 2019',
+                                   solution_version='12.00',
+-                                  project_version='15.0',
++                                  project_version='16.0',
+                                   flat_sln=False,
+                                   uses_vcxproj=True,
+                                   path=path,
+                                   sdk_based=sdk_based,
+                                   default_toolset='v141',
+                                   compatible_sdks=['v8.1', 'v10.0']),
+       '2017': VisualStudioVersion('2017',
+                                   'Visual Studio 2017',
+@@ -395,28 +409,40 @@ def _DetectVisualStudioVersions(versions
+     Possibilities are:
+       2005(e) - Visual Studio 2005 (8)
+       2008(e) - Visual Studio 2008 (9)
+       2010(e) - Visual Studio 2010 (10)
+       2012(e) - Visual Studio 2012 (11)
+       2013(e) - Visual Studio 2013 (12)
+       2015    - Visual Studio 2015 (14)
+       2017    - Visual Studio 2017 (15)
++      2019    - Visual Studio 2019 (16)
++      2022    - Visual Studio 2022 (17)
+     Where (e) is e for express editions of MSVS and blank otherwise.
+   """
+   version_to_year = {
+       '8.0': '2005',
+       '9.0': '2008',
+       '10.0': '2010',
+       '11.0': '2012',
+       '12.0': '2013',
+       '14.0': '2015',
+-      '15.0': '2017'
++      '15.0': '2017',
++      '16.0': '2019',
++      '17.0': '2022',
+   }
+   versions = []
++
++  # MSVC's vcvars*.bat scripts set up extra environment variables we can use:
++  # * path to the VS installation root, for example:
++  #   C:\Program Files\Microsoft Visual Studio\2022\Professional
++  env_vs_path = os.getenv('VSINSTALLDIR')
++  # * VS version, e.g. 17.0
++  env_vs_version = os.getenv('VisualStudioVersion')
++
+   for version in versions_to_check:
+     # Old method of searching for which VS version is installed
+     # We don't use the 2010-encouraged-way because we also want to get the
+     # path to the binaries, which it doesn't offer.
+     keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version,
+             r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version,
+             r'HKLM\Software\Microsoft\VCExpress\%s' % version,
+             r'HKLM\Software\Wow6432Node\Microsoft\VCExpress\%s' % version]
+@@ -443,51 +469,58 @@ def _DetectVisualStudioVersions(versions
+             r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7',
+             r'HKLM\Software\Microsoft\VisualStudio\SxS\VS7',
+             r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VS7']
+     for index in range(len(keys)):
+       path = _RegistryGetValue(keys[index], version)
+       if not path:
+         continue
+       path = _ConvertToCygpath(path)
+-      if version == '15.0':
+-          if os.path.exists(path):
+-              versions.append(_CreateVersion('2017', path))
++      if version_to_tuple(version) >= (15, 0):
++        if os.path.exists(path):
++          versions.append(_CreateVersion(version_to_year[version], path))
+       elif version != '14.0':  # There is no Express edition for 2015.
+         versions.append(_CreateVersion(version_to_year[version] + 'e',
+             os.path.join(path, '..'), sdk_based=True))
+ 
++    if env_vs_version and env_vs_path and env_vs_version == version:
++      versions.append(_CreateVersion(version_to_year[env_vs_version],
++                                     env_vs_path))
++
+   return versions
+ 
+ 
+ def SelectVisualStudioVersion(version='auto', allow_fallback=True):
+   """Select which version of Visual Studio projects to generate.
+ 
+   Arguments:
+     version: Hook to allow caller to force a particular version (vs auto).
+   Returns:
+     An object representing a visual studio project format version.
+   """
+   # In auto mode, check environment variable for override.
+   if version == 'auto':
+     version = os.environ.get('GYP_MSVS_VERSION', 'auto')
+   version_map = {
+-    'auto': ('15.0', '14.0', '12.0', '10.0', '9.0', '8.0', '11.0'),
++    'auto': ('17.0', '16.0', '15.0', '14.0', '12.0', '10.0', '9.0', '8.0',
++             '11.0'),
+     '2005': ('8.0',),
+     '2005e': ('8.0',),
+     '2008': ('9.0',),
+     '2008e': ('9.0',),
+     '2010': ('10.0',),
+     '2010e': ('10.0',),
+     '2012': ('11.0',),
+     '2012e': ('11.0',),
+     '2013': ('12.0',),
+     '2013e': ('12.0',),
+     '2015': ('14.0',),
+     '2017': ('15.0',),
++    '2019': ('16.0',),
++    '2022': ('17.0',),
+   }
+   override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH')
+   if override_path:
+     msvs_version = os.environ.get('GYP_MSVS_VERSION')
+     if not msvs_version:
+       raise ValueError('GYP_MSVS_OVERRIDE_PATH requires GYP_MSVS_VERSION to be '
+                        'set to a particular version (e.g. 2010e).')
+     return _CreateVersion(msvs_version, override_path, sdk_based=True)
+diff --git a/third_party/python/gyp/pylib/gyp/common.py b/third_party/python/gyp/pylib/gyp/common.py
+--- a/third_party/python/gyp/pylib/gyp/common.py
++++ b/third_party/python/gyp/pylib/gyp/common.py
+@@ -1,23 +1,23 @@
+ # Copyright (c) 2012 Google Inc. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ from __future__ import with_statement
+ 
+-import collections
+-import collections.abc
+ import errno
+ import filecmp
+ import os.path
+ import re
+ import tempfile
+ import sys
+ 
++from six.moves import collections_abc
++
+ 
+ # A minimal memoizing decorator. It'll blow up if the args aren't immutable,
+ # among other "problems".
+ class memoize(object):
+   def __init__(self, func):
+     self.func = func
+     self.cache = {}
+   def __call__(self, *args):
+@@ -478,17 +478,17 @@ def uniquer(seq, idfun=None):
+         marker = idfun(item)
+         if marker in seen: continue
+         seen[marker] = 1
+         result.append(item)
+     return result
+ 
+ 
+ # Based on http://code.activestate.com/recipes/576694/.
+-class OrderedSet(collections.abc.MutableSet):
++class OrderedSet(collections_abc.MutableSet):
+   def __init__(self, iterable=None):
+     self.end = end = []
+     end += [None, end, end]         # sentinel node for doubly linked list
+     self.map = {}                   # key --> [key, prev, next]
+     if iterable is not None:
+       self |= iterable
+ 
+   def __len__(self):
+diff --git a/third_party/python/gyp/pylib/gyp/easy_xml_test.py b/third_party/python/gyp/pylib/gyp/easy_xml_test.py
+--- a/third_party/python/gyp/pylib/gyp/easy_xml_test.py
++++ b/third_party/python/gyp/pylib/gyp/easy_xml_test.py
+@@ -76,31 +76,33 @@ class TestSequenceFunctions(unittest.Tes
+           '<RootNamespace>automated_ui_tests</RootNamespace>'
+         '</PropertyGroup>'
+         '<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props"/>'
+         '<PropertyGroup '
+             'Condition="\'$(Configuration)|$(Platform)\'=='
+                        '\'Debug|Win32\'" Label="Configuration">'
+           '<ConfigurationType>Application</ConfigurationType>'
+           '<CharacterSet>Unicode</CharacterSet>'
++          '<SpectreMitigation>SpectreLoadCF</SpectreMitigation>'
+         '</PropertyGroup>'
+       '</Project>')
+ 
+     xml = easy_xml.XmlToString(
+         ['Project',
+           ['PropertyGroup', {'Label': 'Globals'},
+             ['ProjectGuid', '{D2250C20-3A94-4FB9-AF73-11BC5B73884B}'],
+             ['Keyword', 'Win32Proj'],
+             ['RootNamespace', 'automated_ui_tests']
+           ],
+           ['Import', {'Project': '$(VCTargetsPath)\\Microsoft.Cpp.props'}],
+           ['PropertyGroup',
+             {'Condition': "'$(Configuration)|$(Platform)'=='Debug|Win32'",
+              'Label': 'Configuration'},
+             ['ConfigurationType', 'Application'],
+-            ['CharacterSet', 'Unicode']
++            ['CharacterSet', 'Unicode'],
++            ['SpectreMitigation', 'SpectreLoadCF']
+           ]
+         ])
+     self.assertEqual(xml, target)
+ 
+ 
+ if __name__ == '__main__':
+   unittest.main()
+diff --git a/third_party/python/gyp/pylib/gyp/generator/analyzer.py b/third_party/python/gyp/pylib/gyp/generator/analyzer.py
+--- a/third_party/python/gyp/pylib/gyp/generator/analyzer.py
++++ b/third_party/python/gyp/pylib/gyp/generator/analyzer.py
+@@ -519,16 +519,21 @@ def _WriteOutput(params, **values):
+     print('Supplied targets that depend on changed files:')
+     for target in values['targets']:
+       print('\t', target)
+   if 'invalid_targets' in values:
+     values['invalid_targets'].sort()
+     print('The following targets were not found:')
+     for target in values['invalid_targets']:
+       print('\t', target)
++  if 'build_targets' in values:
++    values['build_targets'].sort()
++    print('Targets that require a build:')
++    for target in values['build_targets']:
++      print('\t', target)
+   if 'compile_targets' in values:
+     values['compile_targets'].sort()
+     print('Targets that need to be built:')
+     for target in values['compile_targets']:
+       print('\t', target)
+   if 'test_targets' in values:
+     values['test_targets'].sort()
+     print('Test targets:')
+diff --git a/third_party/python/gyp/pylib/gyp/generator/msvs.py b/third_party/python/gyp/pylib/gyp/generator/msvs.py
+--- a/third_party/python/gyp/pylib/gyp/generator/msvs.py
++++ b/third_party/python/gyp/pylib/gyp/generator/msvs.py
+@@ -1,22 +1,22 @@
+ # Copyright (c) 2012 Google Inc. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ from __future__ import print_function
+ 
+-import collections
+ import copy
+ import ntpath
+ import os
+ import posixpath
+ import re
+ import subprocess
+ import sys
++import collections
+ 
+ import gyp.common
+ import gyp.easy_xml as easy_xml
+ import gyp.generator.ninja as ninja_generator
+ import gyp.MSVSNew as MSVSNew
+ import gyp.MSVSProject as MSVSProject
+ import gyp.MSVSSettings as MSVSSettings
+ import gyp.MSVSToolFile as MSVSToolFile
+@@ -2735,16 +2735,20 @@ def _GetMSBuildConfigurationDetails(spec
+   properties = {}
+   for name, settings in spec['configurations'].items():
+     msbuild_attributes = _GetMSBuildAttributes(spec, settings, build_file)
+     condition = _GetConfigurationCondition(name, settings)
+     character_set = msbuild_attributes.get('CharacterSet')
+     config_type = msbuild_attributes.get('ConfigurationType')
+     _AddConditionalProperty(properties, condition, 'ConfigurationType',
+                             config_type)
++    spectre_mitigation = msbuild_attributes.get('SpectreMitigation')
++    if spectre_mitigation:
++      _AddConditionalProperty(properties, condition, 'SpectreMitigation',
++                              spectre_mitigation)
+     if config_type == 'Driver':
+       _AddConditionalProperty(properties, condition, 'DriverType', 'WDM')
+       _AddConditionalProperty(properties, condition, 'TargetVersion',
+                               _ConfigTargetVersion(settings))
+     if character_set:
+       if 'msvs_enable_winrt' not in spec :
+         _AddConditionalProperty(properties, condition, 'CharacterSet',
+                                 character_set)
+@@ -2816,16 +2820,18 @@ def _ConvertMSVSBuildAttributes(spec, co
+       directory = MSVSSettings.ConvertVCMacrosToMSBuild(msvs_attributes[a])
+       if not directory.endswith('\\'):
+         directory += '\\'
+       msbuild_attributes[a] = directory
+     elif a == 'CharacterSet':
+       msbuild_attributes[a] = _ConvertMSVSCharacterSet(msvs_attributes[a])
+     elif a == 'ConfigurationType':
+       msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a])
++    elif a == 'SpectreMitigation':
++      msbuild_attributes[a] = msvs_attributes[a]
+     else:
+       print('Warning: Do not know how to convert MSVS attribute ' + a)
+   return msbuild_attributes
+ 
+ 
+ def _ConvertMSVSCharacterSet(char_set):
+   if char_set.isdigit():
+     char_set = {
+diff --git a/third_party/python/gyp/pylib/gyp/generator/ninja.py b/third_party/python/gyp/pylib/gyp/generator/ninja.py
+--- a/third_party/python/gyp/pylib/gyp/generator/ninja.py
++++ b/third_party/python/gyp/pylib/gyp/generator/ninja.py
+@@ -9,16 +9,17 @@ import copy
+ import hashlib
+ import json
+ import multiprocessing
+ import os.path
+ import re
+ import signal
+ import subprocess
+ import sys
++import six
+ import gyp
+ import gyp.common
+ from gyp.common import OrderedSet
+ import gyp.msvs_emulation
+ import gyp.MSVSUtil as MSVSUtil
+ import gyp.xcode_emulation
+ try:
+   from cStringIO import StringIO
+@@ -746,17 +747,17 @@ class NinjaWriter(object):
+             extra_bindings.append(('name', cygwin_munge(basename)))
+           else:
+             assert var == None, repr(var)
+ 
+         outputs = [self.GypPathToNinja(o, env) for o in outputs]
+         if self.flavor == 'win':
+           # WriteNewNinjaRule uses unique_name for creating an rsp file on win.
+           extra_bindings.append(('unique_name',
+-              hashlib.md5(outputs[0]).hexdigest()))
++              hashlib.md5(six.ensure_binary(outputs[0])).hexdigest()))
+ 
+         self.ninja.build(outputs, rule_name, self.GypPathToNinja(source),
+                          implicit=inputs,
+                          order_only=prebuild,
+                          variables=extra_bindings)
+ 
+         all_outputs.extend(outputs)
+ 
+diff --git a/third_party/python/gyp/pylib/gyp/msvs_emulation.py b/third_party/python/gyp/pylib/gyp/msvs_emulation.py
+--- a/third_party/python/gyp/pylib/gyp/msvs_emulation.py
++++ b/third_party/python/gyp/pylib/gyp/msvs_emulation.py
+@@ -2,25 +2,27 @@
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ This module helps emulate Visual Studio 2008 behavior on top of other
+ build systems, primarily ninja.
+ """
+ 
+-import collections
+ import os
+ import re
+ import subprocess
+ import sys
+ 
++from six.moves import collections_abc
++
+ from gyp.common import OrderedSet
+ import gyp.MSVSUtil
+ import gyp.MSVSVersion
++from gyp.MSVSVersion import version_to_tuple
+ 
+ try:
+   # basestring was removed in python3.
+   basestring
+ except NameError:
+   basestring = str
+ 
+ 
+@@ -32,19 +34,20 @@ def QuoteForRspFile(arg):
+   processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for
+   Windows programs)."""
+   # See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment
+   # threads. This is actually the quoting rules for CommandLineToArgvW, not
+   # for the shell, because the shell doesn't do anything in Windows. This
+   # works more or less because most programs (including the compiler, etc.)
+   # use that function to handle command line arguments.
+ 
+-  # Use a heuristic to try to find args that are paths, and normalize them
+-  if arg.find('/') > 0 or arg.count('/') > 1:
+-    arg = os.path.normpath(arg)
++  if not os.getenv('GYP_MSVS_DISABLE_PATH_NORMALIZATION'):
++    # Use a heuristic to try to find args that are paths, and normalize them
++    if arg.find('/') > 0 or arg.count('/') > 1:
++      arg = os.path.normpath(arg)
+ 
+   # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes
+   # preceding it, and results in n backslashes + the quote. So we substitute
+   # in 2* what we match, +1 more, plus the quote.
+   arg = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg)
+ 
+   # %'s also need to be doubled otherwise they're interpreted as batch
+   # positional arguments. Also make sure to escape the % so that they're
+@@ -86,43 +89,43 @@ def _GenericRetrieve(root, default, path
+     return root
+   return _GenericRetrieve(root.get(path[0]), default, path[1:])
+ 
+ 
+ def _AddPrefix(element, prefix):
+   """Add |prefix| to |element| or each subelement if element is iterable."""
+   if element is None:
+     return element
+-  if (isinstance(element, collections.abc.Iterable) and
++  if (isinstance(element, collections_abc.Iterable) and
+       not isinstance(element, basestring)):
+     return [prefix + e for e in element]
+   else:
+     return prefix + element
+ 
+ 
+ def _DoRemapping(element, map):
+   """If |element| then remap it through |map|. If |element| is iterable then
+   each item will be remapped. Any elements not found will be removed."""
+   if map is not None and element is not None:
+     if not callable(map):
+       map = map.get # Assume it's a dict, otherwise a callable to do the remap.
+-    if (isinstance(element, collections.abc.Iterable) and
++    if (isinstance(element, collections_abc.Iterable) and
+         not isinstance(element, basestring)):
+       element = filter(None, [map(elem) for elem in element])
+     else:
+       element = map(element)
+   return element
+ 
+ 
+ def _AppendOrReturn(append, element):
+   """If |append| is None, simply return |element|. If |append| is not None,
+   then add |element| to it, adding each item in |element| if it's a list or
+   tuple."""
+   if append is not None and element is not None:
+-    if (isinstance(element, collections.abc.Iterable) and
++    if (isinstance(element, collections_abc.Iterable) and
+         not isinstance(element, basestring)):
+       append.extend(element)
+     else:
+       append.append(element)
+   else:
+     return element
+ 
+ 
+@@ -133,17 +136,18 @@ def _FindDirectXInstallation():
+   # Return previously calculated value, if there is one
+   if hasattr(_FindDirectXInstallation, 'dxsdk_dir'):
+     return _FindDirectXInstallation.dxsdk_dir
+ 
+   dxsdk_dir = os.environ.get('DXSDK_DIR')
+   if not dxsdk_dir:
+     # Setup params to pass to and attempt to launch reg.exe.
+     cmd = ['reg.exe', 'query', r'HKLM\Software\Microsoft\DirectX', '/s']
+-    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
++    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
++                         universal_newlines=True)
+     for line in p.communicate()[0].splitlines():
+       if 'InstallPath' in line:
+         dxsdk_dir = line.split('    ')[3] + "\\"
+ 
+   # Cache return value
+   _FindDirectXInstallation.dxsdk_dir = dxsdk_dir
+   return dxsdk_dir
+ 
+@@ -316,17 +320,17 @@ class MsvsSettings(object):
+     return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86')
+ 
+   def _TargetConfig(self, config):
+     """Returns the target-specific configuration."""
+     # There's two levels of architecture/platform specification in VS. The
+     # first level is globally for the configuration (this is what we consider
+     # "the" config at the gyp level, which will be something like 'Debug' or
+     # 'Release'), VS2015 and later only use this level
+-    if self.vs_version.short_name >= 2015:
++    if int(self.vs_version.short_name) >= 2015:
+       return config
+     # and a second target-specific configuration, which is an
+     # override for the global one. |config| is remapped here to take into
+     # account the local target-specific overrides to the global configuration.
+     arch = self.GetArch(config)
+     if arch == 'x64' and not config.endswith('_x64'):
+       config += '_x64'
+     if arch == 'x86' and config.endswith('_x64'):
+@@ -480,17 +484,17 @@ class MsvsSettings(object):
+         map={'false': '-', 'true': ''}, prefix='/Zc:wchar_t')
+     cl('EnablePREfast', map={'true': '/analyze'})
+     cl('AdditionalOptions', prefix='')
+     cl('EnableEnhancedInstructionSet',
+         map={'1': 'SSE', '2': 'SSE2', '3': 'AVX', '4': 'IA32', '5': 'AVX2'},
+         prefix='/arch:')
+     cflags.extend(['/FI' + f for f in self._Setting(
+         ('VCCLCompilerTool', 'ForcedIncludeFiles'), config, default=[])])
+-    if self.vs_version.project_version >= 12.0:
++    if version_to_tuple(self.vs_version.project_version) >= (12, 0):
+       # New flag introduced in VS2013 (project version 12.0) Forces writes to
+       # the program database (PDB) to be serialized through MSPDBSRV.EXE.
+       # https://msdn.microsoft.com/en-us/library/dn502518.aspx
+       cflags.append('/FS')
+     # ninja handles parallelism by itself, don't have the compiler do it too.
+     cflags = [x for x in cflags if not x.startswith('/MP')]
+     return cflags
+ 
+@@ -1045,17 +1049,18 @@ def GenerateEnvironmentFiles(toplevel_bu
+     return cl_paths
+   vs = GetVSVersion(generator_flags)
+   cl_paths = {}
+   for arch in archs:
+     # Extract environment variables for subprocesses.
+     args = vs.SetupScript(arch)
+     args.extend(('&&', 'set'))
+     popen = subprocess.Popen(
+-        args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++        args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++        universal_newlines=True)
+     variables, _ = popen.communicate()
+     if popen.returncode != 0:
+       raise Exception('"%s" failed with error %d' % (args, popen.returncode))
+     env = _ExtractImportantEnvironment(variables)
+ 
+     # Inject system includes from gyp files into INCLUDE.
+     if system_includes:
+       system_includes = system_includes | OrderedSet(
+@@ -1066,17 +1071,18 @@ def GenerateEnvironmentFiles(toplevel_bu
+     f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'w')
+     f.write(env_block)
+     f.close()
+ 
+     # Find cl.exe location for this architecture.
+     args = vs.SetupScript(arch)
+     args.extend(('&&',
+       'for', '%i', 'in', '(cl.exe)', 'do', '@echo', 'LOC:%~$PATH:i'))
+-    popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE)
++    popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE,
++                             universal_newlines=True)
+     output, _ = popen.communicate()
+     cl_paths[arch] = _ExtractCLPath(output)
+   return cl_paths
+ 
+ def VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja):
+   """Emulate behavior of msvs_error_on_missing_sources present in the msvs
+   generator: Check that all regular source files, i.e. not created at run time,
+   exist on disk. Missing files cause needless recompilation when building via
+diff --git a/third_party/python/gyp/pylib/gyp/win_tool.py b/third_party/python/gyp/pylib/gyp/win_tool.py
+--- a/third_party/python/gyp/pylib/gyp/win_tool.py
++++ b/third_party/python/gyp/pylib/gyp/win_tool.py
+@@ -125,17 +125,18 @@ class WinTool(object):
+     # "On Unix with shell=True [...] if args is a sequence, the first item
+     # specifies the command string, and any additional items will be treated as
+     # additional arguments to the shell itself.  That is to say, Popen does the
+     # equivalent of:
+     #   Popen(['/bin/sh', '-c', args[0], args[1], ...])"
+     # For that reason, since going through the shell doesn't seem necessary on
+     # non-Windows don't do that there.
+     link = subprocess.Popen(args, shell=sys.platform == 'win32', env=env,
+-                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++                            universal_newlines=True)
+     out, _ = link.communicate()
+     for line in out.splitlines():
+       if (not line.startswith('   Creating library ') and
+           not line.startswith('Generating code') and
+           not line.startswith('Finished generating code')):
+         print(line)
+     return link.returncode
+ 
+@@ -192,18 +193,18 @@ class WinTool(object):
+           '-manifest %(out)s.manifest %(intermediate_manifest)s '
+           '-out:%(out)s.assert.manifest' % variables)
+       assert_manifest = '%(out)s.assert.manifest' % variables
+       our_manifest = '%(out)s.manifest' % variables
+       # Load and normalize the manifests. mt.exe sometimes removes whitespace,
+       # and sometimes doesn't unfortunately.
+       with open(our_manifest, 'r') as our_f:
+         with open(assert_manifest, 'r') as assert_f:
+-          our_data = our_f.read().translate(None, string.whitespace)
+-          assert_data = assert_f.read().translate(None, string.whitespace)
++          our_data = re.sub(r'\s+', '', our_f.read())
++          assert_data = re.sub(r'\s+', '', assert_f.read())
+       if our_data != assert_data:
+         os.unlink(out)
+         def dump(filename):
+           print(filename, file=sys.stderr)
+           print('-----', file=sys.stderr)
+           with open(filename, 'r') as f:
+             print(f.read(), file=sys.stderr)
+             print('-----', file=sys.stderr)
+@@ -218,17 +219,18 @@ class WinTool(object):
+         return 1
+ 
+   def ExecManifestWrapper(self, arch, *args):
+     """Run manifest tool with environment set. Strip out undesirable warning
+     (some XML blocks are recognized by the OS loader, but not the manifest
+     tool)."""
+     env = self._GetEnv(arch)
+     popen = subprocess.Popen(args, shell=True, env=env,
+-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++                             universal_newlines=True)
+     out, _ = popen.communicate()
+     for line in out.splitlines():
+       if line and 'manifest authoring warning 81010002' not in line:
+         print(line)
+     return popen.returncode
+ 
+   def ExecManifestToRc(self, arch, *args):
+     """Creates a resource file pointing a SxS assembly manifest.
+@@ -250,17 +252,18 @@ class WinTool(object):
+         '/tlb', tlb,
+         '/h', h,
+         '/dlldata', dlldata,
+         '/iid', iid,
+         '/proxy', proxy,
+         idl]
+     env = self._GetEnv(arch)
+     popen = subprocess.Popen(args, shell=True, env=env,
+-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++                             universal_newlines=True)
+     out, _ = popen.communicate()
+     # Filter junk out of stdout, and write filtered versions. Output we want
+     # to filter is pairs of lines that look like this:
+     # Processing C:\Program Files (x86)\Microsoft SDKs\...\include\objidl.idl
+     # objidl.idl
+     lines = out.splitlines()
+     prefixes = ('Processing ', '64 bit Processing ')
+     processing = set(os.path.basename(x)
+@@ -269,32 +272,34 @@ class WinTool(object):
+       if not line.startswith(prefixes) and line not in processing:
+         print(line)
+     return popen.returncode
+ 
+   def ExecAsmWrapper(self, arch, *args):
+     """Filter logo banner from invocations of asm.exe."""
+     env = self._GetEnv(arch)
+     popen = subprocess.Popen(args, shell=True, env=env,
+-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++                             universal_newlines=True)
+     out, _ = popen.communicate()
+     for line in out.splitlines():
+       if (not line.startswith('Copyright (C) Microsoft Corporation') and
+           not line.startswith('Microsoft (R) Macro Assembler') and
+           not line.startswith(' Assembling: ') and
+           line):
+         print(line)
+     return popen.returncode
+ 
+   def ExecRcWrapper(self, arch, *args):
+     """Filter logo banner from invocations of rc.exe. Older versions of RC
+     don't support the /nologo flag."""
+     env = self._GetEnv(arch)
+     popen = subprocess.Popen(args, shell=True, env=env,
+-                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
++                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
++                             universal_newlines=True)
+     out, _ = popen.communicate()
+     for line in out.splitlines():
+       if (not line.startswith('Microsoft (R) Windows (R) Resource Compiler') and
+           not line.startswith('Copyright (C) Microsoft Corporation') and
+           line):
+         print(line)
+     return popen.returncode
+ 
+diff --git a/third_party/python/gyp/pylib/gyp/xcode_emulation.py b/third_party/python/gyp/pylib/gyp/xcode_emulation.py
+--- a/third_party/python/gyp/pylib/gyp/xcode_emulation.py
++++ b/third_party/python/gyp/pylib/gyp/xcode_emulation.py
+@@ -721,16 +721,18 @@ class XcodeSettings(object):
+     if gc_policy == 'supported':
+       flags.append('-fobjc-gc')
+     elif gc_policy == 'required':
+       flags.append('-fobjc-gc-only')
+ 
+   def _AddObjectiveCARCFlags(self, flags):
+     if self._Test('CLANG_ENABLE_OBJC_ARC', 'YES', default='NO'):
+       flags.append('-fobjc-arc')
++    if self._Test('CLANG_ENABLE_OBJC_WEAK', 'YES', default='NO'):
++      flags.append('-fobjc-weak')
+ 
+   def _AddObjectiveCMissingPropertySynthesisFlags(self, flags):
+     if self._Test('CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS',
+                   'YES', default='NO'):
+       flags.append('-Wobjc-missing-property-synthesis')
+ 
+   def GetCflagsObjC(self, configname):
+     """Returns flags that need to be added to .m compilations."""
+diff --git a/third_party/python/gyp/test/lib/TestGyp.py b/third_party/python/gyp/test/lib/TestGyp.py
+--- a/third_party/python/gyp/test/lib/TestGyp.py
++++ b/third_party/python/gyp/test/lib/TestGyp.py
+@@ -2,28 +2,29 @@
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ TestGyp.py:  a testing framework for GYP integration tests.
+ """
+ from __future__ import print_function
+ 
+-import collections
+ import errno
+ import itertools
+ import os
+ import re
+ import shutil
+ import subprocess
+ import sys
+ import tempfile
+ 
+ from contextlib import contextmanager
+ 
++from six.moves import collections_abc
++
+ import TestCmd
+ import TestCommon
+ from TestCommon import __all__
+ 
+ __all__.extend([
+   'TestGyp',
+ ])
+ 
+@@ -491,17 +492,17 @@ class TestGypCMake(TestGypBase):
+     return self.run(program=self.build_tool, **kw)
+ 
+   def build(self, gyp_file, target=None, status=0, **kw):
+     # Two tools must be run to build, cmake and the ninja.
+     # Allow cmake to succeed when the overall expectation is to fail.
+     if status is None:
+       kw['status'] = None
+     else:
+-      if not isinstance(status, collections.Iterable): status = (status,)
++      if not isinstance(status, collections_abc.Iterable): status = (status,)
+       kw['status'] = list(itertools.chain((0,), status))
+     self.cmake_build(gyp_file, target, **kw)
+     kw['status'] = status
+     self.ninja_build(gyp_file, target, **kw)
+ 
+   def run_built_executable(self, name, *args, **kw):
+     # Enclosing the name in a list avoids prepending the original dir.
+     program = [self.built_file_path(name, type=self.EXECUTABLE, **kw)]
+diff --git a/third_party/python/gyp/test/mac/gyptest-objc-arc.py b/third_party/python/gyp/test/mac/gyptest-objc-arc.py
+--- a/third_party/python/gyp/test/mac/gyptest-objc-arc.py
++++ b/third_party/python/gyp/test/mac/gyptest-objc-arc.py
+@@ -16,11 +16,12 @@ if sys.platform == 'darwin':
+   # set |match| to ignore build stderr output.
+   test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode'],
+                          match = lambda a, b: True)
+ 
+   CHDIR = 'objc-arc'
+   test.run_gyp('test.gyp', chdir=CHDIR)
+ 
+   test.build('test.gyp', 'arc_enabled', chdir=CHDIR)
++  test.build('test.gyp', 'weak_enabled', chdir=CHDIR)
+   test.build('test.gyp', 'arc_disabled', chdir=CHDIR)
+ 
+   test.pass_test()
+diff --git a/third_party/python/gyp/test/mac/objc-arc/c-file.c b/third_party/python/gyp/test/mac/objc-arc/c-file.c
+--- a/third_party/python/gyp/test/mac/objc-arc/c-file.c
++++ b/third_party/python/gyp/test/mac/objc-arc/c-file.c
+@@ -1,6 +1,5 @@
+-#if __has_feature(objc_arc)
++#if __has_feature(objc_arc) || __has_feature(objc_arc_weak)
+ #error "C files shouldn't be ARC'd!"
+ #endif
+ 
+ void c_fun() {}
+-
+diff --git a/third_party/python/gyp/test/mac/objc-arc/cc-file.cc b/third_party/python/gyp/test/mac/objc-arc/cc-file.cc
+--- a/third_party/python/gyp/test/mac/objc-arc/cc-file.cc
++++ b/third_party/python/gyp/test/mac/objc-arc/cc-file.cc
+@@ -1,5 +1,5 @@
+-#if __has_feature(objc_arc)
++#if __has_feature(objc_arc) || __has_feature(objc_arc_weak)
+ #error "C++ files shouldn't be ARC'd!"
+ #endif
+ 
+ void cc_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m b/third_party/python/gyp/test/mac/objc-arc/m-file-arc-weak.m
+copy from third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m
+copy to third_party/python/gyp/test/mac/objc-arc/m-file-arc-weak.m
+--- a/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m
++++ b/third_party/python/gyp/test/mac/objc-arc/m-file-arc-weak.m
+@@ -1,5 +1,9 @@
+ #if __has_feature(objc_arc)
+ #error "ObjC files without CLANG_ENABLE_OBJC_ARC should not be ARC'd!"
+ #endif
+ 
++#if !__has_feature(objc_arc_weak)
++#error "With CLANG_ENABLE_OBJC_WEAK, weak references should be enabled."
++#endif
++
+ void m_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m b/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m
+--- a/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m
++++ b/third_party/python/gyp/test/mac/objc-arc/m-file-no-arc.m
+@@ -1,5 +1,9 @@
+ #if __has_feature(objc_arc)
+ #error "ObjC files without CLANG_ENABLE_OBJC_ARC should not be ARC'd!"
+ #endif
+ 
++#if __has_feature(objc_arc_weak)
++#error "Without CLANG_ENABLE_OBJC_WEAK, weak references should be disabled."
++#endif
++
+ void m_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/m-file.m b/third_party/python/gyp/test/mac/objc-arc/m-file.m
+--- a/third_party/python/gyp/test/mac/objc-arc/m-file.m
++++ b/third_party/python/gyp/test/mac/objc-arc/m-file.m
+@@ -1,5 +1,9 @@
+ #if !__has_feature(objc_arc)
+ #error "ObjC files with CLANG_ENABLE_OBJC_ARC should be ARC'd!"
+ #endif
+ 
++#if !__has_feature(objc_arc_weak)
++#error "Weak references should always be enabled for ARC."
++#endif
++
+ void m_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm b/third_party/python/gyp/test/mac/objc-arc/mm-file-arc-weak.mm
+copy from third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm
+copy to third_party/python/gyp/test/mac/objc-arc/mm-file-arc-weak.mm
+--- a/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm
++++ b/third_party/python/gyp/test/mac/objc-arc/mm-file-arc-weak.mm
+@@ -1,5 +1,9 @@
+ #if __has_feature(objc_arc)
+ #error "ObjC++ files without CLANG_ENABLE_OBJC_ARC should not be ARC'd!"
+ #endif
+ 
++#if !__has_feature(objc_arc_weak)
++#error "With CLANG_ENABLE_OBJC_WEAK, weak references should be enabled."
++#endif
++
+ void mm_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm b/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm
+--- a/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm
++++ b/third_party/python/gyp/test/mac/objc-arc/mm-file-no-arc.mm
+@@ -1,5 +1,9 @@
+ #if __has_feature(objc_arc)
+ #error "ObjC++ files without CLANG_ENABLE_OBJC_ARC should not be ARC'd!"
+ #endif
+ 
++#if __has_feature(objc_arc_weak)
++#error "Without CLANG_ENABLE_OBJC_WEAK, weak references should be disabled."
++#endif
++
+ void mm_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/mm-file.mm b/third_party/python/gyp/test/mac/objc-arc/mm-file.mm
+--- a/third_party/python/gyp/test/mac/objc-arc/mm-file.mm
++++ b/third_party/python/gyp/test/mac/objc-arc/mm-file.mm
+@@ -1,5 +1,9 @@
+ #if !__has_feature(objc_arc)
+ #error "ObjC++ files with CLANG_ENABLE_OBJC_ARC should be ARC'd!"
+ #endif
+ 
++#if !__has_feature(objc_arc_weak)
++#error "Weak references should always be enabled for ARC."
++#endif
++
+ void mm_fun() {}
+diff --git a/third_party/python/gyp/test/mac/objc-arc/test.gyp b/third_party/python/gyp/test/mac/objc-arc/test.gyp
+--- a/third_party/python/gyp/test/mac/objc-arc/test.gyp
++++ b/third_party/python/gyp/test/mac/objc-arc/test.gyp
+@@ -13,33 +13,41 @@
+       'type': 'static_library',
+       'sources': [
+         'c-file.c',
+         'cc-file.cc',
+         'm-file.m',
+         'mm-file.mm',
+       ],
+       'xcode_settings': {
+-        'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
+-        'MACOSX_DEPLOYMENT_TARGET': '10.6',
+-        'ARCHS': [ 'x86_64' ],  # For the non-fragile objc ABI.
+         'CLANG_ENABLE_OBJC_ARC': 'YES',
+       },
+     },
+ 
+     {
++      'target_name': 'weak_enabled',
++      'type': 'static_library',
++      'sources': [
++        'c-file.c',
++        'cc-file.cc',
++        'm-file-arc-weak.m',
++        'mm-file-arc-weak.mm',
++      ],
++      'xcode_settings': {
++        'CLANG_ENABLE_OBJC_WEAK': 'YES',
++      },
++    },
++
++    {
+       'target_name': 'arc_disabled',
+       'type': 'static_library',
+       'sources': [
+         'c-file.c',
+         'cc-file.cc',
+         'm-file-no-arc.m',
+         'mm-file-no-arc.mm',
+       ],
+       'xcode_settings': {
+-        'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
+-        'MACOSX_DEPLOYMENT_TARGET': '10.6',
+-        'ARCHS': [ 'x86_64' ],  # For the non-fragile objc ABI.
+       },
+     },
+   ],
+ }
+ 
+diff --git a/third_party/python/gyp/test/win/compiler-flags/spectre-mitigation.gyp b/third_party/python/gyp/test/win/compiler-flags/spectre-mitigation.gyp
+new file mode 100644
+--- /dev/null
++++ b/third_party/python/gyp/test/win/compiler-flags/spectre-mitigation.gyp
+@@ -0,0 +1,44 @@
++# Copyright (c) 2023 Google Inc. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++{
++ 'targets': [
++    {
++      'target_name': 'test_sm_notset',
++      'product_name': 'test_sm_notset',
++      'type': 'executable',
++      'msvs_configuration_attributes': {
++        'SpectreMitigation': 'false'
++      },
++      'sources': ['hello.cc'],
++    },
++    {
++      'target_name': 'test_sm_spectre',
++      'product_name': 'test_sm_spectre',
++      'type': 'executable',
++      'msvs_configuration_attributes': {
++        'SpectreMitigation': 'Spectre'
++      },
++      'sources': ['hello.cc'],
++    },
++    {
++      'target_name': 'test_sm_spectre_load',
++      'product_name': 'test_sm_spectre_load',
++      'type': 'executable',
++      'msvs_configuration_attributes': {
++        'SpectreMitigation': 'SpectreLoad'
++      },
++      'sources': ['hello.cc'],
++    },
++    {
++      'target_name': 'test_sm_spectre_load_cf',
++      'product_name': 'test_sm_spectre_load_cf',
++      'type': 'executable',
++      'msvs_configuration_attributes': {
++        'SpectreMitigation': 'SpectreLoadCF'
++      },
++      'sources': ['hello.cc'],
++    }
++  ]
++}
+

+ 9 - 2
mozilla-release/patches/series

@@ -7069,9 +7069,7 @@ NOBUG-20210216-9b29bb9d-87a1.patch
 1721370-92a1.patch
 1721370-92a1.patch
 1716613-92a1.patch
 1716613-92a1.patch
 1728996-httpbrotli-25310.patch
 1728996-httpbrotli-25310.patch
-1602259-2-VS2019-gyp-25310.patch
 1728988-1-VS2022-base-25310.patch
 1728988-1-VS2022-base-25310.patch
-1728988-2-VS2022-gyp-25310.patch
 1724107-7814.patch
 1724107-7814.patch
 1721107-7814.patch
 1721107-7814.patch
 1724101-7814.patch
 1724101-7814.patch
@@ -7618,5 +7616,14 @@ TOP-NOBUG-fixnasmcheck-25320.patch
 1902935-seamonkey-credits-25320.patch
 1902935-seamonkey-credits-25320.patch
 1862395-incorrect-version-resistfingerprinting-v2-25320.patch
 1862395-incorrect-version-resistfingerprinting-v2-25320.patch
 1737436-use-mozilla-compat-version-define-25320.patch
 1737436-use-mozilla-compat-version-define-25320.patch
+1664083-82a1.patch
+1683797-1-88a1.patch
+1683797-2-88a1.patch
+1683797-4-88a1.patch
+1716972-91a1.patch
+1722540-92a1.patch
 1715900-99a1.patch
 1715900-99a1.patch
+1833379-115a1.patch
+1602259-2-VS2019-gyp-25320.patch
+1728988-2-VS2022-gyp-25320.patch
 1857492-120a1.patch
 1857492-120a1.patch