VCV Rack 2 on NixOS / Nix

Hi folks,

I use VCV Rack on NixOS. NixOS is a Linux distribution built on the Nix package management system, which uses the Nix functional programming language to define software packages in a declarative way. Precompiled VCV Rack binaries don’t work natively on NixOS for technical easons I explain in the next paragraph; skip ahead for the current state of VCV Rack 2 on NixOS.

The advantages of using Nix on NixOS include seamless system upgrades, easy switching between different system configurations, and the ability to have different conflicting versions of the same software installed side-by-side in a local software cache called the Nix store; each discrete package and its dependencies are identified by cryptographic hashes so when you start your system or launch an application all the needed package versions are connected by symlinks; if you need to revert to an earlier system configuration or update a shared library version for some applications but not others, Nix just updates the symlinks accordingly instead of actually replacing any software. This comes at a cost of more disk space usage, but the use can periodically purge unused packages and system configurations from the Nix store. Another disadvantage is that because Nix has a unique system for locating shared libraries and other dependencies, Makefiles and other build scripts need to be wrapped to work with dependencies installed via Nix, and most precompiled Linux binaries don’t work on NixOS without being patched to load appropriate shared library versions from the Nix store.

VCV Rack 1 has been available to install via Nix for a while and there’s an open pull request to update this package to the free version of VCV Rack 2: vcv-rack: 1.1.6 -> 2.0.3 by jpotier · Pull Request #148479 · NixOS/nixpkgs · GitHub

I have been testing this Nix package for VCV Rack 2 on my own system; it works great and will hopefully be merged soon. However, Pro is another kettle of fish and it’s discussed a little on the pull request linked above. Pro would probably have to be a separate package from the free version. There are existing Nix packages that patch proprietary binaries at install time so that they can link to dependencies in the Nix store, but the examples I know of are binaries that you can download without authentication, where licenses or subscriptions are checked at runtime, so getting Pro working with Nix would probably require some creative collaboration between VCV devs and Nix packagers. If you have bought Pro or are thinking of buying it and you use NixOS, I’d be interested to hear from you so we can establish whether there’s a userbase for Pro on NixOS and potentially test a Pro package for Nix if that ever comes about.

2 Likes

Nix sounds really interesting, such a clever and innovative way to run a system. It sounds a bit like gentoo, if you have everything set correct it’s a dream but it’s a lot of work getting there.

You might be better off emailing support directly about this.

I’m curious though and I’m not sure I understand the issue, from what you’ve said, if you set up the correct symlinks for it then it should work shouldn’t it? Is it just an issue with packaging?

1 Like

So where most Linux distributions would keep shared libraries in a common directory like /usr/lib, NixOS doesn’t even have a /usr/lib and doesn’t symlink its libraries from a shared location. Instead, each package links to the specific versions of the specific shared libraries it needs in the Nix store, avoiding any path collisions. So in addition to the symlinks, a precompiled binary needs to be patched because the linker stage of compilation has inserted references to shared libraries in /usr/lib and these need to be changed to point to correct Nix store locations.

The specific problem when it comes to VCV Rack Pro is that normally, the Nix package manager would just pull the binary from some public URL, unauthenticated, run a checksum, and do that patching in the background so the user doesn’t have to worry about it. (You’re right to compare it to Gentoo; I think it also shares some traits with BSD ports and container image manifests.) But my understanding is that it can’t do that with VCV Rack Pro because downloading that binary requires being logged in (authenticated) to the VCV Rack web site using an account with a verified purchase. So installing Rack Pro on Nix would require some alternative approach like giving Nix access to the user’s VCV Rack account credentials or providing some mechanism outside the standard package database for patching and installing the binary after the user has manually downloaded it. Actually a relatively easy way to do it would be to run the binary in a container based on a more standard Linux distro, but part of the charm of Nix is that it offers some of the sandboxing and dependency management properties of containers without the CPU overhead.

Anyhow you’re probably right that this is better handled by contacting support directly, but since I only use standalone Rack (though I’m a VCV commercial plugin customer) I want to prove that people would actually use Pro on NixOS before I make the case to VCV Rack devs that they should support this.

1 Like

I have bought VCV Rack 2 Pro and I’m using NixOS. I’d be very interested in Rack 2 Pro support and I’d be willing to help testing etc.

1 Like

Any luck here? I started using NixOS myself and am a paying VCV rack 2 customer.

please contact vcv support.

Got VCV Rack 2 Pro working as standalone. Can’t use the vst in Bitwig though. Sharing my solution for future reference:

  1. Login to vcvrack.com, download Rack 2 Pro.
  2. Add the zip archive to the store: nix store add-file RackPro-2.4.1-lin-x64.zip
  3. Create a nix derivation to install vcv rack:
vcv-rack = pkgs.vcv-rack.overrideAttrs (old: {
  name = "VCV-RackPro";
  version = "2.4.1";
  src = pkgs.requireFile {
    message = "run \"nix store add-file RackPro-2.4.1-lin-x64.zip\"";
    name = "RackPro-2.4.1-lin-x64.zip";
    # sha256 obtained with: nix-hash --flat --type sha256 RackPro-2.4.1-lin-x64.zip
    sha256 = "";
  };
  nativeBuildInputs = with pkgs; [
    copyDesktopItems
    makeWrapper
    wrapGAppsHook
    autoPatchelfHook
    unzip
  ];
  buildInputs = old.buildInputs ++ [
    pkgs.stdenv.cc.cc.lib # for providing libstdc++.so.6 and libgcc_s.so.1
    pkgs.stdenv.cc.libc   # for providing libc.so.6 and libm.so.6
  ];
  unpackPhase = ''
    unzip $src
  '';
  prePatch = "";
  dontPatch = true;
  dontConfigure = true;
  dontBuild = true;
  installPhase = ''
    runHook preInstall

    # copy vst/clap plugins
    mkdir -p $out/lib/vst
    cp 'VCV Rack 2.so' $out/lib/vst
    cp -r 'VCV Rack 2.vst3' $out/lib/vst
    mkdir -p $out/lib/clap
    cp 'VCV Rack 2.clap' $out/lib/clap

    # copy vcv rack
    mkdir -p $out/bin
    cd Rack2Pro
    cp Rack $out/bin
    cp libRack.so $out/lib

    # Rack needs to find the directory Rack2Pro, at one of these locations:
    # - ~/.local/share/VCV/
    # - $XDG_DATA_HOME/VCV/
    # - /usr/share/VCV/
    # - /opt/VCV/
    # or through the variable RACK_SYSTEM_DIR.
    cd ../
    cp -r Rack2Pro $out
    cd Rack2Pro

    mkdir -p $out/share/vcv-rack
    cp -r cacert.pem Core.json res $out/share/vcv-rack
    cp -r Fundamental.vcvplugin LICENSE.html template.vcv template-plugin.vcv $out/share/vcv-rack

    runHook postInstall
  '';
  # set RACK_SYSTEM_DIR env variable
  postInstall = (if old ? postInstall then old.postInstall else "") + ''
    wrapProgram $out/bin/Rack --set RACK_SYSTEM_DIR  $out
  '';
  meta.description = "Open-source virtual modular synthesizer -- paid edition";
  });
  1. Add this derivation to your list of packages, rebuild.
  2. (Not sure if necessary) Set up musnix

Got the vst working: I just needed to define the RACK_SYSTEM_DIR environment variable. Here’s a nix file that I just import in my home.nix:

{ config, pkgs, ... }:
let
  vcv-rack = pkgs.vcv-rack.overrideAttrs (old: rec {
    name = "VCV-RackPro";
    version = "2.5.2";
    src = pkgs.requireFile {
      message = "run \"nix store add-file RackPro-${version}-lin-x64.zip\"";
      name = "RackPro-${version}-lin-x64.zip";
      # sha256 obtained with: nix-hash --flat --type sha256 RackPro-2.5.2-lin-x64.zip
      sha256 = "";
    };
    nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.unzip pkgs.autoPatchelfHook ];
    buildInputs = old.buildInputs ++ [
      pkgs.stdenv.cc.cc.lib # for providing libstdc++.so.6 and libgcc_s.so.1
      pkgs.stdenv.cc.libc   # for providing libc.so.6 and libm.so.6
    ];
    unpackPhase = ''
      unzip $src
    '';
    prePatch = "";
    dontPatch = true;
    dontConfigure = true;
    dontBuild = true;
    installPhase = ''
      runHook preInstall

      # copy vst/clap plugins
      mkdir -p $out/lib/vst
      cp 'VCV Rack 2.so' $out/lib/vst
      cp 'VCV Rack 2 FX.so' $out/lib/vst
      cp -r 'VCV Rack 2.vst3' $out/lib/vst

      mkdir -p $out/lib/clap
      cp 'VCV Rack 2.clap' $out/lib/clap

      # copy vcv rack
      mkdir -p $out/bin
      cd Rack2Pro
      cp Rack $out/bin
      cp libRack.so $out/lib

      # Rack needs to find the directory Rack2Pro, at one of these locations:
      # - ~/.local/share/VCV/
      # - $XDG_DATA_HOME/VCV/
      # - /usr/share/VCV/
      # - /opt/VCV/
      # or through the variable RACK_SYSTEM_DIR.
      mkdir $out/Rack2Pro
      cp -r * $out/Rack2Pro

      mkdir -p $out/share/vcv-rack
      cp -r cacert.pem Core.json res $out/share/vcv-rack
      cp -r Fundamental-2.6.0-lin-x64.vcvplugin LICENSE.html template.vcv template-plugin.vcv $out/share/vcv-rack

      runHook postInstall
    '';
    # set RACK_SYSTEM_DIR env variable
    postInstall = (if old ? postInstall then old.postInstall else "") + ''
      wrapProgram $out/bin/Rack --set RACK_SYSTEM_DIR  $out
    '';
    meta.description = "Open-source virtual modular synthesizer -- paid edition";
  });
in
{
  home.packages = [ vcv-rack ];
  # Define the RACK_SYSTEM_DIR variable
  home.sessionVariables = {
    RACK_SYSTEM_DIR = "${vcv-rack.outPath}";
  };
  home.file.".vst".source  = vcv-rack.outPath + "/lib/vst";
  home.file.".clap".source = vcv-rack.outPath + "/lib/clap";
}

1 Like