Use `buildInputs` or nativeBuildInputs` for `nix-shell`?

According to the Nixpkgs manual,

  • buildInputs is for

    programs and libraries used by the new derivation at run-time

  • whereas nativeBuildInputs contains

    programs and libraries used at build-time that, if they are a compiler or similar tool, produce code to run at run-time—i.e. tools used to build the new derivation

So does it matter? Worked with Nix expressions using both, and never experienced any issues, but I’m wondering if there is a “right way” or if there’s a situation where one of them could backfire?

(See more on buildInputs vs nativeBuildInputs in Nixpkgs issue #19370.)

9 Likes

for nix-shell, most people use a shell.nix + mkShell. In which case it doesn’t really matter as nix-shell doesn’t really make distinctions between them. https://github.com/NixOS/nixpkgs/blob/8d57f75f7a1d04ecbf30333c104c9124cfca9331/pkgs/build-support/mkshell/default.nix#L31

In general though, nativeBuildInputs is useful for cross-compilation as commands from those derivations will be available on the buildPlatform and execute at build time. Whereas buildInputs will likely be the architecture of the hostPlatform, so the derivation can link against those inputs (and be used at run-time).

There’s some cases like python where you may need to list them both as a nativeBuildInputs and as a buildInput, if the package needs to run python during build and will link against it.

13 Likes

Thanks, and there’s a lot to unpack. What follows are mostly just notes so that it will make sense to me later.

Looking at the source of mkShell that you linked, it will call mkDerivation in the end.

As you stated that nix-shell treats both buildInputs and nativeBuildInputs the same (does this apply to other *Inputs as well?), I went ahead and poked around in NixOS/nix to find the source of nix-shell. Am I on the right track looking at nix-build.cc? My C knowledge is next to nothing, but the line below tells me that I’m probably am.

// nix-build.cc, line 89
auto myName = runEnv ? "nix-shell" : "nix-build";

Couldn’t figure out yet how and where *Inputs end up though.

1 Like

Is there a reason why mkShell puts all inputs together?

I wanted to setup a shell for cross compilation using the following:

with import <nixpkgs> {
  crossSystem = (import <nixpkgs> {}).lib.systems.examples.aarch64-multiplatform;
};

mkShell {
  nativeBuildInputs = [ cmake ];
  buildInputs = [ poco boost ];
}

My expectation was to have cmake that can run on the host, while the poco and boost library are available for aarch64.

But it seems everything, even cmake is available only for aarch64.

Is there another way to setup a cross compilation shell?

1 Like

you will want buildPackages.cmake in this case

$ nix repl
Welcome to Nix version 2.4pre20201205_a5d85d0. Type :? for help.

nix-repl> :l
Added 13482 variables.

nix-repl> pkgsCross.aarch64-multiplatform.cmake
«derivation /nix/store/y68j9l006dp3mcpd5dx32rm6278k1i73-cmake-3.19.3-aarch64-unknown-linux-gnu.drv»

nix-repl> pkgsCross.aarch64-multiplatform.buildPackages.cmake
«derivation /nix/store/br19j78h50ihp2yw8jfmgnn5fwkvgivd-cmake-3.19.3.drv»

nix-repl> cmake
«derivation /nix/store/br19j78h50ihp2yw8jfmgnn5fwkvgivd-cmake-3.19.3.drv»

notice that the last two are from the host machine.

4 Likes