When reading config.log, with old-configure output, we may get non-ascii
strings, but that currently fails because we're using plain open() to
read it. So use encoded_open() instead (which does the same job for
other files in the same script).
Because the build system can be encapsulated in mach, python configure
can have a pipe as stdout/stderr, and in that case, sys.stdout/stderr
have an ascii encoding, failing to print out anything that doesn't
fit in ascii, consequently failing to print the things we've read from
config.log. So reopen stdout and stderr with the right encoding in
the configure output handler.
This moves test installation for test files out of the monolithic install
manifest for $objdir/_tests, and determines the test and support files
to install based on the object derived from all-tests.json. Additionally,
the files resulting from TEST_HARNESS_FILES are installed, as some tests
will depend on them.
As a result, the time to install tests when invoking the test runner will
scale with the number of tests requested to run rather than the entire set
of tests in the tree, resulting in significantly less overhead.
MozReview-Commit-ID: LeIrUVh1yD4
This extracts the logic from the emitter that handles support files in ini
manifests to a seperate function in testing.py, so that this logic can be
re-used to determine how to install all the files necessary to run a particular
test fon the corresponding object in all-tests.json.
MozReview-Commit-ID: GSEhEGm09IL
DONTBUILD NPOTB
If the target triple is noisy, let's just accept -arm and -i386
instead of being strict. We can be more strict when things have
settled.
MozReview-Commit-ID: FDNJ3TuY51d
--HG--
extra : rebase_source : 3db70abe6818fbe0360406f20de899867232df02
extra : amend_source : d324c229b1713adb844407078d6cc4d00d84b56d
A few notes:
* This doesn't accommodate general OMNIJAR_NAME definitions. The
current name (assets/omni.ja) is baked into the product in a few
places, and is very unlikely to change, so we just error out if this
isn't true.
* This makes the package-manifest.in file authoritative for what goes
into assets/, libs/, and the APK root. Previously,
package-manifest.in wrote into assets/ and libs/ but
upload-files-APK.mk also had a convoluted DIST_FILES filtering
process to work through before a file actually made it into the APK.
* This is intentional about repackaging. It simplifies the repackage
step rather than trying to make unpackage-then-repackage the same as
just package. I pretty much never get repackaging correct the first
time; this should help. (I've manually tested it.)
* The ALREADY_SZIPPED during repackaging is subsumed by the previous
check if UNPACKAGE is set. The custom linker expects stored, not
deflated, libraries, so there's some small legwork to accommodate
that in mozjar.
MozReview-Commit-ID: JvVtIUSX685
--HG--
extra : rebase_source : fd8a9cfe3dc364d23b1065995db599f99e676e38
The initial goal of templates was to provide a way to write shorter
constructs for some generic tasks during configure. But the limitations
of the sandbox and the properties of templates made them used for more
general functions.
Consequently, this led to templates having to be available from
anywhere, which, in turn, led to difficult to introspect constructs.
With bug 1257823, we've made almost everything use set_config and
similar functions from the global scope, but we don't enforce that
those primitives are only used at the global scope.
This change does that: it enforces that primitives are only used at
the global scope. Or in templates.
Now, since templates were used for other purposes than generic uses
of other primitives, we now allow non-template functions to be declared.
Those can be used everywhere, but don't have access to the sandbox
primitives.
Currently, we have @advanced, that gives the decorated functions access
to all the builtins and consequently, to the import statement.
That is a quite broad approach and doesn't allow to easily introspect
what functions are importing which modules.
This change introduces a new decorator that allows to import modules one
by one into the decorated functions.
Note: by the end of the change series, @advanced will be gone.
So far, we've been using the lowercase of the variable name, but it's
not enough for some special cases. Those special cases could do their
own business, but then, they'd have to duplicate 90% of check_prog,
which is less desirable.
While DummyFunction is descriptive of what the instances are (and they
can't even be called), the various uses of isintance(obj, DummyFunction)
are kind of confusing, especially when they are in moz.configure land
(and this bug is about to add another one).
subprocess functions doesn't directly take file-like objects, so add a
minimalistic wrapper to do the right thing instead of subprocess.call
when given a file-like object.
And since the file is also used for old-configure, close our handle on
the file before spawning old-configure, and make old-configure append
there instead of truncating the file.
DMD currently uses a very hacky form of "sampling" by default to avoid
recording stack traces for all blocks. This makes DMD run faster than when it
records all stack traces.
This patch changes the sampling method used; in fact, it avoids "sampling" at
all. The existence of all heap blocks is now recorded exactly, but by default
we only record an allocation stack for each heap block if a Bernoulli trial
succeeds. This choice works well because getting the stack trace is ~100x
slower than recording the block's existence.
Overall, this approach is simpler and it also gives better output -- the choice
of which blocks to record allocation stacks for is mathematically sound, no
stack trace gets blamed for allocations it didn't do, and block counts and
sizes are now always exact.
Other specific things changed.
- All notion of sampling is removed from the various data structures.
- The --sample-below option is removed in favour of --stacks={partial,full}.
- The format of the JSON output file has changed.
- The names of various test files have changed to reflect concept changes.
--HG--
rename : memory/replace/dmd/test/full-empty-cumulative-expected.txt => memory/replace/dmd/test/complete-empty-cumulative-expected.txt
rename : memory/replace/dmd/test/full-empty-dark-matter-expected.txt => memory/replace/dmd/test/complete-empty-dark-matter-expected.txt
rename : memory/replace/dmd/test/full-empty-live-expected.txt => memory/replace/dmd/test/complete-empty-live-expected.txt
rename : memory/replace/dmd/test/full-unsampled1-dark-matter-expected.txt => memory/replace/dmd/test/complete-full1-dark-matter-expected.txt
rename : memory/replace/dmd/test/full-unsampled1-live-expected.txt => memory/replace/dmd/test/complete-full1-live-expected.txt
rename : memory/replace/dmd/test/full-unsampled2-cumulative-expected.txt => memory/replace/dmd/test/complete-full2-cumulative-expected.txt
rename : memory/replace/dmd/test/full-unsampled2-dark-matter-expected.txt => memory/replace/dmd/test/complete-full2-dark-matter-expected.txt
rename : memory/replace/dmd/test/full-sampled-live-expected.txt => memory/replace/dmd/test/complete-partial-live-expected.txt
extra : rebase_source : 47d287405dc5e9075f08addaba49e879c2c6e23f
Before, virtualenv.py may have attempted to use 3rd party
(untrusted) pip indices when installing wheels for pip,
setuptools, and wheel. These dependencies are vendored in
the tree for a reason. So don't let virtualenv contact the
outside world.
MozReview-Commit-ID: 6BCU0WegJO1
--HG--
extra : rebase_source : 6231235486e8cfa784e67e8b18004dd63d8aaf36
While we're addressing virtualenv foo, let's ensure we are running
the latest version. This also pulls in newer versions of pip (8.1.1),
setuptools (20.3), and wheel (0.29.0).
MozReview-Commit-ID: G5uSy66Kd6u
--HG--
extra : rebase_source : 804f230adcf77335c79a93537d9623ac3836d9bf
@depends functions are declared like the following:
@depends('--option', other_function, '--other-option', ...)
def ...
To simplify some of the processing related to those arguments it's
passed, keep a tuple of Option and DummyFunction objects corresponding
to those arguments.
For the same reasons as set_config is being moved to the global scope,
we're moving set_define to the global scope here. An additional change
is that set_define is now part of the sandbox itself instead of being
defined within the sandbox, which makes it share the implementation
details with set_config.
The way set_config is set currently makes it difficult to introspect
moz.configure files to know what configuration items are being set,
because they're hidden in the control flow of functions.
This makes some of the moz.configure more convoluted, but this is why
there are templates, and we can improve the recurring cases afterwards.
Currently, ConfigureSandbox._db stores two different kind of
information. This split those in two different instance variables
instead, making things clearer.
The way functions are being sandboxed in moz.configure land is that
their global namespace is being replaced with a limited and identifiable
dict. And we avoid re-wrapping a function that already received this
treatment.
The problem is that template functions have their global namespace
replaced, and any function that is defined within the template inherits
that global namespace. So when it comes time to wrap those functions
defined in templates with e.g. depends, we detect that they're already
wrapped although they are not, because we look if their global namespace
is of the recognizable type we use when replacing it.
So instead of looking at the global namespace type, keep track of all
functions that are wrapped.
Currently, if a @depends function doesn't have a return statement or
return None, a result is automatically set from all the set_config()
called from the function.
As we're going to move set_config to the global namespace, and as this
feature is only used once, and it's only used for something that was
written before ReadOnlyNamespace was exposed to the sandbox, we can
"safely" get rid of it.
This will be needed to teach artifact builds to extract files from
omni.ja files whose content is loaded into memory (from a tar
archive).
MozReview-Commit-ID: LH2HkKx5Zj3
--HG--
extra : rebase_source : 7f6b176f0ef9fc87889151d1d02da62de8a455d8
extra : source : 266928b5a7615fa054c70adf0f649cbb3f085e8d
This change adds a `Version` type to moz.configure which is a small
wrapper around `distutils.version.Version`. It's suitable for wrapping
version numbers in configure checks and doing equality or greater-than
less-than comparisons in a sensible way.
MozReview-Commit-ID: BOL6yvemulG
--HG--
extra : rebase_source : 3b463eac0499086f8acffda0d01418b6ab17f3d6
extra : amend_source : aebd6e40c408d9f868623b2f53fcdf7455e2fff5
In Python parens around an expression without a trailing comma is not a tuple,
so ('foo') == 'foo'. This is really easy to screw up with check_progs, which
coerces progs to a list and would give you ['f','o','o'] in this case. This
patch enforces that the progs argument is a tuple or list and errors if it
is not.
MozReview-Commit-ID: 7BJZuF9B8D5
--HG--
extra : rebase_source : 5db9a6b4bb9ef7195c2513407810093bff5e9174
extra : amend_source : f67ab46c2ac00a2a95cfc67e9763ac12b690ac14
If we add an ObjDirPath as an input to a GENERATED_FILES script, we
should run it in the misc tier to ensure the dependent files are created
beforehand. We need to use Path objects instead of raw filenames in the
GeneratedFile object so the recursive make backend can distinguish
between source and objdir files.
MozReview-Commit-ID: 9thHTi75zdI
While rare, this is something we support for e.g. --enable-eme, where it
can be either given with no values, "adobe", some future other EME GMP
adapter names, or a combination of them.
This will make it easier for binaries only archive generation to consult
the list of binaries that are relevant to packaging.
This does overlap somewhat with compile databases. Perhaps someday the
logic could converge.
While I was here, I cleaned up writing of the all-tests.json file to
avoid an intermediate string variable.
This patch adds to_dict methods on some frontend data types. There is
room to improve the serialization of these types. For example, we could
use __slots__ to drive the default formatter. We could also leverage a
custom JSONEncoder class that knows how to call to_dict() on instances.
In the spirit of perfect is the enemy of done, I think this should be
deferred to a follow-up bug.
MozReview-Commit-ID: XVnKB1MNqu
--HG--
extra : source : 4167dfdf10457360c9c94ee6e55b03ef1b92c16d
extra : histedit_source : 2f3f10bbb8ef9da8c57b0d85cbf4ea80242eff1a%2C1a5654253181d75eecd5dfaca2c87e353f8126cd
Now when we print instances in a debugger, we'll see something like:
<StaticLibrary: other-licenses/snappy/libother-licenses_snappy.a>
<StaticLibrary: toolkit/library/StaticXULComponentsEnd/libStaticXULComponentsEnd.a>
<SharedLibrary: toolkit/library/XUL>
<StaticLibrary: toolkit/library/libxul_s.a>
<HostProgram: config/nsinstall_real>
<Program: memory/replace/logalloc/replay/logalloc-replay>
<SimpleProgram: mfbt/tests/TestArrayUtils>
... instead of the the class name and memory address.
MozReview-Commit-ID: 8zdrM6KfP8U
--HG--
extra : source : 84849ad026c9ba1bbf71c93172b0a03440e51bec
This will make it easier for binaries only archive generation to consult
the list of binaries that are relevant to packaging.
This does overlap somewhat with compile databases. Perhaps someday the
logic could converge.
While I was here, I cleaned up writing of the all-tests.json file to
avoid an intermediate string variable.
This patch adds to_dict methods on some frontend data types. There is
room to improve the serialization of these types. For example, we could
use __slots__ to drive the default formatter. We could also leverage a
custom JSONEncoder class that knows how to call to_dict() on instances.
In the spirit of perfect is the enemy of done, I think this should be
deferred to a follow-up bug.
MozReview-Commit-ID: XVnKB1MNqu
--HG--
extra : rebase_source : 376c93467dde3450c7c21cff918cb34913a3c5fe
Now when we print instances in a debugger, we'll see something like:
<StaticLibrary: other-licenses/snappy/libother-licenses_snappy.a>
<StaticLibrary: toolkit/library/StaticXULComponentsEnd/libStaticXULComponentsEnd.a>
<SharedLibrary: toolkit/library/XUL>
<StaticLibrary: toolkit/library/libxul_s.a>
<HostProgram: config/nsinstall_real>
<Program: memory/replace/logalloc/replay/logalloc-replay>
<SimpleProgram: mfbt/tests/TestArrayUtils>
... instead of the the class name and memory address.
MozReview-Commit-ID: 8zdrM6KfP8U
--HG--
extra : rebase_source : 7f964ad44a0061674f77d5716a6769a4aedb9e6c
I'm not sure when this changed, but at least Visual Studio 2015
doesn't always emit a space between the line number and the ": warning"
text in cl.exe output.
Making the space optional in the regular expression enables one a
VS2015 build to capture 375 warnings instead of 17. We still fail to
capture some warnings (notably generic warnings about bad command
arguments and linker warnings). But that can be dealt with later.
MozReview-Commit-ID: q402CxTrQK
--HG--
extra : rebase_source : 6376a65b8d8145d68bad9b795b6abd6f4becefbd
Virtualenv will sometimes find a different executable from its sys.executable on OS X,
causing a check in the build system comparing filesizes between sys.executable and virtualenv
python to fail, resulting in clobbering and re-building the virtualenv every time the virtualenv
is activated, causing the build backend and more to be re-built.
Instead of checking file sizes directly, this commit causes us to record the size and version of the
Python executable that created the virtualenv. If the Python executable checked is not the virtualenv
Python, or we have a different version than was used to create the virtualenv, then the virtualenv is
considered to be out of date.
MozReview-Commit-ID: KmrVfQCtbS3
--HG--
extra : rebase_source : d2b87325e10da6dfcd74f8b0d2ef7c0efb71595b
Virtualenv will sometimes find a different executable from its sys.executable on OS X,
causing a check in the build system comparing filesizes between sys.executable and virtualenv
python to fail, resulting in clobbering and re-building the virtualenv every time the virtualenv
is activated, causing the build backend and more to be re-built.
Instead of checking file sizes directly, this commit causes us to record the size and path to the Python
executable that created the virtualenv. If the Python executable checked is not the virtualenv
Python, or the python that was used to create the interpreter, then the virtualenv is considered
to be out of date.
MozReview-Commit-ID: KmrVfQCtbS3
When writing e.g. Japanese text files on Windows, the text is encoded in
mbcs. So if a mozconfig is edited this way, and contains non ascii
characters, they won't be utf-8 as we're currently trying to decode
them, but mbcs.
This is currently preventing a command from having both args and subcommands at the same
time.
MozReview-Commit-ID: 66frAqamGjv
--HG--
extra : rebase_source : 3bbd1cb508e5aab7ba7f9936c0c486ed8f626fe9
This adds support for an SDK_FILES variable in moz.build, which creates
a FinalTargetFiles object to install files into dist/sdk/
MozReview-Commit-ID: 97a5NdbZmmD
--HG--
extra : rebase_source : ad8d521ec56fe4610437c8d2d503c545894b40c2
The changes made to PATH by activating the in-tree virtualenv cause some git-cinnabar commands
in subprocesses to fail, because git cinnabar is expecting mercurial to be installed, while it
is not available from the in-tree virtualenv. To work around this, the changes to PATH made by
virtualenv are undone, allowing git-cinnabar to find system python, which is likely to have
mercurial installed.
MozReview-Commit-ID: 47ceHvMmuyf
--HG--
extra : rebase_source : 199d3b01fc49b2760ee14a08d4400a1addf83eac
On a CLOSED TREE because DONTBUILD NPOTB
MozReview-Commit-ID: 56vyz2CRJsU
--HG--
extra : amend_source : 4ec60bc95019147225479c32b6982dc33c649cc4
extra : histedit_source : c3dc78da75a8f5b3985024a7d73ac92ab80628c2
This moves all the reading mozconfig, finding autoconf, refreshing the
old configure, and running the old configure into sandboxed
moz.configure. This effectively bootstraps the sandboxed python configure.
Generally speaking, the configuration needs forward-slashes in paths.
We might as well make it hard(er) to set configuration items with
backslash separators on Windows by exposing mozpath.* functions in place
of os.path functions. The downside is that functions explicitly
importing os will still get the real os.path functions.
The upcoming move of the configure.py initialization to sandboxed
moz.configure changes the path separators for topsrcdir and topobjdir
from native to always use forward-slashes, which confuses the hell out
of the test_base.py test. Settle the issue by declaring that
MozbuildObject will always use forward-slashed paths for topsrcdir
and topobjdir.
The nice side effect is that now we can have actual dicts for defines
and substs from the start, which simplifies so things, although it
requires adjustments to some unit tests.
Creating a .metadata_never_index file in a directory apparently
disables Spotlight indexing.
MozReview-Commit-ID: Di4DGZK6VOL
--HG--
extra : rebase_source : feffa0785174b11cf88a2b7ffdbd9aa5eeb98ac7
extra : amend_source : 838aca018ab91720b6b29b64b846a3ef107b6c88
Using ccache can have a big impact on compile times but we don't currently
capture ccache statistics.
MozReview-Commit-ID: CdrScyAh64I
--HG--
extra : rebase_source : 70dca7ae153ae1c7ce3a241820ab7d18cb6aaa0d
We need to consider CONFIGURE_SUBST_FILES as generated files when
processing FinalTargetFiles and related variables. Additionally, we have
to make sure that we actually recurse into such directories during the
export phase.
MozReview-Commit-ID: 6ZwHMzjoT6t
--HG--
extra : rebase_source : e39e26ad8b84bcaa757c56048c9c80f5be270d9c
The Windows content indexing service has been known to scan the objdir.
This can add significant system overhead and slow down builds or
subsequent operations. The objdir is meant to be a short-lived black box
and there really isn't a major benefit to indexing it.
There is a file attribute on Windows that disables content indexing.
This commit adds a utility function for creating a directory and
optionally disabling indexing on it. We call it at the top of
`mach build` to ensure the objdir as content indexing disabled.
MozReview-Commit-ID: 68gxCxbkVAN
--HG--
extra : rebase_source : 8e95d9b2923dccadbe54288bea25883937e2f004
We don't process IPDL and WebIDL files during artifact builds. The
backend shouldn't need to care about them.
Before: 2001 total backend files; 2001 created; 0 updated; 0 unchanged; 0 deleted
After: 1945 total backend files; 1945 created; 0 updated; 0 unchanged; 0 deleted
After this change, we no longer write any .cpp files to the objdir
during config.status for artifact builds.
As part of this, we stopped generated webidlsrcs.mk and the build broke
because of an unguarded use in a Makefile.
After this change, only 102/3366 files in the objdir after
`mach configure` are not a) in _virtualenv b) named backend.mk
c) named Makefile (~950 each of backend.mk and Makefile).
MozReview-Commit-ID: 11AIn1i4x4f
--HG--
extra : rebase_source : ac90bb9f6be8b7b986aa0a61b3ccc203a18346a6
I can't think of a good reason why unified C++ files need to exist
during artifact builds. Let's not write them in this build config.
Before: 2517 total backend files; 2517 created; 0 updated; 0 unchanged; 0 deleted
After: 2001 total backend files; 2001 created; 0 updated; 0 unchanged; 0 deleted
No measureable change in performance on Linux. But on Windows where file
creation is in the ~1ms range, this will surely result in a speedup of
several hundred milliseconds.
We are still generating some .cpp files during artifact builds. This will be
addressed in subsequent commits.
MozReview-Commit-ID: Lqx36YE8qZZ
--HG--
extra : rebase_source : 8af5a9915e78af7aee2aa335552689fe33975400
Future commits will add a number of consumers. This will cut down on
boilerplate.
MozReview-Commit-ID: 8h4VWBXXd8O
--HG--
extra : rebase_source : 3376f015f1766eedcef60e9393b6d68474ffb634
As previous measurements have shown, creating/appending files
on Windows/NTFS is slow because the CloseHandle() Win32 API takes
1-3ms to complete. This is apparently due to a fundamental issue
with NTFS extents. A way to work around this slowness is to use
multiple threads for I/O so file closing doesn't block execution
as much.
This commit updates the file copier to use a thread pool of 4
threads when processing file copies. Additional threads appear
to have diminishing returns.
On my i7-6700K, this reduces the time for processing the tests install
manifest (24,572 files) on Windows from ~22.0s to ~12.5s in the best
case.
Using the thread pool globally resulted in a performance regression
on Linux. Given the performance sensitivity of manifest copying,
I thought it best to implement a slightly redundant non-Windows
branch to preserve performance. For the record, that same machine
running Linux is capable of processing nearly the same install
manifest (24,616 files) in ~2.2s in the best case.
MozReview-Commit-ID: B9LbKaOoO1u
--HG--
extra : rebase_source : e9fee3861a70e1da9d18448f8435f4bd3e28c647
This adds a simple schema for build telemetry data. We can make it more
restrictive once we have a better feeling for what kind of data we want
to submit.
This also moves more common data about the system to the telemetry handler.
We leave psutil derivied information in the resource usage data as not every
system will have psutil installed.
MozReview-Commit-ID: CFRq1Ow6AOf
--HG--
extra : rebase_source : 3022d8f5d20e3d4f9dc871cf2217a6dad2f22e05
self._pushhead_cache no longer exists. But self._tree_cache does!
This was causing AttributeError when running `mach artifact clear-cache`
and other misc `mach artifact` sub-commands.
MozReview-Commit-ID: CP8NL6eCfhD
--HG--
extra : rebase_source : 0afd11722e304c8e0ecd9a305023d43dff79dddd
extra : amend_source : ad3df6d780e7b968573588e9a1029f1a1c9d18b0
Currently, config.status runs `mach artifact install`. mach commands prefix
output lines with elapsed time by default. When running from `mach build`,
there will be 2 sets of times in `mach artifact install` output lines.
When config.status is run directly, there will be no times printed
except for `mach artifact install`. It is weird both ways.
Fix it by not printing lines when running `mach artifact install` from
config.status.
MozReview-Commit-ID: GVinyI4Z0qr
--HG--
extra : rebase_source : 80aa5714a0249d9974becee183e7cfde7143f556
extra : amend_source : a89bca7af847f73efd18fb0a09bc9e76d8943577
Previously, we We were running version 2.5.1 of requests. Newer
versions have several bug fixes and even address a CVE.
Source was obtained from
https://pypi.python.org/packages/source/r/requests/requests-2.9.1.tar.gz
and checked in without modification. This should be a rubber stamp
review.
MozReview-Commit-ID: 9tFSVJFfwGh
--HG--
extra : rebase_source : 985a63b3e09d7abd5089bdb29ebef8d7314c59f2
Opt-in by adding --enable-gradle-mobile-android-builds.
Gradle dependencies (including the Android-Gradle plugin) are assumed
to be present. Local developers will fetch them from the jcentral
repository.
Android-specific Maven dependencies are shipped as "extras" with the
Android SDK, and should be found automatically by the Android-Gradle
plugin.
MozReview-Commit-ID: 966XgddWgEu
--HG--
extra : rebase_source : 8e8c6156e1d06813c250662e104fd14c621d91ab
extra : source : 306cf0271d3e3a344fcbfd2baf75e0450c288cf1
extra : histedit_source : d17446714236c408699a0953882e84ac3a192380%2Cc21b166af79ef1e00215748820bc2670405ac1dc
The moz.build data is now sufficient to, with some convolution, generate
the same compilation database that recursing the tree with the showbuild
target does.
The resulting code is not the prettiest, and exposes the shortcomings of
the current moz.build data model. It is however a first step towards
fixing those shortcomings, because they are now more clearly identified.
This was validated on all platforms on try by checking the output of
mach build-backend -b CompileDB -d -n
is empty when backing out the patch after running
mach build-backend -b CompileDB
once.
There are a few difficult directories to handle, with limited usefulness
compared to having the CompileDB properly filled for everything else
in a timely manner, so skip them for now.
The most common issue I'm hearing with eslint is people who have an outdated
node installed. This does a quick check to verify the version is high enough
before linting.
MozReview-Commit-ID: Em0jn18OUYo
--HG--
extra : rebase_source : 5325eb5f556f93e09d48fb123e0abb625aa77b84
This adds a substs field and cherrypicks the MOZ_ARTIFACT_BUILDS field so
we can determine whether or not an artifact build occurred.
MozReview-Commit-ID: 8aio8mP8pmR
--HG--
extra : rebase_source : aa0dc2b7ef61e8b02d202c3a631d276e019d3dfd