Contents

edit New in all-packages.nix

The main nix packages expression has a parameter setting the information for the cross-compilation target. When set, this will allow us to cross-build:

... , crossSystem ? null, ...

This crossSystem should be an attribute set with enough information about the target. Therefore it cannot be passed through "--argstr crossSystem mytarget", and it should be written in a nix file apart. For example, we can use this 'comtrend.nix':

import ./default.nix   # The root nixpkgs default.nix
{
  crossSystem = {
    config = "mips-unknown-linux";
    bigEndian = true;
    arch = "mips";
    float = "soft";
    withTLS = true;
    libc = "uclibc";
    platform = {
      name = "comtrend";
      kernelMajor = "2.6";
      kernelBaseConfig = "bcm63xx_defconfig";
      kernelHeadersBaseConfig = "bcm63xx_defconfig";
      uboot = null;
      kernelArch = "mips";
      kernelAutoModules = false;
      kernelTarget = "vmlinux.bin";
    };
    openssl.system = "linux-generic32";
    gcc = {
      arch = "mips32";
    };
  };
}

For more options available, you can check the relevant nix expressions involved in the build you want.

Some 'platforms' are defined in nixpkgs already (check the all-packages.nix and platform.nix files there). Hydra cross-builds some packages, to test the cross-building expressions. And you can look at some crossSystem expressions in my configurations directory.

edit New stdenv.mkDerivation

edit New derivations

The attribute set resulting from a stdenv.mkDerivation call returns the usual result comming from a usual native build, with two additional attributes:

  • hostDrv - the derivation cross-built
  • buildDrv - the derivation built in for the build system (a usual native build).

Thus, these calls equivalently build the native derivation for 'bison' (mentioning the 'comtrend.nix' above):

nix-build -A bison default.nix
nix-build -A bison comtrend.nix
nix-build -A bison.buildDrv comtrend.nix

If we want to cross-build bison for the arm target described above, we can run:

nix-build -A bison.hostDrv comtrend.nix

edit New buildInputs

In the attribute set mkDerivation expect as parameters, the usual buildInputs got a new meaning when building hostDrv derivations, and a new buildNativeInputs got introduced, making a total of:

  • buildNativeInputs: derivations built for the build system (native builds), needed for the actual cross-build.
  • buildInputs: derivations built for the host-system (to be run in the target), needed for the actual cross-build.
  • propagatedBuildInputs: in addition to being a dependency of the current built, this derivation built for the host-system will be an input for any derivation requiring the actual host derivation being built.
  • propagatedBuildNativeInputs: in addition to being a dependency of the current built, this derivation built for the build-system (native build) will be an input for any derivation requiring the actual host derivation being built.

For usual derivations in the native build, buildInputs and buildNativeInputs get merged and built for the native system, and analogous for propagatedBuildInputs and propagatedBuildNativeInputs.

TODO: These variables should be renamed just before merging the branch into the mainline. Attributes ending with "*buildInputs" should be renamed to "*hostInputs" and attributes ending with "*buildNativeInputs" should be renamed to "*buildInputs". This renaming is pending until the final merge to avoid the complexity of merging mainline updates into the branch.

edit New variables in the builder

In the environment variables the derivation builder will receive when asking for the hostDrv to be built, there will be the new variable $crossConfig defined to the GNU Configuration triplet set in the crossSystem nixpkgs parameter.

edit What are we testing

edit Derivations

  • xorg.xeyes
  • bison
  • uboot (this derivation is actually meant for a sheevaplug u-boot)

edit GNU Configurations

  • armv5tel-unknown-linux-gnueabi
  • armv5tel-unknown-linux-uclibceabi
  • armv5tel-unknown-linux-uclibceabi
  • mips-unknown-linux

edit Actual problems to be solved

  • gcc 4.4.2 cannot be bootstrapped, because building the bare-metal (without libc or os) first gcc fails. This does not happen in 4.4.1 or 4.4.3(svn) [SOLVED in nixpkgs]
  • Adding other libc than glibc:
    • For uclibc, gcc 4.3.4 needed a patch on libmudflap running a the host CPP instead of the target, on "configure". [SOLVED in nixpkgs]

edit History

edit Motivation

I wanted to cross-build uboot for the sheevaplug, in order to debug it.

edit The stdenv hack

When I had a working cross compiler to build uboot, Nicolas Pierron insisted on trying to get the whole relationships between packages in nixpkgs to be usable also for cross-compilation. He came in with a stdenv adapter that I used to bring cross-compilation capabilities to nixpkgs stdenv.

edit Bootstrap of the compiler

  1. Build binutils for the target (binutilsCross)
  2. Build a bare-metal gcc (gcc without libc), using the binutils built
  3. I wrote a gcc-cross-wrapper to allow the proper wrapping of the cross-gcc, cross-binutils, and cross-libc (gccCrossStageStatic (from gcc44_realCross or gcc43_realCross))
  4. Build a glibc with the bare-metal gcc wrapped and the binutils (libcCross = glibc211Cross or uclibcCross)
  5. Build a normal gcc + g++ with the libc just built
  6. Wrap the last gcc + g++ with the proper libc, for then cross-build whatever program (gccCrossStageFinal (from gcc44_realCross or gcc43_realCross))

edit gcc-cross-wrapper, the stdenv adapter

The stdenv adapter brings into the builder PATH the gcc-cross-wrapper (it includes the cross-compiler and cross-libc). The gcc-cross-wrapper has a setup-hook that modifies the configureFlags, so the calls to the autotools configure script are attempted for a cross build.

Also cmake has an adaptation for crossbuilding.

edit Final stdenv

The stdenv in nixpkgs is aware of the nixpkgs parameter "crossSystem", explained above, and according to it, brings into the stdenv generic builder PATH the final gcc-cross-wrapper, and the gcc-cross-wrapper setup-hook sets up the configure scripts properly for a cross-build.

It needs some help from the user, defining for each stdenv.mkDerivation the attributes buildInputs and buildNativeInputs properly, as explained above. That will determine what is cross built, what not, what gets into CFLAGS/LDFLAGS for the cross compiler, and what for the native compiler.