Cross Compiling: Difference between revisions
m improved wording in binary cache section |
m add a small desc of host/build platform |
||
| Line 1: | Line 1: | ||
{{Expansion}} | {{Expansion}} | ||
[[Nixpkgs]] provides excellent support in configuring it for cross-platform compiling tasks since 18.09<sup>[citation needed]</sup>. | |||
In order to prepare Nixpkgs for a cross-compiling environment, it needs to be aware of both the platform that performs the build-step, and the platform that will execute the resulting binaries. The former is referred to as the <code>buildPlatform</code>, while the latter is <code>hostPlatform</code>.<blockquote>If you were compiling a program from your system for a Raspberry PI, you would be the <code>buildPlatform</code> whereas the Raspberry PI would be the <code>hostPlatform</code>.</blockquote>Furthermore, in order to provide a more granular control to declaring dependencies in these environments, Nixpkgs derivations expose an exhaustive set of attributes that can explicitly define when are where dependencies are required. An exhaustive reference to these can be found in the [https://nixos.org/manual/nixpkgs/unstable/#ssec-stdenv-dependencies-propagated Nixpkgs manual]. | |||
== Getting Started == | == Getting Started == | ||
Nixpkgs exposes two configuration attributes that map internally to the expected behaviors of the build/host platforms as described above. These attributes can be set when importing Nixpkgs as a Nix expression:<syntaxhighlight lang="nix"> | |||
let | let | ||
pkgs = import <nixpkgs> {}; | pkgs = import <nixpkgs> { | ||
in pkgs | localSystem = "x86_64-linux"; # buildPlatform | ||
</syntaxhighlight>The above will provide a derivation result for the hello derivation that can run on an <code>aarch64</code> system. | crossSystem = "aarch64-linux"; # hostPlatform | ||
}; | |||
in pkgs.hello | |||
</syntaxhighlight>The above will provide a derivation result for the hello derivation that can run on an <code>aarch64-linux</code> system. This can sometimes be tedious especially for common <code>hostPlatform</code> targets. Fortunately, Nixpkgs exposes a <code>pkgsCross</code> attribute that provides pre-configured cross compiling targets. The snippet above converted to using <code>pkgsCross</code> can be shorted to:<syntaxhighlight lang="nix"> | |||
let | let | ||
pkgs = import <nixpkgs> { | pkgs = import <nixpkgs> { | ||
localSystem = "x86_64-linux"; | |||
localSystem = "x86_64-linux"; | |||
}; | }; | ||
in pkgs. | in pkgs.pkgsCross.aarch64-multiplatform.hello | ||
</syntaxhighlight>You can perform the same operations using the CLI, | </syntaxhighlight>You can perform the same operations using the CLI, and Nix will correctly evaluate the <code>localSystem</code> based on your current system:<syntaxhighlight lang="bash"> | ||
nix-build '<nixpkgs>' -A pkgsCross.aarch64-multiplatform.hello # nix-legacy | nix-build '<nixpkgs>' -A pkgsCross.aarch64-multiplatform.hello # nix-legacy | ||
nix build nixpkgs#pkgsCross.aarch64-multiplatform.hello # nix3 | nix build nixpkgs#pkgsCross.aarch64-multiplatform.hello # nix3 | ||
| Line 23: | Line 24: | ||
$ nix-instantiate --eval --expr 'builtins.attrNames (import <nixpkgs> {}).pkgsCross' --json | nix-shell -p jq --command 'jq' # nix-legacy | $ nix-instantiate --eval --expr 'builtins.attrNames (import <nixpkgs> {}).pkgsCross' --json | nix-shell -p jq --command 'jq' # nix-legacy | ||
$ nix eval --impure --expr 'builtins.attrNames (import <nixpkgs> {}).pkgsCross' --json | nix run nixpkgs#jq # nix3 | $ nix eval --impure --expr 'builtins.attrNames (import <nixpkgs> {}).pkgsCross' --json | nix run nixpkgs#jq # nix3 | ||
</syntaxhighlight>If you instead prefer to write your systems directly, through <code>localSystem</code> and <code>crossSystem</code>, you can refer to [https://github.com/NixOS/nixpkgs/blob/master/lib/systems/examples.nix nixpkgs/lib/systems/examples.nix] for | </syntaxhighlight>If you instead prefer to write your systems directly, through <code>localSystem</code> and <code>crossSystem</code>, you can refer to [https://github.com/NixOS/nixpkgs/blob/master/lib/systems/examples.nix nixpkgs/lib/systems/examples.nix] for examples of platforms exposed as attributes. These can be directly used in-place for the aforementioned arguments:<syntaxhighlight lang="nix"> | ||
let | let | ||
lib = import <nixpkgs/lib>; | lib = import <nixpkgs/lib>; | ||
| Line 40: | Line 41: | ||
{ | { | ||
pkgs ? import <nixpkgs> { | pkgs ? import <nixpkgs> { | ||
localSystem = "x86_64-linux"; | |||
crossSystem = "aarch64-linux"; | crossSystem = "aarch64-linux"; | ||
}, | }, | ||
| Line 86: | Line 87: | ||
</syntaxhighlight>The above snippet will drop you into a devshell that provides <code>pkg-config</code> as a native binary (accessible through <code>$PKG_CONFIG</code>), while also allowing linking to a valid <code>libGL</code> for the <code>crossSystem</code>. | </syntaxhighlight>The above snippet will drop you into a devshell that provides <code>pkg-config</code> as a native binary (accessible through <code>$PKG_CONFIG</code>), while also allowing linking to a valid <code>libGL</code> for the <code>crossSystem</code>. | ||
For more information regarding the above, namely the usage of <code>nativeBuildInputs</code> and <code>buildInputs</code>, see [https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-dependencies stdenv dependencies] for a in-depth explanation. Alternatively, a simplified explanation can be found in a comment on the [https://github.com/NixOS/nixpkgs/pull/50881 | For more information regarding the above, namely the usage of <code>nativeBuildInputs</code> and <code>buildInputs</code>, see [https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-dependencies stdenv dependencies] for a in-depth explanation. Alternatively, a simplified explanation can be found in a comment on the [https://github.com/NixOS/nixpkgs/pull/50881 Nixpkgs repo]. | ||
== Tips and tricks == | == Tips and tricks == | ||