<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Dependencies &amp;mdash; csantosb</title>
    <link>https://infosec.press/csantosb/tag:Dependencies</link>
    <description>Random thoughts</description>
    <pubDate>Thu, 16 Apr 2026 14:03:37 +0000</pubDate>
    <item>
      <title>guix crash course</title>
      <link>https://infosec.press/csantosb/guix-crash-course</link>
      <description>&lt;![CDATA[img br/&#xA;Guix reveals as a practical means of handling dependencies. However, the amount of information available to start using it may appear as a bit overwhelming for a beginner, letting the feeling of a tool reserved to a reduced community or experts. Far from that. Here you’ll find everything you need to get started with guix, with a light touch on using it for #modernhw. !--more-- br/&#xA;We will concentrate in the use of #guix as an external package manager on top of a #linux distribution based on #systemd. We’ll let aside using and referring to #guixsystem as a full operating system by itself (which I never used anyway). This way, in the context of #modernhw, we may keep on using our favorite tools, environment and workflow. As an addition, we have everything that guix provides at our disposal, without affecting our local packages configuration: guix acts as an extra layer on top of our current OS, without any interference with it. You’ll have the possibility to install any guix software, remove it afterward or make use of the fancy features guix has to offer, without your host OS ever noticing what’s going on. br/&#xA;All what follows is roughly based on the guix reference manual and the guix cookbook, so refer to them for more on depth explanations. This article is strongly influenced by my personal experience as a daily driver, so next topics are necessarily biased towards my own needs. br/&#xA;There is much more to say about guix, but this is just an introductory crash course, right ? br/&#xA;&#xA;install&#xA;&#xA;First things first. You need to be root to proceed to a binary guix installation. Just download the installer, and follow the instructions. br/&#xA;After that, you’ll be using guix as a regular user, and all what follows must be run without any special rights beyond accessing to your home directory. Behind the curtains, guix computes what’s necessary through the running guix daemon, handled by your host’s systemd. br/&#xA;&#xA;packages&#xA;&#xA;Packages are built definitions. At no surprise, they are installed (or removed) with br/&#xA;&#xA;guix search synthesis&#xA;guix install yosys&#xA;guix remove python&#xA;&#xA;Definitions, in turn, are guile descriptions on how and where to obtain code source, a precise and unambiguous reference to it, how to process and how to install it, along with the necessary input dependencies, its kind, and how to use them. Definitions may be seen as customized default build templates, which avoids complicated package definitions, simplifying its design. Thus, a default build template called python-build-system exist, for example, for producing python packages. A package definition customizes the way this template is used, modifying its default package, source, etc. fields. br/&#xA;Definitions are built on isolated, minimalistic environments. Once built, packages are deposit in the guix store under /gnu/store. Each package is given a unique hash: changing the definition, or any of its inputs, produces a different package and hash. This is what usually is referred to as functional package management of #dependencies. br/&#xA;A package may have multiple outputs (out, by default, but also doc, etc.). Packages are built locally following the package definition. To avoid long run times and wasting cpu cycles, guix introduces substitutes or pre-built packages available on remote (substitute) servers. When available, substitutes are downloaded, which avoids having to built packages locally. Otherwise, your local computing resources will be put to contribution, which is far from ideal, so better configure your substitute servers before anything else (check your systemd guix-daemon file). It is possible to verify substitute availability with br/&#xA;&#xA;guix weather ghdl-clang&#xA;&#xA;  https://guix.bordeaux.inria.fr ☀&#xA;--  100.0 % des substituts sont disponibles (1 sur 1)  &lt;--&#xA;    6,2 Mio de fichiers nar (compressés)&#xA;    39,6 Mio sur le disque (décompressé)&#xA;    0,777 secondes par requête (0,8 secondes en tout)&#xA;    1,3 requêtes par seconde&#xA;&#xA;It is crucial to understand that a given package built will be identical to any other build of this same package, regardless of the host computer, which is what holds the validity of the very idea of substitutes, and guarantees #reproducibility. This holds for any guix construction, including shell containers (see below). br/&#xA;Keep that in mind. br/&#xA;&#xA;profiles and generations&#xA;&#xA;After first install, guix will create on your behalf a default profile under ~/.guix-profile. All operations (install, remove) will affect this profile, unless you decide to point somewhere else (with the modifier -p $GUIXPROFILE). br/&#xA;&#xA;guix package -p $GUIXPROFILE --list-installed&#xA;&#xA;coreutils       9.1     out     /gnu/store/fk39d3y3zyr6ajyzy8d6ghd0sj524cs5-coreutils-9.1&#xA;git             2.46.0  out     /gnu/store/wyhw9f49kvc7qvbsbfgm09lj0cpz1wlb-git-2.46.0&#xA;fw-open-logic   3.0.1   out     /gnu/store/hrgdvswmvqcyai4pqmr7df0kpyyak94j-fw-open-logic-3.0.1&#xA;osvvm-scripts   2024.09 out     /gnu/store/xhxr3y1k8838my6mfk992kn392pwszjm-osvvm-scripts-2024.09&#xA;osvvm-uart      2024.09 out     /gnu/store/x3pjf95h8p3mbcx4zxb6948xfq3y3vg8-osvvm-uart-2024.09&#xA;fd              9.0.0   out     /gnu/store/nx0hz1y3g7iyi4snyza7rl5600z73xyn-fd-9.0.0&#xA;make            4.4.1   out     /gnu/store/963iman5zw7zdf128mqhklihvjh6habm-make-4.4.1&#xA;tcllib          1.19    out     /gnu/store/443vgrmwac1mvipyhin5jblsml9lplxf-tcllib-1.19&#xA;tcl             8.6.12  out     /gnu/store/w2icygvc0h294bzak0dyfafq649sdqvn-tcl-8.6.12&#xA;ghdl-clang      4.1.0   out     /gnu/store/sy0ryysxwbkzj6gpfka20fs27knmgmkd-ghdl-clang-4.1.0&#xA;&#xA;Each profile generation will consist on a set of symbolic links pointing to /gnu/store. A new generation is produced when you install or remove something. This will only redefine your profile’s links, and so the status of the profile (and the packages you have access to). Generations are roughly the equivalent of #git commits, if this helps. They are nothing but collections of links pointing to the store, where packages are installed. Each collection defines a generation and so the current status of a guix profile. br/&#xA;You may roll back to previous generations, or move forward, but only linear generation histories are allowed. In you go back n generations, and then create a new one, your previous history is lost. br/&#xA;&#xA;guix package -p $GUIXPROFILE --list-generations&#xA;&#xA;In addition to creating links, a profile redefines the environment variables (following the profle contents), appending, prepending or replacing the current ones. This way, the user enters an augmented context, having access to the packages in the profile. br/&#xA;Note that, inside a profile, the user still have access to the external system: for example, the PATH env variable is augmented with the profile bin directory, but former binaries are still there. To get a higher degree of isolation, we need shell containers (see below). br/&#xA;&#xA;clean&#xA;&#xA;From time to time, don’t forget to clean the store, removing stuff no profile and generation is pointing to, with br/&#xA;&#xA;guix gc&#xA;&#xA;Before that, remove old generations from your profiles, unless you plan to make use of them at some point. br/&#xA;&#xA;upgrade&#xA;&#xA;Upgrade guix current profile with br/&#xA;&#xA;guix pull &amp;&amp; guix upgrade&#xA;&#xA;This will create a new generation in your default profile, including updates to all your packages in current profile. Pulling syncs local guix with remote guix repository, fetching updates locally. Upgrade will deploy these updates to your profile. br/&#xA;Remember also to br/&#xA;&#xA;sudo -i guix pull&#xA;sudo systemctl daemon-reload&#xA;sudo systemctl restart guix-daemon&#xA;&#xA;to upgrade the system daemon, so that it is never too delayed with respect to your guix in use. br/&#xA;&#xA;manifest, channels&#xA;&#xA;If not already clear from the previous, remember that it is possible to replicate environments (contexts, profiles, dependencies) using a couple of #plaintext files. br/&#xA;First, the #manifest.scm, which includes the list of packages in the environment. As an example, export your current profile with br/&#xA;&#xA;guix package -p $GUIXPROFILE --export-manifest   manifest.scm&#xA;&#xA;Put it somewhere under version control, and replicate your environment somewhere else with br/&#xA;&#xA;guix package -p $GUIXPROFILE -m manifest.scm&#xA;&#xA;That’s all it takes to get exactly the same development context in another host, for example. br/&#xA;But you’re right, I see you follow. This is not enough. You also need to freeze which guix version you’re using (guix, as any other package manager, not always installs the same version of some package). You need also a #channels.scm file. It may be produced with br/&#xA;&#xA;guix describe --format=channels -p $GUIXPROFILE   channels.scm&#xA;&#xA;and includes the list of channels in use, along with a hash to identify which version of the channels to use, among the whole history of channel revisions (the #git commit of the channel repository). Then, import it somewhere else with br/&#xA;&#xA;guix pull -C channels.scm&#xA;&#xA;examples&#xA;&#xA;Fixing your channels, its revision and the list of packages is all you need to eliminate any ambiguity, achieving #reproducibility and #determinism. Remember that this is the best advantage of guix, after all. Say you publish something (report, article, paper, blog ticket). If you provide a git repository with these two files, anyone else will be br/&#xA;able, hopefully, to replicate your asserts. br/&#xA;As a typical example, when you have a complex #vhdl design, including a large set of dependencies, you need a means to handle them. Here, we assume the #dependencies may be vhdl compilers, tcl shells, python interpreters, unit testing libraries, verification frameworks. etc. ... but also other vhdl modules, each in its own git repository. br/&#xA;At this point, you’ll need, first, to fix your channels.scm to &#34;freeze&#34; the repositories status. Here we are using, for example, the electronics, guix-science and guix channels, each in a fix release given by a commit hash. br/&#xA;&#xA;(list (channel&#xA;       (name &#39;electronics)&#xA;       (url &#34;https://git.sr.ht/~csantosb/guix.channel-electronics&#34;)&#xA;       (branch &#34;main&#34;)&#xA;       (commit&#xA;        &#34;2cad57b4bb35cc9250a7391d879345b75af4ee0a&#34;)&#xA;       (introduction&#xA;        (make-channel-introduction&#xA;         &#34;ba1a85b31202a711d3e3ed2f4adca6743e0ecce2&#34;&#xA;         (openpgp-fingerprint&#xA;          &#34;DA15 A1FC 975E 5AA4 0B07  EF76 F1B4 CAD1 F94E E99A&#34;))))&#xA;      (channel&#xA;       (name &#39;guix-science)&#xA;       (url &#34;https://codeberg.org/guix-science/guix-science.git&#34;)&#xA;       (branch &#34;master&#34;)&#xA;       (commit&#xA;        &#34;1ced1b3b913b181e274ca7ed2239d6661c5154c9&#34;)&#xA;       (introduction&#xA;        (make-channel-introduction&#xA;         &#34;b1fe5aaff3ab48e798a4cce02f0212bc91f423dc&#34;&#xA;         (openpgp-fingerprint&#xA;          &#34;CA4F 8CF4 37D7 478F DA05  5FD4 4213 7701 1A37 8446&#34;))))&#xA;      (channel&#xA;       (name &#39;guix)&#xA;       (url &#34;https://git.savannah.gnu.org/git/guix.git&#34;)&#xA;       (branch &#34;master&#34;)&#xA;       (commit&#xA;        &#34;3e2442de5268782213b04048463fcbc5d76accd7&#34;)&#xA;       (introduction&#xA;        (make-channel-introduction&#xA;         &#34;9edb3f66fd807b096b48283debdcddccfea34bad&#34;&#xA;         (openpgp-fingerprint&#xA;          &#34;BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA&#34;)))))&#xA;&#xA;Then, you need the list of dependencies necessary to your design. These are provided in a manifest.scm file, as for example in br/&#xA;&#xA;(specifications-  manifest&#xA; (list &#34;ghdl-clang&#34;&#xA;       &#34;tcl&#34;&#xA;       &#34;tcllib&#34;&#xA;       &#34;make&#34;&#xA;       &#34;python-vunit&#34;&#xA;       &#34;osvvm-uart&#34;&#xA;       &#34;osvvm-scripts&#34;&#xA;       &#34;fw-open-logic&#34;&#xA;       &#34;git&#34;&#xA;       &#34;which&#34;&#xA;       &#34;findutils&#34;&#xA;       &#34;coreutils&#34;))&#xA;&#xA;One may include these two files in the design, in a different testing #git branch, for example. Then, all it takes to run your design in a reproducible way is cloning the design git repository, checking out the testing branch, and running #guix time machine (see next) to replicate a local profile containing all the design’s dependencies. Remember that here we include also all third party firmware modules instantiated in our design. br/&#xA;&#xA;time machine&#xA;&#xA;How guix guarantees that it is possible to reproduce a profile in the future ? The trick consist on asking current guix version to call a previous guix version (the one we define), to deploy the profile with the packages we need. br/&#xA;For example: let&#39;s ask guix-5 to make use of guix-4 to install emacs-30 package, which is only available in the guix-4 repositories, whereas guix-5 only provides emacs-32. br/&#xA;This mechanism is called time-machine. It is used as, for example: br/&#xA;&#xA;guix time-machine --channels=channels.scm -- package -p $GUIXPROFILE -m manifest.scm&#xA;&#xA;Here, up-to-date guix uses time machine to roll back to the former guix version defined in channels.scm. Then, former guix calls the package command to install under $GUIXPROFILE the list of packages defined in the manifest.scm file. br/&#xA;What’s important to understand here is that this will produce exactly the same output regardless of the host and the point in time when we run this command. The profile we produce is always the same, by design. And this is what is relevant for #modernhw. br/&#xA;&#xA;shell containers&#xA;&#xA;Guix includes a command to create independent environments from the rest of our host system. This provides an increased degree of isolation when compared to profiles, as the later lie on top of, and only augment, our current shell. Shell containers create a new, almost empty by default, minimalistic context for us to install packages. br/&#xA;&#xA;guix shell --container --link-profile --emulate-fhs coreutils which python-vunit osvvm-uart&#xA;guix shell --container --link-profile --emulate-fhs -m manifest.scm&#xA;&#xA;or, if one needs determinism br/&#xA;&#xA;guix time-machine --channels=channels.scm -- shell --container --link-profile --emulate-fhs -m manifest.scm&#xA;&#xA;The --link-profile flag will link the contents of $GUIXPROFILE under /gnu/store to ~/.guix-profile. br/&#xA;The --emulate-fs will, well, reproduce the standard file system under /, as some packages expect this layout and fail otherwise. br/&#xA;coreutils and which packages will be helpful, otherwise, not even ls command is present within the container. Minimalistic, I said. I should have use isolated instead. br/&#xA;&#xA;packs&#xA;&#xA;Great. But. What if guix is not around ? How do I use it in a cluster, or in another host where guix is not yet available ? How do I distribute my dependencies, environments, etc. to a non-yet-guix-user ? No problem, guix pack is intended to be used as a simple way of &#34;packaging&#34; guix contexts (understood as a set of packages), deploying them afterward in a target host. This is next step after profiles and shell containers. br/&#xA;Guix pack comes equipped with several different backends, producing contexts in the most habitual and useful formats. For example, the following command will pack #emacs, #ghdl and #yosys for you to use where you need it. br/&#xA;&#xA;guix pack -f docker emacs ghdl-clang yosys&#xA;&#xA;In the context of #modernhw, #docker images may be used for #ci tests, uploading the image to a remote #gitforge registry; #apptainer containers can be sent and run in a #hpc cluster; .tar.gz compresses files are a clean may of installing non-existing software in a remote machine. Furthermore, one has the possibility of packaging all the project #dependencies in a manifest.scm file, and distribute it along with the source code to anyone willing to use it. No instructions about the proper environment to run the project, no complicated installation of dependencies. Stop asking third party users in your README to handle your dependencies for you. br/&#xA;A simple docker pull pointing to a #forge image repository is enough when guix is not locally available. Long run times ? Use a #forge #ci custom runner in your own hardware with your #singularity image. Remote work to an #ssh server with obsolete software ? Pack, send and untar your favorite development tools and create a custom profile, no admin rights needed. The possibilities are endless. br/&#xA;And most important: the advantage of this approach over a classical docker or singularity files for producing the images is #reproducibility: every single time you build the image, you’ll get the exact same binary product. Use the --save-provenance flag to store in the image itself the manifest you used to create it. br/&#xA;Good luck trying to achieve the same with a docker file. br/&#xA;&#xA;importing&#xA;&#xA;Now, guix is not a universal tool for installing anything around. What about this obscure #python package no one uses but you ? You’d absolutely need this #emacs package you just found on #codeberg which guix doesn’t provide. Rust, go ... There are plenty of pieces of code around not being yet packaged along with guix. No problem. Guix incorporates a simple and elegant way of extending the amount of packages you’ll be able to install. Just import them. br/&#xA;&#xA;guix import pypi itsdangerous&#xA;guix import crate becareful&#xA;guix import gem wow&#xA;&#xA;Previous commands will issue a new package definition corresponding to a package already handled by the language own package manager. #Dependencies, you say ? Use the --recursive flag. Once you have the definition, you’ll be able to build, install and use the corresponding package. br/&#xA;Check in the documentation the surprising amount of backends available, you’ll be gratefully surprised. br/&#xA;&#xA;software heritage&#xA;&#xA;Last, but not least. br/&#xA;You have guix, its package definitions and all the fancy tools which come along. But. What if you don’t have access to the source code ? In this case, all the previous becomes meaningless: remember that guix is a fully bootstrapped distribution, being built from the very bottom up. Building a package from its source means having access to the source, which most of the time is hosted in a #gitforge. But #forges disappear, especially proprietary ones, repositories relocate or are just obsoleted and get replaced. br/&#xA;In this case, guix gets you covered by falling back to Software Heritage (#SH). This initiative, with support of the UNESCO, collects, preserves, and shares the source code of all software that is publicly available, including its full development history. The collection is trigger automatically by a crawler, manually with a browser plugin or by guix itself when developers lint package definitions. br/&#xA;If, in ten years, you try to replicate one of your papers, and you plan to recreate your environment to run your code and reproduce your plots, you won’t be bothered by nowadays python 3.10 having being obsoleted, abandon and buried in history of computers by #guile. SH keeps a copy for you to sleep better at night. br/&#xA;&#xA;channels&#xA;&#xA;Channels, as a feature to extend guix repository of definitions, deserve its own chapter. br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/blog.csantosb/blob/master/pics/guix-crash-course.png" alt="img"> <br/>
Guix reveals as a <a href="https://infosec.press/csantosb/use-guix" rel="nofollow">practical means</a> of handling <a href="https://infosec.press/csantosb/on-dependencies" rel="nofollow">dependencies</a>. However, the amount of information available to start using it may appear as a bit overwhelming for a beginner, letting the feeling of a tool reserved to a reduced community or experts. Far from that. Here you’ll find everything you need to get started with <a href="https://guix.gnu.org/" rel="nofollow">guix</a>, with a light touch on using it for <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>.  <br/>
We will concentrate in the use of <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> as an external package manager on top of a <a href="/csantosb/tag:linux" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">linux</span></a> distribution based on <a href="/csantosb/tag:systemd" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">systemd</span></a>. We’ll let aside using and referring to <a href="/csantosb/tag:guixsystem" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guixsystem</span></a> as a full operating system by itself (which I never used anyway). This way, in the context of <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>, we may keep on using our favorite tools, environment and workflow. As an addition, we have everything that guix provides at our disposal, without affecting our local packages configuration: guix acts as an extra layer on top of our current OS, without any interference with it. You’ll have the possibility to install any guix software, remove it afterward or make use of the fancy features guix has to offer, without your host OS ever noticing what’s going on. <br/>
All what follows is roughly based on the <a href="https://guix.gnu.org/manual/en/html_node/index.html" rel="nofollow">guix reference manual</a> and the <a href="https://guix.gnu.org/cookbook/en/guix-cookbook.html" rel="nofollow">guix cookbook</a>, so refer to them for more on depth explanations. This article is strongly influenced by my personal experience as a daily driver, so next topics are necessarily biased towards my own needs. <br/>
There is <a href="https://www.futurile.net/resources/guix/" rel="nofollow">much more to say</a> about guix, but this is just an introductory crash course, right ? <br/></p>

<h1 id="install">install</h1>

<p>First things first. You need to be root to proceed to a <a href="https://guix.gnu.org/manual/en/html_node/Binary-Installation.html" rel="nofollow">binary guix installation</a>. Just download the installer, and follow the instructions. <br/>
After that, you’ll be using guix as a regular user, and all what follows must be run without any special rights beyond accessing to your home directory. Behind the curtains, guix computes what’s necessary through the running guix daemon, handled by your host’s systemd. <br/></p>

<h1 id="packages">packages</h1>

<p>Packages are built definitions. At no surprise, they are installed (or removed) with <br/></p>

<pre><code class="language-sh">guix search synthesis
guix install yosys
guix remove python
</code></pre>

<p><a href="https://guix.gnu.org/cookbook/en/html_node/A-_0060_0060Hello-World_0027_0027-package.html" rel="nofollow">Definitions</a>, in turn, are <a href="https://guix.gnu.org/cookbook/en/html_node/A-Scheme-Crash-Course.html" rel="nofollow">guile</a> descriptions on how and where to obtain code source, a precise and unambiguous reference to it, how to process and how to install it, along with the necessary input dependencies, its kind, and how to use them. Definitions may be seen as customized default <a href="https://guix.gnu.org/manual/en/html_node/Build-Systems.html" rel="nofollow">build templates</a>, which avoids complicated package definitions, simplifying its design. Thus, a default build template called <code>python-build-system</code> exist, for example, for producing python packages. A package definition customizes the way this template is used, modifying its default package, source, etc. fields. <br/>
Definitions are built on isolated, minimalistic environments. Once built, packages are deposit in the guix store under <code>/gnu/store</code>. Each package is given a unique hash: changing the definition, or any of its inputs, produces a different package and hash. This is what usually is referred to as <a href="https://arxiv.org/abs/1305.4584" rel="nofollow">functional package management</a> of <a href="/csantosb/tag:dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dependencies</span></a>. <br/>
A package may have multiple outputs (<code>out</code>, by default, but also <code>doc</code>, etc.). Packages are built locally following the package definition. To avoid long run times and wasting cpu cycles, guix introduces <a href="https://guix.gnu.org/manual/en/html_node/Substitutes.html" rel="nofollow">substitutes</a> or pre-built packages available on remote (substitute) servers. When available, substitutes are downloaded, which avoids having to built packages locally. Otherwise, your local computing resources will be put to contribution, which is far from ideal, so better configure your substitute servers before anything else (check your systemd <code>guix-daemon</code> file). It is possible to verify substitute availability with <br/></p>

<pre><code class="language-sh">guix weather ghdl-clang
</code></pre>

<pre><code class="language-sh">  https://guix.bordeaux.inria.fr ☀
--&gt; 100.0 % des substituts sont disponibles (1 sur 1)  &lt;--
    6,2 Mio de fichiers nar (compressés)
    39,6 Mio sur le disque (décompressé)
    0,777 secondes par requête (0,8 secondes en tout)
    1,3 requêtes par seconde
</code></pre>

<p>It is <strong>crucial</strong> to understand that <em>a given package built will be identical to any other build of this same package</em>, regardless of the host computer, which is what holds the validity of the very idea of substitutes, and guarantees <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a>. This holds for any guix construction, including shell containers (see below). <br/>
Keep that in mind. <br/></p>

<h1 id="profiles-and-generations">profiles and generations</h1>

<p>After first install, guix will create on your behalf a default profile under <code>~/.guix-profile</code>. All operations (install, remove) will affect this profile, unless you decide to point somewhere else (with the modifier <code>-p $GUIX_PROFILE</code>). <br/></p>

<pre><code class="language-sh">guix package -p $GUIX_PROFILE --list-installed
</code></pre>

<pre><code class="language-sh">coreutils       9.1     out     /gnu/store/fk39d3y3zyr6ajyzy8d6ghd0sj524cs5-coreutils-9.1
git             2.46.0  out     /gnu/store/wyhw9f49kvc7qvbsbfgm09lj0cpz1wlb-git-2.46.0
fw-open-logic   3.0.1   out     /gnu/store/hrgdvswmvqcyai4pqmr7df0kpyyak94j-fw-open-logic-3.0.1
osvvm-scripts   2024.09 out     /gnu/store/xhxr3y1k8838my6mfk992kn392pwszjm-osvvm-scripts-2024.09
osvvm-uart      2024.09 out     /gnu/store/x3pjf95h8p3mbcx4zxb6948xfq3y3vg8-osvvm-uart-2024.09
fd              9.0.0   out     /gnu/store/nx0hz1y3g7iyi4snyza7rl5600z73xyn-fd-9.0.0
make            4.4.1   out     /gnu/store/963iman5zw7zdf128mqhklihvjh6habm-make-4.4.1
tcllib          1.19    out     /gnu/store/443vgrmwac1mvipyhin5jblsml9lplxf-tcllib-1.19
tcl             8.6.12  out     /gnu/store/w2icygvc0h294bzak0dyfafq649sdqvn-tcl-8.6.12
ghdl-clang      4.1.0   out     /gnu/store/sy0ryysxwbkzj6gpfka20fs27knmgmkd-ghdl-clang-4.1.0
</code></pre>

<p>Each profile generation will consist on a set of symbolic links pointing to <code>/gnu/store</code>. A new generation is produced when you install or remove something. This will only redefine your profile’s links, and so the status of the profile (and the packages you have access to). Generations are roughly the equivalent of <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> commits, if this helps. They are nothing but collections of links pointing to the store, where packages are installed. Each collection defines a generation and so the current status of a guix profile. <br/>
You may roll back to previous generations, or move forward, but only linear generation histories are allowed. In you go back n generations, and then create a new one, your previous history is lost. <br/></p>

<pre><code class="language-sh">guix package -p $GUIX_PROFILE --list-generations
</code></pre>

<p>In addition to creating links, a profile redefines the environment variables (following the profle contents), appending, prepending or replacing the current ones. This way, the user enters an augmented context, having access to the packages in the profile. <br/>
Note that, inside a profile, the user still have access to the external system: for example, the PATH env variable is augmented with the profile bin directory, but former binaries are still there. To get a higher degree of isolation, we need shell containers (see below). <br/></p>

<h1 id="clean">clean</h1>

<p>From time to time, don’t forget to clean the store, removing stuff no profile and generation is pointing to, with <br/></p>

<pre><code class="language-sh">guix gc
</code></pre>

<p>Before that, remove old generations from your profiles, unless you plan to make use of them at some point. <br/></p>

<h1 id="upgrade">upgrade</h1>

<p>Upgrade guix current profile with <br/></p>

<pre><code class="language-sh">guix pull &amp;&amp; guix upgrade
</code></pre>

<p>This will create a new generation in your default profile, including updates to all your packages in current profile. <code>Pulling</code> syncs local guix with remote guix repository, fetching updates locally. <code>Upgrade</code> will deploy these updates to your profile. <br/>
Remember also to <br/></p>

<pre><code class="language-sh">sudo -i guix pull
sudo systemctl daemon-reload
sudo systemctl restart guix-daemon
</code></pre>

<p>to upgrade the system daemon, so that it is never too delayed with respect to your guix in use. <br/></p>

<h1 id="manifest-channels">manifest, channels</h1>

<p>If not already clear from the previous, remember that it is possible to <a href="https://guix.gnu.org/manual/en/html_node/Replicating-Guix.html" rel="nofollow">replicate</a> environments (contexts, profiles, dependencies) using a couple of <a href="/csantosb/tag:plaintext" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">plaintext</span></a> files. <br/>
First, the <code>#manifest.scm</code>, which includes the list of packages in the environment. As an example, export your current profile with <br/></p>

<pre><code class="language-sh">guix package -p $GUIX_PROFILE --export-manifest &gt; manifest.scm
</code></pre>

<p>Put it somewhere under version control, and replicate your environment somewhere else with <br/></p>

<pre><code class="language-sh">guix package -p $GUIX_PROFILE -m manifest.scm
</code></pre>

<p>That’s all it takes to get exactly the same development context in another host, for example. <br/>
But you’re right, I see you follow. This is not enough. You also need to freeze which guix version you’re using (guix, as any other package manager, not always installs the same version of some package). You need also a <code>#channels.scm</code> file. It may be produced with <br/></p>

<pre><code class="language-sh">guix describe --format=channels -p $GUIX_PROFILE &gt; channels.scm
</code></pre>

<p>and includes the list of <a href="https://infosec.press/csantosb/guix-channels" rel="nofollow">channels</a> in use, along with a hash to identify <em>which version</em> of the channels to use, among the whole history of channel revisions (the <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> commit of the channel repository). Then, import it somewhere else with <br/></p>

<pre><code class="language-sh">guix pull -C channels.scm
</code></pre>

<h2 id="examples">examples</h2>

<p>Fixing your channels, its revision and the list of packages is all you need to eliminate any ambiguity, achieving <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> and <a href="/csantosb/tag:determinism" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">determinism</span></a>. Remember that this is the best advantage of guix, after all. Say you publish something (report, article, paper, blog ticket). If you provide a git repository with these two files, anyone else will be <br/>
able, hopefully, to replicate your asserts. <br/>
As a typical example, when you have a complex <a href="/csantosb/tag:vhdl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">vhdl</span></a> design, including <a href="https://infosec.press/csantosb/on-dependencies" rel="nofollow">a large set of dependencies</a>, you need a means to handle them. Here, we assume the <a href="/csantosb/tag:dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dependencies</span></a> may be vhdl compilers, tcl shells, python interpreters, unit testing libraries, verification frameworks. etc. ... but also other vhdl modules, each in its own git repository. <br/>
At this point, you’ll need, first, to fix your <code>channels.scm</code> to “freeze” the repositories status. Here we are using, for example, the <a href="https://git.sr.ht/~csantosb/guix.channel-electronics" rel="nofollow">electronics</a>, <a href="https://git.sr.ht/~csantosb/guix.channel-electronics" rel="nofollow">guix-science</a> and guix channels, each in a fix release given by a commit hash. <br/></p>

<pre><code class="language-scheme">(list (channel
       (name &#39;electronics)
       (url &#34;https://git.sr.ht/~csantosb/guix.channel-electronics&#34;)
       (branch &#34;main&#34;)
       (commit
        &#34;2cad57b4bb35cc9250a7391d879345b75af4ee0a&#34;)
       (introduction
        (make-channel-introduction
         &#34;ba1a85b31202a711d3e3ed2f4adca6743e0ecce2&#34;
         (openpgp-fingerprint
          &#34;DA15 A1FC 975E 5AA4 0B07  EF76 F1B4 CAD1 F94E E99A&#34;))))
      (channel
       (name &#39;guix-science)
       (url &#34;https://codeberg.org/guix-science/guix-science.git&#34;)
       (branch &#34;master&#34;)
       (commit
        &#34;1ced1b3b913b181e274ca7ed2239d6661c5154c9&#34;)
       (introduction
        (make-channel-introduction
         &#34;b1fe5aaff3ab48e798a4cce02f0212bc91f423dc&#34;
         (openpgp-fingerprint
          &#34;CA4F 8CF4 37D7 478F DA05  5FD4 4213 7701 1A37 8446&#34;))))
      (channel
       (name &#39;guix)
       (url &#34;https://git.savannah.gnu.org/git/guix.git&#34;)
       (branch &#34;master&#34;)
       (commit
        &#34;3e2442de5268782213b04048463fcbc5d76accd7&#34;)
       (introduction
        (make-channel-introduction
         &#34;9edb3f66fd807b096b48283debdcddccfea34bad&#34;
         (openpgp-fingerprint
          &#34;BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA&#34;)))))

</code></pre>

<p>Then, you need the list of dependencies necessary to your design. These are provided in a <code>manifest.scm</code> file, as for example in <br/></p>

<pre><code class="language-scheme">(specifications-&gt;manifest
 (list &#34;ghdl-clang&#34;
       &#34;tcl&#34;
       &#34;tcllib&#34;
       &#34;make&#34;
       &#34;python-vunit&#34;
       &#34;osvvm-uart&#34;
       &#34;osvvm-scripts&#34;
       &#34;fw-open-logic&#34;
       &#34;git&#34;
       &#34;which&#34;
       &#34;findutils&#34;
       &#34;coreutils&#34;))
</code></pre>

<p>One may include these two files in the design, in a different <code>testing</code> <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> branch, for example. Then, all it takes to run your design in a reproducible way is cloning the design git repository, checking out the <code>testing</code> branch, and running <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> time machine (see next) to replicate a local profile containing all the design’s dependencies. Remember that here we include also all third party firmware modules instantiated in our design. <br/></p>

<h1 id="time-machine">time machine</h1>

<p>How guix guarantees that it is possible to reproduce a profile in the future ? The trick consist on asking current guix version to call a previous guix version (the one we define), to deploy the profile with the packages we need. <br/>
For example: let&#39;s ask guix-5 to make use of guix-4 to install emacs-30 package, which is only available in the guix-4 repositories, whereas guix-5 only provides emacs-32. <br/>
This mechanism is called time-machine. It is used as, for example: <br/></p>

<pre><code class="language-sh">guix time-machine --channels=channels.scm -- package -p $GUIX_PROFILE -m manifest.scm
</code></pre>

<p>Here, up-to-date guix uses time machine to roll back to the former guix version defined in <code>channels.scm</code>. Then, former guix calls the <code>package</code> command to install under <code>$GUIX_PROFILE</code> the list of packages defined in the <code>manifest.scm</code> file. <br/>
What’s important to understand here is that this will produce exactly the same output regardless of the host and the point in time when we run this command. The profile we produce is always the same, by design. And <em>this is what is relevant for <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a></em>. <br/></p>

<h1 id="shell-containers">shell containers</h1>

<p>Guix includes a command to create independent environments from the rest of our host system. This provides an increased degree of isolation when compared to profiles, as the later lie on top of, and only augment, our current shell. Shell containers create a new, almost empty by default, minimalistic context for us to install packages. <br/></p>

<pre><code class="language-sh">guix shell --container --link-profile --emulate-fhs coreutils which python-vunit osvvm-uart
guix shell --container --link-profile --emulate-fhs -m manifest.scm
</code></pre>

<p>or, if one needs determinism <br/></p>

<pre><code class="language-sh">guix time-machine --channels=channels.scm -- shell --container --link-profile --emulate-fhs -m manifest.scm
</code></pre>

<p>The <code>--link-profile</code> flag will link the contents of <code>$GUIX_PROFILE</code> under <code>/gnu/store</code> to <code>~/.guix-profile</code>. <br/>
The <code>--emulate-fs</code> will, well, reproduce the standard file system under <code>/</code>, as some packages expect this layout and fail otherwise. <br/>
<code>coreutils</code> and <code>which</code> packages will be helpful, otherwise, not even <code>ls</code> command is present within the container. Minimalistic, I said. I should have use isolated instead. <br/></p>

<h1 id="packs">packs</h1>

<p>Great. But. What if guix is not around ? How do I use it in a cluster, or in another host where guix is not yet available ? How do I distribute my dependencies, environments, etc. to a non-yet-guix-user ? No problem, <code>guix pack</code> is intended to be used as a <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-pack.html" rel="nofollow">simple way</a> of “packaging” guix contexts (understood as a set of packages), deploying them afterward in a target host. This is next step after profiles and shell containers. <br/>
Guix pack comes equipped with several different backends, producing contexts in the most habitual and useful formats. For example, the following command will pack <a href="/csantosb/tag:emacs" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">emacs</span></a>, <a href="/csantosb/tag:ghdl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ghdl</span></a> and <a href="/csantosb/tag:yosys" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">yosys</span></a> for you to use where you need it. <br/></p>

<pre><code class="language-sh">guix pack -f docker emacs ghdl-clang yosys
</code></pre>

<p>In the context of <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>, <a href="/csantosb/tag:docker" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">docker</span></a> images may be used for <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> tests, uploading the image to a remote <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> registry; <a href="/csantosb/tag:apptainer" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">apptainer</span></a> containers can be sent and run in a <a href="/csantosb/tag:hpc" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">hpc</span></a> cluster; .tar.gz compresses files are a clean may of installing non-existing software in a remote machine. Furthermore, one has the possibility of packaging all the project <a href="/csantosb/tag:dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dependencies</span></a> in a <code>manifest.scm</code> file, and distribute it along with the source code to anyone willing to use it. No instructions about the proper environment to run the project, no complicated installation of dependencies. <em>Stop asking third party users in your README to handle <strong>your dependencies</strong> for you</em>. <br/>
A simple <code>docker pull</code> pointing to a <a href="/csantosb/tag:forge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">forge</span></a> image repository is enough when guix is not locally available. Long run times ? Use a <a href="/csantosb/tag:forge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">forge</span></a> <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> custom runner in your own hardware with your <a href="/csantosb/tag:singularity" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">singularity</span></a> image. Remote work to an <a href="/csantosb/tag:ssh" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ssh</span></a> server with obsolete software ? Pack, send and untar your favorite development tools and create a custom profile, no admin rights needed. The possibilities are endless. <br/>
And most important: the advantage of this approach over a classical docker or singularity files for producing the images is <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a>: every single time you build the image, you’ll get the exact same binary product. Use the <code>--save-provenance</code> flag to store in the image itself the manifest you used to create it. <br/>
Good luck trying to achieve the same with a docker file. <br/></p>

<h1 id="importing">importing</h1>

<p>Now, guix is not a universal tool for installing anything around. What about this obscure <a href="/csantosb/tag:python" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">python</span></a> package no one uses but you ? You’d absolutely need this <a href="/csantosb/tag:emacs" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">emacs</span></a> package you just found on <a href="/csantosb/tag:codeberg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">codeberg</span></a> which guix doesn’t provide. Rust, go ... There are plenty of pieces of code around not being yet packaged along with guix. No problem. Guix incorporates a simple and elegant way of extending the amount of packages you’ll be able to install. Just <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-import.html" rel="nofollow">import them</a>. <br/></p>

<pre><code class="language-sh">guix import pypi itsdangerous
guix import crate becareful
guix import gem wow
</code></pre>

<p>Previous commands will issue a new package definition corresponding to a package already handled by the language own package manager. <a href="/csantosb/tag:Dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Dependencies</span></a>, you say ? Use the <code>--recursive</code> flag. Once you have the definition, you’ll be able to build, install and use the corresponding package. <br/>
Check in the <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-import.html" rel="nofollow">documentation</a> the surprising amount of backends available, you’ll be gratefully surprised. <br/></p>

<h1 id="software-heritage">software heritage</h1>

<p>Last, but not least. <br/>
You have guix, its package definitions and all the fancy tools which come along. But. What if you don’t have access to the source code ? In this case, all the previous becomes meaningless: remember that guix is a fully bootstrapped distribution, <a href="https://infosec.press/csantosb/use-guix" rel="nofollow">being built from the very bottom up</a>. Building a package from its source means having access to the source, which most of the time is hosted in a <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a>. But <a href="/csantosb/tag:forges" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">forges</span></a> disappear, especially proprietary ones, repositories relocate or are just obsoleted and get replaced. <br/>
In this case, guix gets you covered by falling back to <a href="https://www.softwareheritage.org/2019/04/18/software-heritage-and-gnu-guix-join-forces-to-enable-long-term-reproducibility/" rel="nofollow">Software Heritage</a> (<a href="/csantosb/tag:SH" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">SH</span></a>). This initiative, <a href="https://www.unesco.org/en/articles/celebrating-software-source-code-digital-heritage" rel="nofollow">with support of the UNESCO</a>, collects, preserves, and shares the source code of all software that is publicly available, including its full development history. The collection is trigger automatically by a crawler, manually with a <a href="https://www.softwareheritage.org/browser-extensions/" rel="nofollow">browser plugin</a> or by guix itself when developers lint package definitions. <br/>
If, in ten years, you try to replicate one of your papers, and you plan to recreate your environment to run your code and reproduce your plots, you won’t be bothered by nowadays python 3.10 having being obsoleted, abandon and buried in history of computers by <a href="/csantosb/tag:guile" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guile</span></a>. SH keeps a copy for you to sleep better at night. <br/></p>

<h1 id="channels">channels</h1>

<p><a href="https://guix.gnu.org/manual/en/html_node/Channels.html" rel="nofollow">Channels</a>, as a feature to extend guix repository of definitions, deserve <a href="https://infosec.press/csantosb/guix-channels" rel="nofollow">its own chapter</a>. <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/guix-crash-course</guid>
      <pubDate>Fri, 29 Nov 2024 15:25:48 +0000</pubDate>
    </item>
    <item>
      <title>guix</title>
      <link>https://infosec.press/csantosb/use-guix</link>
      <description>&lt;![CDATA[img br/&#xA;As one understands with time and a bit of experience, keeping track of the whole bunch of #dependencies necessary to handle daily when doing digital hardware design may reveal as an error-prone task. And yet, this is not to speak about regressions, incompatibilities and most important, #reproducibility of results. Luckyly enough, this is precisely the problem that #guix intends to solve, in an elegant, minimalistic and open way, using only #freesoftware. !--more-- br/&#xA;&#xA;Nix&#xA;&#xA;Functional package management is a paradigm pioneer by nix and developed by Eelco Dolstra in his influential PhD Thesis. It is based on building each of the nodes in the graph of dependencies based solely in its inputs, contents, and node definition, producing a new node. The process repeats for every single node in the graph. In what concerns operating systems and software management, this comes to a radical different approach to classical package management. Simply put, every new build lives its life, regardless of the remaining builds. This makes it possible to have access to the kind of advanced utilities which ease our lives: declarative configurations, profiles, rollbacks, generations, etc. Forget the dependency hell. br/&#xA;Guix is founded on a similar approach, keeping its own set of rules as it only packages #freesoftware. There are around 30.000 of them as for today, including all the usual suspects. Within the context of #modernhw, guix is to be understood as a dependency management tool with advanced capabilities. Sure, it handles software, but there is no reason to use it exclusively as a software manager. It may handle IP blocks, documentation, bibliographic references, and more generally, all what concerns #plaintext files in a #gitforge. It understands versions, licences, dependencies, repositories and all kinds of relationships between them. Furthermore, it embeds a pragmatic language, guile, to script package definitions, declaring the behavior of nodes in our graph of dependencies. br/&#xA;&#xA;Reproducibility&#xA;&#xA;The most relevant feature of guix turns out to be its bootstraping capabilities. Full source bootstrap comes to building the whole dependency graph right from the bottom, based on a core minimum of trusted binary seeds. From that point upwards the whole distribution is self-contained, as all that it builds is included in guix itself. Any available package is founded on a package definition included in guix, its source code available online in a #git repository, and its dependencies. Each of the latest, follows the same rules, down to the bottom of the graph where a trust seed is necessary. br/&#xA;Why is this necessary and useful for #modernhw ? Because it provides #reproducibility for free, as reproducible builds are granted here. Turns out that this is at the very heart of guix and produces #determinism, meaning that same operations will produce same outputs, no matter when, no matter what, no matter where. Game over to ambiguity. Determinism, coupled to its declarative nature, reveals as a simple means to track our dependencies history without ambiguity. br/&#xA;Let’s take an example, and say we have a Vivado project in the form of a set of #tcl files. To build the logic of our favourite #fpga, we require also a couple of external firmware dependencies as IP block in their own git repositories, with tagged revisions, being mutually dependent and incompatible, following the tag in use. Not all of them are compliant with our project. Each of the firmware modules incorporates its own set of VHDL versioned dependencies, along with its associated documentation. We need to provide a python testing framework (you guess it), along with its verification libraries. We need to create a static web site with the instructions on how to download, instantiate, compile and deploy each different version of our project for a couple of thousand users out there, each with a different #gnulinux system, version and configuration of installed software and libraries. Take it for granted, each user need a different version of our project, as they need to guarantee compatibility with their own internal developments. And we need to provide the correct version of every tool, compatible with our code and scripts. The right version, I do mean. Not any random version. br/&#xA;Can you imagine the pain ? Now, suppose that you could describe in a couple of #plaintext manifest files the status of your project. End of the history. Users willing to reproduce your project and dependencies only need to git clone the manifest files and install them locally, regardless of their system, of their present libraries or of their abilities. No problem if the host OS doesn’t provide the necessary software, guix handles the situation. Users just do make and the whole project is deployed, tested and simulated, using the right version of each node in the graph. This is Guix at its best. br/&#xA;Not yet convinced ? Take a look at here. br/&#xA;Feeling like tempted ? Start by a crash course to guix. br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/guix.png" alt="img"> <br/>
As one understands with time and a bit of experience, keeping track of the whole bunch of <a href="/csantosb/tag:dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dependencies</span></a> necessary to handle daily when doing digital hardware design may reveal as an error-prone task. And yet, this is not to speak about regressions, incompatibilities and most important, <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> of results. Luckyly enough, this is precisely the problem that <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> intends to solve, in an elegant, minimalistic and open way, using only <a href="/csantosb/tag:freesoftware" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">freesoftware</span></a>.  <br/></p>

<h1 id="nix">Nix</h1>

<p>Functional package management is a paradigm pioneer by <a href="https://nixos.org/" rel="nofollow">nix</a> and developed by <a href="https://edolstra.github.io/" rel="nofollow">Eelco Dolstra</a> in his influential <a href="https://edolstra.github.io/pubs/phd-thesis.pdf" rel="nofollow">PhD Thesis</a>. It is based on building each of the nodes in the graph of dependencies based solely in its inputs, contents, and node definition, producing a new node. The process repeats for every single node in the graph. In what concerns operating systems and software management, this comes to a radical different approach to classical package management. Simply put, every new build lives its life, regardless of the remaining builds. This makes it possible to have access to the kind of advanced utilities which ease our lives: declarative configurations, profiles, rollbacks, generations, etc. Forget the <a href="https://en.wikipedia.org/wiki/Dependency_hell" rel="nofollow">dependency hell</a>. <br/>
<a href="https://guix.gnu.org/" rel="nofollow">Guix</a> is founded on a similar approach, keeping its own set of rules as it only packages <a href="/csantosb/tag:freesoftware" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">freesoftware</span></a>. There are around <a href="https://packages.guix.gnu.org/" rel="nofollow">30.000 of them</a> as for today, including all the usual suspects. Within the context of <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>, guix is to be understood as a dependency management tool with advanced capabilities. Sure, it handles software, but there is no reason to use it exclusively as a software manager. It may handle IP blocks, documentation, bibliographic references, and more generally, all what concerns <a href="/csantosb/tag:plaintext" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">plaintext</span></a> files in a <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a>. It understands versions, licences, dependencies, repositories and all kinds of relationships between them. Furthermore, it embeds a pragmatic language, <a href="https://www.gnu.org/software/guile/" rel="nofollow">guile</a>, to script package definitions, declaring the behavior of nodes in our graph of dependencies. <br/></p>

<h1 id="reproducibility">Reproducibility</h1>

<p>The most relevant feature of guix turns out to be its <a href="https://guix.gnu.org/manual/en/html_node/Bootstrapping.html" rel="nofollow">bootstraping</a> capabilities. <a href="https://guix.gnu.org/en/blog/2023/the-full-source-bootstrap-building-from-source-all-the-way-down/" rel="nofollow">Full source bootstrap</a> comes to building the whole dependency graph right from the bottom, based on a core minimum of trusted binary seeds. From that point upwards the whole distribution is self-contained, as all that it builds is included in guix itself. Any available package is founded on a package definition included in guix, its source code available online in a <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> repository, and its dependencies. Each of the latest, follows the same rules, down to the bottom of the graph where a trust seed is necessary. <br/>
Why is this necessary and useful for <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> ? Because it provides <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> for free, as <a href="https://reproducible-builds.org/" rel="nofollow">reproducible builds</a> are granted here. Turns out that this is at the very heart of guix and produces <a href="/csantosb/tag:determinism" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">determinism</span></a>, meaning that same operations will produce same outputs, no matter when, no matter what, no matter where. Game over to ambiguity. Determinism, coupled to its declarative nature, reveals as a simple means to track our dependencies history without ambiguity. <br/>
Let’s take an example, and say we have a <a href="https://www.amd.com/es/products/software/adaptive-socs-and-fpgas/vivado.html" rel="nofollow">Vivado</a> project in the form of a set of <a href="/csantosb/tag:tcl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">tcl</span></a> files. To build the logic of our favourite <a href="/csantosb/tag:fpga" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">fpga</span></a>, we require also a couple of external firmware dependencies as IP block in their own git repositories, with tagged revisions, being mutually dependent and incompatible, following the tag in use. Not all of them are compliant with our project. Each of the firmware modules incorporates its own set of VHDL versioned dependencies, along with its associated documentation. We need to provide a python testing framework (you guess it), along with its verification libraries. We need to create a static web site with the instructions on how to download, instantiate, compile and deploy each different version of our project for a couple of thousand users out there, each with a different <a href="/csantosb/tag:gnulinux" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gnulinux</span></a> system, version and configuration of installed software and libraries. Take it for granted, each user need a different version of our project, as they need to guarantee compatibility with their own internal developments. And we need to provide the correct version of every tool, compatible with our code and scripts. <strong>The right version</strong>, I do mean. <em>Not any random version</em>. <br/>
Can you imagine the pain ? Now, suppose that you could describe in a couple of <a href="/csantosb/tag:plaintext" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">plaintext</span></a> <a href="https://infosec.press/csantosb/guix-crash-course#examples" rel="nofollow">manifest files</a> the status of your project. End of the history. Users willing to reproduce your project and dependencies only need to git clone the manifest files and install them locally, regardless of their system, of their present libraries or of their abilities. No problem if the host OS doesn’t provide the necessary software, guix handles the situation. Users just do <code>make</code> and the whole project is deployed, tested and simulated, using the right version of each node in the graph. This is Guix at its best. <br/>
Not yet convinced ? Take a look at <a href="https://csantosb.gitlab.io/ip/talks/hdl-lib_proposal/" rel="nofollow">here</a>. <br/>
Feeling like tempted ? Start by a <a href="https://infosec.press/csantosb/guix-crash-course" rel="nofollow">crash course</a> to guix. <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/use-guix</guid>
      <pubDate>Tue, 31 Jan 2023 23:00:00 +0000</pubDate>
    </item>
    <item>
      <title>on dependencies</title>
      <link>https://infosec.press/csantosb/on-dependencies</link>
      <description>&lt;![CDATA[img br/&#xA;Digital hardware design implies dealing with a lot of scripts, configurations, packages, project files, documentation, specifications, bibliographies, data sheets, software, etc. and, of course, a lot of code. Each one comes with its own version history. This is not a problem, as we have #git. But when it comes to #dependencies between different sets, how do we handle the complexity ? !--more-- br/&#xA;Dependencies create a graph between each of its components (nodes). This way, documentation refers to a package, which complies with some scripts, related to project files for a given software. This forms a tree of dependencies, closely related, including duplicated dependencies, as one document may correspond to different pieces of code, forming a loop. And yet, this is not the whole picture. br/&#xA;Each node in the graph incorporates its own history of revisions: a given version of the documentation refers to a particular version of a firmware module, which links to a specific version of a data sheet, sending the user to a certain version of a bibliographic reference. This happens with the whole graph and is usually referred to as dependency hell. The complexity comes from the fact that, when one upgrades a node (to a more recent version), its new dependencies (new versions) are pulled along with it. But, in the most general case, those are also necessary for some other node in the graph, which prevents the upgrade from happening, unless more than one version of the node exists at some point in time. The mess arises. br/&#xA;Classical examples are software package managers, python being its most relevant example (specially due to the amount of dependency managers which coexist). Another good example is operating systems: when one decides to upgrade #librewolf web browser, all the necessary dynamic library dependencies of the new release must be pulled too; some of them maybe happens to be necessary for #emacs, which breaks. Package managers need to keep track of the whole history of graph of dependencies and deal with upgrades, software install and removal so as to keep a coherence between the whole system. Hell in heaven. OS must be seen as a set of nodes in a dependency graph moving forward in time, with obsoleted old releases impossible to reach anymore. br/&#xA;As engineers, this rings a bell. What happens when we upgrade proprietary software to support new hardware (Vivado, looking at you now) ?. A new software release implies new versions of IP cores, sometimes incompatible with previous versions, with different versions of documentation, sometimes incorporating its own set of regressions. #Tcl scripts may break, too, or require an upgrade of interpreters. The hell goes for long ... How do we check that our code performs correctly after an upgrade ? How to ensure that no side effects come with it ? Is it possible to be sure that data sheets are still relevant ? Is this paper compatible with the new upgrade ? Can we automatize all of that, or do we need to proceed by hand ? I guess you catch the idea. br/&#xA;modernhw makes it mandatory to use a tool to deal with dependencies. And a very good one, if you want my opinion, including all the necessary scripting capabilities and flexibility we need to cope with our scripts, configurations, packages, project files, documentation, specifications, bibliographies, data sheets, software, etc. and, of course, a lot of code. br/&#xA;Do we have such a tool ? Sure. Its name is #guix. br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/dependencies.png" alt="img"> <br/>
Digital hardware design implies dealing with a lot of scripts, configurations, packages, project files, documentation, specifications, bibliographies, data sheets, software, etc. and, of course, a lot of code. Each one comes with its own version history. This is not a problem, as we have <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a>. But when it comes to <a href="/csantosb/tag:dependencies" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dependencies</span></a> between different sets, <a href="https://csantosb.gitlab.io/ip/talks/hdl-lib_what_is_needed/" rel="nofollow">how do we handle the complexity</a> ?  <br/>
Dependencies create a graph between each of its components (nodes). This way, documentation refers to a package, which complies with some scripts, related to project files for a given software. This forms a tree of dependencies, closely related, including duplicated dependencies, as one document may correspond to different pieces of code, forming a loop. And yet, this is not the whole picture. <br/>
Each node in the graph incorporates its own history of revisions: a given version of the documentation refers to a particular version of a firmware module, which links to a specific version of a data sheet, sending the user to a certain version of a bibliographic reference. This happens with the whole graph and is usually referred to as <a href="https://en.wikipedia.org/wiki/Dependency_hell" rel="nofollow">dependency hell.</a> The complexity comes from the fact that, when one upgrades a node (to a more recent version), its new dependencies (new versions) are pulled along with it. But, in the most general case, those are also necessary for some other node in the graph, which prevents the upgrade from happening, unless more than one version of the node exists at some point in time. The mess arises. <br/>
Classical examples are software package managers, <a href="https://medium.com/knerd/the-nine-circles-of-python-dependency-hell-481d53e3e025" rel="nofollow">python</a> being its most relevant example (specially due to the amount of dependency managers which coexist). Another good example is operating systems: when one decides to upgrade <a href="/csantosb/tag:librewolf" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">librewolf</span></a> web browser, all the necessary dynamic library dependencies of the new release must be pulled too; some of them maybe happens to be necessary for <a href="/csantosb/tag:emacs" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">emacs</span></a>, which breaks. Package managers need to keep track of the whole history of graph of dependencies and deal with upgrades, software install and removal so as to keep a coherence between the whole system. Hell in heaven. OS must be seen as a set of nodes in a dependency graph moving forward in time, with obsoleted old releases impossible to reach anymore. <br/>
As engineers, this rings a bell. What happens when we upgrade proprietary software to support new hardware (<a href="https://www.amd.com/es/products/software/adaptive-socs-and-fpgas/vivado.html" rel="nofollow">Vivado</a>, looking at you now) ?. A new software release implies new versions of IP cores, sometimes incompatible with previous versions, with different versions of documentation, sometimes incorporating its own set of regressions. <a href="/csantosb/tag:Tcl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Tcl</span></a> scripts may break, too, or require an upgrade of interpreters. The hell goes for long ... How do we check that our code performs correctly after an upgrade ? How to ensure that no side effects come with it ? Is it possible to be sure that data sheets are still relevant ? Is this paper compatible with the new upgrade ? Can we automatize all of that, or do we need to proceed by hand ? I guess you catch the idea. <br/>
<a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> makes it mandatory to use a tool to deal with dependencies. And a very good one, if you want my opinion, including all the necessary scripting capabilities and flexibility we need to cope with our scripts, configurations, packages, project files, documentation, specifications, bibliographies, data sheets, software, etc. and, of course, a lot of code. <br/>
Do we have such a tool ? Sure. Its name is <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a>. <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/on-dependencies</guid>
      <pubDate>Tue, 31 Jan 2023 23:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>