Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-haskell dependencies #7

Closed
CMCDragonkai opened this issue Oct 6, 2018 · 6 comments
Closed

Non-haskell dependencies #7

CMCDragonkai opened this issue Oct 6, 2018 · 6 comments
Assignees

Comments

@CMCDragonkai
Copy link
Member

The proper way to bring in non-haskell dependencies when using cabal2nix is to again use package.yaml. This means we don't add dependencies directly into the default.nix.

For example to bring in clang. We need to add it to the build-tools or system-build-tools in the package.yaml.

Note that system-build-tools is what it should be at the latest version of hpack. On older versions it's build-tools. The change was added here: sol/hpack@c1d4ba7 This can be added like:

build-tools:
- clang
system-build-tools:
- clang

Then you update the cabal.nix and also the cabal file using cabal2nix and hpack. And then you should see clang appear in both the buildInputs of default.nix and shell.nix.

@CMCDragonkai
Copy link
Member Author

CMCDragonkai commented Mar 3, 2019

This gist is important as well: https://gist.github.com/CMCDragonkai/8b5cc041cea4a7e45a9cb89f849eaaf8

Especially if you're doing separate compilation of C files using just gcc inside the nix-shell.

@CMCDragonkai
Copy link
Member Author

CMCDragonkai commented Apr 7, 2019

For non-haskell dependencies that are libraries. Apparently the proper way is to put down in package.yaml:

extra-libraries:
  - libmnl
  - libnftnl
  - linuxHeaders

This will put the dependency into librarySystemDepends which mean it will be available in both nix-build and nix-shell.

It also automatically makes cabal configure try to find these libraries. However I have not figured out how to resolve this since cabal then fails to compile. I'm guessing I'm missing something else that requires to refer to these libraries.

@CMCDragonkai
Copy link
Member Author

CMCDragonkai commented Apr 7, 2019

Ok I found the problem: NixOS/cabal2nix#413

Basically Cabal/Hpack expects that extra-libraries refers to actual C libraries that will be linked.

So if you state extra-libraries: libmnl, it will actually try to link to -llibmnl. However this is problematic, because often the name of the library to be linked is something different like -lmnl. So -llibmnl will result in an error.

But if we change to -lmnl, the problem is that cabal2nix will generate a cabal.nix that wants mnl as a package attribute. And in nixpkgs, the package is called libmnl.

So what does cabal2nix do? It maintains a mapping of common library names to the package names in Nixpkgs.

This means we have to request them to maintain these mappings everytime we meet a dependency that isn't mapped already. However... as a stop-gap, we can fill in these mappings ourselves when we load the cabal.nix. So we use extra-libraries: mnl and then when importing the cabal.nix, we have to put mnl = pkgs.libmnl;.

drv = haskellPackages.callPackage (import ./cabal.nix) { mnl = libmnl; };

BTW, Nix puts these C dependencies in NIX_CFLAGS_COMPILE. Not sure what else is here.

However this doesn't solve the problem for things like linuxHeaders which are just include files with no corresponding thing to link to, since we just may need it.

@CMCDragonkai
Copy link
Member Author

Do note if using the callPackage pattern, you need to make sure to overwrite the parameter in default.nix to be a top level package, if there are name conflicts between the top level package name and another haskell package name.

This was referenced Aug 1, 2020
@CMCDragonkai
Copy link
Member Author

The #24 takes over from #23. #23 shows an example of how to use CPP to put compile time macros into the Haskell program. So I'm going to close that one, but it is still useful reference for everybody in case they need a compile time macro. @DrFacepalm @nzhang-zh @Zachaccino

@CMCDragonkai
Copy link
Member Author

Solved this for Haskell Demo.

But in general there is 2 solutions:

A. You consider project to be a Haskell dependency (something distributed on hackage)
B. You consider the project to be a standard package (something that is on Nix)

In the A side, you must keep default.nix a callpackage derivation.

In the B side, you can dispense with that requirement, make default.nix something that can use stdenv.mkDerivation, and then you are using a Haskell project within it.

B may be relevant if there's a lot of non-Haskell stuff, a multi-language and many dependency project.

If you are doing B, you will end up using the haskellPackages.callPackage which will be whatever haskell compiler is considered the "default" compiler for that package set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants