stdenv.hostPlatform.emulator use case

I’m trying to understand what’s the use case the stdenv.hostPlatform.emulator function.

Found this issue:

But I’m still unable to wrap my head around a possible usage.

Went digging around nixpkgs, and found out that some package use the following code — example taken from gnmic:

  nativeBuildInputs = [ installShellFiles ];
  postInstall = let emulator = stdenv.hostPlatform.emulator buildPackages; in ''
    installShellCompletion --cmd gnmic \
      --bash <(${emulator} $out/bin/gnmic completion bash) \
      --fish <(${emulator} $out/bin/gnmic completion fish) \
      --zsh  <(${emulator} $out/bin/gnmic completion zsh)

Is this to ensure that the buidPlatform can the program generated to the hostPlatform? If so, it’s only possible to achieve this through the emulator function? Would there be no other way to ensure that the built program can execute on the host platform?

Yeah the naming convention there is… not particularly helpful.

stdenv.hostPlatform.emulator is a function which will select an emulator suitable for emulating binaries built for stdenv.hostPlatform. You pass it a packageset containing packages which run on the platform which the emulator runs on.

So stdenv.hostPlatform.emulator buildPackages gives you an emulator that runs on buildPackages.stdenv.hostPlatform and which runs programs built for stdenv.hostPlatform. Which is almost always what you want when writing packages for nixpkgs.

1 Like

So in the case of the gnmic example, what’s happening is: to avoid a possible mismatch between the buildPlatform and the hostPlaftorm — let’s say the former is x86_64-unknown-linux-gnu and the latter aarch64-unknown-linux-gnu —, stdenv.hostPlatform.emulator is used.

By doing so, the built binary — $out/bin/gnmic — won’t be run directly, but under a call to either the runtimeShell, wine, qemu, wasmtime or mmix, depending on which condition of the if-statement of the selectEmulator function is satisfied. So, It can run on the buildPlatform as if it was running on the hostPlatform.

Is this understanding correct?