Translations:FAQ/133/en

From NixOS Wiki

I installed a library but my compiler is not finding it. Why?

With nix, only applications should be installed into profiles. Libraries are used using nix-shell. If you want to compile a piece of software that requires zlib (or openssl, sqlite etc.) and uses pkg-config to discover it, run

$ nix-shell -p gcc pkg-config zlib

to get into a shell with the appropriate environment variables set. In there, a configure script (with C Autotools, C++ CMake, Rust Cargo etc.) will work as expected.

This applies to other language environments too. In some cases the expressions to use are a bit different, e.g. because the interpreter needs to be wrapped to have some additional environment variables passed to it. The manual has a section on the subject.

Note that software built in such a shell may stop working after a garbage collection. This is because Nix only tracks dependencies of paths within the store. A clean build in a fresh shell can fix this one-off, but the long-term solution is to package the software in question rather than using a shell build regularly.

If you have a lot of dependencies, you may want to write a nix expression that includes your dependencies so that you can simply use nix-shell rather than writing out each dependency every time or keeping your development environment in your shell history. A minimal example looks like this:

# default.nix
with import <nixpkgs> {};
stdenv.mkDerivation {
    name = "dev-environment"; # Probably put a more meaningful name here
    buildInputs = [ pkg-config zlib ];
}

Why does it work like that?

This helps ensure purity of builds: on other distributions, the result of building a piece of software may depend on which other software you have installed. Nix attempts to avoid this to the greatest degree possible, which allows builds of a piece of software to be identical (in the ideal case) no matter where they're built, by requiring all dependencies to be declared.

Why not use nix-env -i hello?

nix-env -i hello is slower and tends to be less precise than nix-env -f '<nixpkgs>' -iA hello. This is because it will evaluate all of nixpkgs searching for packages with the name hello, and install the one determined to be the latest (which may not even be the one that you want). Meanwhile, with -A, nix-env will evaluate only the given attribute in nixpkgs. This will be significantly faster, consume significantly less memory, and more likely get you what you want.

nix-env -u has the same problem, searching for all the packages in the user environment by name and upgrading them. This may lead to unwanted major-version upgrades like JDK 8 → JDK 9. If you want to have a declarative user environment, you may wish to use Home Manager. It is also possible to home-bake a pure nix solution like LnL's. With this setup, you can update your packages by simply running nix-rebuild.

When do I update stateVersion

Keep stateVersion to the version you originally installed.[1]

The system.stateVersion option is described as such:

Every once in a while, a new NixOS release may change configuration defaults in a way incompatible with stateful data. For instance, if the default version of PostgreSQL changes, the new version will probably be unable to read your existing databases. To prevent such breakage, you can set the value of this option to the NixOS release with which you want to be compatible. The effect is that NixOS will option defaults corresponding to the specified release (such as using an older version of PostgreSQL).

Frequent answers:

  • stateVersion has nothing to do with the current version of the system[2]
  • Do NOT change the stateVersion in the configuration; [it] tells nixos what version your state is; changing it will break the things [it is] meant to fix.[3]

When can I update stateVersion?

When:

  1. You have read all release notes starting from your stateVersion.
  2. You have verified all instances of stateVersion in the code in <nixpkgs/nixos>.
  3. You have made all manual interventions as required by the changes previously inventoried.

I cannot find $package when running nix-env -qaP even with channels configured

Not all packages are listed. Packages may not be listed because:

  • the package is unfree, like e.g. unrar and teamspeak_client; see Unfree software for more information
  • the package is part of an attribute set and nix-env doesn't recurse into this set (see pkgs.recurseIntoAttrs), use nix-env -qaP -A haskellPackages for listing these entries

Unfree software, sometimes called nonfree software, is software that cannot be freely modified or distributed. Nixpkgs provides packages for unfree software, but additional configuration is required before they can be used.

Using unfree packages

Per-package (preferred)

This method works for both NixOS system level configuration and Home Manager:

 
/etc/nixos/configuration.nix
{
  nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
    "vscode"
  ];
}

For all packages

This method works for both NixOS system level configuration and Home Manager:

 
/etc/nixos/configuration.nix
{
  nixpkgs.config.allowUnfree = true;
}

Command line

You won't be able to install or search for an unfree package as a user unless you explicitly enable it:

 
~/.config/nixpkgs/config.nix
{
  allowUnfree = true;
}

Temporarily allowing

For temporary allowing unfree packages, you can use an environment variable:

$ NIXPKGS_ALLOW_UNFREE=1 nix-shell -p vscode

Note for the new nix3-style commands, you need to pass --impure as well:

$ NIXPKGS_ALLOW_UNFREE=1 nix run nixpkgs#vscode --impure

Hydra

Hydra does not build unfree software, and unfree software is unavailable in cache.nixos.org.

See also