Currently, many tasks fetch content from the Internets. A problem with
that is fetching from the Internets is unreliable: servers may have
outages or be slow; content may disappear or change out from under us.
The unreliability of 3rd party services poses a risk to Firefox CI.
If services aren't available, we could potentially not run some CI tasks.
In the worst case, we might not be able to release Firefox. That would
be bad. In fact, as I write this, gmplib.org has been unavailable for
~24 hours and Firefox CI is unable to retrieve the GMP source code.
As a result, building GCC toolchains is failing.
A solution to this is to make tasks more hermetic by depending on
fewer network services (which by definition aren't reliable over time
and therefore introduce instability).
This commit attempts to mitigate some external service dependencies
by introducing the *fetch* task kind.
The primary goal of the *fetch* kind is to obtain remote content and
re-expose it as a task artifact. By making external content available
as a cached task artifact, we allow dependent tasks to consume this
content without touching the service originally providing that
content, thus eliminating a run-time dependency and making tasks more
hermetic and reproducible over time.
We introduce a single "fetch-url" "using" flavor to define tasks that
fetch single URLs and then re-expose that URL as an artifact. Powering
this is a new, minimal "fetch" Docker image that contains a
"fetch-content" Python script that does the work for us.
We have added tasks to fetch source archives used to build the GCC
toolchains.
Fetching remote content and re-exposing it as an artifact is not
very useful by itself: the value is in having tasks use those
artifacts.
We introduce a taskgraph transform that allows tasks to define an
array of "fetches." Each entry corresponds to the name of a "fetch"
task kind. When present, the corresponding "fetch" task is added as a
dependency. And the task ID and artifact path from that "fetch" task
is added to the MOZ_FETCHES environment variable of the task depending
on it. Our "fetch-content" script has a "task-artifacts"
sub-command that tasks can execute to perform retrieval of all
artifacts listed in MOZ_FETCHES.
To prove all of this works, the code for fetching dependencies when
building GCC toolchains has been updated to use `fetch-content`. The
now-unused legacy code has been deleted.
This commit improves the reliability and efficiency of GCC toolchain
tasks. Dependencies now all come from task artifacts and should always
be available in the common case. In addition, `fetch-content` downloads
and extracts files concurrently. This makes it faster than the serial
application which we were previously using.
There are some things I don't like about this commit.
First, a new Docker image and Python script for downloading URLs feels
a bit heavyweight. The Docker image is definitely overkill as things
stand. I can eventually justify it because I want to implement support
for fetching and repackaging VCS repositories and for caching Debian
packages. These will require more packages than what I'm comfortable
installing on the base Debian image, therefore justifying a dedicated
image.
The `fetch-content static-url` sub-command could definitely be
implemented as a shell script. But Python is readily available and
is more pleasant to maintain than shell, so I wrote it in Python.
`fetch-content task-artifacts` is more advanced and writing it in
Python is more justified, IMO. FWIW, the script is Python 3 only,
which conveniently gives us access to `concurrent.futures`, which
facilitates concurrent download.
`fetch-content` also duplicates functionality found elsewhere.
generic-worker's task payload supports a "mounts" feature which
facilitates downloading remote content, including from a task
artifact. However, this feature doesn't exist on docker-worker.
So we have to implement downloading inside the task rather than
at the worker level. I concede that if all workers had generic-worker's
"mounts" feature and supported concurrent download, `fetch-content`
wouldn't need to exist.
`fetch-content` also duplicates functionality of
`mach artifact toolchain`. I probably could have used
`mach artifact toolchain` instead of writing
`fetch-content task-artifacts`. However, I didn't want to introduce
the requirement of a VCS checkout. `mach artifact toolchain` has its
origins in providing a feature to the build system. And "fetching
artifacts from tasks" is a more generic feature than that. I think
it should be implemented as a generic feature and not something that is
"toolchain" specific.
I think the best place for a generic "fetch content" feature is in
the worker, where content can be defined in the task payload. But as
explained above, that feature isn't universally available. The next
best place is probably run-task. run-task already performs generic,
very-early task preparation steps, such as performing a VCS checkout.
I would like to fold `fetch-content` into run-task and make it all
driven by environment variables. But run-task is currently Python 2
and achieving concurrency would involve a bit of programming (or
adding package dependencies). I may very well port run-task to Python
3 and then fold fetch-content into it. Or maybe we leave
`fetch-content` as a standalone script.
MozReview-Commit-ID: AGuTcwNcNJR
--HG--
extra : source : 0b941cbdca76fb2fbb98dc5bbc1a0237c69954d0
extra : histedit_source : a3e43bdd8a9a58550bef02fec3be832ca304ea93
After this change, we consistently import GPG keys from files in
the GCC build scripts.
MozReview-Commit-ID: BcyvCQoGbMS
--HG--
extra : source : 5fce34a460b51e45ac280a9f0cb8bad896fbcff1
extra : histedit_source : 01621ea8111315c251a9493a11efca72c2ba3c7d
Currently, many tasks fetch content from the Internets. A problem with
that is fetching from the Internets is unreliable: servers may have
outages or be slow; content may disappear or change out from under us.
The unreliability of 3rd party services poses a risk to Firefox CI.
If services aren't available, we could potentially not run some CI tasks.
In the worst case, we might not be able to release Firefox. That would
be bad. In fact, as I write this, gmplib.org has been unavailable for
~24 hours and Firefox CI is unable to retrieve the GMP source code.
As a result, building GCC toolchains is failing.
A solution to this is to make tasks more hermetic by depending on
fewer network services (which by definition aren't reliable over time
and therefore introduce instability).
This commit attempts to mitigate some external service dependencies
by introducing the *fetch* task kind.
The primary goal of the *fetch* kind is to obtain remote content and
re-expose it as a task artifact. By making external content available
as a cached task artifact, we allow dependent tasks to consume this
content without touching the service originally providing that
content, thus eliminating a run-time dependency and making tasks more
hermetic and reproducible over time.
We introduce a single "fetch-url" "using" flavor to define tasks that
fetch single URLs and then re-expose that URL as an artifact. Powering
this is a new, minimal "fetch" Docker image that contains a
"fetch-content" Python script that does the work for us.
We have added tasks to fetch source archives used to build the GCC
toolchains.
Fetching remote content and re-exposing it as an artifact is not
very useful by itself: the value is in having tasks use those
artifacts.
We introduce a taskgraph transform that allows tasks to define an
array of "fetches." Each entry corresponds to the name of a "fetch"
task kind. When present, the corresponding "fetch" task is added as a
dependency. And the task ID and artifact path from that "fetch" task
is added to the MOZ_FETCHES environment variable of the task depending
on it. Our "fetch-content" script has a "task-artifacts"
sub-command that tasks can execute to perform retrieval of all
artifacts listed in MOZ_FETCHES.
To prove all of this works, the code for fetching dependencies when
building GCC toolchains has been updated to use `fetch-content`. The
now-unused legacy code has been deleted.
This commit improves the reliability and efficiency of GCC toolchain
tasks. Dependencies now all come from task artifacts and should always
be available in the common case. In addition, `fetch-content` downloads
and extracts files concurrently. This makes it faster than the serial
application which we were previously using.
There are some things I don't like about this commit.
First, a new Docker image and Python script for downloading URLs feels
a bit heavyweight. The Docker image is definitely overkill as things
stand. I can eventually justify it because I want to implement support
for fetching and repackaging VCS repositories and for caching Debian
packages. These will require more packages than what I'm comfortable
installing on the base Debian image, therefore justifying a dedicated
image.
The `fetch-content static-url` sub-command could definitely be
implemented as a shell script. But Python is readily available and
is more pleasant to maintain than shell, so I wrote it in Python.
`fetch-content task-artifacts` is more advanced and writing it in
Python is more justified, IMO. FWIW, the script is Python 3 only,
which conveniently gives us access to `concurrent.futures`, which
facilitates concurrent download.
`fetch-content` also duplicates functionality found elsewhere.
generic-worker's task payload supports a "mounts" feature which
facilitates downloading remote content, including from a task
artifact. However, this feature doesn't exist on docker-worker.
So we have to implement downloading inside the task rather than
at the worker level. I concede that if all workers had generic-worker's
"mounts" feature and supported concurrent download, `fetch-content`
wouldn't need to exist.
`fetch-content` also duplicates functionality of
`mach artifact toolchain`. I probably could have used
`mach artifact toolchain` instead of writing
`fetch-content task-artifacts`. However, I didn't want to introduce
the requirement of a VCS checkout. `mach artifact toolchain` has its
origins in providing a feature to the build system. And "fetching
artifacts from tasks" is a more generic feature than that. I think
it should be implemented as a generic feature and not something that is
"toolchain" specific.
I think the best place for a generic "fetch content" feature is in
the worker, where content can be defined in the task payload. But as
explained above, that feature isn't universally available. The next
best place is probably run-task. run-task already performs generic,
very-early task preparation steps, such as performing a VCS checkout.
I would like to fold `fetch-content` into run-task and make it all
driven by environment variables. But run-task is currently Python 2
and achieving concurrency would involve a bit of programming (or
adding package dependencies). I may very well port run-task to Python
3 and then fold fetch-content into it. Or maybe we leave
`fetch-content` as a standalone script.
MozReview-Commit-ID: AGuTcwNcNJR
--HG--
extra : rebase_source : 4918b8c3bac53d63665006802054038bfbca0314
After this change, we consistently import GPG keys from files in
the GCC build scripts.
MozReview-Commit-ID: BcyvCQoGbMS
--HG--
extra : rebase_source : 657ccce8e242cabdfaff396fd0d6439754a3f364
This build target doesn't have LTO enabled on it (yet)
MozReview-Commit-ID: 56tAHMyvH7o
--HG--
extra : rebase_source : 90039cd8e97332e2ef8aad7908b8a04b2869f4a5
This relies on the fact that providing multiple --version-script
combines them all, so we effectively create a new symbol version
that has no global symbol, but hides the std:🧵:_M_start_thread
symbols.
This version script trick happens to work with BFD ld, gold, and lld.
The downside is that when providing multiple --version-script's, ld
doesn't want any of them to have no version at all. So for the libraries
that do already have a version script (through SYMBOLS_FILE), we use a
version where there used to be none, using the library name as the
version. Practically speaking, this binds the libraries a little closer
than they used to be, kind of non-flat namespace on OSX (which is the
default there), meaning the dynamic linker will actively want to use
symbols from those libraries instead of a system library that might
happen to have the same symbol name.
--HG--
extra : rebase_source : a7f672c35609d993849385ddb874ba791b34f929
Version 2.25.1's libiberty can choke on some symbols. That was fixed in
2.27. As of writing, the last version is 2.30. Conservatively go with
2.28.1, which is the same major version (2.28) as what is currently in
Debian stable.
--HG--
extra : rebase_source : 9e5ba94421a1568f662cfd98af7168ea1c890934
This relies on the fact that providing multiple --version-script
combines them all, so we effectively create a new symbol version
that has no global symbol, but hides as much std::* stuff as possible.
The added symbol script could use `extern "C++"` syntax and demangled
symbols but there is no guarantee the demangled symbols won't change.
Plus, it's not possible to match demangled symbols that have a return
type: they contain a space, and the only way to match that is to use
double quotes, which doesn't allow globs at the same time.
This version script trick happens to work with BFD ld, gold, and lld.
The downside is that when providing multiple --version-script's, ld
doesn't want any of them to have no version at all. So for the libraries
that do already have a version script (through SYMBOLS_FILE), we use a
version where there used to be none, using the library name as the
version. Practically speaking, this binds the libraries a little closer
than they used to be, kind of non-flat namespace on OSX (which is the
default there), meaning the dynamic linker will actively want to use
symbols from those libraries instead of a system library that might
happen to have the same symbol name.
--HG--
extra : rebase_source : 78adb64b90e75ebad203b8a647b305c9d7198d16
In the span of one week, both gmplib.org and multiprecision.org,
respective home of gmp and mpc have gone down. The latter is still down.
It turns out that all versions of gmp and mpfr we need are mirrored on
ftp.gnu.org, so we can just use that instead. For mpc, versions > 1.0
are on ftp.gnu.org, but not earlier versions.
The one mpc version <= 1.0 we do need is 0.8.2, and a copy of the exact
same archive, as per its sha256, which we're already checking per the
gcc build scripts, can be found on snapshot.debian.org. We lose gpg
validation on the way, but since we're already checking the sha256,
that's a fine tradeoff.
At least this unblocks changes to toolchains until multiprecision.org
comes back online.
--HG--
extra : rebase_source : f2bc67f8757655d99bfd9735b80d7205f7bfe47b
And adapt the build-gcc.sh script for the changes to
contrib/download_prerequisites.
--HG--
rename : taskcluster/scripts/misc/build-gcc-6-linux.sh => taskcluster/scripts/misc/build-gcc-7-linux.sh
extra : rebase_source : b1d785777b8c141c0eb0f52a73734abd2db21b94
The fedora project is migrating from pkgs.fedoraproject.org to
src.fedoraproject.org. We should use the newer URL, particularly because the
later has a globally trusted TLS certificate.
MozReview-Commit-ID: 7TducICRR0k
--HG--
extra : rebase_source : 88e58d064d1699e853527019200d6fbd4989d6b3
They were added in bug 1427344 to reduce the differences between builds
on CentOS docker images and builds on Debian docker images. We're now
entirely on Debian docker images, so we can back this out.
--HG--
extra : rebase_source : 672e389cb8d6dbf7860a989024690de18e5c320e
As of bug 1430036 it was only set when building on CentOS, and as of bug
1432398, we don't have CentOS-based docker images anymore.
--HG--
extra : rebase_source : 5ade9bee773bca3283cfdb9d69209033fe82253f
By default, wget prints dots every 1k bytes. This can render a
lot of output for large files. We switch to the "mega" style, which
makes each dot represent 64k, thus reducing output by up to 64x.
We also force the use of dot display. By default, it uses "bar"
which attempts to use terminal formatting if possible. Since most
of this code executes in CI and terminal control characters can
interfere with logged output, we force the use of "dot." (Although
wget appears to automatically switch to dot in TC today. But
consistency is good.)
MozReview-Commit-ID: IpTWJdcauTV
--HG--
extra : rebase_source : 5c9aa1bbdcd78eaa0b31347ad026a2c1beaedc03
Switching to Debian build images will force a version bump from
pulseaudio 0.9.something to pulseaudio 2.0. Practically speaking, as
long as bug 1427150 is fixed (which it is), this is strictly better,
because this enables all the PA_CHECK_VERSION(2,0,0) code in libcubeb,
which handles port availability (whether output is plugged or not), and
with bug 1427150, it does so in a backward compatible manner.
Now, since this is a behavior change from what we're currently shipping,
this has the potential of triggering unexpected test failures, or break
sound for users. The likelyhood of the latter happening is rather low,
though, because Linux distros have been building with pulseaudio >= 2.0
for a long time and we haven't heard about port availability breaking
sound for them. But it's still better to decouple this change from the
switch to Debian.
We abuse the build-gtk3.sh script which installs gtk3 in the CentOS
build image to install pulseaudio as well.
--HG--
extra : rebase_source : eb4e4033c50d59117b5199d1653d85f871503b2f
One of the last remaining differences when building Firefox on Debian
with all the changes we've done so far is that linking against the
system libc statically links some CRT objects. This causes massive
differences in the resulting binaries because of slight differences
in those objects (because they weren't compiled with the same compiler
and because they're not for the exact same glibc version)
In practice, their content difference don't cause any problem. If they
did, we wouldn't be able to run our builds on newer systems than those
we build them on. The only hypothetical risk would be to run on systems
with a glibc older than Debian 7's, but those already can't run Firefox
anyways (those systems don't have Gtk+3, which is a system requirement).
AFAICT, this is only an hypothetical problem anyways, even such systems
with Gtk+3 should be able to run those builds. Plus, this is a change
that will happen anyways when switching to Debian-based build images,
since they would be using the CRT objects from there. We're merely
making it happen earlier so that the differences from switching to
Debian-based build images are more tractable.
Note we only do this when building GCC on Debian, allowing to roll back
to CentOS-based toolchains by just switching back the toolchain jobs to
use the desktop-build docker image again.
When building on Debian (which we now are), this means we enable
.init_array/.fini_array.
When building on CentOS, this means no change. Which implies we could
roll back to CentOS-based toolchains by just switching back the
toolchain jobs to use the desktop-build docker image again.
This change causes massive differences in the resulting binaries because
of the offset differences, but practically speaking, there is no
difference. .init_array/.fini_array have been supported in glibc for 18
years.
Currently, the build can finish succesfully even when one of the
programs fails to build and is not included in the final artifact. The
macosx build then fails because of that, which is the wrong place to
be failing.
--HG--
extra : rebase_source : 4a41b2f96eea45d3eefa2734900603b6e6ee0ea5
The system binutils and gcc are built with that option on Debian, but
not on CentOS. That makes no practical difference, except for the fact
that when building GCC, we use our own-built binutils (as per bug
1427316), but use the system GCC. And a GCC built with --with-sysroot=/
doesn't work with a binutils built without. However, a GCC built without
--with-sysroot=/ works fine with a binutils built with it. So this
change is compatible with building our GCC on both CentOS and Debian.
We're currently building GCC with the system binutils, which, at the
moment, is whatever version is available on the CentOS 6 build
environments. With the imminent switch to Debian 7, that will be a
different version.
It turns out the GCC configure script does enable some features
depending on the binutils it's built with. For the most notable
differences it makes when going from Centos 6 to Debian, it enables
.init_array/.fini_array depending on the binutils version, and enables
the use of CFI advances depending on gas and objdump respectively
supporting and displaying DW_CFA_advance_loc.
But we're already building a fixed version of binutils (which happens to
be more recent than the one in both CentOS 6 and Debian 7), and we're
using that version when using GCC to build, so we can just as much use
the version we built to build GCC.
In order to avoid any changes to the resulting builds, we explicitly
turn off .init_array/.fini_array (which currently happens implicitly
when building on CentOS 6). This will ensure that there is not other
change to the builds due to this binutils version bump
(.init_array/.fini_array being enabled shifts everything in the
binaries, so it makes the whole diff full of noise)
mk_add_options has this kind of awkward feature where
mk_add_options VAR=value
would set VAR for the build through client.mk, but not when running
make -C objdir target. But
mk_add_options "export VAR=value"
does.
We might want to change that on the long run, but the side effects would
have to be calculated first.
OTOH, we have automation jobs that run compilations during `make check`
(e.g. rusttests), which is not invoked through client.mk. So they
currently don't get the same PATH as the build part, meaning that
they're using system binutils instead of the one from the GCC toolchain
package.
--HG--
extra : rebase_source : aab7f221243c486cf70c7b0c91b9313231050ed8
In bug 1426785, Gtk+3 build was moved to docker image creation time, and
at the same time, the removal of .la files was stripped, because it
seemed too broad to do that in /usr/local/lib*, and because I didn't
really remember why it was there in the first place.
I now do remember, and that's because libtool likes to add useless
dependencies on libraries just because direct dependencies transitively
depend on them. For example, this adds a dependency on libffi to
libpangocairo, which doesn't use it directly.
I also happens that /usr/local/lib* is empty at the moment we build
gtk3, so we can just do the cleanup there.
On its own, this change is useless, but:
- it restores the libraries in their state pre-bug 1426785,
- it helps reduce some differences when building on Debian (for bug
1399679), easing the comparison of those builds.
--HG--
extra : rebase_source : 3fa644d8ae5eb4ccac5940c7d3605201f589936d
It now only does something trivial, which also happens to be a no-op
because it's the default. It does have a commented entry for possible
gtk+2 builds, but we're soon going to remove that possibility anyways in
bug 1278282.
--HG--
extra : rebase_source : 9ac927bb7bd8c057264c8f6f9ca5cbf79a839c4e
Now that build environment docker images have gtk+3 installed in
/usr/local, adjust mozconfigs to point pkg-config there, and remove
all the glue that was required to build using the tooltool package.
Also remove the --x-libraries=/usr/lib on 32-bits builds, which only
confuses the linker.
--HG--
extra : rebase_source : c7de7b3959a3c6b77ea202d9609c891b5b7ec442
Back when we started needing gtk+3 to build Firefox, we were using mock
to setup the build environment, and a tooltool package was the most
sensible way to handle this.
Fast forward to today, and we're close to moving the build environment
to Debian, which comes with gtk+3 packages. But in order to simplify
the various checks for the transition, it is desirable to stop using the
tooltool package. Which we can actually do in a reasonable way now that
we use docker images instead of mock, by building and installing gtk+3
in the build environment images.
So we modify the script that was producing the gtk+3 tooltool packages
such that it installs gtk+3 in the docker images, both 32 and 64 bits.
And invoke it when creating the desktop build environment docker images.
--HG--
extra : rebase_source : 75e987d6de7f3ae8a3d9b478fc173e191d28aace
It now only does something trivial, which also happens to be a no-op
because it's the default. It does have a commented entry for possible
gtk+2 builds, but we're soon going to remove that possibility anyways in
bug 1278282.
--HG--
extra : rebase_source : 0de751e523ee002bbe6638d223eb384364edd22b
Now that build environment docker images have gtk+3 installed in
/usr/local, adjust mozconfigs to point pkg-config there, and remove
all the glue that was required to build using the tooltool package.
Also remove the --x-libraries=/usr/lib on 32-bits builds, which only
confuses the linker.
--HG--
extra : rebase_source : 22b1273ae4b78807b355d33ed5895bdfe83a141d