Customizing Haskell network library

Hi,

I build my Haskell project with nix and I wrote a patch for “network” library. The library has cabal file, but there autotools are also involved and callCabal2Nix fails with:

Configuring network-3.1.1.1...
Warning: The 'build-type' is 'Configure' but there is no 'configure' script.
You probably need to run 'autoreconf -i' to generate it.
....
No uhc found
Setup: configure script not found.
builder for '/nix/store/z0w45kxv3w9p2mzmjihqyfqi91gh7aci-network-3.1.1.1.drv' failed with exit code 1
cannot build derivation '/nix/store/nkpjmg5f2fy25vjh597251wgm17g88dq-ghc-8.6.5-with-packages.drv': 1 dependencies couldn't be built
error: build of '/nix/store/nkpjmg5f2fy25vjh597251wgm17g88dq-ghc-8.6.5-with-packages.drv' failed

nixpkgs root sha is 795ef4f46f66c9ca6ab43929135f7ebb6170711b

I tried to plug in autoreconfHook but build gets problem with missing make file then:

derivation for network is just borrowed from nixpkgs repo. there is no sign of autotools at all.
There is no template for generating make file.

    network = pkgs.callPackage
    ({

     }:
     pkgs.stdenv.mkDerivation {
        pname = "network";
        version = "3.1.1.9";
        src = pkgs.fetchFromGitHub {
          owner = "yaitskov";
          repo = "network";
          rev = "40bb40bc185669fb1b1ec6b254bc185fc2a8221d";
          sha256 = "02mnhnn8my6qxl1b89ph954js3p6w761hdm3d52gaapja7w997fm";
        };

        nativeBuildInputs = [ pkgs.autoreconfHook pkgs.autoconf  pkgs.automake];

       libraryHaskellDepends = [ (pkgs.haskellPackages.base) (pkgs.haskellPackages.bytestring) (pkgs.haskellPackages.deepseq) ];
       testHaskellDepends = [ (pkgs.haskellPackages.base) 
         (pkgs.haskellPackages.bytestring) (pkgs.haskellPackages.directory) (pkgs.haskellPackages.hspec) (pkgs.haskellPackages.HUnit) ];
       
       testToolDepends = [ (pkgs.haskellPackages.hspec-discover) ];
       description = "Low-level networking interface"; 
     }) {};
checking for struct msghdr.msg_control... yes
checking for struct msghdr.msg_accrights... no
checking for struct sockaddr.sa_len... no
configure: creating ./network.buildinfo
configure: creating ./config.status
config.status: creating include/HsNetworkConfig.h
building
no Makefile, doing nothing
installing
install flags: SHELL=/nix/store/f7jzmxq9bpbxsg69cszx56mw14n115n5-bash-4.4-p23/bin/bash install
make: *** No rule to make target 'install'.  Stop.
builder for '/nix/store/b4psl3p87j4hmjrshsxssfg9pp6dkpx1-network-3.1.1.9.drv' failed with exit code 2

I found that following overlay is doing the job:

hfinal: hprev:

  rec {
    network = (hfinal.callCabal2nix "network" sources.network {}).overrideAttrs (attrs: {
      configurePhase = ''
        autoreconf -i
        ${attrs.configurePhase}
      '';
      buildInputs = [ pkgs.autoconf pkgs.haskellPackages.HUnit pkgs.haskellPackages.hspec ];
    });
  }

I’d recommend doing something like this (although I haven’t tested it):

hfinal: hprev: with pkgs.haskell.lib.compose; {
  network = overrideCabal (drv: {
    nativeBuildInputs = drv.nativeBuildInputs or [] ++ [
      pkgs.buildPackages.autoreconfHook
    ];
  }) (hfinal.callCabal2nix "network" sources.network {});
}

Reasoning being:

  • Use haskell.lib.compose.overrideCabal over overrideAttrs: overrideCabal is to haskellPackages.mkDerivation what overrideAttrs is to stdenv.mkDerivation. With haskellPackages.mkDerivation being an abstraction over stdenv.mkDerivation, you risk undoing some of the extra logic haskellPackages.mkDerivation adds to the build instruction and subtly breaking the build.
  • Use autoreconfHook which is a setup hook provided by nixpkgs that regenerates autoconf files – no need to reinvent anything here. We use buildPackages since this needs to be executed while building, so in the event of cross compilation it needs to run on the build platform (buildPackages needs to be specified manually, since we’re not getting autoreconfHook via callPackage).
  • We don’t need to specify HUnit etc. manually, since callCabal2nix will detect it. In your overlay you caused the need for this by overwriting buildInputs instead of extending it (e.g. using attrs.buildInputs or [] ++ [ pkgs.autoconf ]).
1 Like