-
8. [Optional Quadruple-precision Support] Step 8:
cross-gcc
(libquadmath
) -
9. [Optional Fortran Support] Step 9:
cross-gcc
(libgfortran
)
-
The usage of ftpmirror for GNU packages is preferred.
-
We also try to use the smallest tarballs available from upstream (in order of preference):
- zst
- lz
- xz
- bzip2
- gz
Please don't change $MSYSROOT
to $CURDIR/toolchain/$XTARGET
like CLFS and
other implementations do because it'll break here (even if binutils
insists on
installing stuff to that directory).
-
All architectures require a static libgcc (aka
libgcc-static
) to be built beforemusl
. -
libgcc-static
won't be linked against any C library, and will suffice to to buildmusl
for these architectures. -
All listed archs were tested and are fully working!
- aarch64
- armv4t
- armv5te
- armv6
- armv6kz (Raspberry Pi 1 Models A, B, B+, the Compute Module, and the Raspberry Pi Zero)
- armv7
- i486
- i586
- i686
- m68k
- microblaze
- microblazeel
- mips64
- mips64el
- mipsisa64r6
- mipsisa64r6el
- or1k
- powerpc
- powerpcle
- powerpc64
- powerpc64le
- riscv64
- s390x
- sh2
- sh2be
- sh2-fdpic
- sh2be-fdpic
- sh4
- sh4be
- x86-64
We start by using the tools available on the host system. We then switch to ours when they're available.
-
The
--parallel
flag will use all available cores on the host system (3 * nproc
is being used instead of the traditional2 * nproc + 1
, since it ensures parallelism). -
It's also common to see
--enable-secureplt
added tocross-gcc
arguments when the target ispowerpc*
, but that's only the case to getmusl
to support 32-bitpowerpc
(as instructed bymusl
's wiki, along with--with-long-double-64
, which was replaced by--without-long-double-128
in recentgcc
versions). For 64-bitpowerpc
likepowerpc64
andpowerpc64le
, there's no need to explicitly specify it (This needs more investigation, but it works fine without it). -
XARCH
is the arch that we are supporting and the user chooses -
LARCH
is the arch that is supported by thelinux
kernel (found in$SRCDIR/linux/linux-$linux_ver/arch/
) -
MARCH
is the arch that is supported bymusl
(found in$SRCDIR/musl/musl-$musl_ver/arch/
) -
XTARGET
is the final target triplet
There's no such option as --with-float=hard
for this arch.
--enable-decimal-float
is the default on z9-ec and higher (e.g. z196).
-
The flags being used with
make
ensure that no documentation is being built, and it preventsbinutils
from requiringtexinfo
(binutils
looks formakeinfo
, and it fails if it doesn't find it, and the build stops). -
Also please don't use
MAKEINFO=false
(which is whatmusl-cross-make
does), becausebinutils
will still fail.
This is important as debugging will be easier knowing what the environmental variables are, and instead of assuming, the system can tell us by printing each of them to the log file.
Currently only gcc
is being patched to provide pure 64-bit support for 64-bit
architectures (this means that /lib/
will be used instead of /lib64/
, and
/lib32/
will be used instead of /lib/
).
-
We only want the headers to configure
gcc
... Also withmusl
installs, you almost always should use aDESTDIR
(this should be the equivalent of setting--with-sysroot
when configuringgcc
andbinutils
. -
We also need to pass
ARCH=$MARCH
andprefix=/usr
since we haven't configuredmusl
yet, to get the right versions ofmusl
headers for the target architecture.
-
Unlike
musl
,--prefix
for GNU stuff means where we expect them to be installed, so specifying it will save you the need to add aDESTDIR
when installingcross-binutils
. -
The
--target
specifies that we're cross compiling, andbinutils
tools will be prefixed by the value provided to it. There's no need to specify--build
and--host
asconfig.guess
andconfig.sub
are now smart enough to figure them in ALMOST all GNU packages (yup, I'm looking at yougcc
...). -
The use of
--disable-werror
is a necessity now, as the build will fail without it, or it may throw implicit-fallthrough warnings, among others (thanks to Aurelian). -
Notice how we specify a
--with-sysroot
here to tellbinutils
to consider the passed value as the root directory of our target system in which it'll search for target headers and libraries.
-
We manually track GCC's prerequisites instead of relying on
contrib/download_prerequisites
ingcc
's source tree. -
Again, what's mentioned in
cross-binutils
applies here. -
C++ language support is needed to successfully build
gcc
, sincegcc
has big chunks of its source code written in C++. -
LTO is not a default language, but is built by default because
--enable-lto
is enabled by default. -
If you want to use
zstd
as a backend for LTO, just add--with-zstd
below and make sure you havezstd
(orzstd-devel
or whatever it's called) installed on your host. -
Notice how we're not optimizing
libgcc-static
by passing-O0
to both theCFLAGS
andCXXFLAGS
as we're only usinglibgcc-static
to buildmusl
, then we rebuild it later on as a fulllibgcc-shared
.
-
We need a separate build directory for
musl
now that we have ourcross-gcc
ready. Using the same directory asmusl
headers without reconfiguringmusl
would break the ABI. -
musl
can be configured with a nonexistentlibgcc-static
(which is whatmusl-cross-make
does), but we're able to buildlibgcc.a
beforemusl
so it's considered existent here. (We can configuremusl
with a nonexistentlibgcc.a
then go back to$BLDDIR/cross-gcc
and buildlibgcc.a
, then come back to$BLDDIR/musl
and buildmusl
(which again is whatmusl-cross-make
does), but that's a lot of jumping, and we end up rebuildinglibgcc
later on as a shared version to be able to compile the rest ofgcc
libs, so why confuse ourselves...). -
We can specify
install-libs install-tools
instead ofinstall
(since we already have the headers installed (withinstall-headers above
)), but apparently theinstall
target automatically skips the headers if it found them already installed. -
Almost all implementations of
musl
based toolchains change the symlink between LDSO and the libc.so because it'll be wrong almost always...
-
After building
musl
, we need to rebuildlibgcc
but this time aslibgcc-shared
to be able to build the followinggcc
libs (libstdc++-v3
andlibgomp
which would complain about a missing-lgcc_s
and would error out withC compiler doesn't work
...). -
We need to run
make distclean
and not justmake clean
to make sure the leftovers from the building oflibgcc-static
are gone so we can buildlibgcc-shared
without having to restart the entire build just to buildlibgcc-shared
! -
We specify
enable_shared=yes
here which may not be needed but is highly recommended to ensure that this step results in a shared version oflibgcc
.
It's a good idea to leave the support for C++ enabled as many programs require
it (e.g. gcc
).
If you're planning on targeting a machine with two or more cores, then it might
be a good idea to enable support for OpenMP optimizations as well (beware as
some packages may fail to build with OpenMP enabled e.g. grub
).
If you're building a toolchain with Fortran support (or otherwise need or want support for quadruple-precision floating point arithmetic), you will want to enable support for libquadmath. This is enabled when building for Fortran by default.
If you're building Fortran support, mussel
will build gcc's implementation of
Fortran's standard library.
-
If you're planning on targeting a Linux system then it's a good idea to include support for Linux kernel headers as several packages require them.
-
We first perform a
mrproper
to ensure that our kernel source tree is clean. -
We won't be polluting our kernel source tree which is why we're specifying
O=$BLDDIR/linux
(which I believe may or may not be used since we're only installing the kernel header files and not actually building anything, but just to be safe...). -
The
headers_install
target requiresrsync
to be available (this is the default as of5.3
, it also performs additional cleaning on*.cmd
files which may require manual cleaning if we're manually copying the headers (in the case ofrsync
not being available, which isn't recommended)).
-
As of
gcc
10, the flag-fno-common
is now enabled by default, which in most cases is a good thing because it helps in performance but forpkgconf
it will result in breakage which is why we're passing-fcommon
instead. -
Since we're building our own
pkgconf
it should be able to run on where the toolchain will be hosted, and it will be built on the same machine that we used to build our toolchain, this makes--build
equal to--host
equal to the machine we're building everything on. There's no need to set--target
becausepkgconf
doesn't produce binaries or executables that can be run on a given target, hence the option is irrelevant here. You might also notice that since--build
is equal to--host
(which is mostlyx86_64-pc-linux-gnu
) then why aren't we using the host'spkg-config
orpkgconf
in the first place (since both ours and the host's will be compiled using the same toolchain installed on the host system), and we already answered that in theREADME.md
file (we can make use of the host'spkg-config
orpkgconf
by setting 3-5 environment variables that point to where we're storing our relevant.pc
files). The only advantage we have when building our ownpkg-config
orpkgconf
is that we can configure these options at compile time instead of relying on environment variables, and that's pretty much about it... -
It's also a good idea to symlink
pkg-config
topkgconf
.