Difference between revisions of "Cross Compiling"

From NixOS Wiki
Jump to: navigation, search
(add a link to the examples of target systems in nixpkgs)
(→‎How to obtain a shell with a cross compiler: mention using callPackage to have native build inputs)
Line 29: Line 29:
  
 
Examples of how to specify your target system can be found in [https://github.com/NixOS/nixpkgs/blob/master/lib/systems/examples.nix lib/systems/examples.nix].
 
Examples of how to specify your target system can be found in [https://github.com/NixOS/nixpkgs/blob/master/lib/systems/examples.nix lib/systems/examples.nix].
 +
 +
The example above does not work as is with build dependencies (<code>nativeBuildInputs</code>). A solution is to use <code>callPackage</code> to enable splicing:
 +
<syntaxhighlight lang="nix">
 +
let pkgs = import <nixpkgs> {
 +
  crossSystem = {
 +
    config = "aarch64-unknown-linux-gnu";
 +
  };
 +
};
 +
in
 +
  pkgs.callPackage (
 +
    {mkShell, pkg-config, zlib}:
 +
    mkShell {
 +
      nativeBuildInputs = [ pkg-config ]; # you build dependencies here
 +
      buildInputs = [ zlib ]; # your dependencies here
 +
    }
 +
  ) {}
 +
</syntaxhighlight>
 +
See also {{issue|49526}}.
  
 
== How to specify dependencies ==
 
== How to specify dependencies ==

Revision as of 14:17, 8 May 2019

For building arm software check out the Article NixOS on ARM
If you are looking for building 32bit software, check out Packaging/32bit Applications
Quick example to cross compile a package: Cheatsheet#Cross-compile_packages.

Cross-Compiling in nixpkgs unstable (pre-18.09)

A lot has happened in 2018 and now cross-compilation is well supported within the unstable branch of nixpkgs. The basic idea is to use pkgsCross.platform instead of pkgs:

nix build -f channel:nixos-unstable pkgsCross.raspberryPi.emacs

How to obtain a shell with a cross compiler

Create a file crossShell.nix as follows:

with import <nixpkgs> {
  crossSystem = {
    config = "aarch64-unknown-linux-gnu";
  };
};

mkShell {
  buildInputs = [ zlib ]; # your dependencies here
}

and then use it to obtain a shell:

nix-shell crossShell.nix

The resulting shell will have $CC etc. set to the right compiler.

Examples of how to specify your target system can be found in lib/systems/examples.nix.

The example above does not work as is with build dependencies (nativeBuildInputs). A solution is to use callPackage to enable splicing:

let pkgs = import <nixpkgs> {
  crossSystem = {
    config = "aarch64-unknown-linux-gnu";
  };
};
in
  pkgs.callPackage (
    {mkShell, pkg-config, zlib}:
    mkShell {
      nativeBuildInputs = [ pkg-config ]; # you build dependencies here
      buildInputs = [ zlib ]; # your dependencies here
    }
  ) {}

See also Issue.png#49526.

How to specify dependencies

Depending in which if packages are required at build time or at runtime they need to go to different inputs the derivation.

  • If it is used at build-time it's depsBuildXXX
    • compiler producing native binaries go to depsBuildBuild
    • compiler producing cross binaries, all setup hooks and programs executed by the builder go to depsBuildHost
      • common examples: pkgconfig, autoreconfHook, makeWrapper, intltool, bison, flex
  • If it is used at run-time it's depsHostXXX. [Stack linking doesn't effect this, even if it allows us to forget where things came from.]
    • if it’s an interpreter that will be needed by an installed script, it should go in depsHostTarget.
    • otherwise it is probably only needed at build time and can go in depsBuildHost
  • If it is a tool and "acts" (e.g. helps build) on build-time stuff, then it's depsXXXBuild
  • If it is a tool and "acts" on run-time stuff, then it's depsXXXHost
  • if it is not a tool, it's depsXXX(XXX+1)(build + 1 == host, host +1 == target) for backwards compatibility, use nativeBuildInputs instead of depsBuildHost and buildInputs instead of depsHostTarget.

Source: https://github.com/NixOS/nixpkgs/pull/50881#issuecomment-440772499


References

Additional resources