jungle/web/content/intro-nix/ch3.md

161 lines
4.5 KiB
Markdown

---
title: "Chapter 3: Custom packages"
date: 2023-09-15
weight: 3
---
## Adding more packages
So far we have define all the packages using:
```nix
pkgs.mkShell rec {
pname = "my-shell";
buildInputs = with pkgs.bsc; [
ovni osumb # other packages here...
];
};
```
This line specifies that all packages come from the `pkgs.bsc` set. We can add
additional packages adding them to the list:
```nix
pkgs.mkShell rec {
pname = "my-shell";
buildInputs = with pkgs.bsc; [
ovni osumb sonar
];
};
```
And running `nix develop` again:
```txt
hut% nix develop
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
[nix-develop]$ printf '%s\n' $buildInputs
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1
/nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0
```
In the jungle cluster, the default MPI implementation is currently set to MPICH,
as it can be shown with ldd:
```txt
[nix-develop]$ ldd $(which ovnisync) | grep mpi
libmpi.so.12 => /nix/store/nnnaly6hgylravdrmqkhpx1ndg5p79nc-mpich-4.1.2/lib/libmpi.so.12 (0x00007ffff5200000)
```
Now, what if we want to replace the MPI implementation by another one?
## Modifying a package
You notice that the packages we are using are coming directly from the ones
specified in jungle. However, what if we need to modify some option at build
time or change a dependency?
The Nix language is used to describe how to build each package, and can be
extended to create derived versions very easily.
Let's focus on the `ovni` package. First, to load the definition we can use the
`nix edit` command, which opens the definition file using the editor defined in
`$EDITOR`:
```txt
hut% nix edit jungle#bsc.ovni
...
```
This particular package has several inputs that can be modified directly:
```txt
{
stdenv
, lib
, cmake
, mpi
, fetchFromGitHub
, useGit ? false
, gitBranch ? "master"
, gitUrl ? "ssh://git@bscpm03.bsc.es/rarias/ovni.git"
, gitCommit ? "d0a47783f20f8b177a48418966dae45454193a6a"
, enableDebug ? false
}:
...
```
For example, the `enableDebug` flag, currently set to false, affects how the
build is configured:
```txt
cmakeBuildType = if (enableDebug) then "Debug" else "Release";
```
Now, to change this option we could replace `ovni` for our version:
```nix
{
inputs.jungle.url = "jungle";
nixConfig.bash-prompt = "\[nix-develop\]$ ";
outputs = { self, jungle }:
let
pkgs = jungle.outputs.packages.x86_64-linux;
ovniDebug = pkgs.bsc.ovni.override { enableDebug = true; };
in {
devShells.x86_64-linux.default = pkgs.mkShell rec {
pname = "my-shell";
buildInputs = with pkgs.bsc; [
ovniDebug osumb sonar
];
};
};
}
```
And then, when we now enter the develop shell we can see that ovni gets build
with the Debug option:
```txt
hut% nix develop -L
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
ovni> unpacking sources
ovni> unpacking source archive /nix/store/cz4si0vsw85r9s6dyiqr5ybngh9aympi-source
ovni> source root is source
ovni> patching sources
ovni> updateAutotoolsGnuConfigScriptsPhase
ovni> configuring
ovni> fixing cmake files...
ovni> cmake flags: ... -DCMAKE_BUILD_TYPE=Debug ...
...
[nix-develop]$ which ovniver
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/bin/ovniver
[nix-develop]$ file $(which ovniver) | fold
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/bin/ovniver: ELF 64-bit L
SB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/st
ore/9la894yvmmksqlapd4v16wvxpaw3rg70-glibc-2.37-8/lib/ld-linux-x86-64.so.2, for
GNU/Linux 3.10.0, with debug_info, not stripped
```
And we see that the ovniver program is now compiled with debug symbols.
However, this *only* replaces the ovni package that we specify in the shell. The
sonar library also depends on ovni, but that package is still using the old one:
```txt
[nix-develop]$ find $buildInputs -name 'libovni.so.1'
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/lib/libovni.so.1
[nix-develop]$ find $buildInputs -name 'libsonar-mpi.so'
/nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0/lib/libsonar-mpi.so
[nix-develop]$ ldd /nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0/lib/libsonar-mpi.so | grep ovni
libovni.so.1 => /nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0/lib/libovni.so.1 (0x00007ffff7f8d000)
```
In the [next chapter](../ch4) we will see how to replace packages in such a way
that all the dependences are automatically updated too.