Nix vs. Linux Standard Base: Difference between revisions

imported>Fadenb
m →‎Building from Source: syntax highlighting
imported>Roberth
Some advice around build/install from source + give an overview of package modification methods (modify package should be factored into new page)
Line 11: Line 11:
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>.


== Building from Source ==
== 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.


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
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.


== Installing 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 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.
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 ==
== Workflow ==
Line 34: Line 33:
In LSB distributions, after installing a package, you would go to /usr/whatever and edit the files you want to change.
In LSB distributions, after installing a package, you would go to /usr/whatever and edit the files you want to change.


With Nix, 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).
With Nix, 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). Although modifying a file in the store seems like an easy quick fix, it should be regarded as bad as modifying the memory of a running process, because it has almost all the analogous downsides.
 
To modify the behavior of a Nix package, you typically have more than one option. The first approach you may consider is changing its runtime configuration: passing command line options, environment variables or configuration files that exist outside the package itself. Not modifying the definition of a package has the benefit of being able to use the publicly available Hydra build cache.
 
If the software as packaged does not have the flexibility you need, you have various options.
 
Conceptually the most simple option is to duplicate the package definition in a local file where you make your changes. You will be able to install and use it locally, while only having to learn the basics of Nix packaging.
 
If you expect your changes to be generally useful to others, you may consider creating a pull request for [https://github.com/NixOS/nixpkgs nixpkgs on github]. This has the benefit that others can help maintaining the package and that a binary of your package will be available for you to download.


To modify a Nix package, 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 achieve changing one of the files installed. Maybe you can pass a parameter to the program, or use environment variables.
If upstreaming into the official NixPkgs is not an option, consider creating an overlay. This is slightly more involved at first, but is easier to maintain than a NixPkgs fork and, unlike a fork, it can be combined with other overlays. In an overlay, you can also choose not to redefine the package, but only override part of the arguments or derivation attributes. For example, you may only need to change one of the [https://nixos.org/nixpkgs/manual/#sec-stdenv-phases stdenv build phases].


[[Category:Discussion]]
[[Category:Discussion]]