Prepare a flake with a broken dependency

I want to prepare a Haskell package for FlakeHub. However, nix build says:

       error: Package ‘llvm-tf-16.0’ in /nix/store/s7qhsczh84gmrdvr6kqj33bab2x0dx0i-source/pkgs/development/haskell-modules/hackage-packages.nix:194254 is marked as broken, refusing to evaluate.

Thus I try export NIXPKGS_ALLOW_BROKEN=1 and nix build --impure successfully builds my package.

How to proceed? Can I add allowBroken to the llvm-tf package in my flake.nix and how and is this a good idea when preparing for FlakeHub?

I can add the line

  nixConfig = { allowBroken = true; };

to my flake.nix. This leads to:

$ nix build
do you want to allow configuration setting 'allowBroken' to be set to 'true' (y/N)? y
do you want to permanently mark this value as trusted (y/N)? y
...

and then the error about broken llvm-tf-16.0 is raised again.

There’s no great solution to this currently. Meta checks (brokenness, licensing, …) are implemented as part of the stdenv builder.

I.e., when nix evaluates your package, as part of the stdenv.mkDerivation call, some code in nixpkgs will check if the package metadata says that the package is broken, and if so, it throws an error, which aborts evaluation.

All of the “please don’t do this” configuration parsing is therefore defined and implemented in nixpkgs directly - nix does not have a concept of licenses or broken packages. This in turn means that you somehow need to set this configuration in the nixpkgs config, rather than the nix config.

In theory, you could write config to ~/.config/nixpkgs/config.nix, and checks will also try to read environment variables, but nix permits neither in flakes’ pure eval mode.

So we’re stuck. There’s no good first party support for this when using flakes.

The best you can do is import the nixpkgs in question and set the config directly when you do so:

let
  system = "x86_64-linux";
  pkgs = import inputs.nixpkgs {
    inherit system;
    config = {
      allowBroken = true;
    };
  };

This is an antipattern, but it’s the only way to do this for now.

If you use NixOS, home-manager or nix-darwin you can also use their nixpkgs config, which I’d recommend doing instead of the above when possible. This only applies to the nixpkgs whose lib.x you called to make your config, though.

For unfree packages there is nixpkgs-unfree, but that’s just a crutch for the most common use case until there is first party support.

A proper solution is probably years off, nothing has been proposed yet and the current state of flakes will not even be stabilized anytime soon. Maybe the various forks will shake up the situation a bit.

I’d also suggest (if you plan to have the flake consumed by other flakes) that you expose an overlay for said packages, which would allow the configuration of any other nixpkgs instance that uses the overlay to apply properly. (This would also avoid the antipattern mentioned above, as the overlay would be applied against the existing nixpkgs instance.)

1 Like

Eventually I want to upload the Flake to FlakeHub. So I assume, that
antipatterns will not work.

I also had the idea of overlaying the broken package with a working
version - however in this case the version marked as broken is actually
working. How can I overlay a package with itself?

There’s no reason to. The point of publishing your package in an overlay is that the eventual consumer can use import nixpkgs once to allow the broken package, instead of depending on several inputs which all evaluate separate nixpkgses.

That said, if the package is not actually broken, why not fix that upstream? Or at least overrideAttrs to mark it as not broken?

Ok, I try that.

I can build the “broken” package locally in the haskell-updates branch:

nixpkgs$ git checkout haskell-updates && git pull
nixpkgs$ nix-build --no-out-link -A haskellPackages.llvm-tf --arg config ‘{ allowBroken = true; }’

Where can I find out why the package failed at the Nix build servers?

I try searching in:

https://hydra.nixos.org/jobset/nixpkgs/haskell-updates#tabs-jobs

I can find some packages containing “llvm” in the name, but nothing
matches “llvm-tf”. :frowning:

I’m not too familiar with the haskell packaging conventions, but usually packages are marked broken when they don’t work at runtime.

The overrideAttrs trick works at least.

My output section now starts this way:

   outputs = { self, nixpkgs }:
     let
       system = "x86_64-linux";
       pkgs = nixpkgs.legacyPackages.${system};
       overlay = final: prev: {
         llvm-tf = prev.llvm-tf.overrideAttrs(old: {
           meta = old.meta // { broken = false; };
         });
       };
       myHaskellPackages = pkgs.haskellPackages.extend overlay;
     in
     ...
1 Like