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.
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
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.
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)
Both the cc crate and the rust compiler may want to use "cc", which,
on automation, points to the system GCC compiler instead of ours.
As a workaround, we add a cc symbolic link in the GCC toolchain artifact
so that, as long as the GCC toolchain artifact's bin directory is in
$PATH early enough, it's picked over /usr/bin/cc.
The "contract" for toolchains is that extracting foo.tar.xz creates a
directory named foo/. That is however not true for mingw32.tar.xz, which
extracts into gcc/, possibly overwriting files from the gcc.tar.xz
archive (which is also used for mingw builds, for the host part).
This is also not true for nsis.tar.xz, but it reportedly has problems
when it's not in the same directory as mingw32.
But mingw32 doesn't actually need to be mixed with gcc, so it's better
to separate them as they are supposed to be.
It becomes a library of some sort, so that multiple scripts can benefit
from it to build different versions of GCC.
The GPG key associated with GCC is also refreshed from keys.gnupg.net,
adding a new subkey, used to sign newer versions of GCC (and
postprocessed with pgpstrip to make it smaller).
We can just check the GPG signature for the upstream tarballs that are
GPG signed. We keep a copy of the relevant GPG keys in tree so that
we only use a controlled set of keys.
I validated the GPG keys by:
- Creating a fresh keyring.
- Importing the keys with gpg --receive-key.
- Importing my own GPG public key in that keyring.
- Importing the gpg keys that the PGP pathfinder told me were on the path
to those keys (which weren't directly in their keyring, so I had to
manually find some steps first).
- Using `gpg --check-sigs` to validate that the all those keys I got are
the right ones.
Then the relevant GPG keys were exported with `gpg --export --armor` and
stripped with https://github.com/glandium/pgpstrip/.
For MPC, the first GPG-signed version upstream was 0.8.2, while the GCC
script to download prerequisites downloads 0.8.1. So instead of using
0.8.1, we use 0.8.2, which we can verify.
For GMP, the GCC script downloads 4.3.2. The only web-of-trust path is
through a revoked key, which signs a revoked uid of the GMP key.
Releases newer than 5.1.0 are signed with a new key that can be
validated with the steps above. So instead of using 4.3.2, we use 5.1.3
(last of the 5.1.x line).
But MPFR 2.4.2, which the GCC script downloads, doesn't build against
GMP 5.1.3, so instead of that, we use MPFR 3.1.5.
Sadly, the remaining GCC prerequisites are not signed, so I had to:
- Download the files from ftp.gnu.org.
- Download the corresponding files from snapshot.debian.org.
- Compare the raw files when possible, or the uncompressed (not extracted)
files (when, thankfully, they matched).
- Validate those snapshot.debian.org files checksums against the
checksums in the corresponding Sources.bz2/xz files.
- Validate the Sources.bz2/xz checksums against the corresponding InRelease
files.
- Validate the InRelease files GPG signatures against the Debian
archives keyring.
With all those things we actually don't get through the GCC script, we
also change how we get those prerequisites, by diverting the commands
the script runs and making it output the urls instead of downloading and
extracting the files.
All downloaded files, GPG-validated or otherwise, have their SHA-256
digest checked against a list in build/unix/build-gcc/checksums.
We build gcc after clang, and extract libgcc libraries and libstdc++
headers from gcc and place them in the clang installation directory in a
way that clang favors before it searches the system for libraries and
includes.