5 ms·
It's interesting how Nix's selling point is that its non-standard file system structure allows multiple versions/flavors of the same package to be installed at
by stabbles 3y ago
It's interesting how Nix's selling point is that its non-standard file system structure allows multiple versions/flavors of the same package to be installed at the same time, yet if I understand correctly, it often has one version per package per Nix version? It's more like install multiple versions of the same package at a different time?
Compare this to the model we have in Spack (which is inspired by nix), where there's one recipe per package for many versions, and you can define different build flavors, conditional dependencies (and conditional pretty much everything).
The difference is that Spack has a dependency solver and Nix apparently does not?
For example the curl package [1] has tons of versions, and its `tls` package variant has conditional values depending on the version:
variant("tls", values=("gnutls", conditional("mbedtls", when="@7.46:"), ...), multi=True)
And dependencies are specified as
depends_on("gnutls", when="tls=gnutls")
with when("tls=mbedtls"):
depends_on("mbedtls@2:", when="@7.79:")
depends_on("mbedtls@:2", when="@:7.78")
This allows you both to install all sorts of curls, like `spack install curl tls=mbedtls` (gives you something >= 7.46), or `spack install curl@7.77 tls=mbedtls` gives you a curl with an old mbedtls, etc.
[1] https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/curl/package.py https://github.com/spack/spack/blob/develop/var/spack/repos/...
- _7tgr 3y agoProbably because it's pretty easy to just use an older package from a different version of Nixpkgs (just use an override that defines the attribute for a package in your current Nixpkgs as the same package in an older Nixpkgs). It'll transparently pull the older version from the binary cache, too, if available. The only difficulty is finding the right Nixpkgs commit hash, which this solves. I think I find the Nix way to be a bit cleaner, though I'm unaware of the full set of pros/cons. Worth noting that the Nix package definition for curl at [1] is a little easier to read for me since it doesn't have the duplicated code for each version. [1] https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/curl/default.nix https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/netw...
- nathan_phoenix 3y ago> yet if I understand correctly, it often has one version per package per Nix version? Both yeah and no. Taking the example of nodejs, you have all the supported major releases like nodejs_16, nodejs_18, etc. for each Nix revision[1], but within each revision you only have a specific version of the package. E.g. nodejs_16 is 16.3.1 for revision at date X. There are benefits and drawbacks of managing a package repo like that, with revisions which implicitely pin all packages and it's dependencies at once, but it's too long of a topic to write about here. > For example the curl package [1] has tons of versions [...] So does it in nix (curlMinimal, curlWithGnuTls, curlHTTP3, etc)[2]. In that regard nix and Spack are similar. [1]: A revision is like a shapshot of all the packages at a given point in time. [2]: https://search.nixos.org/packages?channel=23.05&from=0&size=50&sort=relevance&type=packages&query=curl https://search.nixos.org/packages?channel=23.05&from=0&size=...
- stabbles 3y agoThe main difference is that Spack has a single definition of a package, and in Spack language `curlMinimal`, `curlWithGnuTls`, and `curlHTTP3` are all "concretizations" of curl. That has the advantage that dependents can say `depends_on("curl")` if they don't care about the flavor -- only if they somehow require curl with GNU tls, they say `depends_on("curl tls=gnutls")`.
- nathan_phoenix 3y agoOh, didn't know, thanks for the explanation! Does seem like an interesting concept, will check out Speck more in-depth.
- aseipp 3y agoNix also has a single definition of the curl package. The curl package itself can take tons of flags as inputs, indicating how it should be built, and you can then have curlMinimal, curlWithGnuTLS, and curlHTTP3 all as different 'names' for curl with those arguments applied. A package just says it has a 'curl' input and any user can "call" that package, providing any flavor of 'curl' they want as input. You can override those inputs at a global level and local level in various ways. I suspect you mean some other semantic difference, but if that's all you mean, it's not different from Nix in practice, from what it sounds like? https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/networking/curl/default.nix https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/netw...
- Cloudef 3y agoThis is what nix lets you do basically https://github.com/Cloudef/nixos-flake/blob/master/flake.nix#L5-L13 https://github.com/Cloudef/nixos-flake/blob/master/flake.nix... as well as this https://github.com/Cloudef/nixos-flake/blob/master/modules/defaults-darwin.nix#L66-L95 https://github.com/Cloudef/nixos-flake/blob/master/modules/d... Also here I'm referring to specific version of zig for this particular LSP's config file, but it never goes to my PATH https://github.com/Cloudef/nixos-flake/blob/master/modules/neovim.nix#L6-L22 https://github.com/Cloudef/nixos-flake/blob/master/modules/n...
- aseipp 3y ago> It's interesting how Nix's selling point is that its non-standard file system structure allows multiple versions/flavors of the same package to be installed at the same time, yet if I understand correctly, it often has one version per package per Nix version? You're talking about Nixpkgs, and it's a cultural choice. In the past there used to be more of this, where e.g. the Haskell community had lots of variants of the same library all at once, because users and other libraries wanted them. But it became untenable to maintain and you in practice have to do tons of effort to vendor things. And once many of the subcommunities began moving to auto-generated packages (e.g. generating Nix packages from Haskell packages), it becomes much easier to have a single globally consistent repository of versions that all are known to work together, generated by the host-language dependency resolver, with minor fixes applied on demand. There are some things that do have multiple versions in the main repository, e.g. LLVM. But in practice having like 10 versions of everything is a huge chore and only done on demand in practice if users want it, and it has real overhead cognitively and in build time and in maintainer time. You can define your own Nix flake with every version of every Python library in it if you want. But in practice people sort of pick versions of things that make QA a real chore. EDIT: Also, for like 99% of cases, what users think is cool but hardly do is to run both pieces of software at the exact same time concurrently. They typically just want atomic upgrades and rollbacks. For example, you change your git revision at work and get whole new tools, your old tools still work if you go back to the old git revision at no loss. So the need to only have one version "globally" under one name isn't a big deal in practice, because people often are only dealing with one global name. They just don't want their packages to get corrupted during an upgrade or switchover or something otherwise breaks.
- HL33tibCe7 3y agoNot sure if anyone has mentioned this yet, but “spack” is an ableist slur in Britain
- Aerbil313 3y ago...and literally no one cares.