let
  inherit (import <nixpkgs> {}) lib stdenv;

  # helper to make a really simply derivation
  deriv = { name, deps, buildDeps, ... }: stdenv.mkDerivation {
    inherit name;
    deps = deps (lib.mapAttrs (_: pkg: pkg.drvBuilder pkg) buildDeps);
    buildCommand = "cat $deps > $out"; 
  };

  asDerivation = lib.mapAttrs (_: pkg: pkg.drvBuilder pkg);

  close = super: set: let s = lib.mapAttrs (_: pkg: pkg s super) set; in s;

  pkgs = {
    foo = self: super: { 
      name = "foo"; 
      buildDeps = {}; 
      deps = ctx: []; 
      drvBuilder = deriv; 
    };

    bar = self: super: { 
      name = "bar"; 
      buildDeps = { inherit (self) foo; }; 
      deps = ctx: [ ctx.foo ]; 
      drvBuilder = deriv; 
    };

    qux = self: super: { 
      name = "qux"; 
      buildDeps = { inherit (self) foo bar; }; 
      deps = ctx: [ ctx.foo ctx.bar ]; drvBuilder = deriv;
    };
  };
in asDerivation (close {} pkgs)