Cross Compiling: Difference between revisions
m more clear edits with correct references to platforms |
Improve examples |
||
| Line 44: | Line 44: | ||
localSystem = "x86_64-linux"; | localSystem = "x86_64-linux"; | ||
crossSystem = "aarch64-linux"; | crossSystem = "aarch64-linux"; | ||
}, | }, | ||
}: | }: | ||
pkgs.mkShell { | pkgs.callPackage ( | ||
{ | |||
} | mkShell, | ||
}: | |||
mkShell { | |||
# By default this provides gcc, ar, ld, and some other bare minimum tools | |||
} | |||
) { } | |||
</syntaxhighlight>Entering this development shell via <code>nix-shell shell.nix</code> will add the relevant compiler tools to your PATH temporarily. Similar to other Linux systems, all cross-compiling tools are prefixed with relevant platform prefixes, which means simply typing <code>gcc</code> will not work. However, the provided <code>mkShell</code> will introduce environment variables for your devshell, such as <code>$CC</code>, <code>$AR</code>, <code>$LD</code>, and more. At the time of writing, official documentation on an exhaustive list of these variables does not exist, but you can view them for your devshell through the command-line:<syntaxhighlight lang="bash"> | </syntaxhighlight>Entering this development shell via <code>nix-shell shell.nix</code> will add the relevant compiler tools to your PATH temporarily. Similar to other Linux systems, all cross-compiling tools are prefixed with relevant platform prefixes, which means simply typing <code>gcc</code> will not work. However, the provided <code>mkShell</code> will introduce environment variables for your devshell, such as <code>$CC</code>, <code>$AR</code>, <code>$LD</code>, and more. At the time of writing, official documentation on an exhaustive list of these variables does not exist, but you can view them for your devshell through the command-line:<syntaxhighlight lang="bash"> | ||
$ $EDITOR $(nix-build ./shell.nix) # opens your EDITOR with a massive bash script full of declare -x ... | $ $EDITOR $(nix-build ./shell.nix) # opens your EDITOR with a massive bash script full of declare -x ... | ||
| Line 61: | Line 67: | ||
If you would prefer to continue building within the devshell, you can use [https://nixos.org/guides/nix-pills/13-callpackage-design-pattern callPackage], which will ''magically'' resolve the dependencies for the correct architecture, provided you place them in the correct attributes:<syntaxhighlight lang="nix"> | If you would prefer to continue building within the devshell, you can use [https://nixos.org/guides/nix-pills/13-callpackage-design-pattern callPackage], which will ''magically'' resolve the dependencies for the correct architecture, provided you place them in the correct attributes:<syntaxhighlight lang="nix"> | ||
{ | { | ||
pkgs ? import <nixpkgs> { | pkgs ? import <nixpkgs> { | ||
localSystem = "x86_64-linux"; | |||
crossSystem = "aarch64-linux"; | crossSystem = "aarch64-linux"; | ||
}, | }, | ||
| Line 71: | Line 76: | ||
{ | { | ||
mkShell, | mkShell, | ||
hello, | |||
pkg-config, | pkg-config, | ||
libGL, | libGL, | ||
}: | }: | ||
mkShell { | mkShell { | ||
# | strictDeps = true; | ||
# host/target agnostic programs | |||
depsBuildBuild = [ | |||
hello | |||
]; | |||
# compilers & linkers & dependecy finding programs | |||
nativeBuildInputs = [ | nativeBuildInputs = [ | ||
pkg-config | pkg-config | ||
]; | ]; | ||
# libraries | |||
# | |||
buildInputs = [ | buildInputs = [ | ||
libGL | libGL | ||
]; | ]; | ||
} | } | ||
) {} | ) { } | ||
</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>. | ||
| Line 109: | Line 118: | ||
=== Leveraging the binary cache === | === Leveraging the binary cache === | ||
You will likely have noticed that resolving derivations through either pkgsCross or a configured Nixpkgs instance results in your system needing to build the binary. This is because cross-compiled binaries are not cached on the official [[Binary Cache|binary cache]]. Fortunately, there are a small set of systems that are actively built and cached officially. At the time of writing, this only includes <code>aarch64-linux</code>, <code>aarch64-darwin</code>, <code>i686-linux</code>, <code>x86_64-linux</code>, and <code>x86_64-darwin</code>. If your platform targets include these, you may be able to leverage a slight hack to avoid large-scale builds.<blockquote>Please note that this is not recommended, as it hacks around some internal details of Nixpkgs which are subject to change at any time.</blockquote>An example of this using <code>pkgs.SDL2</code>:<syntaxhighlight lang="nix"> | You will likely have noticed that resolving derivations through either pkgsCross or a configured Nixpkgs instance results in your system needing to build the binary. This is because cross-compiled binaries are not cached on the official [[Binary Cache|binary cache]]. Fortunately, there are a small set of systems that are actively built and cached officially. At the time of writing, this only includes <code>aarch64-linux</code>, <code>aarch64-darwin</code>, <code>i686-linux</code>, <code>x86_64-linux</code>, and <code>x86_64-darwin</code>. If your platform targets include these, you may be able to leverage a slight hack to avoid large-scale builds.<blockquote>Please note that this is not recommended, as it hacks around some internal details of Nixpkgs which are subject to change at any time, and the storage requirements will be higher due to duplicate(but different system) packages.</blockquote>An example of this using <code>pkgs.SDL2</code>:<syntaxhighlight lang="nix"> | ||
let | let | ||
# this will use aarch64 binaries from binary cache, so no need to build those | # this will use aarch64 binaries from binary cache, so no need to build those | ||
pkgsArm = import <nixpkgs> { | pkgsArm = import <nixpkgs> { | ||
localSystem = "aarch64-linux"; | |||
}; | }; | ||
| Line 122: | Line 131: | ||
# we want to hack on SDL, don't want to hack on those. Some even don't cross-compile | # we want to hack on SDL, don't want to hack on those. Some even don't cross-compile | ||
inherit (pkgsArm) | inherit (pkgsArm) | ||
xorg libpulseaudio libGL guile systemd libxkbcommon | xorg | ||
libpulseaudio | |||
libGL | |||
guile | |||
systemd | |||
libxkbcommon | |||
; | ; | ||
}) | }) | ||
]; | ]; | ||
localSystem = "x86_64-linux"; | |||
crossSystem = "aarch64-linux"; | crossSystem = "aarch64-linux"; | ||
}; | }; | ||
in pkgsCross. | in | ||
pkgsCross.callPackage ( | |||
{ | |||
SDL2, | |||
wayland, | |||
wayland-protocols, | |||
wayland-scanner, | |||
wayland wayland-protocols | }: | ||
SDL2.override { | |||
} | inherit | ||
wayland | |||
wayland-protocols | |||
wayland-scanner | |||
; | |||
} | |||
) { } | |||
</syntaxhighlight> | </syntaxhighlight> | ||