Cross Compiling: Difference between revisions

Frontear (talk | contribs)
m minor grammar edit
Frontear (talk | contribs)
m more clear edits with correct references to platforms
Line 28: Line 28:
   lib = import <nixpkgs/lib>;
   lib = import <nixpkgs/lib>;
   pkgs = import <nixpkgs> {
   pkgs = import <nixpkgs> {
    #localSystem = ...;
     crossSystem = lib.systems.examples.aarch64-multiplatform;
     crossSystem = lib.systems.examples.aarch64-multiplatform;
   };
   };
Line 63: Line 64:
{
{
   pkgs ? import <nixpkgs> {
   pkgs ? import <nixpkgs> {
    #localSystem = ...;
     crossSystem = "aarch64-linux";
     crossSystem = "aarch64-linux";
   },
   },
Line 74: Line 76:
   }:
   }:
   mkShell {
   mkShell {
     # Derivations that must run on the localSystem, referred to as the buildPlatform.
     # Derivations that must run on the buildPlatform.
     nativeBuildInputs = [
     nativeBuildInputs = [
       pkg-config
       pkg-config
     ];
     ];


     # Derivations that must link with the crossSystem, referred to as the targetPlatform.
     # Derivations that must link with the targetPlatform.
     buildInputs = [
     buildInputs = [
       libGL
       libGL
Line 94: Line 96:
By using [[QEMU]], we can natively execute a cross-compiled binary through an emulation layer. This will result in degraded performance but is very suitable for testing the functionality of a binary.
By using [[QEMU]], we can natively execute a cross-compiled binary through an emulation layer. This will result in degraded performance but is very suitable for testing the functionality of a binary.


If you are on NixOS, this functionality can be provided automatically on any cross-compiled binary by setting [https://nixos.org/manual/nixos/unstable/options#opt-boot.binfmt.emulatedSystems boot.binfmt.emulatedSystems] in your configuration. After rebuilding, attempting to run a cross-compiled binary will automatically invoke <code>qemu</code> indirectly.<syntaxhighlight lang="bash">
If you are on NixOS, this functionality can be provided automatically on any cross-compiled binary by setting [https://nixos.org/manual/nixos/unstable/options#opt-boot.binfmt.emulatedSystems boot.binfmt.emulatedSystems] in your configuration. After rebuilding, attempting to run a cross-compiled binary will automatically invoke <code>qemu</code> indirectly through the [https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html binfmt_misc kernel feature].<syntaxhighlight lang="bash">
$ ./result
$ ./result
Hello World!
Hello World!
Line 107: Line 109:


=== 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]]. However, for some systems, natively compiled binaries are cached. 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>. As a result, this section is only applicable to a very small number of cross-compilation situations.
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 can leverage the binary cache to correctly substitute some applicable derivations without causing a local build.<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">
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
Line 126: Line 126:
       })
       })
     ];
     ];
    #localSystem = ...;
     crossSystem = "aarch64-linux";
     crossSystem = "aarch64-linux";
   };
   };
Line 151: Line 152:


* [https://logs.nix.samueldr.com/nixos/2018-08-03#1533327247-1533327971; 2018-08-03 discussion on #nixos] ([https://matrix.to/#/!AinLFXQRxTuqNpXyXk:matrix.org/$15333274371713496LOAor:matrix.org Mirror of chat on Matrix.org])
* [https://logs.nix.samueldr.com/nixos/2018-08-03#1533327247-1533327971; 2018-08-03 discussion on #nixos] ([https://matrix.to/#/!AinLFXQRxTuqNpXyXk:matrix.org/$15333274371713496LOAor:matrix.org Mirror of chat on Matrix.org])
* [https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html Kernel documentation on binfmt_misc]


[[Category:nix]]
[[Category:nix]]
[[Category:Development]]
[[Category:Development]]