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.
EDIT:
This has gotten a lot of views over the years, wanted to expand on this:
-
nativeBuildInputs: Should be used for commands which need to run at build time (e.g.cmake) or shell hooks (e.g.autoPatchelfHook). These packages will be of the buildPlatforms architecture, and added toPATH. -
buildInputs: Should be used for things that need to be linked against (e.g.openssl). These will be of the hostPlaform’s architecture. WithstrictDeps = true;(or by extension cross-platform builds), these will not be added to PATH. However, linking related variables will capture these packages (e.g.NIX_LD_FLAGS,CMAKE_PREFIX_PATH,PKG_CONFIG_PATH)
In the early days of nix, packages were expected to be built by x86_64 and target x86_64. It wasn’t until later where cross compilation support was adopted. But to not break nix expressions outside of nixpkgs, the transition to enforcing the differences never happened. Individual packages can “opt-in” to using the more strict tooling divide by setting strictDeps = true; which will roughly emulate how PATH, NIX_CLFAGS_COMPILE, NIX_LD_FLAGS and other environment variables are constructed similar to a cross-platform build.
Outside of cross-compilation, adhering to good practices for nativeBuildInputs is still recommended because certain variables (e.g. XDG_DATA_DIRS) are safe to append to when of the same buildPlatform, but same is not true of hostPlatform packages. This can result in other quality-of-life additions such as bash completion being available for packages listed in nativeBuildInputs, but not for packages in buildInputs.
Additional Context:
- Taking a package and pulling either the build or host platform variant is called splicing.
- Packages specific to the buildPlatform can be found in
buildPackages. This sometimes can be useful when using overrides, which may not respect splicing. - Similarly
targetPackageshave packages specific to the target platform (generally not useful for most packages except toolchains). - The default package set already targets
hostPlatform, so you those are just referenced bypkgsin a general sense.
- Packages specific to the buildPlatform can be found in
-
nativeBuildInputsandbuildInputsare technically “legacy” terms, although still the standard convention in most nix packages. However, unless you’re writing packages which export toolchains (e.g.gcc,clang, interpreters), you likely wont need to use the more accurratedepsXXXYYYvariants.