nixOS + Haskell + stack + OpenGL + freeglut

4

我已经阅读了NixOS, Haskell, opengl : problems with building and running openGL programs以及其他相关问题,但是我无法让一个简单的Haskell gloss项目正常工作(该项目在几个月前曾经工作过)。

使用github项目

请尝试以下步骤:

$ 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

此项目使用堆栈 Nix 集成,参考此答案中的说明。但由于最近 mesa 已更名,因此在 stack.yaml 中相关部分现在应为:
nix:
  enable: true
  packages: [libGL libGLU freeglut]

从头开始

确保您已安装cabal、stack和nix。然后按照以下命令操作:

$ mkdir tempgloss
$ cd tempgloss

请创建两个文件,其内容如下:
$ 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]

现在执行:
$ cabal init --is-executable -n --main-is=Main.hs -d gloss -d base -l MIT
[...]
$ stack build
[...]
$ stack exec tempgloss 

这里出了什么问题?

@BartekBanachewicz,我不写C代码。 - Turion
@BartekBanachewicz,glxgears按预期工作。(安装为软件包,而非从源代码编译) - Turion
你是在使用NixOS还是在其他发行版上使用Nix?如果你在其他发行版上使用Nix,那么你不能真正地运行硬件加速的东西,除非进行一些技巧性的操作。(Nix试图带来自己的图形驱动程序,但它与你的内核和/或X服务器不兼容)。 - typetetris
请在问题本身中包含足够的信息(而不是外部资源),以重现您的问题。 - Daniel Wagner
2
你可以使用http://github.com/guibou/nixGL在非NixOS发行版上运行任何nix OpenGL应用程序。 - Guillaum
显示剩余5条评论
2个回答

1

这个解决方案已经被弃用,建议使用我的另一个解决方案,它使用了nixGL

问题在于stack覆盖了您的nixos安装的LD_LIBRARY_PATH。默认情况下,它包含类似于/run/opengl-driver/lib:/run/opengl-driver-32/lib的内容,并被stack用提供的库路径覆盖。对我来说,它包含:/nix/store/v1d3fmjjqzd1wh84w8dmy4i3hxzgaybf-libGL-1.0.0/lib:/nix/store/y9s4bbn6j54flhpggccrmjd7cv3nkw60-glu-9.0.0/lib:/nix/store/jx7018a4yvd0x79qwp8ad15h5isy1ny3-freeglut-3.0.0/lib:/nix/store/5z8gx1bjw5s0q96n191k0a8caqr4r580-ghc-8.4.3/lib:/nix/store/yypprmw8hrmvwyhhz23w8z25yjvdhnxb-git-2.18.0/lib:/nix/store/iw94llkj05wgaz268mlzvgx8jkbi1ss0-gcc-wrapper-7.3.0/lib:/nix/store/rxaclc3vhxbzgfllv7601i85z854h48a-gmp-6.1.2/lib

我没有一个简单的解决方案,这实际上很痛苦,因为堆栈不会更改二进制文件的rpath,而是覆盖LD_LIBRARY_PATH

我的快速而肮脏的解决方案:

  • a)从堆栈内获取LD_LIBRARY_PATH

stack exec -- env | grep LD_LIBRARY_PATH LD_LIBRARY_PATH=/nix/store/v1d3fmjjqzd1wh84w8dmy4i3hxzgaybf-libGL-1.0.0/lib:/nix/store/y9s4bbn6j54flhpggccrmjd7cv3nkw60-glu-9.0.0/lib:/nix/store/jx7018a4yvd0x79qwp8ad15h5isy1ny3-freeglut-3.0.0/lib:/nix/store/5z8gx1bjw5s0q96n191k0a8caqr4r580-ghc-8.4.3/lib:/nix/store/yypprmw8hrmvwyhhz23w8z25yjvdhnxb-git-2.18.0/lib:/nix/store/iw94llkj05wgaz268mlzvgx8jkbi1ss0-gcc-wrapper-7.3.0/lib:/nix/store/rxaclc3vhxbzgfllv7601i85z854h48a-gmp-6.1.2/lib

  • b) 获取当前的LD_LIBRARY_PATH

$ echo $LD_LIBRARY_PATH /run/opengl-driver/lib:/run/opengl-driver-32/lib

  • c) 获取可执行文件的真实路径

$ stack exec --no-nix-pure which rhine-gloss-gears /tmp/rhine/rhine-gloss/.stack-work/install/x86_64-linux-nix/nightly-2018-09-26/8.4.3/bin/rhine-gloss-gears

在这里,--no-nix-pure 允许 stack 查看当前环境中应该可用的 which

d) 使用以下方式将所有内容连接起来:

LD_LIBRARY_PATH=yourLD_LIBRARY_PATH:theOneFromStack the_executable_path

例如:

LD_LIBRARY_PATH=/run/opengl-driver/lib:/run/opengl-driver-32/lib:/nix/store/v1d3fmjjqzd1wh84w8dmy4i3hxzgaybf-libGL-1.0.0/lib:/nix/store/y9s4bbn6j54flhpggccrmjd7cv3nkw60-glu-9.0.0/lib:/nix/store/jx7018a4yvd0x79qwp8ad15h5isy1ny3-freeglut-3.0.0/lib:/nix/store/5z8gx1bjw5s0q96n191k0a8caqr4r580-ghc-8.4.3/lib:/nix/store/yypprmw8hrmvwyhhz23w8z25yjvdhnxb-git-2.18.0/lib:/nix/store/iw94llkj05wgaz268mlzvgx8jkbi1ss0-gcc-wrapper-7.3.0/lib:/nix/store/rxaclc3vhxbzgfllv7601i85z854h48a-gmp-6.1.2/lib /tmp/rhine/rhine-gloss/.stack-work/install/x86_64-linux-nix/nightly-2018-09-26/8.4.3/bin/rhine-gloss-gears


0

我刚刚推出了一个新版本的nixGL: http://github.com/guibou/nixgl,它允许您以以下方式运行程序:

stack exec --no-nix-pure nixGLIntel rhine-gloss-gears

(如果需要,将nixGLIntel替换为nixGLNvidianixGLNvidiaBumblebee)。


为什么nixGL不是nixpkgs的一部分?或者说,为什么nixGL的修复没有被包含在nixpkgs中? - Turion
我应该将它作为一个nixpkgs软件包提交。然而,要解决所有问题并不容易,因为这取决于硬件和应用程序构建所使用的nixpkgs版本。例如,如果你有上周的nixpkgs克隆和一个Nvidia驱动程序,那么你需要一个不同的nixGL版本来构建,而我则使用了更近期的nixpkgs克隆和Intel驱动程序。 - Guillaum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接