How to "merge" several derivation outputs for plugin system?

In this scenario there are usually two derivations, the package itself and a wrapper derivation that joins the package with the plugins. The general pattern goes like this:

{ stdenv, runCommand... }:
let
  # creates a new derivation that wraps the package binary and attaches to the plugins somehow.
  withPlugins = plugins:
    # some time it's possible to reference all the plugins individually
    # if they all need to live in a folder then use symlinkJoin
    let pluginsRef = symlinkJoin { name = "${pkg.name}-plugins"; paths = plugins; }; in
    runCommand "${pkg.name}-with-plugins" {
      buildInputs = [ makeWrapper ];
      passthru.withPlugins = moarPlugins: withPlugins (moarPlugins ++ plugins);
    } ''
      makeWrapper ${package}/bin/whatever $out/bin/whatever \
        --set PLUGIN_PATH ${pluginsRef}
    '';

  pkg = stdenv.mkDerivation {
    # ...
    passthru = inherit withPlugins;
  };
in
  pkg

Like this it’s then possible to invoke thepackage.withPlugins with a list of plugins and get a new version of the package bound to those plugins.

2 Likes