|
@@ -0,0 +1,514 @@
|
|
|
+# HG changeset patch
|
|
|
+# User Mike Shal <mshal@mozilla.com>
|
|
|
+# Date 1575594452 0
|
|
|
+# Node ID ad679d570e5283c1375791dc8b1f84f43e535ad4
|
|
|
+# Parent 33ee50767117992f2b72b1f737f4fcb890a43110
|
|
|
+Bug 1563403 - Use 3-tier PGO for local MOZ_PGO=1 builds; r=firefox-build-system-reviewers,dmajor,chmanchester
|
|
|
+
|
|
|
+Local PGO builds now use 3-tier machinery under the hood. Instead of a
|
|
|
+single object directory that gets cleaned in between the instrumented
|
|
|
+and profile-use builds, now the instrumented build uses a separate
|
|
|
+'${objdir}/instrumented' directory. This makes it easier to handle
|
|
|
+within mach since we can drive the two builds with environment variables
|
|
|
+and keep all build artifacts separate, without needing to do manual
|
|
|
+cleanup in between.
|
|
|
+
|
|
|
+Differential Revision: https://phabricator.services.mozilla.com/D50098
|
|
|
+
|
|
|
+diff --git a/Makefile.in b/Makefile.in
|
|
|
+--- a/Makefile.in
|
|
|
++++ b/Makefile.in
|
|
|
+@@ -122,21 +122,18 @@ endif
|
|
|
+ install-tests: install-test-files
|
|
|
+
|
|
|
+ .PHONY: install-test-files
|
|
|
+ install-test-files:
|
|
|
+ $(call py3_action,process_install_manifest,--track install__test_files.track _tests _build_manifests/install/_test_files)
|
|
|
+
|
|
|
+ include $(topsrcdir)/build/moz-automation.mk
|
|
|
+
|
|
|
+-# dist and _tests should be purged during cleaning. However, we don't want them
|
|
|
+-# purged during PGO builds because they contain some auto-generated files.
|
|
|
+-ifneq ($(filter-out maybe_clobber_profiledbuild,$(MAKECMDGOALS)),)
|
|
|
++# dist and _tests should be purged during cleaning.
|
|
|
+ GARBAGE_DIRS += dist _tests
|
|
|
+-endif
|
|
|
+
|
|
|
+ # Dummy rule for the cases below where we don't depend on dist/include
|
|
|
+ recurse_pre-export::
|
|
|
+
|
|
|
+ # Windows PGO builds don't perform a clean before the 2nd pass. So, we want
|
|
|
+ # to preserve content for the 2nd pass on Windows. Everywhere else, we always
|
|
|
+ # process the install manifests as part of export.
|
|
|
+ # For the binaries rule, not all the install manifests matter, so force only
|
|
|
+@@ -163,41 +160,16 @@ ifdef ENABLE_TESTS
|
|
|
+ # Additional makefile targets to call automated test suites
|
|
|
+ include $(topsrcdir)/testing/testsuite-targets.mk
|
|
|
+ endif
|
|
|
+ endif
|
|
|
+
|
|
|
+ default all::
|
|
|
+ $(call BUILDSTATUS,TIERS $(TIERS) $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS)))
|
|
|
+
|
|
|
+-# PGO build target.
|
|
|
+-profiledbuild::
|
|
|
+- $(call BUILDSTATUS,TIERS pgo_profile_generate pgo_package pgo_profile pgo_clobber pgo_profile_use)
|
|
|
+- $(call BUILDSTATUS,TIER_START pgo_profile_generate)
|
|
|
+- $(MAKE) default MOZ_PROFILE_GENERATE=1 MOZ_LTO=
|
|
|
+- $(call BUILDSTATUS,TIER_FINISH pgo_profile_generate)
|
|
|
+- $(call BUILDSTATUS,TIER_START pgo_package)
|
|
|
+- $(MAKE) package MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
|
|
|
+- rm -f jarlog/en-US.log
|
|
|
+- $(call BUILDSTATUS,TIER_FINISH pgo_package)
|
|
|
+- $(call BUILDSTATUS,TIER_START pgo_profile)
|
|
|
+- JARLOG_FILE=jarlog/en-US.log $(PYTHON) $(topsrcdir)/build/pgo/profileserver.py 10
|
|
|
+- $(call BUILDSTATUS,TIER_FINISH pgo_profile)
|
|
|
+- $(call BUILDSTATUS,TIER_START pgo_clobber)
|
|
|
+- $(MAKE) maybe_clobber_profiledbuild
|
|
|
+- $(call BUILDSTATUS,TIER_FINISH pgo_clobber)
|
|
|
+- $(call BUILDSTATUS,TIER_START pgo_profile_use)
|
|
|
+- $(MAKE) default MOZ_PROFILE_USE=1
|
|
|
+- $(call BUILDSTATUS,TIER_FINISH pgo_profile_use)
|
|
|
+-
|
|
|
+-# Change default target to PGO build if PGO is enabled.
|
|
|
+-ifdef MOZ_PGO
|
|
|
+-OVERRIDE_DEFAULT_GOAL := profiledbuild
|
|
|
+-endif
|
|
|
+-
|
|
|
+ include $(topsrcdir)/config/rules.mk
|
|
|
+
|
|
|
+ ifdef SCCACHE_VERBOSE_STATS
|
|
|
+ default::
|
|
|
+ -$(CCACHE) --show-stats --stats-format=json > sccache-stats.json
|
|
|
+ @echo "===SCCACHE STATS==="
|
|
|
+ -$(CCACHE) --show-stats
|
|
|
+ @echo "==================="
|
|
|
+@@ -252,41 +224,16 @@ endif
|
|
|
+ .PHONY: update-packaging
|
|
|
+ update-packaging:
|
|
|
+ $(MAKE) -C tools/update-packaging
|
|
|
+
|
|
|
+ .PHONY: package-generated-sources
|
|
|
+ package-generated-sources:
|
|
|
+ $(call py3_action,package_generated_sources,'$(DIST)/$(PKG_PATH)$(GENERATED_SOURCE_FILE_PACKAGE)')
|
|
|
+
|
|
|
+-#XXX: this is a hack, since we don't want to clobber for MSVC
|
|
|
+-# PGO support, but we can't do this test in client.mk
|
|
|
+-ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
|
|
|
+-# No point in clobbering if PGO has been explicitly disabled.
|
|
|
+-ifndef NO_PROFILE_GUIDED_OPTIMIZE
|
|
|
+-maybe_clobber_profiledbuild: clean
|
|
|
+-else
|
|
|
+-maybe_clobber_profiledbuild:
|
|
|
+-endif
|
|
|
+-else
|
|
|
+-ifdef CLANG_CL
|
|
|
+-maybe_clobber_profiledbuild: clean
|
|
|
+-# 32-bit PGO is currently blocked by bug 1479800
|
|
|
+-ifeq ($(CPU_ARCH),x86_64)
|
|
|
+- $(LLVM_PROFDATA) merge -o $(DEPTH)/merged.profdata $(DEPTH)/*.profraw
|
|
|
+-endif
|
|
|
+-else
|
|
|
+-maybe_clobber_profiledbuild:
|
|
|
+- $(RM) $(DIST)/bin/*.pgc
|
|
|
+- find $(DIST)/$(MOZ_APP_NAME) -name '*.pgc' -exec mv {} $(DIST)/bin \;
|
|
|
+-endif # CLANG_CL
|
|
|
+-endif
|
|
|
+-
|
|
|
+-.PHONY: maybe_clobber_profiledbuild
|
|
|
+-
|
|
|
+ # Look for R_386_PC32 relocations in shared libs, these
|
|
|
+ # break x86_64 builds and SELinux users.
|
|
|
+ ifeq ($(OS_TARGET)_$(TARGET_XPCOM_ABI),Linux_x86-gcc3)
|
|
|
+ check::
|
|
|
+ @relcount=`find $(DIST)/bin -name '*.so' | xargs objdump -R | grep R_386_PC32 | wc -l` && if test $$relcount -gt 0; then echo 'FAILED: R_386_PC32 relocations detected in a shared library. Did you use a system header without adding it to config/system-headers?'; exit 1; else echo 'PASSED'; fi
|
|
|
+ endif
|
|
|
+
|
|
|
+ ifdef JS_STANDALONE
|
|
|
+diff --git a/build/docs/pgo.rst b/build/docs/pgo.rst
|
|
|
+--- a/build/docs/pgo.rst
|
|
|
++++ b/build/docs/pgo.rst
|
|
|
+@@ -18,22 +18,11 @@ configure flags and then build. e.g. in
|
|
|
+ ac_add_options MOZ_PGO=1
|
|
|
+
|
|
|
+ Then::
|
|
|
+
|
|
|
+ $ ./mach build
|
|
|
+
|
|
|
+ This is roughly equivalent to::
|
|
|
+
|
|
|
+-#. Perform a build with *MOZ_PROFILE_GENERATE=1*
|
|
|
+-#. Performing a run of the instrumented binaries
|
|
|
+-#. $ make maybe_clobber_profiledbuild
|
|
|
+-#. Perform a build with *MOZ_PROFILE_USE=1*
|
|
|
+-
|
|
|
+-Differences between toolchains
|
|
|
+-==============================
|
|
|
+-
|
|
|
+-There are some implementation differences depending on the compiler
|
|
|
+-toolchain being used.
|
|
|
+-
|
|
|
+-The *maybe_clobber_profiledbuild* step gets its name because of a
|
|
|
+-difference. On Windows, this step merely moves some *.pgc* files around.
|
|
|
+-Using GCC or Clang, it is equivalent to a *make clean*.
|
|
|
++#. Perform a build with *--enable-profile-generate* in $topobjdir/instrumented
|
|
|
++#. Perform a run of the instrumented binaries with build/pgo/profileserver.py
|
|
|
++#. Perform a build with *--enable-profile-use* in $topobjdir
|
|
|
+diff --git a/build/moz.configure/lto-pgo.configure.1563403.later b/build/moz.configure/lto-pgo.configure.1563403.later
|
|
|
+new file mode 100644
|
|
|
+--- /dev/null
|
|
|
++++ b/build/moz.configure/lto-pgo.configure.1563403.later
|
|
|
+@@ -0,0 +1,54 @@
|
|
|
++--- lto-pgo.configure
|
|
|
+++++ lto-pgo.configure
|
|
|
++@@ -6,30 +6,32 @@
|
|
|
++
|
|
|
++ # PGO
|
|
|
++ # ==============================================================
|
|
|
++ llvm_profdata = check_prog('LLVM_PROFDATA', ['llvm-profdata'],
|
|
|
++ allow_missing=True,
|
|
|
++ paths=toolchain_search_path)
|
|
|
++
|
|
|
++ js_option('--enable-profile-generate',
|
|
|
+++ env='MOZ_PROFILE_GENERATE',
|
|
|
++ nargs='?',
|
|
|
++ choices=('cross',),
|
|
|
++ help='Build a PGO instrumented binary')
|
|
|
++
|
|
|
++ imply_option('MOZ_PGO',
|
|
|
++ depends_if('--enable-profile-generate')(lambda _: True))
|
|
|
++
|
|
|
++ set_config('MOZ_PROFILE_GENERATE',
|
|
|
++ depends_if('--enable-profile-generate')(lambda _: True))
|
|
|
++
|
|
|
++ set_define('MOZ_PROFILE_GENERATE',
|
|
|
++ depends_if('--enable-profile-generate')(lambda _: True))
|
|
|
++
|
|
|
++ js_option('--enable-profile-use',
|
|
|
+++ env='MOZ_PROFILE_USE',
|
|
|
++ nargs='?',
|
|
|
++ choices=('cross',),
|
|
|
++ help='Use a generated profile during the build')
|
|
|
++
|
|
|
++ js_option('--with-pgo-profile-path',
|
|
|
++ help='Path to the directory with unmerged profile data to use during the build',
|
|
|
++ nargs=1)
|
|
|
++
|
|
|
++@@ -46,17 +48,17 @@ set_config('MOZ_PROFILE_USE',
|
|
|
++ @depends('--with-pgo-profile-path', '--enable-profile-use', llvm_profdata, check_build_environment)
|
|
|
++ @imports('os')
|
|
|
++ def pgo_profile_path(path, pgo_use, profdata, build_env):
|
|
|
++ topobjdir = build_env.topobjdir
|
|
|
++ if topobjdir.endswith('/js/src'):
|
|
|
++ topobjdir = topobjdir[:-7]
|
|
|
++
|
|
|
++ if not path:
|
|
|
++- return os.path.join(topobjdir, 'merged.profdata')
|
|
|
+++ return os.path.join(topobjdir, 'instrumented', 'merged.profdata')
|
|
|
++ if path and not pgo_use:
|
|
|
++ die('Pass --enable-profile-use to use --with-pgo-profile-path.')
|
|
|
++ if path and not profdata:
|
|
|
++ die('LLVM_PROFDATA must be set to process the pgo profile.')
|
|
|
++ if not os.path.isfile(path[0]):
|
|
|
++ die('Argument to --with-pgo-profile-path must be a file.')
|
|
|
++ if not os.path.isabs(path[0]):
|
|
|
++ die('Argument to --with-pgo-profile-path must be an absolute path.')
|
|
|
+diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py
|
|
|
+--- a/build/pgo/profileserver.py
|
|
|
++++ b/build/pgo/profileserver.py
|
|
|
+@@ -33,16 +33,20 @@ if __name__ == '__main__':
|
|
|
+ docroot=os.path.join(build.topsrcdir, "build", "pgo"))
|
|
|
+ httpd.start(block=False)
|
|
|
+
|
|
|
+ locations = ServerLocations()
|
|
|
+ locations.add_host(host='127.0.0.1',
|
|
|
+ port=PORT,
|
|
|
+ options='primary,privileged')
|
|
|
+
|
|
|
++ old_profraw_files = glob.glob('*.profraw')
|
|
|
++ for f in old_profraw_files:
|
|
|
++ os.remove(f)
|
|
|
++
|
|
|
+ with TemporaryDirectory() as profilePath:
|
|
|
+ # TODO: refactor this into mozprofile
|
|
|
+ profile_data_dir = os.path.join(build.topsrcdir, 'testing', 'profiles')
|
|
|
+ with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh:
|
|
|
+ base_profiles = json.load(fh)['profileserver']
|
|
|
+
|
|
|
+ prefpaths = [os.path.join(profile_data_dir, profile, 'user.js')
|
|
|
+ for profile in base_profiles]
|
|
|
+@@ -79,16 +83,18 @@ if __name__ == '__main__':
|
|
|
+ % ret)
|
|
|
+ httpd.stop()
|
|
|
+ sys.exit(ret)
|
|
|
+
|
|
|
+ jarlog = os.getenv("JARLOG_FILE")
|
|
|
+ if jarlog:
|
|
|
+ env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog)
|
|
|
+ print("jarlog: %s" % env["MOZ_JAR_LOG_FILE"])
|
|
|
++ if os.path.exists(jarlog):
|
|
|
++ os.remove(jarlog)
|
|
|
+
|
|
|
+ cmdargs = ["http://localhost:%d/index.html" % PORT]
|
|
|
+ runner = FirefoxRunner(profile=profile,
|
|
|
+ binary=binary,
|
|
|
+ cmdargs=cmdargs,
|
|
|
+ env=env)
|
|
|
+ runner.start(debug_args=debug_args, interactive=interactive)
|
|
|
+ ret = runner.wait()
|
|
|
+diff --git a/python/mozbuild/mozbuild/build_commands.py b/python/mozbuild/mozbuild/build_commands.py
|
|
|
+--- a/python/mozbuild/mozbuild/build_commands.py
|
|
|
++++ b/python/mozbuild/mozbuild/build_commands.py
|
|
|
+@@ -1,24 +1,28 @@
|
|
|
+ # This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
+ # file, # You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
+
|
|
|
+ from __future__ import absolute_import, print_function, unicode_literals
|
|
|
+
|
|
|
+ import argparse
|
|
|
+ import os
|
|
|
++import subprocess
|
|
|
+
|
|
|
+ from mach.decorators import (
|
|
|
+ CommandArgument,
|
|
|
+ CommandProvider,
|
|
|
+ Command,
|
|
|
+ )
|
|
|
+
|
|
|
+ from mozbuild.base import MachCommandBase
|
|
|
++from mozbuild.util import ensure_subprocess_env
|
|
|
++from mozbuild.mozconfig import MozconfigLoader
|
|
|
++import mozpack.path as mozpath
|
|
|
+
|
|
|
+ from mozbuild.backend import (
|
|
|
+ backends,
|
|
|
+ )
|
|
|
+
|
|
|
+ BUILD_WHAT_HELP = '''
|
|
|
+ What to build. Can be a top-level make target or a relative directory. If
|
|
|
+ multiple options are provided, they will be built serially. Takes dependency
|
|
|
+@@ -68,25 +72,74 @@ class Build(MachCommandBase):
|
|
|
+ be rebuilding, perform a vanilla `mach build` to rebuild the world.
|
|
|
+ """
|
|
|
+ from mozbuild.controller.building import (
|
|
|
+ BuildDriver,
|
|
|
+ )
|
|
|
+
|
|
|
+ self.log_manager.enable_all_structured_loggers()
|
|
|
+
|
|
|
++ loader = MozconfigLoader(self.topsrcdir)
|
|
|
++ mozconfig = loader.read_mozconfig(loader.AUTODETECT)
|
|
|
++ doing_pgo = 'MOZ_PGO=1' in mozconfig['configure_args']
|
|
|
++ append_env = None
|
|
|
++
|
|
|
++ if doing_pgo:
|
|
|
++ if what:
|
|
|
++ raise Exception('Cannot specify targets (%s) in MOZ_PGO=1 builds' %
|
|
|
++ what)
|
|
|
++ instr = self._spawn(BuildDriver)
|
|
|
++ orig_topobjdir = instr._topobjdir
|
|
|
++ instr._topobjdir = mozpath.join(instr._topobjdir, 'instrumented')
|
|
|
++
|
|
|
++ append_env = {'MOZ_PROFILE_GENERATE': '1'}
|
|
|
++ status = instr.build(
|
|
|
++ what=what,
|
|
|
++ disable_extra_make_dependencies=disable_extra_make_dependencies,
|
|
|
++ jobs=jobs,
|
|
|
++ directory=directory,
|
|
|
++ verbose=verbose,
|
|
|
++ keep_going=keep_going,
|
|
|
++ mach_context=self._mach_context,
|
|
|
++ append_env=append_env)
|
|
|
++ if status != 0:
|
|
|
++ return status
|
|
|
++
|
|
|
++ # Packaging the instrumented build is required to get the jarlog
|
|
|
++ # data.
|
|
|
++ status = instr._run_make(
|
|
|
++ directory=".", target='package',
|
|
|
++ silent=not verbose, ensure_exit_code=False,
|
|
|
++ append_env=append_env)
|
|
|
++ if status != 0:
|
|
|
++ return status
|
|
|
++
|
|
|
++ pgo_env = os.environ.copy()
|
|
|
++ pgo_env['LLVM_PROFDATA'] = instr.config_environment.substs.get('LLVM_PROFDATA')
|
|
|
++ pgo_env['JARLOG_FILE'] = mozpath.join(orig_topobjdir, 'jarlog/en-US.log')
|
|
|
++ pgo_cmd = [
|
|
|
++ instr.virtualenv_manager.python_path,
|
|
|
++ mozpath.join(self.topsrcdir, 'build/pgo/profileserver.py'),
|
|
|
++ ]
|
|
|
++ subprocess.check_call(pgo_cmd, cwd=instr.topobjdir,
|
|
|
++ env=ensure_subprocess_env(pgo_env))
|
|
|
++
|
|
|
++ # Set the default build to MOZ_PROFILE_USE
|
|
|
++ append_env = {'MOZ_PROFILE_USE': '1'}
|
|
|
++
|
|
|
+ driver = self._spawn(BuildDriver)
|
|
|
+ return driver.build(
|
|
|
+ what=what,
|
|
|
+ disable_extra_make_dependencies=disable_extra_make_dependencies,
|
|
|
+ jobs=jobs,
|
|
|
+ directory=directory,
|
|
|
+ verbose=verbose,
|
|
|
+ keep_going=keep_going,
|
|
|
+- mach_context=self._mach_context)
|
|
|
++ mach_context=self._mach_context,
|
|
|
++ append_env=append_env)
|
|
|
+
|
|
|
+ @Command('configure', category='build',
|
|
|
+ description='Configure the tree (run configure and config.status).')
|
|
|
+ @CommandArgument('options', default=None, nargs=argparse.REMAINDER,
|
|
|
+ help='Configure options')
|
|
|
+ def configure(self, options=None, buildstatus_messages=False, line_handler=None):
|
|
|
+ from mozbuild.controller.building import (
|
|
|
+ BuildDriver,
|
|
|
+diff --git a/python/mozbuild/mozbuild/controller/building.py b/python/mozbuild/mozbuild/controller/building.py
|
|
|
+--- a/python/mozbuild/mozbuild/controller/building.py
|
|
|
++++ b/python/mozbuild/mozbuild/controller/building.py
|
|
|
+@@ -1069,17 +1069,18 @@ class CCacheStats(object):
|
|
|
+ class BuildDriver(MozbuildObject):
|
|
|
+ """Provides a high-level API for build actions."""
|
|
|
+
|
|
|
+ def __init__(self, *args, **kwargs):
|
|
|
+ MozbuildObject.__init__(self, *args, **kwargs)
|
|
|
+ self.mach_context = None
|
|
|
+
|
|
|
+ def build(self, what=None, disable_extra_make_dependencies=None, jobs=0,
|
|
|
+- directory=None, verbose=False, keep_going=False, mach_context=None):
|
|
|
++ directory=None, verbose=False, keep_going=False, mach_context=None,
|
|
|
++ append_env=None):
|
|
|
+ """Invoke the build backend.
|
|
|
+
|
|
|
+ ``what`` defines the thing to build. If not defined, the default
|
|
|
+ target is used.
|
|
|
+ """
|
|
|
+ self.mach_context = mach_context
|
|
|
+ warnings_path = self._get_state_filename('warnings.json')
|
|
|
+ monitor = self._spawn(BuildMonitor)
|
|
|
+@@ -1137,17 +1138,18 @@ class BuildDriver(MozbuildObject):
|
|
|
+ 'config_status_deps.in')):
|
|
|
+ if previous_backend and 'Make' not in previous_backend:
|
|
|
+ clobber_requested = self._clobber_configure()
|
|
|
+
|
|
|
+ if config is None:
|
|
|
+ print(" Config object not found by mach.")
|
|
|
+
|
|
|
+ config_rc = self.configure(buildstatus_messages=True,
|
|
|
+- line_handler=output.on_line)
|
|
|
++ line_handler=output.on_line,
|
|
|
++ append_env=append_env)
|
|
|
+
|
|
|
+ if config_rc != 0:
|
|
|
+ return config_rc
|
|
|
+
|
|
|
+ config = self.reload_config_environment()
|
|
|
+
|
|
|
+ if config.substs.get("MOZ_USING_CCACHE"):
|
|
|
+ ccache = config.substs.get("CCACHE")
|
|
|
+@@ -1236,34 +1238,36 @@ class BuildDriver(MozbuildObject):
|
|
|
+
|
|
|
+ # Build target pairs.
|
|
|
+ for make_dir, make_target in target_pairs:
|
|
|
+ # We don't display build status messages during partial
|
|
|
+ # tree builds because they aren't reliable there. This
|
|
|
+ # could potentially be fixed if the build monitor were more
|
|
|
+ # intelligent about encountering undefined state.
|
|
|
+ no_build_status = '1' if make_dir is not None else ''
|
|
|
++ tgt_env = dict(append_env or {})
|
|
|
++ tgt_env['NO_BUILDSTATUS_MESSAGES'] = no_build_status
|
|
|
+ status = self._run_make(
|
|
|
+ directory=make_dir, target=make_target,
|
|
|
+ line_handler=output.on_line, log=False, print_directory=False,
|
|
|
+ ensure_exit_code=False, num_jobs=jobs, silent=not verbose,
|
|
|
+- append_env={
|
|
|
+- b'NO_BUILDSTATUS_MESSAGES': no_build_status},
|
|
|
++ append_env=tgt_env,
|
|
|
+ keep_going=keep_going)
|
|
|
+
|
|
|
+ if status != 0:
|
|
|
+ break
|
|
|
+
|
|
|
+ elif status is None:
|
|
|
+ # If the backend doesn't specify a build() method, then just
|
|
|
+ # call client.mk directly.
|
|
|
+ status = self._run_client_mk(line_handler=output.on_line,
|
|
|
+ jobs=jobs,
|
|
|
+ verbose=verbose,
|
|
|
+- keep_going=keep_going)
|
|
|
++ keep_going=keep_going,
|
|
|
++ append_env=append_env)
|
|
|
+
|
|
|
+ self.log(logging.WARNING, 'warning_summary',
|
|
|
+ {'count': len(monitor.warnings_database)},
|
|
|
+ '{count} compiler warnings present.')
|
|
|
+
|
|
|
+ # Try to run the active build backend's post-build step, if possible.
|
|
|
+ try:
|
|
|
+ active_backend = config.substs.get('BUILD_BACKENDS', [None])[0]
|
|
|
+@@ -1416,34 +1420,35 @@ class BuildDriver(MozbuildObject):
|
|
|
+ except Exception:
|
|
|
+ # Ignore Exceptions in case we can't find config.status (such
|
|
|
+ # as when doing OSX Universal builds)
|
|
|
+ pass
|
|
|
+
|
|
|
+ return status
|
|
|
+
|
|
|
+ def configure(self, options=None, buildstatus_messages=False,
|
|
|
+- line_handler=None):
|
|
|
++ line_handler=None, append_env=None):
|
|
|
+ # Disable indexing in objdir because it is not necessary and can slow
|
|
|
+ # down builds.
|
|
|
+ mkdir(self.topobjdir, not_indexed=True)
|
|
|
+ self._write_mozconfig_json()
|
|
|
+
|
|
|
+ def on_line(line):
|
|
|
+ self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
|
|
|
+
|
|
|
+ line_handler = line_handler or on_line
|
|
|
+
|
|
|
+ options = ' '.join(shell_quote(o) for o in options or ())
|
|
|
+- append_env = {b'CONFIGURE_ARGS': options.encode('utf-8')}
|
|
|
++ append_env = dict(append_env or {})
|
|
|
++ append_env['CONFIGURE_ARGS'] = options
|
|
|
+
|
|
|
+ # Only print build status messages when we have an active
|
|
|
+ # monitor.
|
|
|
+ if not buildstatus_messages:
|
|
|
+- append_env['NO_BUILDSTATUS_MESSAGES'] = '1'
|
|
|
++ append_env['NO_BUILDSTATUS_MESSAGES'] = b'1'
|
|
|
+ status = self._run_client_mk(target='configure',
|
|
|
+ line_handler=line_handler,
|
|
|
+ append_env=append_env)
|
|
|
+
|
|
|
+ if not status:
|
|
|
+ print('Configure complete!')
|
|
|
+ print('Be sure to run |mach build| to pick up any changes')
|
|
|
+
|
|
|
+diff --git a/python/mozbuild/mozbuild/mozconfig.py b/python/mozbuild/mozbuild/mozconfig.py
|
|
|
+--- a/python/mozbuild/mozbuild/mozconfig.py
|
|
|
++++ b/python/mozbuild/mozbuild/mozconfig.py
|
|
|
+@@ -226,16 +226,22 @@ class MozconfigLoader(object):
|
|
|
+ name, value = match.group('var'), match.group('value')
|
|
|
+
|
|
|
+ if name == 'MOZ_MAKE_FLAGS':
|
|
|
+ result['make_flags'] = value.split()
|
|
|
+ continue
|
|
|
+
|
|
|
+ if name == 'MOZ_OBJDIR':
|
|
|
+ result['topobjdir'] = value
|
|
|
++ if parsed['env_before'].get('MOZ_PROFILE_GENERATE') == '1':
|
|
|
++ # If MOZ_OBJDIR is specified in the mozconfig, we need to
|
|
|
++ # make sure that the '/instrumented' directory gets appended
|
|
|
++ # for the first build to avoid an objdir mismatch when
|
|
|
++ # running 'mach package' on Windows.
|
|
|
++ result['topobjdir'] = mozpath.join(result['topobjdir'], 'instrumented')
|
|
|
+ continue
|
|
|
+
|
|
|
+ result['make_extra'].append(o)
|
|
|
+
|
|
|
+ return result
|
|
|
+
|
|
|
+ def _parse_loader_output(self, output):
|
|
|
+ mk_options = []
|