NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18k stars 14.01k forks source link

Why is there random_1_2_0 in hackage-packages.nix? #91733

Closed idontgetoutmuch closed 4 years ago

idontgetoutmuch commented 4 years ago

Describe the bug I want to use the latest version of random but it seems I have to use random_1_2_0. This causes nix to rebuild ghc.

Expected behavior I'd like to be able to use the latest version of random without having to do anything special i.e. random should point at random-1.2 in hackage and ghc should not get rebuilt.

Notify maintainers

@peti

sternenseemann commented 4 years ago

When generating the hackage-packages.nix hackage2nix uses a configuration which has certain default versions for packages set (based on stackage LTS haskell). This is intended to provide a package set with package versions that are overall compatible with each other. Unlike stackage, hackage-package.nix also contains the latest version of a package if an older version is set, in your case random_1_2_0. This is the entry for random from LTS haskell.

idontgetoutmuch commented 4 years ago

@sternenseemann thanks - so how do I tell nix I want to use random_1_2_0 without getting into to some sort of dependency hell?

If I try

let
  myHaskellPackageOverlay = self: super: {
    myHaskellPackages = super.haskellPackages.override {
    overrides = hself: hsuper: rec {
    random-fu     = super.haskell.lib.disableLibraryProfiling (hself.callPackage  ./random-fu { });
    random-source = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./random-source { random = myRandom; });
    rvar          = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./rvar { });

    myRandom =
      let newRandomSrc = builtins.fetchTarball {
        url = "https://hackage.haskell.org/package/random-1.2.0/random-1.2.0.tar.gz";
        sha256 = "06s3mmqbsfwv09j2s45qnd66nrxfp9280gnl9ng8yh128pfr7bjh";
      };
    in
      super.haskell.lib.dontCheck (
        hself.callCabal2nix "random" newRandomSrc {
        }
      );
    };
  };
};

  nixpkgs = import <nixpkgs> { overlays = [ myHaskellPackageOverlay ]; };

in

nixpkgs.myHaskellPackages.callPackage ./tests/speed {
  random-source = nixpkgs.myHaskellPackages.random-source;
  random-fu     = nixpkgs.myHaskellPackages.random-fu;
}

then I get

Setup: Encountered missing or private dependencies:
splitmix ==0.1.*

builder for '/nix/store/wwi71jianla2znbgb0pn2ph3dm6ib35l-random-1.2.0.drv' failed with exit code 1
cannot build derivation '/nix/store/k0b5lysfqiqdpwsmmr0684jkl6skx8gk-random-source-0.3.0.8.drv': 1 dependencies couldn't be built
cannot build derivation '/nix/store/zlzw0nmfzq3h9k5dzb5k9b09c0vczg6d-speed-tests-0.0.0.1.drv': 1 dependencies couldn't be built
error: build of '/nix/store/zlzw0nmfzq3h9k5dzb5k9b09c0vczg6d-speed-tests-0.0.0.1.drv' failed

Ok so I can get the version of splitmix I need

let
  myHaskellPackageOverlay = self: super: {
    myHaskellPackages = super.haskellPackages.override {
    overrides = hself: hsuper: rec {
    random-fu     = super.haskell.lib.disableLibraryProfiling (hself.callPackage  ./random-fu { }); # { random-shuffle = myRandomShuffle; });
    random-source = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./random-source { random = myRandom; }); # { random = myRandom; mersenne-random-pure64 = myMersenne; });
    rvar          = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./rvar { });

    myRandom =
      let newRandomSrc = builtins.fetchTarball {
        url = "https://hackage.haskell.org/package/random-1.2.0/random-1.2.0.tar.gz";
        sha256 = "06s3mmqbsfwv09j2s45qnd66nrxfp9280gnl9ng8yh128pfr7bjh";
      };
    in
      super.haskell.lib.dontCheck (
        hself.callCabal2nix "random" newRandomSrc {
          splitmix = mySplitMix;
        }
      );

      mySplitMix =
        let newSplitMixSrc = builtins.fetchTarball {
          url = "https://hackage.haskell.org/package/splitmix-0.1/splitmix-0.1.tar.gz";
          sha256 = "1k7l07h2w4fhjdqiqvw48if0irx0ngv6niach265j7lbfxsm8qql";
        };
      in
        super.haskell.lib.dontCheck (hself.callCabal2nix "splitmix" newSplitMixSrc {});

    };
  };
};

  nixpkgs = import <nixpkgs> { overlays = [ myHaskellPackageOverlay ]; };

in

nixpkgs.myHaskellPackages.callPackage ./tests/speed {
  random-source = nixpkgs.myHaskellPackages.random-source;
  random-fu     = nixpkgs.myHaskellPackages.random-fu;
}

But now I get

Warning:
    This package indirectly depends on multiple versions of the same package. This is very likely to cause a compile failure.
      package mersenne-random-pure64 (mersenne-random-pure64-0.2.2.0-2yA9x39Gwr68e1qwz3kOtN) requires random-1.1-CUqV1zxrwrE4K5XCdTZSYy
      package random-source (random-source-0.3.0.9) requires random-1.2.0-5ahspqQGuId4hDT8TJF2rs

*** abort because of serious configure-time warning from Cabal

Ok we can add in mersenne-random-pure64

let
  myHaskellPackageOverlay = self: super: {
    myHaskellPackages = super.haskellPackages.override {
    overrides = hself: hsuper: rec {
    random-fu     = super.haskell.lib.disableLibraryProfiling (hself.callPackage  ./random-fu { }); # { random-shuffle = myRandomShuffle; });
    random-source = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./random-source { random = myRandom; mersenne-random-pure64 = myMersenne; });
    rvar          = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./rvar { });

    myRandom =
      let newRandomSrc = builtins.fetchTarball {
        url = "https://hackage.haskell.org/package/random-1.2.0/random-1.2.0.tar.gz";
        sha256 = "06s3mmqbsfwv09j2s45qnd66nrxfp9280gnl9ng8yh128pfr7bjh";
      };
    in
      super.haskell.lib.dontCheck (
        hself.callCabal2nix "random" newRandomSrc {
          splitmix = mySplitMix;
        }
      );

      mySplitMix =
        let newSplitMixSrc = builtins.fetchTarball {
          url = "https://hackage.haskell.org/package/splitmix-0.1/splitmix-0.1.tar.gz";
          sha256 = "1k7l07h2w4fhjdqiqvw48if0irx0ngv6niach265j7lbfxsm8qql";
        };
      in
        super.haskell.lib.dontCheck (hself.callCabal2nix "splitmix" newSplitMixSrc {});

      myMersenne =
        let newMersenneSrc = builtins.fetchTarball {
          url = "https://hackage.haskell.org/package/mersenne-random-pure64-0.2.2.0/mersenne-random-pure64-0.2.2.0.tar.gz";
          sha256 = "12r0wp35lmxn3k17pz7jjpljcskhj3yfkf8zd6vkx81fg1k2lfhk";
        };
      in
        super.haskell.lib.dontCheck (hself.callCabal2nix "mersenne-random-pure64" newMersenneSrc {random = myRandom; });
    };
  };
};

  nixpkgs = import <nixpkgs> { overlays = [ myHaskellPackageOverlay ]; };

in

nixpkgs.myHaskellPackages.callPackage ./tests/speed {
  random-source = nixpkgs.myHaskellPackages.random-source;
  random-fu     = nixpkgs.myHaskellPackages.random-fu;
  mersenne-random-pure64 = nixpkgs.myHaskellPackages.myMersenne;
}

But now I get

Warning:
    This package indirectly depends on multiple versions of the same package. This is very likely to cause a compile failure.
      package random-shuffle (random-shuffle-0.0.4-DNqQdCUiiVF3hilxbMkny0) requires random-1.1-CUqV1zxrwrE4K5XCdTZSYy
      package MonadRandom (MonadRandom-0.5.1.2-CJYGjs2grhnIGVYLkfUk5Q) requires random-1.1-CUqV1zxrwrE4K5XCdTZSYy
      package random-source (random-source-0.3.0.9-JAqrGdQo2pwIR9RGPY6gv1) requires random-1.2.0-5ahspqQGuId4hDT8TJF2rs
      package random-fu (random-fu-0.2.7.5) requires random-1.2.0-5ahspqQGuId4hDT8TJF2rs
      package mersenne-random-pure64 (mersenne-random-pure64-0.2.2.0-LEmFT5aHB7I6zXNuf7qrHL) requires random-1.2.0-5ahspqQGuId4hDT8TJF2rs

I can keep going but I am not sure when this will end.

sternenseemann commented 4 years ago

Yeah, this is the kind of problem setting specific versions that work together tries to avoid. What you can try is to override the version of random globally. That should work if all packages you depend on (indirectly) work with that version (if not I'm actually not sure if that is even theoretically resovable with haskell):

let mhp = pkgs.haskellPackages.override {
      overrides = self: super: {
        random = super.random_1_2_0;
      };
  };
in mhp.callPackage ./bla.nix { }
idontgetoutmuch commented 4 years ago

Sadly with

let
  myHaskellPackageOverlay = self: super: {
    myHaskellPackages = super.haskellPackages.override {
    overrides = hself: hsuper: rec {
        random = hsuper.random_1_2_0;
        mkDerivation = args: hsuper.mkDerivation (args // {
          doCheck = false;
          doHaddock = false;
        });

    random-fu     = super.haskell.lib.disableLibraryProfiling (hself.callPackage  ./random-fu { });
    random-source = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./random-source { });
    rvar          = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./rvar { });

    };
  };
};

  nixpkgs = import <nixpkgs> { overlays = [ myHaskellPackageOverlay ]; };

in

nixpkgs.myHaskellPackages.callPackage ./tests/speed {
  random-source = nixpkgs.myHaskellPackages.random-source;
  random-fu     = nixpkgs.myHaskellPackages.random-fu;
}

I get

error: infinite recursion encountered, at undefined position
(use '--show-trace' to show detailed location information)
bqv commented 4 years ago

%s/hself.call/hsuper.call/

idontgetoutmuch commented 4 years ago

Hmmm - I thought I had tried that but in any event this worked

let
  myHaskellPackageOverlay = self: super: {
    myHaskellPackages = super.haskellPackages.override {
    overrides = hself: hsuper: rec {
        random = hsuper.random_1_2_0;
        mkDerivation = args: hsuper.mkDerivation (args // {
          doCheck = false;
          doHaddock = false;
        });

    random-fu     = super.haskell.lib.disableLibraryProfiling (hself.callPackage  ./random-fu { });
    random-source = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./random-source { random = hsuper.random_1_2_0; });
    rvar          = super.haskell.lib.disableLibraryProfiling (hself.callPackage ./rvar { });
    splitmix      = hsuper.splitmix_0_1;
    MonadRandom   = hsuper.MonadRandom_0_5_2;
    };
  };
};

  nixpkgs = import <nixpkgs> { overlays = [ myHaskellPackageOverlay ]; };

in

nixpkgs.myHaskellPackages.callPackage ./tests/speed {
  random-source = nixpkgs.myHaskellPackages.random-source;
  random-fu     = nixpkgs.myHaskellPackages.random-fu;
}