Translations:FAQ/133/en

From NixOS Wiki
Revision as of 03:43, 9 September 2024 by FuzzyBot (talk | contribs) (Importing a new version from external source)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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 refers to software that has restrictive licensing on modification and/or redistribution. This type of software cannot be freely provided or distributed in an official capacity, which means that unfree software is neither built by Hydra, nor cached on the official binary cache. Despite this, Nixpkgs offers a very large collection of unfree software as derivations, however they cannot be used by default without configuring Nixpkgs and opting in to unfree software usage.

Nixpkgs manual on allowing unfree packages