Nix vs. Linux Standard Base: Difference between revisions

From NixOS Wiki
imported>Fadenb
(Created page with "==I want a package installed in the system== In most distributions, asking for a package to be installed, means having all its files available in the root filesystem (<code>/{...")
 
(Partial copy edit)
 
(11 intermediate revisions by 6 users not shown)
Line 1: Line 1:
==I want a package installed in the system==
This article is a comparison between the [[Nix package manager]] and the [https://en.wikipedia.org/wiki/Linux_Standard_Base Linux Standard Base] (LSB) standard that the package managers of most conventional Linux distributions follow.
In most distributions, asking for a package to be installed, means having all its files available in the root filesystem (<code>/{,usr}/{bin,etc,lib,sbin,...}</code>).


In nixpkgs, the installed files of a package go into a ''profile'' (as if it was a rootfs), and you can have as many profiles as you want. There is the notion of each user having at least one profile, so `~/.nix-profile` points to the last version of the profile the user chose (last generation).
== Package Installation ==


By default, the only part of the system made aware of the contents of the user profile is the PATH. The user PATH is set through bashrc to include `~/.nix-profile/bin`. So, by default, installing a nixpkgs program means "having it in the PATH". A simple operation like <code>nix-env -i firefox</code> is meant to update the nix store, then generate a new profile in the store having all the programs ''installed'' plus the new one, and updating the symlink `~/.nix-profile`, so `~/.nix-profile/bin` will contain a symlink to the executable of firefox. Then a user can type <code>firefox</code> and have it running.
In most distributions, files of an installed package are stored under <code>/{,usr}/{bin,etc,lib,...}</code>.
 
With Nix, the files of a package go into a ''profile'' (as if it was a rootfs), and users can have as many profiles as they want.
 
By default, the only part of the system made aware of the contents of the user profile is the PATH. The user PATH is set through bashrc to include `~/.nix-profile/bin`. So, by default, installing a Nix package means "having it in the PATH". A simple operation like <code>nix-env -i firefox</code> is meant to update the nix store, then generate a new profile in the store having all the programs ''installed'' plus the new one, and updating the symlink `~/.nix-profile`, so `~/.nix-profile/bin` will contain a symlink to the executable of firefox. Then a user can type <code>firefox</code> and have it running.


If other kind of files are to be found by programs looking at the usual `<code>/{,usr}/{bin,etc,lib,sbin,...}</code>` locations, other variables may be of help. For example, gcc would welcome <code>CPATH</code> and <code>LIBRARY_PATH</code>. And the dynamic loader will welcome <code>LD_LIBRARY_PATH</code>.
If other kind of files are to be found by programs looking at the usual `<code>/{,usr}/{bin,etc,lib,sbin,...}</code>` locations, other variables may be of help. For example, gcc would welcome <code>CPATH</code> and <code>LIBRARY_PATH</code>. And the dynamic loader will welcome <code>LD_LIBRARY_PATH</code>.


==I want to download an arbitrary source, and build it==
== Build and install from Source ==
 
In most LSB distributions, you ask for the development tools to be installed into the system. And then you also install dependencies of the package you want to build, and then go on building the source you downloaded. The dependencies are found, and your program builds fine.
In most LSB distributions, you ask for the development tools to be installed into the system. And then you also install dependencies of the package you want to build, and then go on building the source you downloaded. The dependencies are found, and your program builds fine.


In nixpkgs, you can install the needed development tools into your profile (gcc-wrapper, gnumake), and the dependencies for the source you want to build (libpng, qt, ...). Once that done, set the environment variables (for gcc): <code>CPATH=~/.nix-profile/include; LIBRARY_PATH=~/.nix-profile/lib; QTDIR=~/nix-profile</code>... And then you should get your build running
With Nix, you can install the needed development tools into your profile (gcc-wrapper, gnumake), and the dependencies for the source you want to build (libpng, qt, ...). Once that done, set the environment variables (for gcc): <syntaxhighlight lang="bash" inline>CPATH=~/.nix-profile/include; LIBRARY_PATH=~/.nix-profile/lib; QTDIR=~/nix-profile</syntaxhighlight>... And then you should get your build running. In most LSB distributions, you proceed like the section above to build the program, and then run <code>make install</code> to get it into /usr/local, overwritting any files you had there.


==I want to install a program from source==
Using Nix, if you built your program like the section above, you may end up having /usr/local files depending on dynamic libraries only present in your profile. That situation may require a <code>LD_LIBRARY_PATH</code> variable, or your ld.so.conf pointing to your profile, but this situation can end in your programs not working if you remove those dependencies from your profile. This would be also a problem in your LSB distribution, if you remove uninstall packages required by programs you put manually in /usr/local.
In most LSB distributions, you proceed like the section above to build the program, and then run <code>make install</code> to get it into /usr/local, overwritting any files you had there.


Using nixpkgs, if you built your program like the section above, you may end up having /usr/local files depending on dynamic libraries only present in your profile. That situation may require a <code>LD_LIBRARY_PATH</code> variable, or your ld.so.conf pointing to your profile, but this situation can end in your programs not working if you remove those dependencies from your profile. This would be also a problem in your LSB distribution, if you remove uninstall packages required by programs you put manually in /usr/local.
Therefore, it is advisable to use Nix not only for acquiring dependencies, but also for managing the build of your package. In fact, creating an ad-hoc Nix package for the software is often easier, because the standard environment in NixPkgs automatically takes care of issues that could arise because of the differences between the Nix and LSB approaches. For example, a well packaged autotools-based project usually builds successfully after specifying its dependencies in Nix, whereas if you would install the dependencies and try to build it yourself, you will have a hard time.


==I want all the nix advantages installing a program from source==
== Workflow ==
A common situation is that LSB distribution users want to keep their habits, but they additionally want the advantages claimed by nix, to mention some:
A common situation is that LSB distribution users want to keep their habits, but they additionally want the advantages claimed by nix, to mention some:
# rollback
# rollback
Line 27: Line 30:
That can be achieved only following the nix style. So, letting nix build your program from source, instead of doing that on your own in your interactive shell through profiles. Nix will provide a common build system, with whatever stated dependencies available at build time, and will also provide a target installation directory. This requires knowing how to write [http://hydra.nixos.org/job/nix/trunk/tarball/latest/download-by-type/doc/manual/#id460419 simple stdenv derivations], and knowing [https://nixos.org/nix/manual/#chap-quick-start where to write them].
That can be achieved only following the nix style. So, letting nix build your program from source, instead of doing that on your own in your interactive shell through profiles. Nix will provide a common build system, with whatever stated dependencies available at build time, and will also provide a target installation directory. This requires knowing how to write [http://hydra.nixos.org/job/nix/trunk/tarball/latest/download-by-type/doc/manual/#id460419 simple stdenv derivations], and knowing [https://nixos.org/nix/manual/#chap-quick-start where to write them].


==I want to modify one of the files installed==
== Modifying a Package ==
In LSB distributions, after installing a package, you would go to /usr/whatever and edit the files you want to change.
In LSB distributions, files installed under {{ic|/usr}} can be edited by the user as needed.
 
Files in the Nix store ({{ic|/nix/store}}) are meant to be read-only and changes are only done using the {{ic|nix}} commands. {{ic|nix-store --verify --check-contents}} can be used to ensure integrity of the store data.
 
To make changes to Nix packages properly, see [[Modifying a Package]].
 
== See also ==


In nixpkgs, any files inside the store (/nix/store, where all nix installed files end up; ~/.nix-profile is a symlink to a store path), are meant to be read-only. That is, nix expects those files only under her control, and it is a requirement to allow rollbacks and reproducibility. Of course the owner of the nix store can change files there, but then you cannot expect rollbacks or reproducibility. "nix-store --verify --check-contents" will tell you if there are files modified in the store (since the creation of each store path).
* [https://ostreedev.github.io/ostree/related-projects/#nixos--nix OSTree comparison to NixOS] &mdash; OSTree, a project to offer [https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard FHS]-compatible "stores", was in large part inspired by NixOS.


To achieve a change in the files installed in nixpkgs, you either patch the nix expression that builds your program (in the [https://nixos.org/nixpkgs/manual/#sec-stdenv-phases phase] maybe - this may be a very easy task to do), or find another way of achieving your goal. By goal, I mean what you meant to achive changing one of the files installed. Maybe you can pass a parameter to the program, or use environment variables.
[[Category:Pedias]]

Latest revision as of 04:55, 8 April 2024

This article is a comparison between the Nix package manager and the Linux Standard Base (LSB) standard that the package managers of most conventional Linux distributions follow.

Package Installation

In most distributions, files of an installed package are stored under /{,usr}/{bin,etc,lib,...}.

With Nix, the files of a package go into a profile (as if it was a rootfs), and users can have as many profiles as they want.

By default, the only part of the system made aware of the contents of the user profile is the PATH. The user PATH is set through bashrc to include `~/.nix-profile/bin`. So, by default, installing a Nix package means "having it in the PATH". A simple operation like nix-env -i firefox is meant to update the nix store, then generate a new profile in the store having all the programs installed plus the new one, and updating the symlink `~/.nix-profile`, so `~/.nix-profile/bin` will contain a symlink to the executable of firefox. Then a user can type firefox and have it running.

If other kind of files are to be found by programs looking at the usual `/{,usr}/{bin,etc,lib,sbin,...}` locations, other variables may be of help. For example, gcc would welcome CPATH and LIBRARY_PATH. And the dynamic loader will welcome LD_LIBRARY_PATH.

Build and install from Source

In most LSB distributions, you ask for the development tools to be installed into the system. And then you also install dependencies of the package you want to build, and then go on building the source you downloaded. The dependencies are found, and your program builds fine.

With Nix, you can install the needed development tools into your profile (gcc-wrapper, gnumake), and the dependencies for the source you want to build (libpng, qt, ...). Once that done, set the environment variables (for gcc): CPATH=~/.nix-profile/include; LIBRARY_PATH=~/.nix-profile/lib; QTDIR=~/nix-profile... And then you should get your build running. In most LSB distributions, you proceed like the section above to build the program, and then run make install to get it into /usr/local, overwritting any files you had there.

Using Nix, if you built your program like the section above, you may end up having /usr/local files depending on dynamic libraries only present in your profile. That situation may require a LD_LIBRARY_PATH variable, or your ld.so.conf pointing to your profile, but this situation can end in your programs not working if you remove those dependencies from your profile. This would be also a problem in your LSB distribution, if you remove uninstall packages required by programs you put manually in /usr/local.

Therefore, it is advisable to use Nix not only for acquiring dependencies, but also for managing the build of your package. In fact, creating an ad-hoc Nix package for the software is often easier, because the standard environment in NixPkgs automatically takes care of issues that could arise because of the differences between the Nix and LSB approaches. For example, a well packaged autotools-based project usually builds successfully after specifying its dependencies in Nix, whereas if you would install the dependencies and try to build it yourself, you will have a hard time.

Workflow

A common situation is that LSB distribution users want to keep their habits, but they additionally want the advantages claimed by nix, to mention some:

  1. rollback
  2. disable any possibility of removing dependencies of an installed program
  3. no side effects to other users (if desired), when installing programs
  4. no effects for the own user (have the program installed in the store, but not referenced in the profile)

That can be achieved only following the nix style. So, letting nix build your program from source, instead of doing that on your own in your interactive shell through profiles. Nix will provide a common build system, with whatever stated dependencies available at build time, and will also provide a target installation directory. This requires knowing how to write simple stdenv derivations, and knowing where to write them.

Modifying a Package

In LSB distributions, files installed under /usr can be edited by the user as needed.

Files in the Nix store (/nix/store) are meant to be read-only and changes are only done using the nix commands. nix-store --verify --check-contents can be used to ensure integrity of the store data.

To make changes to Nix packages properly, see Modifying a Package.

See also