matil019 / haskell-libfuse3

A Haskell binding for libfuse-3.x
https://hackage.haskell.org/package/libfuse3
MIT License
5 stars 1 forks source link

not working under nix #10

Open zoranbosnjak opened 3 years ago

zoranbosnjak commented 3 years ago

This package is marked broken in nixpkgs. I have tried to troubleshoot the problem, but I am not sure what to do. It looks like the package is not properly integrated with nix. There is an extra step required during build (as explained in README), that is autoreconf -fiv. Not sure, but maybe this required step is not performed during automatic nix build process.

Pinging @peti for an idea, what to do in this case.

So, this works:

cd haskell-libfuse3
cabal2nix . --shell > shell.nix
nix-shell
autoreconf -fiv
cabal build

But this does not work:

cd haskell-libfuse3
cabal2nix . --shell > shell.nix
nix-build shell.nix

It fails with the following error:

error: In file included from /nix/store/swa9qg5awjlnsk75011dfkq76lk895ql-fuse-3.10.0/include/fuse3/fuse.h:19,
                 from Internal.hsc:66:
/nix/store/swa9qg5awjlnsk75011dfkq76lk895ql-fuse-3.10.0/include/fuse3/fuse_common.h:838:4: error: #error only API version 30 or greater is supported
  838 | #  error only API version 30 or greater is supported
      |    ^~~~~
In file included from Internal.hsc:67:
/nix/store/swa9qg5awjlnsk75011dfkq76lk895ql-fuse-3.10.0/include/fuse3/fuse_lowlevel.h:22:2: error: #error FUSE_USE_VERSION not defined
   22 | #error FUSE_USE_VERSION not defined
      |  ^~~~~

builder for '/nix/store/1abk98nxacd3l17pk2f462fz8d3zcqsk-libfuse3-0.1.2.0.drv' failed with exit code 1
error: build of '/nix/store/1abk98nxacd3l17pk2f462fz8d3zcqsk-libfuse3-0.1.2.0.drv' failed
matil019 commented 3 years ago

Nice to meet you!

Thank you for your report and I'm sorry for your trouble. I was not aware of the nixpkgs failure out there.

The error message indicates that the C macro FUSE_USE_VERSION is not defined to a certain value. libfuse (the C library) requires it. In this package, it is defined with cc-options in libfuse3.buildinfo, which is generated from the template libfuse3.buildinfo.in by the command autoreconf -fiv ./configure.

So, as you have confirmed, you have to run autoreconf -fiv (v is optional, by the way). Cabal runs ./configure automatically to generate these files. I'm afraid I'm not familiar with nix, so I don't know how to make it work with nixpkgs.

FYI, the value of FUSE_USE_VERSION we use is 31, defined in configure.ac#L12.

EDIT: I confused ./configure with autoreconf.

peti commented 3 years ago

The Cabal file you distribute advertises the build of this package as Simple even though it's clearly not. The proper build type is Configure.

matil019 commented 3 years ago

It's specified as Configure. Am I missing something?

peti commented 3 years ago

Oh, okay. Sorry, I was confused by the message that said running autoreconf -i would fix the build, but in fact that's not the problem the Nix build was having.

matil019 commented 3 years ago

I was wrong 🤦 I meant ./configure, not autoreconf -i. I just confirmed that I can build from a fresh sdist with cabal v2-build without manual autoreconf -fiv. Cabal runs ./configure automatically as expected. Then perhaps the cause is libfuse, the C library this package binds to, being missing? This is just a speculation because I can't find the error log of that Nix build.

zoranbosnjak commented 3 years ago

It looks like libfuse3.buildinfo.in is not picked by the build process. I could make it compile (via nix) if I hardcode the version in the cabal file (at the end of the library section) like this:

  cc-options:          "-DFUSE_USE_VERSION=31"

This works, however I don't like the version number being duplicated.

Another approach I was trying was to change the Setup.hs file, like this:

-main = defaultMain
+main = defaultMainWithHooks autoconfUserHooks

but then it complains with the message:

Setup: configure script not found.

... which I could fix by storing configure file to the repository. I don't think it's a good idea either.

@peti, I am kindly ask you for your advice again. How to fix the nix-build problem properly in this case?

The tests still fail however, so the nix build is not successfull unless I disable the tests. But this is unrelated problem.

ghost commented 2 years ago

@zoranbosnjak

Hello! I'm not a nix user myself but I'm interested in trying to figure this out too (as the error is identical to my stack building failure issue).

I decided to install nix a few hours ago and I came to a similar obstacle as well.

However, I found there's a Nix's feature that allows you to run autoreconf at build time.

Anyways, I managed to build the package from the source using nix-build shell.nix by replacing these two file contents below.

Setup.hs

import Distribution.Simple
main = defaultMainWithHooks autoconfUserHooks

shell.nix

{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false }:

let

  inherit (nixpkgs) pkgs;

  f = { autoreconfHook, pkg-config, mkDerivation, base, bytestring, clock
      , criterion, directory, filepath, fuse3, hspec, lib, process, resourcet
      , temporary, time, unix
      }:
      mkDerivation {
        pname = "libfuse3";
        version = "0.1.2.0";
        src = ./.;
        isLibrary = true;
        isExecutable = true;
        libraryHaskellDepends = [
          base bytestring clock resourcet time unix
        ];
        libraryPkgconfigDepends = [ fuse3 ];
        testHaskellDepends = [
          base bytestring directory filepath hspec process temporary unix
        ];
        benchmarkHaskellDepends = [ base bytestring criterion unix ];
        description = "A Haskell binding for libfuse-3.x";
        license = lib.licenses.mit;
      };

  haskellPackages = if compiler == "default"
                       then pkgs.haskellPackages
                       else pkgs.haskell.packages.${compiler};

  variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;

  drv = variant (haskellPackages.callPackage f {});
in

  #if pkgs.lib.inNixShell then drv.env else drv
  drv.overrideAttrs (attrs: {
    nativeBuildInputs = [ pkgs.autoreconfHook pkgs.pkg-config ];
  })

The test failure still persists however as mentioned, and I'm not sure if this workaround is an ideal solution to the problem, but it's there if anyone else wanna try building it.