When building a haskell project with stack and nix integration that depends on mesa and freeglut, it throws an error.
For example, this package uses libGL, libGLU and freeglut:
$ git clone https://www.github.com/turion/rhine
$ cd rhine/
$ cd rhine-gloss/
$ stack build
$ stack exec rhine-gloss-gears
freeglut (rhine-gloss-gears): ERROR: Internal error <FBConfig with necessary capabilities not found> in function fgOpenWindow
This used to work, until mesa was renamed to libGL.
"x86_64-linux"Linux 4.14.69, NixOS, 19.03pre152634.218ce4de508 (Koi)yesyesnix-env (Nix) 2.1.1"""nixos-19.03pre152634.218ce4de508"/nix/var/nix/profiles/per-user/root/channels/nixosThis occurs on two different systems, both with KDE/plasma
For a MWE, consider the following:
Make sure you have cabal and stack installed. Then follow these commands:
$ mkdir tempgloss
$ cd tempgloss
Create two files with these contents:
$ cat Main.hs
import Graphics.Gloss
main = display (InWindow "Nice Window" (200, 200) (10, 10)) white (Circle 80)
$ cat stack.yaml
resolver: lts-12.10
nix:
enable: true
packages: [libGL libGLU freeglut]
Now execute:
$ cabal init --is-executable -n --main-is=Main.hs -d gloss -d base -l MIT
[...]
$ stack build
[...]
$ stack exec tempgloss
Is this possibly a stack issue?
fwiw, following your (excellent) MWE instructions and invoking cabal2nix . --shell > shell.nix && $(nix-build shell.nix)/bin/tempgloss works.
Looking at the ldd output from both executables, it appears that the stack-built executable is linked against fewer libraries, for instance, this is missing: libglut.so.3 => /nix/store/3s4js4zvhv2cch75lkclhf3xnpa7j0h5-freeglut-3.0.0/lib/libglut.so.3 (0x00007f7d0c817000)
Which seems a bit odd...
Ah! That sounds a lot like stack is doing something wrong! Maybe I'll close here and reopen as a stack issue?
Honestly I know too little about stack to say for sure, I just wanted to give you what information I could get from a small test. But certainly it might be possible that they can help out with this. :)
I'm not sure that stack has anything to do with this issue (more or less all it does is invoking a nix-shell with some options), I don't no the details of OpenGL setup but I think this error is probably related:
$ nix-shell -p glxinfo --run glxinfo
name of display: :0.0
Error: couldn't find RGB GLX visual or fbconfig
I get this on non-NixOS distro (Gentoo in this case), while on NixOs I get a proper output from glxinfo
@qrilka That's related to the impurity of graphics drivers. I don't think it's related to this issue at all.
I won't pretend to understand the libglvnd changes, or that this is the correct approach, but feeding stack packages: [freeglut mesa_noglu.drivers] causes the linking to look correct and exec to work.
That will probably work only if the OS is running on ~mesa~ the free drivers. The point of libGL impurity is that the libGL implementation depends on the currently loaded in-kernel GPU code.
Yeah. I wonder why the libGL approach doesn't seem to link right.
I'd hope this would also work with pkgs.libGL (i.e. the glvnd-provided stubs that try to find the right actual libGL during run-time).
@vcunat It does not, that's what the issue is about. :)
Ah, right :face_with_head_bandage:
@srhb:鈥痀ou're my NixOS heroine now! Thanks!
Note that I still feel this is a wrong solution though. It really should work with LibGL! I just haven't figured out why it doesn't. :)
Yes, it's the best workaround so far though
I have very little understanding of how this workaround works, would anyone mind explaining what the analogous thing would be in a non-stack cabal project?
@masaeedu Since cabal AFAIK hasn't got an explicit nix integration, you would have to add the nix dependencies yourself. They are needed for static or dynamic linking. So without stack, @srhb's approach with this command is the closest: cabal2nix . --shell > shell.nix && $(nix-build shell.nix)/bin/tempgloss
@turboMaCk Thanks. I'm already using cabal2nix (indirectly, via callCabal2Nix invoked by the developPackage thing in nixpkgs). But where would I make the adjustment analogous to the one suggested for the packages field (given that I don't have a stack.yaml file at all)?
you probably wanted to thank to @turion not me @masaeedu.
@masaeedu, two answers.
First of all, cabal2nix will generate a nix expression where your cabal project depends on _other Haskell packages_. If only these dependencies need external libraries, you don't need anything to do, because nix takes care of that already.
If you want to know how to depend on external libraries _in your own project_, just have a look at what cabal2nix does to a package with external library dependencies:
$ cabal unpack OpenGLRaw
Downloading OpenGLRaw-3.3.3.0
Downloaded OpenGLRaw-3.3.3.0
Unpacking to OpenGLRaw-3.3.3.0/
$ cd OpenGLRaw-*
$ cabal2nix .
{ mkDerivation, base, bytestring, containers, fixed, half, libGL
, stdenv, text, transformers
}:
mkDerivation {
pname = "OpenGLRaw";
version = "3.3.3.0";
src = ./.;
libraryHaskellDepends = [
base bytestring containers fixed half text transformers
];
librarySystemDepends = [ libGL ];
homepage = "http://www.haskell.org/haskellwiki/Opengl";
description = "A raw binding for the OpenGL graphics system";
license = stdenv.lib.licenses.bsd3;
}
The relevant list you're looking for is librarySystemDepends.
Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:
For me the cabal approach is now my preferred solution. I don't use stack anymore. If this is still a problem for someone, feel free to reopen and describe what doesn't work for you.
Most helpful comment
I won't pretend to understand the libglvnd changes, or that this is the correct approach, but feeding stack
packages: [freeglut mesa_noglu.drivers]causes the linking to look correct and exec to work.