Nix flakes are (will be) an importing building block of the wider nix ecosystem. Yet, there is little information about how to provide existing software using flakes, or crucially using nix. This article tries to give some answers to those questions.
Introduction
Nix Flakes are getting more and more popular. On GitHub alone more than 2000 repositories are providing a flake definition of some sort . Although still an RFC, the nix foundation seeks to set the foundation for greater adaption. Some work is concerned with making nix flakes more discoverable. More precisely, I am working on bringing flake support to nixos-search. Yet this post is about something else more foundational! This year The first Summer of Nix is supposed to start in August, and will produce a list of new flakes implementing open source projects funded by the European Commission through NLnet and the NGI-0 initiative.
I am working as a mentor for one group of participants in this project. Being a packager of NGI-0 packages before, and on boarding the first participants one issue became apparent: There is documentation about what are flakes and how to write them, yet there is little information about how to approach packaging more complicated, existing and critically, not nix based software?
NOTE
Defining Scope
In this article I want to speak mostly about how to prepare for and approach packaging, both for SoN participants and the broader community. I am aware that there are many pitfalls related to specific ecosystems. These are not part of this article but will be addressed in upcoming ones by me and perhaps other mentors and participants of SoN.
Schema
HELP
Proposed process schema
first considerations
When starting to package a new foreign project I would first check a few important things that could give a hint of what needs to be done and what might cause trouble. In the following I present a some pointers of what that might be. I assume the list to be growing over time as well.
The Readme and installation instructions
Main language
I believe this one will be somewhat intuitive. After all, knowing what language is packaged allows you get an idea about the state of tools that nix offers to help you. To give ypu a glimpse:
package.json
(JavaScript) ~ Javascript projects either for the client side of things or in terms of a nodeJS project are a classical occurrence. There is decent tooling for those through node2nix. Node2nix can be used to generate a nix package for the the project or at least its dependencies from the package.json
file. ~ Yet because JavaScript tends to be very dynamic, people often end up with non standard solutions or some that make heavy use of build scripts. While this can be fine, one should closely inspect how the default build process works. Usually, build steps are defined in the package.json
file under “scripts.build”
which is the command that would be executed by npm
when running npm build
. There, sometimes external scripts are called which might require additional dependencies not considered by node2nix. ~ Speaking of node2nix, depending on the project, you might need to tweak the node version used as the default node version to date is node v12. ~ There is also yarn2nix
for projects using yarn (yarn workspaces are sadly not supported yet)
Python ~ Python projects can make use of different tools depending of the python environment used. There is mach-nix
whcih serves the same purpose as node2nix in the JS world ~ for projects using poetry there is poetry2nix making use of the greater version pinning abilities offered by the project. ~ Note that nixpkgs.python
resolves to Python 21
Haskell ~ Haskell is one of the best supported environments in nix. It has tight integration with Stack and Cabal and can build projects from either of those prject definition files natively using cabal2nix
and the included pkgs.haskellPackages.callCabal2nix
/pkgs.haskellPackages.callStack2nix
- IOHK has also developed a complete but separate haskell stack for nix: haskell.nix ~ References: - https://bytes.zone/posts/callcabal2nix/ - https://www.srid.ca/haskell-nix
Rust ~ Rust packages, are as well very well supported. This is also due to the excellent cargo package manager used by rust. Unsurprisingly, there is a conversion tool crate2nix
~ Be aware about system dependencies that are not picked up automatically: - openssl
will needed to be added to as a buildInput
for many projects - macos some additional frameworks may be needed. The more regularly missing ones are: libiconv
, darwin.apple_sdk.frameworks.SystemConfiguration
, darwin.apple_sdk.frameworks.CoreServices
and darwin.apple_sdk.frameworks.Security
Makefile
(C/C++) ~ Plain C project might be almost the easiest to package. In the optimal case you will be done referencing the source, as the builder will actually call the GNU build machinery by default. You will still need to add all dependencies as buildInputs
. ~ Finding out which libraries are required can be a tedious task. See below for some pointers to approach this task.
What to flake
Types of artifacts
HELP
Proposed hierarchy
Pure builds
Dependencies
build systems / tools
Dependencies (again)
reimplementing in nix / splitting
pitfalls
Mainly own experiences:
yarn workspaces
Nix dev tools
nix develop / nix-shell
Language specifics (teaser)
Haskell package versions
- jailbreak
Python packages
NodeJS
GNU C/C++
-
https://discourse.nixos.org/t/should-python-point-to-python3/10096↩︎