00 Toolchain - Kakemixen/CrossLFS-nix GitHub Wiki
Toolchain
The toolchain is the set of programs used to build the finished program(s). A common problem is to isolate the toolchain from the programs on the host computer. Building stuff in nix fixes this problem, but that doesn't necessarily mean that this is easier.
Contents
The toolchain is more-or-less composed out of a compiler, a set of utils to manipoulate binaries, and a C library. In my case this is gcc, binutils, and musl. These are here built from source to set up a cross-compiling toolchain, which architectures to compile for is configured by simply setting the platforms when compiling the tools.
Platforms
Nix has three platforms defined in stdenv, which map diretly to the platforms as defined by gcc: buildPlatform, hostPlatform, and targetPlatform. Build and host is the easiest to understand, and also the ones used the most. The build platform is the system you build the software on, which is to be hosted on the host platform. You can also say the that the application is to be run on the host platform, as that's probably how most people think about it.
The target platform is the most confusing, but only relevant when building a program to generate other programs, like a compiler. It essentialy is the same as host for the build program, so host squared.
When specifying these in nix, and easy way is to just override the platforms you need from stdenv. Define the config and libc attributes, and use lib.systems.elaborate to fill in the other platform attrobutes.
The thing about platform that's special about nix is related to the gcc-wrapper
GCC-wrapper
When compiling in nix, things are a bit different. It is explained pretty well here, but also longer. Essentialy, the compiler and linker needs to find your headers and libraries, which is normally done by looking in /usr/include and /lib. Since there paths are not a part of the nix system, you need to tell these programs where to find things another way. This other way is the wrapper.
When wrapping the tools with wrapCCWith or wrapBintoolsWith, the platforms as defined in stdenv are looked up in order to figure out which prefixes on the binaries to use, among other things. It is necessary that this is correct according to what you actually compiled the programs with, in order for things to work together nicely.
Pitfalls
- Nix GCC wrapper by default adds several hardening flags. Of importance here is
-Wformat-security, as one cannot compile GCC with that flag.- the
hardeningDisablederivation property can remove such flags, allowing to compile the compiler.
- the
- Setting up the nix wrapper with
wrapCCWithdoesn't work properly if the platforms in the stdenv is not set properly.- the
overridefunctionality is nice here, so that we can usestdenvas a base. - Without the wrapper, finding the required output of previous derivation requires very hacky hacks.
- the
- Keeping in mind that one should be careful with subdirectories of
$out, it impacts the generated nix path.- E.g. only derivations with an
$out/includeare included in theNIX_CFLAGS_COMPILEenv-var, adding them to the include path.
- E.g. only derivations with an