Using non-free libraries in flakes

Hello!

I’m trying to use nix flakes to package some development code and
provide the relevant development environment. However, one of the
python libraries I need uses mkl, and nix develop refuses to fully
evaluate because of this (as it’s unfree).

What then, should I do to enable the use of this unfree library in a
flake?

Thanks,

Sam

1 Like

This should be the same for most nix packages usage:

$ cat ~/.config/nixpkgs/config.nix
{
  allowUnfree = true;
}

It’s set to true there. Error is as follows:

error: --- ThrownError -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
Package ‘mkl-2020.1.217’ in /nix/store/2gvpjwk27dng6c6vw3q3dpfdbza91wmn-source/pkgs/development/libraries/science/math/mkl/default.nix:151 has an unfree license (‘issl’), refusing to evaluate.

a) For `nixos-rebuild` you can set
  { nixpkgs.config.allowUnfree = true; }
in configuration.nix to override this.

b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  { allowUnfree = true; }
to ~/.config/nixpkgs/config.nix.

(use '--show-trace' to show detailed location information)

nix-shell with flake-compatibility works, however.

Thanks,

Sam

do you mind pasting the command that’s failing?

you mention nix develop, but that’s not an official nix command (at least on 2.3.7)

EDIT: I guess nix develop is only available on the nixFlakes verions of nix cli.

Flakes evaluations are pure and therefor don’t source configuration from the user’s home.

The issue is that when using nixpkgs.legacyPackages.x86_64-linux.mkl, that instance of nixpkgs has already been configured. Instead, try importing and constructing another instance of nixpkgs with allowUnfree = true; in the config.

Before:

{
  description = "Flake utils demo";

  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system}; in
      {
        defaultPackage = pkgs.mkl;
      }
    );
}

After:

{
  description = "Flake utils demo";

  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {
          config = { allowUnfree = true; };
        };
      in 
      {
        defaultPackage = pkgs.mkl;
      }
    );
}
1 Like

So does this also mean that flakes do not take into account local overlays, and really anything else mentioned pkgs/top-level/impure.nix?

Actually, I haven’t checked what it does with paths starting with ~/. But it’s not in the spirit of Flakes if it works.

One of the goals is to allow caching of evaluations, which requires to turn off sources of impurities. So builtins like builtins.currentTime, builtins.currentSystem, builtins.getEnv are also disabled or return default values.

2 Likes

This works, mostly. If I want to specify a specific version of nixpkgs
with

inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-20.03";

I get an error about attribute currentSystem being missing:

warning: updating lock file '.../flake.lock':
* Updated 'nixpkgs': 'github:NixOS/nixpkgs/cb1996818edf506c0d1665ab147c253c558a7426' -> 'github:NixOS/nixpkgs/feb9c28902eca0384484004e0b7dfe5ac8661d6c'
warning: Git tree '...' is dirty
error: --- EvalError ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
at: (90:39) in file: /nix/store/hbqx9yg7zc2w70l3myhgrsyhblib5bxm-source/pkgs/top-level/impure.nix

    89|                 else (if args ? localSystem then {}
    90|                       else { system = builtins.currentSystem; }) // localSystem;
      >                                       ^
    91| })

attribute 'currentSystem' missing
(use '--show-trace' to show detailed location information)

Thanks,

Sam

As @zimbatm mentioned

One of the goals is to allow caching of evaluations, which requires to turn off sources of impurities. So builtins like builtins.currentTime , builtins.currentSystem , builtins.getEnv are also disabled or return default values.

you’ll want to replace it with your actual system

nix-repl> lib.platforms.all
[ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "mipsel-linux" "i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd" "x86_64-cygwin" "x86_64-freebsd" "x86_64-linux" "x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris" "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" "x86_64-windows" "i686-windows" "wasm64-wasi" "wasm32-wasi" "x86_64-redox" "powerpc64le-linux" "riscv32-linux" "riscv64-linux" "arm-none" "armv6l-none" "aarch64-none" "avr-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none" "vc4-none" "js-ghcjs" "aarch64-genode" "i686-genode" "x86_64-genode" ]

in your case, it’s likely x86_64-linux assuming you’re on a 64bit linux machine

1 Like

Like this assuming you only care about one system type: https://github.com/ryantm/nixpkgs-update/blob/5749f0029adbf4599b27f5b60a4d7d3d9b88c28d/flake.nix#L20

I potentially care about more than one system type. I had been using
flake-utils and eachDefaultSystem. I ended up adding inherit system;
in the import nixpkgs... and it works.

Thanks,

Sam